Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,15 @@ queries:
execution_strategy: FIXED_REQUEST_NUMBER
requests: 10000
query: |
query AlbumByPK {
albums_by_pk(id: 1) {
query AlbumByPK($id: Int!) {
albums_by_pk(id: $id) {
id
title
}
}
# Optional variables (if the query/mutation uses variables)
variables:
id: 1
- name: AlbumByPKMultiStage
tools: [k6]
execution_strategy: MULTI_STAGE
Expand All @@ -160,12 +163,15 @@ queries:
- duration: 5s
target: 1000
query: |
query AlbumByPK {
albums_by_pk(id: 1) {
query AlbumByPK($id: Int!) {
albums_by_pk(id: $id) {
id
title
}
}
}
# Supply variables (Optional) from CSV file. Each row in the CSV is used in a request. (If 100 rows are provided, 100 queries with different variables are fired). The first row in the CSV must be name of the the variable. This can be used in tandem with the above variables.
variable_file:
file_path: './text.csv' # CSV file path releative to the config file
```

##### Run with Docker
Expand Down Expand Up @@ -241,6 +247,9 @@ config:
artistIds: [1, 2, 3, 4]
some_object:
a_key: a_value
# Supply variables (Optional) from CSV file. Each row in the CSV is used in a Subscription. The first row in the CSV must be name of the the variable. This can be used in tandem with the above variables.
variable_file:
file_path: './text.csv' # CSV file path releative to the config file
```

##### Note: Required Table
Expand Down
5 changes: 5 additions & 0 deletions app/cli/test.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
id,name
1,sandeep
2,raj
3,kumar
4,kandasamy
28 changes: 26 additions & 2 deletions app/queries/bin/k6/loadScript.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
import http from 'k6/http'
import { check } from 'k6'

var cachedFileVariables;
var fileVariablesCurrentIndex = 0;

/**
* Use ES5 syntax
*/
export default function () {
let { url, headers, query, variables } = __ENV
let { url, headers, query, variables, fileVariables } = __ENV

// Can't pass nested JSON in config file, need to parse here because stringified
if (headers) headers = JSON.parse(headers)
if (variables) variables = JSON.parse(variables)
// Storing the JSONified fileVariables to not deserialize in every iteration
if (!cachedFileVariables) {
cachedFileVariables = JSON.parse(fileVariables)
}

let combinedVariables;

if (cachedFileVariables.length!=0) {
// TODO: can look at getting a random value beween 0 and cachedFileVariables.length rather than iterating for ensured randomness
if (fileVariablesCurrentIndex >= cachedFileVariables.length) {
fileVariablesCurrentIndex = 0;
}
combinedVariables = Object.assign({}, variables, cachedFileVariables[fileVariablesCurrentIndex]);
fileVariablesCurrentIndex++;
} else {
combinedVariables = variables;
}


// Prepare query & variables (if provided)
let body = JSON.stringify({ query, variables })
let body = JSON.stringify({ query, variables: combinedVariables })

// Send the request
let res = http.post(url, body, { headers })
Expand Down
73 changes: 57 additions & 16 deletions app/queries/bin/wrk/graphql-bench.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
-- done = function(summary, latency, requests)
json = require "json"

-- Set the default HTTP method and empty "headers" table here
wrk.method = "POST"
wrk.headers = {}

function tprint (tbl, indent)
if not indent then indent = 0 end
for k, v in pairs(tbl) do
Expand Down Expand Up @@ -45,33 +41,67 @@ function print_wrk_config()
print('-----')
end

local threads = {}

function setup(thread)
table.insert(threads, thread)
end

function init(args)
errorCount = 0
url, params = args[0], args[1]
-- print('url', url)
-- print('params', params)
if not params then print('ERROR: NO PARAMS PASSED TO WRK2') end

params = json.decode(params)
--print_params(params)

if params['headers'] ~= nil then
for header, val in pairs(params['headers']) do
wrk.headers[header] = val
end
end
end

function request()
method = 'POST'
path = url
headers = params['headers']

mergedVariables = merge_config_variables_and_file_variables()

wrk.body = json.encode({
body = json.encode({
query = params['query'],
variables = params['variables'],
variables = mergedVariables
})
return wrk.format(method, path, headers, body)
end

-- Merges one row of the variables from CSV file with the variables from config.
-- Row is selected by running the iterator fileVariablesCurrentIndex and resetting it when it reaches the end of the variables from CSV file.
fileVariablesCurrentIndex = 1
function merge_config_variables_and_file_variables()
bodyVariables = {}
if params['variables'] then
bodyVariables = params['variables']
end

--print_wrk_config()
if params['fileVariables'] and table.getn(params['fileVariables']) ~=0 then
if fileVariablesCurrentIndex > table.getn(params['fileVariables']) then
fileVariablesCurrentIndex = 1
end
for k,v in pairs(params['fileVariables'][fileVariablesCurrentIndex]) do
bodyVariables[k] = v
end
fileVariablesCurrentIndex = fileVariablesCurrentIndex + 1
end
return bodyVariables
end

function request()
return wrk.request()
-- TODO: Better error processing. Currently, only the count of errors are maintained and printed to console.
function response(status, headers, body)
jsonBody = json.decode(body)
if jsonBody['errors'] or status ~= 200 then
errorCount = errorCount + 1
end
end

-- For smaller number of connections and requests, the Mean latency value turns out to be nan (in JSON encoding) and this function then throws error.
-- So keep the rps/connections 10+ to get around the issue
function format_summary_to_json(summary, latency)
local stats = {
requests = summary.requests,
Expand Down Expand Up @@ -123,6 +153,17 @@ end
function done(summary, latency, requests)
stats_table, json_stats = format_summary_to_json(summary, latency)
io.stderr:write(json_stats)
allThreadsErrorCount = 0
for index, thread in ipairs(threads) do
allThreadsErrorCount = allThreadsErrorCount + thread:get("errorCount")
end
--Red colored output to console if there are any errors
if allThreadsErrorCount ~= 0 then
io.write("\x1B[31m")
print('Total error responses = ' ..allThreadsErrorCount)
io.write("\x1B[m")
end

-- Commenting out this file write, just grab it and parse it from stderr for now
-- write_file('/tmp/wrk2-stats.json', json_stats)
end
Expand Down
3 changes: 2 additions & 1 deletion app/queries/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"fs-extra": "^9.0.1",
"hdr-histogram-js": "^2.0.0-beta6",
"js-yaml": "^3.14.0",
"lookpath": "^1.1.0"
"lookpath": "^1.1.0",
"neat-csv": "^6.0.1"
},
"devDependencies": {
"@types/autocannon": "^4.1.0"
Expand Down
Loading