Script error panic when I slightly increase the number of users

Hello,

My target environment :

  • EC2 instance type: r5n.24xlarge
  • Chrome Version: google-chrome-stable 116.0.5845.110-1
  • OS: Debian 11.7

EC2 instance configured with Running large tests

I’m using K6 version v0.45.1 with the k6-browser module and I have a script that works locally (Windows 11) with a single VU as well as on my target environment with 40 VUs but when I exceed 70 VUs I get the following error:

[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0xef2e41]
candidateCreateAccount1k   [--------------------------------------] 75 VUs  0m24.7s/3m0s  00/75 iters, 1 per VU
goroutine 174207 [running]:
github.com/grafana/xk6-browser/common.(*FrameManager).NavigateFrame.func1({0x1428c60?, 0xc09a83c540})
        github.com/grafana/xk6-browser@v0.10.0/common/frame_manager.go:586 +0x61
github.com/grafana/xk6-browser/common.createWaitForEventHandler.func1()
        github.com/grafana/xk6-browser@v0.10.0/common/helpers.go:145 +0x1f3
created by github.com/grafana/xk6-browser/common.createWaitForEventHandler
        github.com/grafana/xk6-browser@v0.10.0/common/helpers.go:137 +0x17d

My script:

I used the “console.error” to see where in the script the error occurred, and appears between step 2 and step 3.

import { chromium } from 'k6/experimental/browser';
import { check, sleep } from 'k6';
import exec from 'k6/execution';
import http from 'k6/http';

export const options = {
  scenarios: {
    candidateCreateAccount1k: {

      executor: 'per-vu-iterations',
      vus: 50,
      iterations: 1,
      maxDuration: '3m',
      gracefulStop: '2m',
      env: {
        EMAIL: 'candidate_',
        FIRSTNAME: 'firstname_',
        LASTNAME: 'lastname_'
      }
    }
  },
  tags: {
    test_run_id: 'test-man-70u-62',
  },
  discardResponseBodies: true,
};

