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

Add a RunOnEventLoop method to modulestest.Runtime #3181

Merged
merged 4 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions js/modules/k6/experimental/tracing/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,11 @@ func TestCallingInstrumentedRequestEmitsTraceIdMetadata(t *testing.T) {
// Assert there is no trace_id key in vu metadata before calling an instrumented
// function, and that it's cleaned up after the call.
t.Cleanup(testCase.TestRuntime.EventLoop.WaitOnRegistered)
err = testCase.TestRuntime.EventLoop.Start(func() error {
_, err = rt.RunString(httpBin.Replacer.Replace(`
assert_has_trace_id_metadata(false)
http.request("GET", "HTTPBIN_URL")
assert_has_trace_id_metadata(false)
`))

return err
})
_, err = testCase.TestRuntime.RunOnEventLoop(httpBin.Replacer.Replace(`
assert_has_trace_id_metadata(false)
http.request("GET", "HTTPBIN_URL")
assert_has_trace_id_metadata(false)
`))
require.NoError(t, err)
close(samples)

Expand Down
46 changes: 17 additions & 29 deletions js/modules/k6/http/async_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,21 @@ import (
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.k6.io/k6/js/modulestest"
)

func wrapInAsyncLambda(input string) string {
// This makes it possible to use `await` freely on the "top" level
return "(async () => {\n " + input + "\n })()"
}

func runOnEventLoop(runtime *modulestest.Runtime, code string) error {
// TODO move this in modulestest.Runtime and extend it
err := runtime.EventLoop.Start(func() error {
_, err := runtime.VU.Runtime().RunString(wrapInAsyncLambda(code))
return err
})
runtime.EventLoop.WaitOnRegistered()
return err
}

func TestAsyncRequest(t *testing.T) {
t.Parallel()
t.Run("EmptyBody", func(t *testing.T) {
t.Parallel()
ts := newTestCase(t)

sr := ts.tb.Replacer.Replace
err := runOnEventLoop(ts.runtime, sr(`
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(sr(`
var reqUrl = "HTTPBIN_URL/cookies"
var res = await http.asyncRequest("GET", reqUrl);
var jar = new http.CookieJar();
Expand All @@ -50,26 +39,26 @@ func TestAsyncRequest(t *testing.T) {
}
if (res.request["cookies"]["key2"][0].name != "key2") { throw new Error("wrong http request cookies: " + JSON.stringify(JSON.stringify(res.request["cookies"]["key2"]))) }
if (res.request["headers"]["User-Agent"][0] != "TestUserAgent") { throw new Error("wrong http request headers: " + JSON.stringify(res.request)) }
`))
`)))
assert.NoError(t, err)
})
t.Run("NonEmptyBody", func(t *testing.T) {
t.Parallel()
ts := newTestCase(t)

sr := ts.tb.Replacer.Replace
err := runOnEventLoop(ts.runtime, sr(`
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(sr(`
var res = await http.asyncRequest("POST", "HTTPBIN_URL/post", {a: "a", b: 2}, {headers: {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"}});
if (res.status != 200) { throw new Error("wrong status: " + res.status); }
if (res.request["body"] != "a=a&b=2") { throw new Error("http request body was not set properly: " + JSON.stringify(res.request))}
`))
`)))
assert.NoError(t, err)
})
t.Run("Concurrent", func(t *testing.T) {
t.Parallel()
ts := newTestCase(t)
sr := ts.tb.Replacer.Replace
err := runOnEventLoop(ts.runtime, sr(`
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(sr(`
let start = Date.now()
let p1 = http.asyncRequest("GET", "HTTPBIN_URL/delay/200ms").then(() => { return Date.now() - start})
let p2 = http.asyncRequest("GET", "HTTPBIN_URL/delay/100ms").then(() => { return Date.now() - start})
Expand All @@ -78,8 +67,7 @@ func TestAsyncRequest(t *testing.T) {
if (time1 < time2) {
throw("request that should've taken 200ms took less time then one that should take 100ms " + time1 +">" + time2 )
}

`))
`)))
assert.NoError(t, err)
})
}
Expand All @@ -102,7 +90,7 @@ func TestAsyncRequestResponseCallbackRace(t *testing.T) {
// t.Log(s) // uncomment for debugging
})
require.NoError(t, err)
err = runOnEventLoop(ts.runtime, ts.tb.Replacer.Replace(`
_, err = ts.runtime.RunOnEventLoop(wrapInAsyncLambda(ts.tb.Replacer.Replace(`
let call = (i) => {
log("s"+i)
if (i > 200) { return null; }
Expand All @@ -113,7 +101,7 @@ func TestAsyncRequestResponseCallbackRace(t *testing.T) {
call(0)
await http.asyncRequest("GET", "HTTPBIN_URL/redirect/20").then(() => log("!!!!!!!!!!!!!!!"+j))
}
`))
`)))
require.NoError(t, err)
}

