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

Fix k6 Hosts option incompatibility #671

Merged
merged 1 commit into from
Dec 8, 2022
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
46 changes: 35 additions & 11 deletions chromium/browser_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package chromium

import (
"context"
"encoding/json"
"errors"
"fmt"
"math/rand"
Expand Down Expand Up @@ -161,10 +162,11 @@ func (b *BrowserType) launch(ctx context.Context, opts *common.LaunchOptions) (*
for k, v := range opts.Env {
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
}
var (
flags = prepareFlags(opts, &(b.vu.State()).Options)
dataDir = b.storage
)
flags, err := prepareFlags(opts, &(b.vu.State()).Options)
if err != nil {
return nil, fmt.Errorf("%w", err)
}
dataDir := b.storage
if err := dataDir.Make("", flags["user-data-dir"]); err != nil {
return nil, fmt.Errorf("%w", err)
}
Expand Down Expand Up @@ -279,7 +281,7 @@ func parseArgs(flags map[string]any) ([]string, error) {
return args, nil
}

func prepareFlags(lopts *common.LaunchOptions, k6opts *k6lib.Options) map[string]any {
func prepareFlags(lopts *common.LaunchOptions, k6opts *k6lib.Options) (map[string]any, error) {
// After Puppeteer's and Playwright's default behavior.
f := map[string]any{
"disable-background-networking": true,
Expand Down Expand Up @@ -327,9 +329,11 @@ func prepareFlags(lopts *common.LaunchOptions, k6opts *k6lib.Options) map[string
ignoreDefaultArgsFlags(f, lopts.IgnoreDefaultArgs)

setFlagsFromArgs(f, lopts.Args)
setFlagsFromK6Options(f, k6opts)
if err := setFlagsFromK6Options(f, k6opts); err != nil {
return nil, err
}

return f
return f, nil
}

// ignoreDefaultArgsFlags ignores any flags in the provided slice.
Expand All @@ -356,24 +360,44 @@ func setFlagsFromArgs(flags map[string]any, args []string) {

// setFlagsFromK6Options adds additional data to flags considering the k6 options.
// Such as: "host-resolver-rules" for blocking requests.
func setFlagsFromK6Options(flags map[string]any, k6opts *k6lib.Options) {
func setFlagsFromK6Options(flags map[string]any, k6opts *k6lib.Options) error {
if k6opts == nil {
return
return nil
}

hostResolver := []string{}
if currHostResolver, ok := flags["host-resolver-rules"]; ok {
hostResolver = append(hostResolver, fmt.Sprintf("%s", currHostResolver))
}

for k, v := range k6opts.Hosts {
// Add the host resolver rules.
//
// This is done by marshaling the k6 hosts option to JSON and then
// unmarshaling it to a map[string]string. This is done because the
// k6 v0.42 changed Hosts from a map to types.NullHosts and doesn't
// expose the map anymore.
//
// TODO: A better way to do this would be to handle the resolver
// rules by communicating with Chromium (and then using Hosts's
// Match method) instead of passing the rules via the command line
// to Chromium.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would we communicate with the chromium? CDP? I don't know why that would be better than passing the rules via the command line. Maybe we need another issue for that? 🙂

Copy link
Member Author

@inancgumus inancgumus Dec 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I'll create another issue next week. Let's get this issue out of the way since we're rushing 🏃 Reminder set 👍😄

var rules map[string]string
b, err := json.Marshal(k6opts.Hosts)
if err != nil {
return fmt.Errorf("marshaling hosts option: %w", err)
}
if err := json.Unmarshal(b, &rules); err != nil {
return fmt.Errorf("unmarshaling hosts option: %w", err)
}
for k, v := range rules {
hostResolver = append(hostResolver, fmt.Sprintf("MAP %s %s", k, v))
}

if len(hostResolver) > 0 {
sort.Strings(hostResolver)
flags["host-resolver-rules"] = strings.Join(hostResolver, ",")
}

return nil
}

// makeLogger makes and returns an extension wide logger.
Expand Down
23 changes: 15 additions & 8 deletions chromium/browser_type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/grafana/xk6-browser/common"

k6lib "go.k6.io/k6/lib"
"go.k6.io/k6/lib/types"
k6types "go.k6.io/k6/lib/types"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand All @@ -16,8 +18,14 @@ import (
func TestBrowserTypePrepareFlags(t *testing.T) {
t.Parallel()

host, err := k6lib.NewHostAddress(net.ParseIP("127.0.0.1"), "8000")
require.NoError(t, err)
// to be used by the tests below
host, err := k6types.NewHost(net.ParseIP("127.0.0.1"), "8000")
require.NoError(t, err, "failed to set up test host")
hosts, err := k6types.NewHosts(map[string]k6types.Host{
"test.k6.io": *host,
"httpbin.test.k6.io": *host,
})
require.NoError(t, err, "failed to set up test hosts")

testCases := []struct {
flag string
Expand Down Expand Up @@ -91,10 +99,7 @@ func TestBrowserTypePrepareFlags(t *testing.T) {
`host-resolver-rules="MAP * www.example.com, EXCLUDE *.youtube.*"`,
}},
changeK6Opts: &k6lib.Options{
Hosts: map[string]*k6lib.HostAddress{
"test.k6.io": host,
"httpbin.test.k6.io": host,
},
Hosts: types.NullHosts{Trie: hosts, Valid: true},
},
expChangedVal: "MAP * www.example.com, EXCLUDE *.youtube.*," +
"MAP httpbin.test.k6.io 127.0.0.1:8000,MAP test.k6.io 127.0.0.1:8000",
Expand Down Expand Up @@ -141,7 +146,8 @@ func TestBrowserTypePrepareFlags(t *testing.T) {
tc.pre(t)
}

flags := prepareFlags(&common.LaunchOptions{}, nil)
flags, err := prepareFlags(&common.LaunchOptions{}, nil)
require.NoError(t, err, "failed to prepare flags")

if tc.expInitVal != nil {
require.Contains(t, flags, tc.flag)
Expand All @@ -151,7 +157,8 @@ func TestBrowserTypePrepareFlags(t *testing.T) {
}

if tc.changeOpts != nil || tc.changeK6Opts != nil {
flags = prepareFlags(tc.changeOpts, tc.changeK6Opts)
flags, err = prepareFlags(tc.changeOpts, tc.changeK6Opts)
require.NoError(t, err, "failed to prepare flags")
if tc.expChangedVal != nil {
assert.Equal(t, tc.expChangedVal, flags[tc.flag])
} else {
Expand Down
33 changes: 29 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.19

require (
github.com/chromedp/cdproto v0.0.0-20221023212508-67ada9507fb2
github.com/dop251/goja v0.0.0-20221025095645-e66ebd086f45
github.com/dop251/goja v0.0.0-20221106173738-3b8a68ca89b4
github.com/fatih/color v1.13.0
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/go-multierror v1.1.1
Expand All @@ -13,44 +13,69 @@ require (
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.0
go.k6.io/k6 v0.41.0
go.k6.io/k6 v0.41.1-0.20221206194017-a2ab89abfdc8
golang.org/x/exp v0.0.0-20221106115401-f9659909a136
golang.org/x/net v0.1.0
gopkg.in/guregu/null.v3 v3.5.0
)

require (
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
github.com/DataDog/datadog-go v0.0.0-20180330214955-e67964b4021a // indirect
github.com/PuerkitoBio/goquery v1.8.0 // indirect
github.com/Soontao/goHttpDigestClient v0.0.0-20170320082612-6d28bb1415c5 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/chromedp/sysutil v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-sourcemap/sourcemap v2.1.4-0.20211119122758-180fcef48034+incompatible // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/grafana/xk6-output-prometheus-remote v0.0.8 // indirect
github.com/grafana/xk6-redis v0.1.1 // indirect
github.com/grafana/xk6-timers v0.1.2 // indirect
github.com/grafana/xk6-websockets v0.1.6 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc // indirect
github.com/jhump/protoreflect v1.13.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.15.11 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mstoykov/atlas v0.0.0-20220811071828-388f114305dd // indirect
github.com/mstoykov/envconfig v1.4.1-0.20220114105314-765c6d8c76f1 // indirect
github.com/mstoykov/k6-taskqueue-lib v0.1.0 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.18.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.14.1-0.20221122130035-8b6e68085b10 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/serenize/snaker v0.0.0-20201027110005-a7ad2135616e // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cobra v1.4.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tidwall/gjson v1.14.3 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
go.buf.build/grpc/go/gogo/protobuf v1.4.9 // indirect
go.buf.build/grpc/go/prometheus/prometheus v1.4.4 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/term v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/time v0.1.0 // indirect
google.golang.org/genproto v0.0.0-20220308174144-ae0e22291548 // indirect
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
google.golang.org/grpc v1.49.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading