K6: Any examples out there on workload modeling?

Created on 29 Aug 2018  路  4Comments  路  Source: loadimpact/k6

I would like to model my workload as realistic as possible, but see nothing in the documentation about constructs as looping and things as markov chains (Percentage -> Scenario).

It should be possible to do this with plain JavaScript, but I'm a bit suprised that there are no example and nobody is asking about this.

Am I missing something?

Thanks!

question

Most helpful comment

I don't think this is very suitable for implementing in k6 itself. I'm not very familiar with markov chains and how other tools implement them, but having a simple graph of pages and probabilities between them and traversing that with a simple JS function seems relatively painless and simple. Something like this:

import http from 'k6/http';

let pageGraph = {
    home: {
        method: "GET",
        url: "https://test.loadimpact.com",
        next: [
            { prob: 0.4, id: "contacts" },
            { prob: 0.5, id: "news" },
            // 10% chance of stop
        ],
    },
    contacts: {
        method: "GET",
        url: "https://test.loadimpact.com/contacts.php",
        next: [
            { prob: 0.8, id: "home" },
            // 20% chance of stop
        ],
    },
    news: {
        method: "GET",
        url: "https://test.loadimpact.com/news.php",
        next: [
            { prob: 0.3, id: "home" },
            { prob: 0.3, id: "contacts" },
            // 40% chance of stop
        ],
    },
};

function traverse(pageId, level) {
    let page = pageGraph[pageId];

    console.log(`VU ${__VU}, ITER ${__ITER}, level ${level}:\t Traversing ${pageId} (${page.method} ${page.url})`)
    http.request(page.method, page.url);
    // Do other stuff if something more complicated is required...

    let acum = 0, rand = Math.random();
    for (let i = 0; i < page.next.length; i++) {
        acum += page.next[i].prob;
        if (acum > rand) {
            // Recursion probably isn't the best way to handle that, but works for a simple example...
            return traverse(page.next[i].id, level + 1);
        }
    }
}

export default function () {
    traverse("home", 0);
};

It can be extended and improved in a lot of ways, of course. That's the main reason I don't think it's a good idea to include it in k6 itself - it isn't something essential to the core functionality of a load-testing tool and it can be easily and more flexibly implemented outside of it. For example, in the above example, I can easily add an http.batch() call in some of those pages, or use group() calls, or any other action via a callback function, but I can't do things like that if we bake some sort of markov chain API in k6 itself. While you can always make something like the above code into a JS library and reuse it across all of your k6 scripts without issues...

Closing this for now, but feel free to reopen if you disagree with my assessment and think that there are good reasons to add something like this in k6.

All 4 comments

Really interested in what use case you have for modeling workload with a markov process? Basically it's a matrix of states with transitional probabilities so simple to implement but why? What use case would need statistical modeling of probable outcomes (paths really but still)?

I am not debunking the idea, I am just curious and would like to see some use cases for this since I have only seen it used in statistical functional quality models.

@micsjo Indeed, I want to use it to model navigation paths in my scenarios. Basically just to create a switch between groups based on percentage:

50% Catalog page
30% Checkout page
20% Account page

Simple to create, but it would be nice if there was a more generic API to do this. This could be an extension on the group feature?

I don't think this is very suitable for implementing in k6 itself. I'm not very familiar with markov chains and how other tools implement them, but having a simple graph of pages and probabilities between them and traversing that with a simple JS function seems relatively painless and simple. Something like this:

import http from 'k6/http';

let pageGraph = {
    home: {
        method: "GET",
        url: "https://test.loadimpact.com",
        next: [
            { prob: 0.4, id: "contacts" },
            { prob: 0.5, id: "news" },
            // 10% chance of stop
        ],
    },
    contacts: {
        method: "GET",
        url: "https://test.loadimpact.com/contacts.php",
        next: [
            { prob: 0.8, id: "home" },
            // 20% chance of stop
        ],
    },
    news: {
        method: "GET",
        url: "https://test.loadimpact.com/news.php",
        next: [
            { prob: 0.3, id: "home" },
            { prob: 0.3, id: "contacts" },
            // 40% chance of stop
        ],
    },
};

function traverse(pageId, level) {
    let page = pageGraph[pageId];

    console.log(`VU ${__VU}, ITER ${__ITER}, level ${level}:\t Traversing ${pageId} (${page.method} ${page.url})`)
    http.request(page.method, page.url);
    // Do other stuff if something more complicated is required...

    let acum = 0, rand = Math.random();
    for (let i = 0; i < page.next.length; i++) {
        acum += page.next[i].prob;
        if (acum > rand) {
            // Recursion probably isn't the best way to handle that, but works for a simple example...
            return traverse(page.next[i].id, level + 1);
        }
    }
}

export default function () {
    traverse("home", 0);
};

It can be extended and improved in a lot of ways, of course. That's the main reason I don't think it's a good idea to include it in k6 itself - it isn't something essential to the core functionality of a load-testing tool and it can be easily and more flexibly implemented outside of it. For example, in the above example, I can easily add an http.batch() call in some of those pages, or use group() calls, or any other action via a callback function, but I can't do things like that if we bake some sort of markov chain API in k6 itself. While you can always make something like the above code into a JS library and reuse it across all of your k6 scripts without issues...

Closing this for now, but feel free to reopen if you disagree with my assessment and think that there are good reasons to add something like this in k6.

@na-- Thank you for the ellaborate answer! I agree that it should not end up in the k6 core. It would be nice if features like this would be available in a add-on library for k6. For now I will write my own.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

athoune picture athoune  路  3Comments

caalle picture caalle  路  4Comments

ayaka209 picture ayaka209  路  4Comments

jrm2k6 picture jrm2k6  路  4Comments

gushengyuan picture gushengyuan  路  3Comments