GithubHelp home page GithubHelp logo

k6-plugin's Introduction

xk6-nebula

This is a k6 extension using the xk6 system.

Used to test NebulaGraph.

Dependency

  • k6 v0.33.0
  • xk6 v0.4.1
  • Golang 1.16+

Version match

k6-plugin now support NebulaGraph above v3.0.0.

Build

To build a k6 binary with this extension, first ensure you have the prerequisites:

Then:

  1. Download xk6:
go install go.k6.io/xk6/cmd/[email protected]
  1. Build the binary:
# build with the latest version.
make 

# build with local source code
make build-dev

# or build with specified version
xk6 build --with github.com/vesoft-inc/k6-plugin@{version}
# e.g. build v0.0.8
xk6 build --with github.com/vesoft-inc/[email protected]
# e.g. build master
xk6 build --with github.com/vesoft-inc/k6-plugin@master

Example

import nebulaPool from 'k6/x/nebulagraph';
import { check } from 'k6';
import { Trend } from 'k6/metrics';

var latencyTrend = new Trend('latency', true);
var responseTrend = new Trend('responseTime', true);

// option configuration, please refer more details in this doc.
var graph_option = {
 address: "192.168.8.6:10010",
 space: "sf1",
 csv_path: "person.csv",
 csv_delimiter: "|",
 csv_with_header: true
};

nebulaPool.setOption(graph_option);
var pool = nebulaPool.init();
// initial session for every vu
var session = pool.getSession()

String.prototype.format = function () {
  var formatted = this;
  var data = arguments[0]

  formatted = formatted.replace(/\{(\d+)\}/g, function (match, key) {
    return data[key]
  })
  return formatted
};

export default function (data) {
  // get csv data from csv file
  let d = session.getData()
  // {0} means the first column data in the csv file
  let ngql = 'go 2 steps from {0} over KNOWS'.format(d)
  let response = session.execute(ngql)
  check(response, {
    "IsSucceed": (r) => r.isSucceed() === true
  });
  // add trend
latencyTrend.add(response.getLatency()/1000);
responseTrend.add(response.getResponseTime()/1000);
};

export function teardown() {
  pool.close()
}

Result

