Skip to content
Open
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
30 changes: 26 additions & 4 deletions js/modules/k6/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,36 @@ func (r *RootModule) NewModuleInstance(vu modules.VU) modules.Instance {
// wrappers (facades) that convert the old k6 idiosyncratic APIs to the new
// proper Client ones that accept Request objects and don't suck
mustExport("get", func(url sobek.Value, args ...sobek.Value) (*Response, error) {
// http.get(url, params) doesn't have a body argument, so we add undefined
// as the third argument to http.request(method, url, body, params)
// http.get(url, params) only accepts a URL and an optional params argument.
// It does not accept a body argument like http.post or http.put.
// Warn the user if they pass more arguments than expected, as they likely
// intended to pass a body (e.g. http.get(url, body, params)), which is
// not supported by HTTP GET.
if len(args) > 1 {
state := mi.vu.State()
if state != nil {
state.Logger.Warnf(
"http.get only accepts a url and an optional params argument. %.0f extra argument(s) will be ignored.",
float64(len(args)-1),
)
}
}
args = append([]sobek.Value{sobek.Undefined()}, args...)
return mi.defaultClient.Request(http.MethodGet, url, args...)
})
mustExport("head", func(url sobek.Value, args ...sobek.Value) (*Response, error) {
// http.head(url, params) doesn't have a body argument, so we add undefined
// as the third argument to http.request(method, url, body, params)
// http.head(url, params) only accepts a URL and an optional params argument.
// It does not accept a body argument like http.post or http.put.
// Warn the user if they pass more arguments than expected.
if len(args) > 1 {
state := mi.vu.State()
if state != nil {
state.Logger.Warnf(
"http.head only accepts a url and an optional params argument. %.0f extra argument(s) will be ignored.",
float64(len(args)-1),
)
}
}
args = append([]sobek.Value{sobek.Undefined()}, args...)
return mi.defaultClient.Request(http.MethodHead, url, args...)
})
Expand Down
81 changes: 81 additions & 0 deletions js/modules/k6/http/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2401,3 +2401,84 @@ func TestGzipped204Response(t *testing.T) {
`))
assert.NoError(t, err)
}

func TestExtraArgsWarning(t *testing.T) {
t.Parallel()
ts := newTestCase(t)
tb := ts.tb
rt := ts.runtime.VU.Runtime()

sr := tb.Replacer.Replace

t.Run("http.get", func(t *testing.T) {
t.Run("no warning with 0 args", func(t *testing.T) {
ts.hook.Drain() // clear previous log entries
_, err := rt.RunString(sr(`http.get("HTTPBIN_URL/get");`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.get only accepts")
assert.Empty(t, entries)
})

t.Run("no warning with 1 arg", func(t *testing.T) {
ts.hook.Drain()
_, err := rt.RunString(sr(`http.get("HTTPBIN_URL/get", null);`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.get only accepts")
assert.Empty(t, entries)
})

t.Run("warning with 2 args", func(t *testing.T) {
ts.hook.Drain()
_, err := rt.RunString(sr(`http.get("HTTPBIN_URL/get", null, null);`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.get only accepts")
require.Len(t, entries, 1)
assert.Contains(t, entries[0].Message, "1 extra argument(s) will be ignored")
})

t.Run("warning with 3 args", func(t *testing.T) {
ts.hook.Drain()
_, err := rt.RunString(sr(`http.get("HTTPBIN_URL/get", null, null, null);`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.get only accepts")
require.Len(t, entries, 1)
assert.Contains(t, entries[0].Message, "2 extra argument(s) will be ignored")
})
})

t.Run("http.head", func(t *testing.T) {
t.Run("no warning with 0 args", func(t *testing.T) {
ts.hook.Drain()
_, err := rt.RunString(sr(`http.head("HTTPBIN_URL/get");`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.head only accepts")
assert.Empty(t, entries)
})

t.Run("no warning with 1 arg", func(t *testing.T) {
ts.hook.Drain()
_, err := rt.RunString(sr(`http.head("HTTPBIN_URL/get", null);`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.head only accepts")
assert.Empty(t, entries)
})

t.Run("warning with 2 args", func(t *testing.T) {
ts.hook.Drain()
_, err := rt.RunString(sr(`http.head("HTTPBIN_URL/get", null, null);`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.head only accepts")
require.Len(t, entries, 1)
assert.Contains(t, entries[0].Message, "1 extra argument(s) will be ignored")
})

t.Run("warning with 3 args", func(t *testing.T) {
ts.hook.Drain()
_, err := rt.RunString(sr(`http.head("HTTPBIN_URL/get", null, null, null);`))
require.NoError(t, err)
entries := testutils.FilterEntries(ts.hook.Drain(), logrus.WarnLevel, "http.head only accepts")
require.Len(t, entries, 1)
assert.Contains(t, entries[0].Message, "2 extra argument(s) will be ignored")
})
})
}
Loading