From 4a36c60d9e9fe679722f287e1955bb8e613bb209 Mon Sep 17 00:00:00 2001 From: Tine Date: Wed, 21 Feb 2024 14:09:22 +0100 Subject: [PATCH] refactor(k6): simplify code --- go.mod | 12 -- go.sum | 27 --- internal/activities/healthcheck.go | 5 +- pkg/k6/env.go | 22 +++ pkg/k6/k6.go | 301 +++++++---------------------- pkg/k6/k6_test.go | 8 +- pkg/k6/test.go | 148 ++++++++++++++ 7 files changed, 244 insertions(+), 279 deletions(-) create mode 100644 pkg/k6/env.go create mode 100644 pkg/k6/test.go diff --git a/go.mod b/go.mod index 4d021d5..42b47f7 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,6 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.0 github.com/gorilla/sessions v1.2.2 github.com/gosimple/slug v1.13.1 - github.com/grafana/xk6-dashboard v0.7.2 - github.com/grafana/xk6-output-prometheus-remote v0.3.1 github.com/labstack/echo/v4 v4.11.4 github.com/lib/pq v1.10.9 github.com/pkg/errors v0.9.1 @@ -28,15 +26,12 @@ require ( replace go.temporal.io/server => github.com/temporalio/temporal v1.23.0-rc2.0.20240207154935-68882596be5d require ( - buf.build/gen/go/gogo/protobuf/protocolbuffers/go v1.31.0-20210810001428-4df00b267f94.1 // indirect - buf.build/gen/go/prometheus/prometheus/protocolbuffers/go v1.31.0-20230627135113-9a12bc2590d2.1 // indirect cloud.google.com/go v0.112.0 // indirect cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.5 // indirect cloud.google.com/go/storage v1.36.0 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect - github.com/DataDog/datadog-go v0.0.0-20180330214955-e67964b4021a // indirect github.com/PuerkitoBio/goquery v1.8.1 // indirect github.com/Soontao/goHttpDigestClient v0.0.0-20170320082612-6d28bb1415c5 // indirect github.com/andybalholm/brotli v1.0.6 // indirect @@ -98,8 +93,6 @@ require ( github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgx/v5 v5.4.3 // indirect @@ -122,7 +115,6 @@ require ( github.com/mccutchen/go-httpbin v1.1.2-0.20190116014521-c5cb2f4802fa // indirect github.com/mitchellh/mapstructure v1.5.0 // 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/ncruces/go-strftime v0.1.9 // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect @@ -130,13 +122,11 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.0 // indirect - github.com/r3labs/sse/v2 v2.10.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/redis/go-redis/v9 v9.0.5 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect @@ -148,7 +138,6 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.4.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/stretchr/testify v1.8.4 // indirect @@ -203,7 +192,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect google.golang.org/grpc v1.61.0 // indirect google.golang.org/protobuf v1.32.0 // indirect - gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/guregu/null.v3 v3.3.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 9f3a1e8..84f8929 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,3 @@ -buf.build/gen/go/gogo/protobuf/protocolbuffers/go v1.31.0-20210810001428-4df00b267f94.1 h1:IpfoSUtXcmtXmL672yCeHx96evE7Z4AyWo8R2lVBU3o= -buf.build/gen/go/gogo/protobuf/protocolbuffers/go v1.31.0-20210810001428-4df00b267f94.1/go.mod h1:Az9fvKFYQGtiDa7cPW9T3Nbw8u3hpmD6wG15RsbQlA0= -buf.build/gen/go/prometheus/prometheus/protocolbuffers/go v1.31.0-20230627135113-9a12bc2590d2.1 h1:aAMGEehZVBrkvsvQYwE4yNrXRYkSX84eZpRaKPiDuxg= -buf.build/gen/go/prometheus/prometheus/protocolbuffers/go v1.31.0-20230627135113-9a12bc2590d2.1/go.mod h1:iqW5nSujn3ZJ9ISZQX3K/uWwjckAp8hz0J4/wNgFBZo= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= @@ -19,8 +15,6 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v0.0.0-20180330214955-e67964b4021a h1:zpQSzEApXM0qkXcpdjeJ4OpnBWhD/X8zT/iT1wYLiVU= -github.com/DataDog/datadog-go v0.0.0-20180330214955-e67964b4021a/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= @@ -89,7 +83,6 @@ github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbi github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b/go.mod h1:v9FBN7gdVTpiD/+LZ7Po0UKvROyT87uLVxTHVky/dlQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -250,10 +243,6 @@ github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6 github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/grafana/xk6-browser v1.3.0 h1:NFDvx56O77e4dBWFIUYQ733lzgbClcVH2Kn/yaACWjM= github.com/grafana/xk6-browser v1.3.0/go.mod h1:Y7fN+spgo9LVLfpxWdkki1bY5EKUk+5B6xaYp4DotPA= -github.com/grafana/xk6-dashboard v0.7.2 h1:CLaWeRfPZ388IS6rBn0nI+lqtX50QoQ73z0Hz5BIrS4= -github.com/grafana/xk6-dashboard v0.7.2/go.mod h1:7HLAY4udlWGXGDQL5gWIi+In3eZRljXi8AnHt1Z+lFM= -github.com/grafana/xk6-output-prometheus-remote v0.3.1 h1:X23rQzlJD8dXWB31DkxR4uPnuRFo8L0Y0H22fSG9xl0= -github.com/grafana/xk6-output-prometheus-remote v0.3.1/go.mod h1:0JLAm4ONsNUlNoxJXAwOCfA6GtDwTPs557OplAvE+3o= github.com/grafana/xk6-redis v0.2.0 h1:iXmAKVlAxafZ/h8ptuXTFhGu63IFsyDI8QjUgWm66BU= github.com/grafana/xk6-redis v0.2.0/go.mod h1:B3PA9PAPJa2/WUfNJCdQwZrbb6D4e6UHIk8dssQbj7w= github.com/grafana/xk6-timers v0.2.3 h1:uShQZ6T+9fpCc9j8AAuBPRMKNneG/TRtkM1uuwhXH4g= @@ -273,10 +262,6 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc h1:KpMgaYJRieDkHZJWY3LMafvtqS/U8xX6+lUN+OKpl/Y= -github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= @@ -389,8 +374,6 @@ github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= -github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -423,8 +406,6 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= -github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/rcrowley/go-metrics v0.0.0-20141108142129-dee209f2455f/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -440,7 +421,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -460,8 +440,6 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= @@ -625,7 +603,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -677,7 +654,6 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -774,12 +750,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= -gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/activities/healthcheck.go b/internal/activities/healthcheck.go index d3a17df..aa609f6 100644 --- a/internal/activities/healthcheck.go +++ b/internal/activities/healthcheck.go @@ -2,10 +2,10 @@ package activities import ( "context" + "log/slog" "net/http" "code.tjo.space/mentos1386/zdravko/pkg/k6" - "go.k6.io/k6/cmd/state" ) type HealtcheckParam struct { @@ -20,8 +20,7 @@ func Healthcheck(ctx context.Context, param HealtcheckParam) (*HealthcheckResult statusCode := http.StatusOK // FIXME - state := state.NewGlobalState(ctx) - execution := k6.NewExecution(state, param.Script) + execution := k6.NewExecution(slog.Default(), param.Script) err := execution.Start(ctx) if err != nil { diff --git a/pkg/k6/env.go b/pkg/k6/env.go new file mode 100644 index 0000000..5422b83 --- /dev/null +++ b/pkg/k6/env.go @@ -0,0 +1,22 @@ +package k6 + +import "strings" + +// ParseEnvKeyValue splits an environment variable string into key and value. +func ParseEnvKeyValue(kv string) (string, string) { + if idx := strings.IndexRune(kv, '='); idx != -1 { + return kv[:idx], kv[idx+1:] + } + return kv, "" +} + +// BuildEnvMap returns a map from raw environment values, such as returned from +// os.Environ(). +func BuildEnvMap(environ []string) map[string]string { + env := make(map[string]string, len(environ)) + for _, kv := range environ { + k, v := ParseEnvKeyValue(kv) + env[k] = v + } + return env +} diff --git a/pkg/k6/k6.go b/pkg/k6/k6.go index e6b1c10..0fe58f3 100644 --- a/pkg/k6/k6.go +++ b/pkg/k6/k6.go @@ -2,39 +2,31 @@ package k6 import ( "context" - "crypto/x509" "fmt" "io" + "log/slog" "net/url" + "os" "strings" "sync" "time" "github.com/sirupsen/logrus" - "go.k6.io/k6/cmd/state" "go.k6.io/k6/errext" "go.k6.io/k6/errext/exitcodes" "go.k6.io/k6/event" "go.k6.io/k6/execution" "go.k6.io/k6/execution/local" - "go.k6.io/k6/js" "go.k6.io/k6/js/common" - "go.k6.io/k6/js/modules" "go.k6.io/k6/lib" - "go.k6.io/k6/lib/executor" "go.k6.io/k6/lib/fsext" "go.k6.io/k6/lib/trace" - "go.k6.io/k6/lib/types" "go.k6.io/k6/loader" "go.k6.io/k6/metrics" "go.k6.io/k6/metrics/engine" "go.k6.io/k6/output" ) -const ( - testTypeJS = "js" -) - const ( // We use an excessively high timeout to wait for event processing to complete, // since prematurely proceeding before it is done could create bigger problems. @@ -47,223 +39,85 @@ const ( waitForTracerProviderStopTimeout = 3 * time.Minute ) -// loadedTest contains all of data, details and dependencies of a loaded -// k6 test, but without any config consolidation. -type loadedTest struct { - sourceRootPath string // contains the raw string the user supplied - pwd string - source *loader.SourceData - fs fsext.Fs - fileSystems map[string]fsext.Fs - preInitState *lib.TestPreInitState - initRunner lib.Runner // TODO: rename to something more appropriate - keyLogger io.Closer - moduleResolver *modules.ModuleResolver +type Execution struct { + FS fsext.Fs + Env map[string]string + Events *event.System + + LoggerCompat *logrus.Logger + + Script string + + Logger *slog.Logger } -func loadLocalTest(gs *state.GlobalState, script string) (*loadedTest, error) { - src, fileSystems, pwd, err := readSource(gs, script) - if err != nil { - return nil, err +func NewExecution(logger *slog.Logger, script string) *Execution { + loggerCompat := logrus.StandardLogger() + + return &Execution{ + FS: fsext.NewOsFs(), + Env: BuildEnvMap(os.Environ()), + Events: event.NewEventSystem(100, loggerCompat), + LoggerCompat: loggerCompat, + Logger: logger, + Script: script, } - resolvedPath := src.URL.String() - gs.Logger.Debugf( - "successfully loaded %d bytes!", - len(src.Data), +} + +func (e *Execution) loadLocalTest() (*loadedAndConfiguredTest, *local.Controller, error) { + data := []byte(e.Script) + + fileSystems := loader.CreateFilesystems(e.FS) + + err := fsext.WriteFile(fileSystems["file"].(fsext.CacheLayerGetter).GetCachingFs(), "/-", data, 0o644) + if err != nil { + return nil, nil, fmt.Errorf("caching data read from -: %w", err) + } + + src := &loader.SourceData{URL: &url.URL{Path: "/-", Scheme: "file"}, Data: data} + e.Logger.Debug( + "successfully loaded bytes!", + "bytes", len(src.Data), ) - gs.Logger.Debugf("Gathering k6 runtime options...") + e.Logger.Debug("Gathering k6 runtime options...") runtimeOptions := lib.RuntimeOptions{} registry := metrics.NewRegistry() state := &lib.TestPreInitState{ - Logger: gs.Logger, + Logger: e.LoggerCompat, RuntimeOptions: runtimeOptions, Registry: registry, BuiltinMetrics: metrics.RegisterBuiltinMetrics(registry), - Events: gs.Events, + Events: e.Events, LookupEnv: func(key string) (string, bool) { - val, ok := gs.Env[key] + val, ok := e.Env[key] return val, ok }, } test := &loadedTest{ - pwd: pwd, - sourceRootPath: "-", - source: src, - fs: gs.FS, - fileSystems: fileSystems, - preInitState: state, + source: src, + fs: e.FS, + fileSystems: fileSystems, + preInitState: state, + logger: e.Logger, + loggerCompat: e.LoggerCompat, } - gs.Logger.Debugf("Initializing k6 runner for (%s)...", resolvedPath) - if err := test.initializeFirstRunner(gs); err != nil { - return nil, fmt.Errorf("could not initialize: %w", err) + e.Logger.Debug("Initializing k6 runner...") + if err := test.initializeFirstRunner(); err != nil { + return nil, nil, fmt.Errorf("could not initialize: %w", err) } - gs.Logger.Debug("Runner successfully initialized!") - return test, nil -} + e.Logger.Debug("Runner successfully initialized!") -func (lt *loadedTest) initializeFirstRunner(gs *state.GlobalState) error { - testPath := lt.source.URL.String() - logger := gs.Logger.WithField("test_path", testPath) - - testType := lt.preInitState.RuntimeOptions.TestType.String - if testType == "" { - testType = testTypeJS - } - - // TODO: k6-cli also has TAR support which might be nice to have. - switch testType { - case testTypeJS: - logger.Debug("Trying to load as a JS test...") - runner, err := js.New(lt.preInitState, lt.source, lt.fileSystems) - // TODO: should we use common.UnwrapGojaInterruptedError() here? - if err != nil { - return fmt.Errorf("could not load JS test '%s': %w", testPath, err) - } - lt.initRunner = runner - lt.moduleResolver = runner.Bundle.ModuleResolver - return nil - default: - return fmt.Errorf("unknown or unspecified test type '%s' for '%s'", testType, testPath) - } -} - -// readSource is a small wrapper around loader.ReadSource returning -// result of the load and filesystems map -func readSource(gs *state.GlobalState, script string) (*loader.SourceData, map[string]fsext.Fs, string, error) { - data := []byte(script) - - filesystems := loader.CreateFilesystems(gs.FS) - - err := fsext.WriteFile(filesystems["file"].(fsext.CacheLayerGetter).GetCachingFs(), "/-", data, 0o644) + configuredTest, err := test.consolidateDeriveAndValidateConfig() if err != nil { - return nil, nil, "", fmt.Errorf("caching data read from -: %w", err) + return nil, nil, err } - return &loader.SourceData{URL: &url.URL{Path: "/-", Scheme: "file"}, Data: data}, filesystems, "/", err -} - -func (lt *loadedTest) consolidateDeriveAndValidateConfig( - gs *state.GlobalState, -) (*loadedAndConfiguredTest, error) { - gs.Logger.Debug("Consolidating config layers...") - - config := lib.Options{} - - config.Apply(lt.initRunner.GetOptions()) - if config.SystemTags == nil { - config.SystemTags = &metrics.DefaultSystemTagSet - } - if config.SummaryTrendStats == nil { - config.SummaryTrendStats = lib.DefaultSummaryTrendStats - } - defDNS := types.DefaultDNSConfig() - if !config.DNS.TTL.Valid { - config.DNS.TTL = defDNS.TTL - } - if !config.DNS.Select.Valid { - config.DNS.Select = defDNS.Select - } - if !config.DNS.Policy.Valid { - config.DNS.Policy = defDNS.Policy - } - if !config.SetupTimeout.Valid { - config.SetupTimeout.Duration = types.Duration(60 * time.Second) - } - if !config.TeardownTimeout.Valid { - config.TeardownTimeout.Duration = types.Duration(60 * time.Second) - } - - gs.Logger.Debug("Parsing thresholds and validating config...") - // Parse the thresholds, only if the --no-threshold flag is not set. - // If parsing the threshold expressions failed, consider it as an - // invalid configuration error. - if !lt.preInitState.RuntimeOptions.NoThresholds.Bool { - for metricName, thresholdsDefinition := range config.Thresholds { - err := thresholdsDefinition.Parse() - if err != nil { - return nil, errext.WithExitCodeIfNone(err, exitcodes.InvalidConfig) - } - - err = thresholdsDefinition.Validate(metricName, lt.preInitState.Registry) - if err != nil { - return nil, errext.WithExitCodeIfNone(err, exitcodes.InvalidConfig) - } - } - } - - config, err := executor.DeriveScenariosFromShortcuts(config, gs.Logger) - if err == nil { - errors := config.Validate() - // FIXME: should show them all. - if len(errors) > 0 { - err = errors[0] - } - } - if err != nil { - return nil, err - } - - return &loadedAndConfiguredTest{ - loadedTest: lt, - config: config, - }, nil -} - -// loadedAndConfiguredTest contains the whole loadedTest, as well as the -// consolidated test config and the full test run state. -type loadedAndConfiguredTest struct { - *loadedTest - config lib.Options -} - -func loadAndConfigureLocalTest( - gs *state.GlobalState, - script string, -) (*loadedAndConfiguredTest, error) { - test, err := loadLocalTest(gs, script) - if err != nil { - return nil, err - } - - return test.consolidateDeriveAndValidateConfig(gs) -} - -// loadSystemCertPool attempts to load system certificates. -func loadSystemCertPool(logger logrus.FieldLogger) { - if _, err := x509.SystemCertPool(); err != nil { - logger.WithError(err).Warning("Unable to load system cert pool") - } -} - -func (lct *loadedAndConfiguredTest) buildTestRunState( - configToReinject lib.Options, -) (*lib.TestRunState, error) { - // This might be the full derived or just the consodlidated options - if err := lct.initRunner.SetOptions(configToReinject); err != nil { - return nil, err - } - - // it pre-loads system certificates to avoid doing it on the first TLS request. - // This is done async to avoid blocking the rest of the loading process as it will not stop if it fails. - go loadSystemCertPool(lct.preInitState.Logger) - - return &lib.TestRunState{ - TestPreInitState: lct.preInitState, - Runner: lct.initRunner, - Options: lct.config, - RunTags: lct.preInitState.Registry.RootTagSet().WithTagsFromMap(configToReinject.RunTags), - }, nil -} - -type Execution struct { - gs *state.GlobalState - - // TODO: figure out something more elegant? - loadConfiguredTest func() (*loadedAndConfiguredTest, execution.Controller, error) + controller := local.NewController() + return configuredTest, controller, nil } func (e *Execution) setupTracerProvider(ctx context.Context, test *loadedAndConfiguredTest) error { @@ -282,16 +136,6 @@ func (e *Execution) setupTracerProvider(ctx context.Context, test *loadedAndConf return nil } -func NewExecution(gs *state.GlobalState, script string) *Execution { - return &Execution{ - gs: gs, - loadConfiguredTest: func() (*loadedAndConfiguredTest, execution.Controller, error) { - test, err := loadAndConfigureLocalTest(gs, script) - return test, local.NewController(), err - }, - } -} - func (e *Execution) Start(ctx context.Context) error { var err error var logger logrus.FieldLogger = logrus.StandardLogger() @@ -310,7 +154,7 @@ func (e *Execution) Start(ctx context.Context) error { runCtx, runAbort := execution.NewTestRunContext(lingerCtx, logger) emitEvent := func(evt *event.Event) func() { - waitDone := e.gs.Events.Emit(evt) + waitDone := e.Events.Emit(evt) return func() { waitCtx, waitCancel := context.WithTimeout(globalCtx, waitEventDoneTimeout) defer waitCancel() @@ -326,35 +170,28 @@ func (e *Execution) Start(ctx context.Context) error { Data: &event.ExitData{Error: err}, }) waitExitDone() - e.gs.Events.UnsubscribeAll() + e.Events.UnsubscribeAll() }() - test, controller, err := e.loadConfiguredTest() + configuredTest, controller, err := e.loadLocalTest() if err != nil { return err } - if test.keyLogger != nil { - defer func() { - if klErr := test.keyLogger.Close(); klErr != nil { - logger.WithError(klErr).Warn("Error while closing the SSLKEYLOGFILE") - } - }() - } - if err = e.setupTracerProvider(globalCtx, test); err != nil { + if err = e.setupTracerProvider(globalCtx, configuredTest); err != nil { return err } waitTracesFlushed := func() { ctx, cancel := context.WithTimeout(globalCtx, waitForTracerProviderStopTimeout) defer cancel() - if tpErr := test.preInitState.TracerProvider.Shutdown(ctx); tpErr != nil { + if tpErr := configuredTest.preInitState.TracerProvider.Shutdown(ctx); tpErr != nil { logger.Errorf("The tracer provider didn't stop gracefully: %v", tpErr) } } // Write the full consolidated *and derived* options back to the Runner. - conf := test.config - testRunState, err := test.buildTestRunState(conf) + conf := configuredTest.config + testRunState, err := configuredTest.buildTestRunState(conf) if err != nil { return err } @@ -398,19 +235,19 @@ func (e *Execution) Start(ctx context.Context) error { if !testRunState.RuntimeOptions.NoSummary.Bool { defer func() { logger.Debug("Generating the end-of-test summary...") - summaryResult, hsErr := test.initRunner.HandleSummary(globalCtx, &lib.Summary{ + summaryResult, hsErr := configuredTest.initRunner.HandleSummary(globalCtx, &lib.Summary{ Metrics: metricsEngine.ObservedMetrics, RootGroup: testRunState.Runner.GetDefaultGroup(), TestRunDuration: executionState.GetCurrentTestRunDuration(), - NoColor: e.gs.Flags.NoColor, + NoColor: true, UIState: lib.UIState{ - IsStdOutTTY: e.gs.Stdout.IsTTY, - IsStdErrTTY: e.gs.Stderr.IsTTY, + IsStdOutTTY: false, + IsStdErrTTY: false, }, }) if hsErr == nil { for _, o := range summaryResult { - _, err := io.Copy(e.gs.Stdout, o) + _, err := io.Copy(os.Stdout, o) if err != nil { logger.WithError(err).Error("failed to write summary output") } @@ -431,7 +268,7 @@ func (e *Execution) Start(ctx context.Context) error { // TODO: attach run status and exit code? runAbort(err) }) - samples := make(chan metrics.SampleContainer, test.config.MetricSamplesBufferSize.Int64) + samples := make(chan metrics.SampleContainer, configuredTest.config.MetricSamplesBufferSize.Int64) waitOutputsFlushed, stopOutputs, err := outputManager.Start(samples) if err != nil { return err diff --git a/pkg/k6/k6_test.go b/pkg/k6/k6_test.go index 078fc06..41e694d 100644 --- a/pkg/k6/k6_test.go +++ b/pkg/k6/k6_test.go @@ -2,15 +2,13 @@ package k6 import ( "context" + "log/slog" "testing" - - "go.k6.io/k6/cmd/state" ) func TestK6(t *testing.T) { ctx := context.Background() - - state := state.NewGlobalState(ctx) + logger := slog.Default() script := ` import http from 'k6/http'; @@ -27,7 +25,7 @@ export default function () { } ` - execution := NewExecution(state, script) + execution := NewExecution(logger, script) err := execution.Start(ctx) if err != nil { diff --git a/pkg/k6/test.go b/pkg/k6/test.go new file mode 100644 index 0000000..63d41be --- /dev/null +++ b/pkg/k6/test.go @@ -0,0 +1,148 @@ +package k6 + +import ( + "crypto/x509" + "fmt" + "log/slog" + "time" + + "github.com/sirupsen/logrus" + "go.k6.io/k6/errext" + "go.k6.io/k6/errext/exitcodes" + "go.k6.io/k6/js" + "go.k6.io/k6/js/modules" + "go.k6.io/k6/lib" + "go.k6.io/k6/lib/executor" + "go.k6.io/k6/lib/fsext" + "go.k6.io/k6/lib/types" + "go.k6.io/k6/loader" + "go.k6.io/k6/metrics" +) + +// loadedTest contains all of data, details and dependencies of a loaded +// k6 test, but without any config consolidation. +type loadedTest struct { + source *loader.SourceData + fs fsext.Fs + fileSystems map[string]fsext.Fs + preInitState *lib.TestPreInitState + initRunner lib.Runner // TODO: rename to something more appropriate + moduleResolver *modules.ModuleResolver + + logger *slog.Logger + loggerCompat *logrus.Logger +} + +func (lt *loadedTest) initializeFirstRunner() error { + testPath := lt.source.URL.String() + logger := lt.logger.With("test_path", testPath) + + logger.Debug("Trying to load as a JS test...") + runner, err := js.New(lt.preInitState, lt.source, lt.fileSystems) + // TODO: should we use common.UnwrapGojaInterruptedError() here? + if err != nil { + return fmt.Errorf("could not load JS test '%s': %w", testPath, err) + } + lt.initRunner = runner + lt.moduleResolver = runner.Bundle.ModuleResolver + return nil +} + +func (lt *loadedTest) consolidateDeriveAndValidateConfig() (*loadedAndConfiguredTest, error) { + lt.logger.Debug("Consolidating config layers...") + + config := lib.Options{} + + config.Apply(lt.initRunner.GetOptions()) + if config.SystemTags == nil { + config.SystemTags = &metrics.DefaultSystemTagSet + } + if config.SummaryTrendStats == nil { + config.SummaryTrendStats = lib.DefaultSummaryTrendStats + } + defDNS := types.DefaultDNSConfig() + if !config.DNS.TTL.Valid { + config.DNS.TTL = defDNS.TTL + } + if !config.DNS.Select.Valid { + config.DNS.Select = defDNS.Select + } + if !config.DNS.Policy.Valid { + config.DNS.Policy = defDNS.Policy + } + if !config.SetupTimeout.Valid { + config.SetupTimeout.Duration = types.Duration(60 * time.Second) + } + if !config.TeardownTimeout.Valid { + config.TeardownTimeout.Duration = types.Duration(60 * time.Second) + } + + lt.logger.Debug("Parsing thresholds and validating config...") + // Parse the thresholds, only if the --no-threshold flag is not set. + // If parsing the threshold expressions failed, consider it as an + // invalid configuration error. + if !lt.preInitState.RuntimeOptions.NoThresholds.Bool { + for metricName, thresholdsDefinition := range config.Thresholds { + err := thresholdsDefinition.Parse() + if err != nil { + return nil, errext.WithExitCodeIfNone(err, exitcodes.InvalidConfig) + } + + err = thresholdsDefinition.Validate(metricName, lt.preInitState.Registry) + if err != nil { + return nil, errext.WithExitCodeIfNone(err, exitcodes.InvalidConfig) + } + } + } + + config, err := executor.DeriveScenariosFromShortcuts(config, lt.loggerCompat) + if err == nil { + errors := config.Validate() + // FIXME: should show them all. + if len(errors) > 0 { + err = errors[0] + } + } + if err != nil { + return nil, err + } + + return &loadedAndConfiguredTest{ + loadedTest: lt, + config: config, + }, nil +} + +// loadedAndConfiguredTest contains the whole loadedTest, as well as the +// consolidated test config and the full test run state. +type loadedAndConfiguredTest struct { + *loadedTest + config lib.Options +} + +// loadSystemCertPool attempts to load system certificates. +func loadSystemCertPool(logger logrus.FieldLogger) { + if _, err := x509.SystemCertPool(); err != nil { + logger.WithError(err).Warning("Unable to load system cert pool") + } +} + +func (lct *loadedAndConfiguredTest) buildTestRunState( + configToReinject lib.Options, +) (*lib.TestRunState, error) { + // This might be the full derived or just the consodlidated options + if err := lct.initRunner.SetOptions(configToReinject); err != nil { + return nil, err + } + + // it pre-loads system certificates to avoid doing it on the first TLS request. + // This is done async to avoid blocking the rest of the loading process as it will not stop if it fails. + go loadSystemCertPool(lct.preInitState.Logger) + + return &lib.TestRunState{ + TestPreInitState: lct.preInitState, + Runner: lct.initRunner, + Options: lct.config, + RunTags: lct.preInitState.Registry.RootTagSet().WithTagsFromMap(configToReinject.RunTags), + }, nil +}