Expand All @@ -126,13 +114,13 @@ func TestAsyncRequestErrors(t *testing.T) {
t.Parallel()
ts := newTestCase(t)

err := runOnEventLoop(ts.runtime, `
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(`
try {
http.asyncRequest("", "").catch((e) => globalThis.promiseRejected = e )
} catch (e) {
globalThis.exceptionThrown = e
}
`)
`))
require.NoError(t, err)
promiseRejected := ts.runtime.VU.Runtime().Get("promiseRejected")
exceptionThrown := ts.runtime.VU.Runtime().Get("exceptionThrown")
Expand All @@ -148,13 +136,13 @@ func TestAsyncRequestErrors(t *testing.T) {
t.Run("throw=false", func(t *testing.T) {
t.Parallel()
ts := newTestCase(t)
err := runOnEventLoop(ts.runtime, `
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(`
var res = await http.asyncRequest("GET", "some://example.com", null, { throw: false });
if (res.error.search('unsupported protocol scheme "some"') == -1) {
throw new Error("wrong error:" + res.error);
}
throw new Error("another error");
`)
`))
require.ErrorContains(t, err, "another error")

logEntry := ts.hook.LastEntry()
Expand All @@ -181,7 +169,7 @@ func TestAsyncRequestErrors(t *testing.T) {
globalThis.exceptionThrown = e
}
`
err := runOnEventLoop(ts.runtime, js)
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(js))
require.NoError(t, err)
promiseRejected := ts.runtime.VU.Runtime().Get("promiseRejected")
exceptionThrown := ts.runtime.VU.Runtime().Get("exceptionThrown")
Expand All @@ -203,7 +191,7 @@ func TestAsyncRequestErrors(t *testing.T) {
var r = await http.asyncRequest("GET", "https:// test.k6.io");
globalThis.ret = {error: r.error, error_code: r.error_code};
`
err := runOnEventLoop(ts.runtime, js)
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(js))
require.NoError(t, err)
ret := rt.GlobalObject().Get("ret")
var retobj map[string]interface{}
Expand Down Expand Up @@ -237,7 +225,7 @@ func TestAsyncRequestErrors(t *testing.T) {
r.json();
globalThis.ret = r.error_code; // not reached because of json()
`
err := runOnEventLoop(ts.runtime, js)
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(js))
ret := rt.GlobalObject().Get("ret")
require.Error(t, err)
assert.Nil(t, ret)
Expand All @@ -256,12 +244,12 @@ func TestAsyncRequestErrors(t *testing.T) {
t.Run("Unroutable", func(t *testing.T) {
t.Parallel()
ts := newTestCase(t)
err := runOnEventLoop(ts.runtime, `
_, err := ts.runtime.RunOnEventLoop(wrapInAsyncLambda(`
try {
http.asyncRequest("GET", "http://sdafsgdhfjg/").catch((e) => globalThis.promiseRejected = e )
} catch (e) {
globalThis.exceptionThrown = e
}`)
}`))
expErr := "lookup sdafsgdhfjg"
require.NoError(t, err)
promiseRejected := ts.runtime.VU.Runtime().Get("promiseRejected")
Expand Down
6 changes: 1 addition & 5 deletions js/modules/k6/http/response_callback_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,7 @@ func TestResponseCallbackInAction(t *testing.T) {
t.Helper()
ts.instance.defaultClient.responseCallback = defaultExpectedStatuses.match

err := ts.runtime.EventLoop.Start(func() error {
_, err := ts.runtime.VU.Runtime().RunString(sr(code))
return err
})
ts.runtime.EventLoop.WaitOnRegistered()
_, err := ts.runtime.RunOnEventLoop(sr(code))
assert.NoError(t, err)
bufSamples := metrics.GetBufferedSamples(samples)

Expand Down
Loading