Is JSON.stringify() necessary for payloads via Shared Array?

So im trying to load a .json file into a SharedArray according to the docs here: SharedArray

Right now my “load” function looks like this:

export function loadData(dataFile) {
  const data = new SharedArray('dataFile', function () {
    const obj = JSON.parse(open(dataFile));
    return obj; 
  })
  return data
}

Which I then load in my test file via:

const data = loadData("/resources/api/cloud-pos-check/cloud-post-check.json");
const body = data[0];

(data[0] above is the JSON object in the JSON file, it is the only object there in that .json file)

It was failing until I realized that what I am sending via the payload was a JavaScript Object/String and NOT actual JSON.

So I have to do JSON.stringify(body) for the payload. Which seems silly because I am opening a JSON file, parsing it to a string then re-converting it to JSON. I guess what I want to know is this necessary?

Can SharedArray HOLD an actual .json value? Or do I need to do what I am doing everytime I need to send an actual .json payload. FWIW If I try to read directly the object that open returns it shows as blank in the console.

Thanks

Hi @mercfh

If you want to just read a file that contains a single JSON, it won’t probably be too big and you could use a simple open. I believe in your case you can attempt:

// init
const body = JSON.parse(open('/resources/api/cloud-pos-check/cloud-post-check.json'));

export default function (data) {
  // VU code
  let resp = session.post(url, body);
}

I did some testing with the script below:

import http from 'k6/http';

let body = JSON.parse(open('./croc.json'));

export let options = {
    vus: 2,
    iterations: 10,
};

export default function (data) {
    // VU code
    let res = http.post('https://httpbin.test.k6.io/anything', body);
    console.log(res.json().form.name);
}

and the croc.json file:

{
    "name": "Berta",
    "sex": "F",
    "date_of_birth": "2019-01-01"
}

Which outputs:

If it’s only a JSON file, with a document, not an array, there is probably no need to use a SharedArray.

I hope this helps.

Cheers!

Hi @mercfh ,

Just to circle back here, using a SharedArray is a good option if the JSON file to read is big / lots of VUs. In that case, create an array with 1 position and just read the first one as you initially proposed. Otherwise, for smaller files, you can use k6 open directly, with examples also in the docs (apart from the example above): JavaScript API: open

For now a SharedArray cannot be used in the setup. Once this is available, SharedArray improvements · Issue #2043 · grafana/k6 · GitHub, it’s a good option to use, an JSON array with a single item.

Cheers!

Thats currently what Im doing. I guess the only “downside” is having to stringify the SharedArray and the code maybe not looking as good (having to call the array indexes). BUT if it’s more performant (In this case I am load testing with around 500 VU’s a lot of the time) it sounds like it makes more sense.

I just wanted to make sure that what I was doing sounded right.

As a side note: In your example your http.post is NOT converting the parsed file to .json. Does that matter? (Since I imagine most payloads are expecting a .JSON payload). I did notice that a lot of the endpoints I tested with I actually forgot to convert them to .JSON and they still worked.

Hi @mercfh

The line let body = JSON.parse(open('./croc.json')); is parsing the file into an object and then this is passed as a parameter to the the POST request let res = http.post('https://httpbin.test.k6.io/anything', body);. It works well for me. I had also tested this with a more complex example based on https://test-api.k6.io (Sample HTTP API test script) - replacing the payload in describe('04. Create a new crocodile', and the croc is created.

Cheers!

I guess it depends on the body needs to be a JSON (string) based object or JavaScript object. Does k6 http library I wonder convert body values that are object to JSON or text perhaps?

This solution works fine for me as long as there is no complexity in JSON file, i had this payload and it always seems

{
"program_label": "start",
"sim_label": "simplesim",
"tag_list": ["test1"],
"state": "draft",
"process_order": {
    "0": "initial"
  }
}

and this payload seems to be read by API as

{
"program_label": "start",
"sim_label": "simplesim",
"tag_list": [],
"state": "draft",
"process_order": {}
}

i see this json is a bit complex with additional arrays and objects inside the JSON, how to handle this and same payload works via Postman without any issue.

1 Like