Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import crypto from k6/experimental/webcrypto capitalizes the names of some methods for a built-in object from http #55

Closed
Dfuz opened this issue Jan 11, 2024 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@Dfuz
Copy link

Dfuz commented Jan 11, 2024

Brief summary

I'm working on a typescript project that includes the k6/experimental/webcrypto library. When I receive a response from the server, I use the built-in .json() method and the following error occurs: "Uncaught (in promise) TypeError: Object has no member 'json'". I decided to print out the methods of this object and got the following:

got object with methods: ["clickLink","hTML","jSON","submitForm"]

Very strange behavior that took a long time to resolve, please look into this.

Here is some snippet:

import { JSONValue } from "k6";
import http from "k6/http";
import { SESSION_SERVICE_URL } from "./urls";

import { crypto } from "k6/experimental/webcrypto";

type CreateSessionIn = {
    sessCtx: {
        ip: string;
        browser: number;
        os: number;
        locationID: number;
        createTime: number;
        updateTime: number;
    }
    userID: number;
    passportID?: string;
    isValuable: boolean;
    ttl: number;
    isApi: boolean;
}

export type CreateSessionOut = {
    id: string;
    hashedSessionID: string;
    createTime: number;
}

function isSessionCreated(response: JSONValue): response is CreateSessionOut {
    return (response as CreateSessionOut).hashedSessionID != undefined;
}

// Get the Object's methods names:
function getMethodsNames(obj: any) {
    return Object.keys(obj)
        .filter((key) => typeof obj[key] === 'function');
}

export function AuthorizeUser(userID: number, isApi: boolean): CreateSessionOut | undefined {
    const payload: CreateSessionIn = {
        userID: userID,
        isApi: isApi,
        isValuable: false,
        sessCtx: {
            ip: "",
            browser: 0, createTime: 0, locationID: 0, os: 0, updateTime: 0
        },
        ttl: 360000
    }

    const response = http.post(`${SESSION_SERVICE_URL}/makeSession`, JSON.stringify(payload), {
        headers: {
            'Content-Type': "application/json",
            'X-Rpc-Ver': "1",
            "X-Request-Id": crypto.randomUUID() // <---- if i remove this line and import then everything will work fine 
        }
    })

    if (!response) {
        console.error("got empty response, throw error")
        throw Error("cannot login user, got bad response")
    }

    console.warn("got object with methods: ", getMethodsNames(response))

    const jsonResponse = response.json();

    if (isSessionCreated(jsonResponse)) {
        return jsonResponse
    }

    return undefined
}

If needed, I can attach the final js-bundles.

k6 version

k6 v0.48.0 (commit/47c0a26798, go1.21.4, linux/amd64)

OS

Ubuntu(WSL)/macOS

Docker version and image (if applicable)

No response

Steps to reproduce the problem

  1. import crypto from k6/experimental/webcrypto
  2. ???
  3. got inverted object names

Expected behaviour

The http response object's method names have not changed

Actual behaviour

The http response object's method names have changed

@Dfuz Dfuz added the bug Something isn't working label Jan 11, 2024
@alecbar
Copy link

alecbar commented Jan 11, 2024

I'm having the same issue

k6 v0.48.0 (go1.21.5, darwin/arm64)
macOS

@mstoykov mstoykov transferred this issue from grafana/k6 Jan 12, 2024
@mstoykov
Copy link
Contributor

Thanks for reporting this 🙇

I have moved the issue to the webcrypto repo, and now that it has been reported it is pretty easy to find that the issue is

vu.Runtime().SetFieldNameMapper(goja.TagFieldNameMapper("json", true))

Given the commit it was added in 056c2f6 it looks like removing it will at least break CryptoKey. This doesn't happen as it is also set in the test

rt.SetFieldNameMapper(goja.TagFieldNameMapper("json", true))

which makes the test a tad less useful. Removing both definitely breaks a bunch of tests.

The issue here is that the SetFieldNameMapper should in practice never be used by anything else but k6 core itself. In k6 core it is already used to work around the fact some fields/methods don't map automatically/automagically correctly - like JSON to json.

It seems it is used for the same reason here in webcrypto. Unfortunately breaking k6 core API is a lot bigger problem. As such I do think webcrypto module should move away from using it and use a different workaround. In this case I guess that will be to create a simple goja Object and set properties on it, instead of using the automagical transformation of go object to goja ones.

cc @grafana/k6-core and @oleiade specifically

@alecbar
Copy link

alecbar commented Jan 15, 2024

How do we get the latest version with this fix?

@mstoykov
Copy link
Contributor

@alecbar you can use the master tag of docker image or compile from master from the main repo.

The fixes have been merged in then.

The next k6 release is v0.49.0 and is expected in 2 weeks on the 29th.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants