Scope of init variables w.r.t. setup, teardown, and handleSummary functions

Where can I find documentation explaining the scope of the variables declared in the init code and how that relates to the scope of the setup, teardown, and handleSummary functions? It seems my setup function cannot alter a variable declared in the init code, but the handleSummary is able to access the variable which is slightly confusing.

Example:

import { textSummary } from 'https://jslib.k6.io/k6-summary/0.0.1/index.js';

let testStartTime = 'Not Set'

export function setup() {
  testStartTime = new Date()
  console.log(`## Start time: ${testStartTime}`)
}

export default function() {
}

export function handleSummary(data) {
  const now = new Date()

  data.LoadTestDetails = {
    testStartTime,
    testEndTime: now,
  }

  const filenameFriendlyNow = now.toISOString().replace(/:/g,'-')
  const summaryFilename = `summary-${filenameFriendlyNow}.json`
  let result = {
    'stdout': textSummary(data, { indent: ' ', enableColors: true }),
  };
  result[summaryFilename] = JSON.stringify(data, null, '\t');

  return result;
}

When running k6, the console output from the setup function shows the correct date:

INFO[0001] ## Start time: Thu Feb 03 2022 11:50:23 GMT+0000 (GMT)  source=console

My summary JSON shows the value of testStartTime that was set in the init code:

	"LoadTestDetails": {
		"testStartTime": "Not Set",
		"testEndTime": "2022-02-03T11:50:36.87Z",
	}

I.e. the testStartTime is the value that was set in the init code, prior to the setup function.

setup(), teardown(), handleSummary() currently run in completely different JS runtimes from each other and from the normal VUs. So they don’t share a common global scope. It’s an implementation detail that might change in the future, but you probably shouldn’t rely on it either way.

What you can do instead is access the data returned from setup() both in the default function and in handleSummary. Try this example:

import { sleep } from "k6";

export function setup() {
    return { startDate: new Date() };
}

export default function (data) {
    sleep(3);
}

export function handleSummary(data) {
    return { 'stdout': `\n\nStarted: ${new Date(data.setup_data.startDate)}\nEnded: ${new Date()}\n\n` };
}
2 Likes

Absolutely excellent @ned , thank you for this.