# -u means how many virtual users, i.e the concurrent users
# -d means the duration that test running, e.g. `3s` means 3 seconds, `5m` means 5 minutes.
>./k6 run nebula-test.js -u 3 -d 3s                                                      


          /\      |‾‾| /‾‾/   /‾‾/
     /\  /  \     |  |/  /   /  /
    /  \/    \    |     (   /   ‾‾\
   /          \   |  |\  \ |  (‾)  |
  / __________ \  |__| \__\ \_____/ .io

testing option: {"pool_policy":"connection","output":"output.csv","output_channel_size":10000,"address":"192.168.8.6:10010","timeout_us":0,"idletime_us":0,"max_size":400,"min_size":0,"username":"root","password":"nebula","space":"sf1","csv_path":"person.csv","csv_delimiter":"|","csv_with_header":true,"csv_channel_size":10000,"csv_data_limit":500000,"retry_times":0,"retry_interval_us":0,"retry_timeout_us":0,"ssl_ca_pem_path":"","ssl_client_pem_path":"","ssl_client_key_path":""}
  execution: local
     script: nebula-test.js
     output: engine

  scenarios: (100.00%) 1 scenario, 3 max VUs, 33s max duration (incl. graceful stop):
           * default: 3 looping VUs for 3s (gracefulStop: 30s)


     ✓ IsSucceed

     █ teardown

     checks...............: 100.00% ✓ 3529        ✗ 0
     data_received........: 0 B     0 B/s
     data_sent............: 0 B     0 B/s
     iteration_duration...: avg=2.54ms min=129.28µs med=1.78ms max=34.99ms p(90)=5.34ms p(95)=6.79ms
     iterations...........: 3529    1174.135729/s
     latency..............: avg=1.98ms min=439µs    med=1.42ms max=27.77ms p(90)=4.11ms p(95)=5.12ms
     responseTime.........: avg=2.48ms min=495µs    med=1.72ms max=34.93ms p(90)=5.27ms p(95)=6.71ms
     vus..................: 3       min=3         max=3
     vus_max..............: 3       min=3         max=3


running (03.0s), 0/3 VUs, 3529 complete and 0 interrupted iterations
default ✓ [======================================] 3 VUs  3s
  • checks, one check per iteration, verify isSucceed by default.
  • data_received and data_sent, used by HTTP requests, useless for NebulaGraph.
  • iteration_duration, time consuming for every iteration.
  • latency, time consuming in NebulaGraph server.
  • responseTime, time consuming in client.
  • vus, concurrent virtual users.

In general

iteration_duration = responseTime + (time consuming for read data from csv)

responseTime = latency + (time consuming for network) + (client decode)

The output.csv saves data as below:

>head output.csv                                                                          

timestamp,nGQL,latency,responseTime,isSucceed,rows,firstRecord,errorMsg
1689576531,go 2 steps from 4194 over KNOWS yield dst(edge),4260,5151,true,1581,32985348838665,
1689576531,go 2 steps from 8333 over KNOWS yield dst(edge),4772,5772,true,2063,32985348833536,
1689576531,go 2 steps from 1129 over KNOWS yield dst(edge),5471,6441,true,1945,19791209302529,
1689576531,go 2 steps from 8698 over KNOWS yield dst(edge),3453,4143,true,1530,28587302322946,
1689576531,go 2 steps from 8853 over KNOWS yield dst(edge),4361,5368,true,2516,28587302324992,
1689576531,go 2 steps from 2199023256684 over KNOWS yield dst(edge),2259,2762,true,967,32985348833796,
1689576531,go 2 steps from 2199023262818 over KNOWS yield dst(edge),638,732,true,0,,
1689576531,go 2 steps from 10027 over KNOWS yield dst(edge),5182,6701,true,3288,30786325580290,
1689576531,go 2 steps from 2199023261211 over KNOWS yield dst(edge),2131,2498,true,739,32985348833794,

Plugin Option

Pool options


Key Type Default Description
pool_policy string connection 'connection' or 'session', using which pool to test
address string NebulaGraph address, e.g. '192.168.8.6:9669,192.168.8.7:9669'
timeout_us int 0 client connetion timeout, 0 means no timeout
idletime_us int 0 client connection idle timeout, 0 means no timeout
max_size int 400 max client connections in pool
min_size int 0 min client connections in pool
username string root NebulaGraph username
password string nebula NebulaGraph password
space string NebulaGraph space

Output options


Key Type Default Description
output string output file path
output_channel_size int 10000 size of output channel

CSV options


Key Type Default Description
csv_path string csv file path
csv_delimiter string , delimiter of csv file
csv_with_header bool false if ture, would ignore the first record
csv_channel_size int 10000 size of csv reader channel
csv_data_limit int 500000 would load [x] rows in memory, and then send to channel in loop

Retry options


Key Type Default Description
retry_times int 0 max retry times
retry_interval_us int 0 interval duration for next retry
retry_timeout_us int 0 retry timeout

SSL options


Key Type Default Description
ssl_ca_pem_path string if it is not blank, would use SSL connection. ca pem path
ssl_client_pem_path string client pem path
ssl_client_key_path string client key path

Batch insert

It can also use k6 for batch insert testing.

# create schema
cd example
nebula-console -addr 192.168.8.61 -port 9669 -u root -p nebula -f schema.ngql

# run testing
../k6 run nebula-test-insert.js -vu 10 -d 30s 

# by default, the batch size is 100, you can change it in `nebula-test-insert.js`
sed -i 's/let batchSize.*/let batchSize = 300/g' nebula-test-insert.js
../k6 run nebula-test-insert.js -vu 10 -d 30s 

Test stages

It can specify the target number of VUs by k6 stages in options. e.g.

import nebulaPool from 'k6/x/nebulagraph';
import { check } from 'k6';
import { Trend } from 'k6/metrics';
import { sleep } from 'k6';

export let options = {
  stages: [
    { duration: '3m', target: 10 },
    { duration: '5m', target: 10 },
    { duration: '10m', target: 35 },
    { duration: '3m', target: 0 },
  ],
};

var latencyTrend = new Trend('latency');
var responseTrend = new Trend('responseTime');

The options means ramping up from 1 to 10 vus in 3 minutes, then running test with 10 vus in 5 minutes.

And then ramping up from 10 vus to 35 vus in 10 minutes.

Then ramping down from 35 vu3 to 0 in 3 minutes.

It is much useful when we test multiple scenarios.

please refer to k6 options

k6-plugin's People

Contributors

aiee avatar darionyaphet avatar fangjinhe avatar harrischu avatar jievince avatar nicole00 avatar shinji-ikarig avatar sophie-xie avatar wey-gu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

k6-plugin's Issues

could not initialize x.js: could not load JS test

Please check the FAQ documentation before raising an issue

python3 run.py stress run -a xxxx -scenario go.Bar --args='-u 100 -d 3s -o csv=test.csv' -s sf1

Describe the bug (required)

run command as below:
scripts/k6 run output/20230817181250/Bar.js -u 100 -d 3s -o csv=test.csv --summary-trend-stats "min,avg,med,max,p(90),p(95),p(99)" --summary-export output/20230817181250/result_100_Bar.json

      /\      |‾‾| /‾‾/   /‾‾/
 /\  /  \     |  |/  /   /  /
/  \/    \    |     (   /   ‾‾\

/ \ | |\ \ | (‾) |
/ __________ \ |__| _\ ____/ .io

ERRO[0000] panic: runtime error: invalid memory address or nil pointer dereference
goroutine 1 [running]:
runtime/debug.Stack()
runtime/debug/stack.go:24 +0x65
go.k6.io/k6/js/common.RunWithPanicCatching.func1()
go.k6.io/[email protected]/js/common/util.go:82 +0x191
panic({0x1508ea0, 0x274f030})
runtime/panic.go:884 +0x212
github.com/dop251/goja.(*Runtime).runWrapped.func1()
github.com/dop251/[email protected]/runtime.go:2516 +0x185
panic({0x1508ea0, 0x274f030})
runtime/panic.go:884 +0x212
github.com/dop251/goja.(*vm).handleThrow(0xc0005a39e0, {0x1508ea0, 0x274f030})
github.com/dop251/[email protected]/vm.go:788 +0x497
github.com/dop251/goja.(*vm).try.func1()
github.com/dop251/[email protected]/vm.go:807 +0x45
panic({0x1508ea0, 0x274f030})
runtime/panic.go:884 +0x212
github.com/dop251/goja.(*vm).handleThrow(0xc0005a39e0, {0x1508ea0, 0x274f030})
github.com/dop251/[email protected]/vm.go:788 +0x497
github.com/dop251/goja.(*vm).runTryInner.func1()
github.com/dop251/[email protected]/vm.go:830 +0x45
panic({0x1508ea0, 0x274f030})
runtime/panic.go:884 +0x212
github.com/vesoft-inc/k6-plugin/pkg/nebulagraph.(*GraphPool).Init(0xc0005aa000)
github.com/vesoft-inc/[email protected]/pkg/nebulagraph/client.go:109 +0x3c
reflect.Value.call({0x1610240?, 0xc0005aa000?, 0x2541160?}, {0x1711175, 0x4}, {0x27a4b60, 0x0, 0xc002707d10?})
reflect/value.go:584 +0x8c5
reflect.Value.Call({0x1610240?, 0xc0005aa000?, 0x0?}, {0x27a4b60?, 0xc000286840?, 0x4?})
reflect/value.go:368 +0xbc
github.com/dop251/goja.(*Runtime).wrapReflectFunc.func1({{0x1a3d530, 0xc002250480}, {0xc00242f100, 0x2, 0x8}})
github.com/dop251/[email protected]/runtime.go:2056 +0x1da
github.com/dop251/goja.(*nativeFuncObject).vmCall(0xc000862780, 0xc0005a39e0, 0x2)
github.com/dop251/[email protected]/func.go:559 +0x1af
github.com/dop251/goja.call.exec(0x4?, 0xc0005a39e0)
github.com/dop251/[email protected]/vm.go:3366 +0x6a
github.com/dop251/goja.(*vm).run(0xc0005a39e0)
github.com/dop251/[email protected]/vm.go:582 +0x62
github.com/dop251/goja.(*vm).runTryInner(0xc0005a39e0?)
github.com/dop251/[email protected]/vm.go:834 +0x70
github.com/dop251/goja.(*baseJsFuncObject).__call(0xc0006c1a40, {0xc001105360?, 0x2, 0xc001105340?}, {0x0?, 0x0}, {0x1a3d530?, 0xc002247c80?})
github.com/dop251/[email protected]/func.go:426 +0x665
github.com/dop251/goja.(*baseJsFuncObject).call(...)
github.com/dop251/[email protected]/func.go:442
github.com/dop251/goja.(*baseJsFuncObject).call(0xc0006c1a01?, {{0x1a3d530, 0xc002247c80}, {0xc001105360, 0x2, 0x2}}, {0x0?, 0x0?})
github.com/dop251/[email protected]/func.go:450 +0x7a
github.com/dop251/goja.(*baseJsFuncObject).Call(0xc001105340?, {{0x1a3d530, 0xc002247c80}, {0xc001105360, 0x2, 0x2}})
github.com/dop251/[email protected]/func.go:382 +0x45
github.com/dop251/goja.AssertFunction.func1.1()
github.com/dop251/[email protected]/runtime.go:2476 +0x74
github.com/dop251/goja.(*vm).try(0xc0005a39e0, 0xc0027083c8)
github.com/dop251/[email protected]/vm.go:811 +0x243
github.com/dop251/goja.(*Runtime).runWrapped(0xc000090800, 0x7f6ac13a2108?)
github.com/dop251/[email protected]/runtime.go:2520 +0x7c
github.com/dop251/goja.AssertFunction.func1({0x1a3d530?, 0xc002247c80?}, {0xc001105360?, 0x16c0dc0?, 0xc002247c80?})
github.com/dop251/[email protected]/runtime.go:2475 +0x92
go.k6.io/k6/js/modules.(*cjsModuleInstance).execute(0xc001105300)
go.k6.io/[email protected]/js/modules/cjsmodule.go:46 +0x3c3
go.k6.io/k6/js/modules.(*ModuleSystem).Require(0xc000398460, 0xc00059c558?, {0xc0003f1300?, 0xc00059c548?})
go.k6.io/[email protected]/js/modules/resolution.go:146 +0x11c
go.k6.io/k6/js/modules.(*ModuleSystem).RunSourceData(0xc000398460, 0xc0005a6ea0)
go.k6.io/[email protected]/js/modules/resolution.go:165 +0xd1
go.k6.io/k6/js.(*Bundle).instantiate.func3.1()
go.k6.io/[email protected]/js/bundle.go:309 +0x2d
go.k6.io/k6/js/eventloop.(*EventLoop).Start(0xc0005b6eb0, 0xc000398500)
go.k6.io/[email protected]/js/eventloop/eventloop.go:177 +0x1bd
go.k6.io/k6/js.(*Bundle).instantiate.func3()
go.k6.io/[email protected]/js/bundle.go:306 +0xb9
go.k6.io/k6/js/common.RunWithPanicCatching({0x1a41ca0?, 0xc000386e80?}, 0xc00063b3e0?, 0xc000398460?)
go.k6.io/[email protected]/js/common/util.go:86 +0x87
go.k6.io/k6/js.(*Bundle).instantiate(0xc0005f5600, 0xc00063b3e0, 0x0)
go.k6.io/[email protected]/js/bundle.go:305 +0x36b
go.k6.io/k6/js.newBundle(
, _, _, {{{0x0, 0x0}}, {{0x0, 0x0}}, {0x0, 0x0}, {{0x0, ...}}, ...}, ...)
go.k6.io/[email protected]/js/bundle.go:117 +0x329
go.k6.io/k6/js.NewBundle(...)
go.k6.io/[email protected]/js/bundle.go:87
go.k6.io/k6/js.New(0xc0005e4800?, 0x5e8?, 0xc00059cc20?)
go.k6.io/[email protected]/js/runner.go:65 +0x5d
go.k6.io/k6/cmd.(*loadedTest).initializeFirstRunner(0xc0001fd8f0, 0xc0005feb00)
go.k6.io/[email protected]/cmd/test_load.go:126 +0x40f
go.k6.io/k6/cmd.loadTest(0xc0005feb00, 0x1510260?, {0xc000199290?, 0xc000536720?, 0xc000534120?})
go.k6.io/[email protected]/cmd/test_load.go:89 +0x6ce
go.k6.io/k6/cmd.loadAndConfigureTest(0x1a2f100?, 0xc0003ab2c0?, {0xc000199290?, 0xc000386e80?, 0xb2620e?}, 0x2554eec?)
go.k6.io/[email protected]/cmd/test_load.go:242 +0x2d
go.k6.io/k6/cmd.(*cmdRun).run(0xc0005ae3b0, 0xc0004d4280, {0xc000199290?, 0x1, 0xb})
go.k6.io/[email protected]/cmd/run.go:69 +0x208
github.com/spf13/cobra.(*Command).execute(0xc0004d4280, {0xc0001991e0, 0xb, 0xb})
github.com/spf13/[email protected]/command.go:856 +0x67c
github.com/spf13/cobra.(*Command).ExecuteC(0xc000212500)
github.com/spf13/[email protected]/command.go:974 +0x3bd
github.com/spf13/cobra.(*Command).Execute(...)
github.com/spf13/[email protected]/command.go:902
go.k6.io/k6/cmd.(*rootCommand).execute(0xc0001b15c0)
go.k6.io/[email protected]/cmd/root.go:104 +0x125
go.k6.io/k6/cmd.Execute()
go.k6.io/[email protected]/cmd/root.go:137 +0x31
main.main()
k6/main.go:12 +0x17

Goja stack:
ERRO[0000] could not initialize 'output/20230817181250/Bar.js': could not load JS test 'file:///root/NebulaGraph-Bench/output/20230817181250/Bar.js': a panic occurred during JS execution: runtime error: invalid memory address or nil pointer dereference

Your Environments (required)

  • OS: uname -a
  • Commit id (e.g. a3ffc7d8)
    Linux b3b7ca219357 6.4.8-orbstack-00059-g106c60a3471f #1 SMP Sun Aug 6 06:44:43 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

How To Reproduce(required)

Steps to reproduce the behavior:

Run the stress test with go1.19.12

Expected behavior

Additional context
without error

sf1

refactor the options for nebula graph

the initial purpose for this k6 plugin was just testing the performance for NebulaGraph.

there're some more options for NebulaGraph, e.g.

HTTP2
security with SSL
SessionPool
Retry policy
...

And it's more complex if keep the original behavior.

So I want to break the original behavior, and using an option like k6, i.e.

let poolOption = {
    key : value
}
pool.setOption(poolOption)

And then document the valid options for nebula graph pool

After increasing concurrency, it is unable to return test results.

100并发可以正常返回,200就会有这个错误,看请求都是正常的,但是压测结果无法返回
ERRO[0080] failed to handle the end-of-test summary error="GoError: failed to open connection, error: failed to verify client version: read tcp *****:22811->******:9669: i/o timeout \n\tat reflect.methodValueCall (native)\n\tat file:****/nebulagraph-bench/templates/k6_config.js.j2:12:27(59)\n"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.