export default async function () {
  const browser = chromium.launch({ headless: true, timeout: '10m', slowMo: '900ms',args:['no-sandbox']});
  const context = browser.newContext();
  //force extend default timeout
  context.setDefaultTimeout(120);

  context.addCookies([
    {
      name: 'my_cookies',
      value: `my_cookie_values`,
      url: 'https://www.mysite.com/',
    },
  ]);

  const page = context.newPage();

  try {
    await page.goto('https://www.mysite.com/login', {
      waitUntil: 'load',
    });

    // CLick on Register link
    const registerLink = page.locator('[href="https://www.mysite.com/register"]');
    await Promise.all([page.waitForNavigation(), registerLink.click()]);

    // Click on "a candidate" option
    const candidateOption = page.locator('.col-md-6:nth-child(1) label');
    await Promise.all([page.waitForNavigation(), candidateOption.click()]);

    // Check url
    check(page, {
      'Register start': page => page.url() === 'https://www.mysite.com/register/individual',
    });

    // Fill register form
    const emailField = page.locator('#email');
    // EMAIL
    const email = `${__ENV.EMAIL}${exec.vu.idInTest}@yopmail.com`
    await Promise.all([emailField.click()]);
    emailField.fill(email);

    const firstnameField = page.locator('#firstname');
    const firstname = `${__ENV.FIRSTNAME}${exec.vu.idInTest}`;
    await Promise.all([firstnameField.click()]);
    firstnameField.fill(firstname);

    const lastnameField = page.locator('#lastname');
    const lastname = `${__ENV.LASTNAME}${exec.vu.idInTest}`;
    await Promise.all([lastnameField.click()]);
    lastnameField.fill(lastname);

    // Click on Next button
    const nextButton = page.locator('.bt-pink.bt-branding.mb-4.btn');
    await Promise.all([nextButton.click()]);

    // Password
    const passwordField = page.locator('#password');
    const password = 'MySecurePassword';
    await Promise.all([passwordField.click()]);
    passwordField.fill(password);

    const confirmPwdField = page.locator('#password-confirmation');
    await Promise.all([confirmPwdField.click()]);
    confirmPwdField.fill(password);

    // Checkbox GCU
    const checkboxGCU = page.locator('.mt-3 > .checkbox > .line-18 > .checkmark');
    await Promise.all([checkboxGCU.click()]);

    // Click on Create my account
    const createAccountButton = page.locator(':nth-child(3) > .text-center > .bt-pink');
    await Promise.all([createAccountButton.click()]);
    sleep(1);

    console.error(`Step 1 - ${exec.vu.idInTest}`);

    // Send email address to activate account
    let data = { user_email: `${email}` };


    // Using a JSON string as body For Personal API
    let res = http.post('https://my-api.com/account-activation', JSON.stringify(data), {
      headers: { 'Content-Type': 'application/json' },
    });

    sleep(2);

    check(res, {
      'status code should be 200': res => res.status === 200,
    });

    console.error(`Step 2 - ${exec.vu.idInTest}`);

    //Force Url to start onboarding
    await page.goto('https://www.mysite.com/_/onboarding/intro', {waitUntil: 'domcontentloaded'});


    sleep(5);

/*
    // Check url
    check(page, {
      'start onboarding': page => page.url() === 'https://www.mysite.com/_/onboarding/intro',
    });
*/
    console.error(`Step 3 - ${exec.vu.idInTest}`);

    // Onboarding
    // Step 1 Before starting
    const nextButtonStep1 = page.locator('#js_next-step-1');
    await Promise.all([nextButtonStep1.click()]);

    // Step 2 : select degree level
    const degreeSelect = page.locator('#select2-degreeLevel-container');
    await Promise.all([degreeSelect.click()]);
    const degreesList = page.locator('#select2-degreeLevel-results');
    degreesList.press('Enter');
    const nextButtonStep2 = page.locator('#js_next-step-2');
    await Promise.all([nextButtonStep2.click()]);

    console.error(`Step 4 - ${exec.vu.idInTest}`);

    // Step 3 : exp pro
    const jobTitleSelect = page.locator('#select2-jobTitle-container');
    await Promise.all([jobTitleSelect.click()]);
    const jobTitleList = page.locator('#select2-jobTitle-results');
    jobTitleList.press('Enter');

    const nextButtonStep3 = page.locator('#js_next-step-3');
    await Promise.all([nextButtonStep3.click()]);

    // Gender
    const radioF = page.locator('#js_radio-female label');
    await Promise.all([radioF.click()]);
    const nextButtonStep4 = page.locator('#js_next-step-4');
    await Promise.all([nextButtonStep4.click()]);

    // Privacy : private
    const privateOption = page.locator(':nth-child(1) > .card > .card-radio');
    await Promise.all([privateOption.click()]);
    const nextButtonStep5 = page.locator('#js_next-step-7');
    await Promise.all([nextButtonStep5.click(), page.waitForNavigation()]);

    // Questionnaires step
    const skipButton = page.locator('a[class="btn-secondary bt-branding"]');
    await Promise.all([skipButton.click()]);

    console.error(`Step 5 - ${exec.vu.idInTest}`);

    page.waitForSelector(`#app > div > div > header > div > div > div > div.v-col.v-col-3 > div > button > span.v-btn__content`);

    // End : checkUrl

    /*check(page, {
      'Candidate redirected to his profile': page => page.url() === 'https://my-aws.assessfirst.com/profile/synthesis'
    });*/

    sleep(3);

    page.waitForSelector(`#app > div > div > header > div > div > div > div.v-col.v-col-9.pa-1 > div > div.brand.d-flex.align-center.mr-8 > a > div`);

    // Check url
    check(page, {
      'Candidate is in his dashboard': page => page.waitForSelector(`#app > div > div > header > div > div > div > div.v-col.v-col-9.pa-1 > div > div.brand.d-flex.align-center.mr-8 > a > div`),
    });

    sleep(2);

    //console.error(`START LOGOUT ########################`);
    const avatarButton = page.locator(`xpath=//*[@id="app"]/div/div/header/div/div/div/div[2]/div/div[2]/div/button/span[3]`);
    await Promise.all([avatarButton.click()]);
    sleep(2);

    const logoutButton = page.locator(`body > div.v-overlay-container > div.v-overlay.v-overlay--absolute.v-overlay--active.v-theme--afTheme.v-locale--is-ltr.v-menu > div > div > div`);
    await Promise.all([logoutButton.click()]);

    //console.error(`END LOGOUT ########################`);

  } finally {
    page.close();
    browser.close();
  }
}

To see if the limitations came from the server, I carried out a simple test with 1000 users, with success.

import { chromium } from 'k6/experimental/browser';
import { check } from 'k6';

export const options = {
    scenarios: {
      simpletest: {
        executor: 'per-vu-iterations',
        vus: 1000,
        iterations: 1,
        maxDuration: '3m',
        gracefulStop: '2m',
      }
    },
    tags: {
      test_run_id: 'test-man-70u-35',
    },
    discardResponseBodies: true,
  };

export default async function () {
  const browser = chromium.launch({ headless: true, timeout: '10m' ,args:['no-sandbox']});
  const context = browser.newContext();

  const page = context.newPage();

  console.error('STEP --0----')

  try {
    await page.goto('https://www.mysite.com/login');


    check(page, {
      header: page.locator(`xpath=/html/body/div[1]/div/div/div[1]/div/div[2]/div[1]/div/h1`).textContent() == 'Login',
    });

    console.error('STEP ----1----')

    await page.goto('https://www.mysite.com/Page2', {waitUntil: 'domcontentloaded'});

    check(page, {
      'Candidate is in his dashboard': page => page.waitForSelector(`xpath=/html/body/pre`),
    });

    console.error('STEP ------2--')

  } finally {
    page.close();
    browser.close();
  }
}

Thanks in advance.

Hi @mpioc,

We fixed many bugs in the latest release. You can get it here: Release v0.46.0 · grafana/k6 · GitHub. Please try with this version and let us know how it goes.

We don’t suggest using sleep. Instead, you can use waitForSelector: waitForSelector(selector[, options]).

If none of this works, could you provide us a test script and an example HTML so that we can reproduce and diagnose the problem?

Thanks!

1 Like

Hi @inancgumus ,

Thank you for your quick reply.

The use of “sleep” was indeed at the root of the problem.

Thanks,

1 Like