How to use Exports method of metrics Package

Best K6 code snippet using metrics.Exports

runner_test.go

Source:runner_test.go Github

copy

Full Screen

1/*2 *3 * k6 - a next-generation load testing tool4 * Copyright (C) 2016 Load Impact5 *6 * This program is free software: you can redistribute it and/or modify7 * it under the terms of the GNU Affero General Public License as8 * published by the Free Software Foundation, either version 3 of the9 * License, or (at your option) any later version.10 *11 * This program is distributed in the hope that it will be useful,12 * but WITHOUT ANY WARRANTY; without even the implied warranty of13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 * GNU Affero General Public License for more details.15 *16 * You should have received a copy of the GNU Affero General Public License17 * along with this program. If not, see <http://www.gnu.org/licenses/>.18 *19 */20package js21import (22 "bytes"23 "context"24 "crypto/tls"25 "crypto/x509"26 "fmt"27 "go/build"28 "io/ioutil"29 stdlog "log"30 "net"31 "net/http"32 "net/url"33 "os"34 "strings"35 "sync"36 "testing"37 "time"38 "github.com/sirupsen/logrus"39 logtest "github.com/sirupsen/logrus/hooks/test"40 "github.com/spf13/afero"41 "github.com/stretchr/testify/assert"42 "github.com/stretchr/testify/require"43 "google.golang.org/grpc/test/grpc_testing"44 "gopkg.in/guregu/null.v3"45 "go.k6.io/k6/core"46 "go.k6.io/k6/core/local"47 "go.k6.io/k6/js/common"48 "go.k6.io/k6/js/modules/k6"49 k6http "go.k6.io/k6/js/modules/k6/http"50 k6metrics "go.k6.io/k6/js/modules/k6/metrics"51 "go.k6.io/k6/js/modules/k6/ws"52 "go.k6.io/k6/lib"53 _ "go.k6.io/k6/lib/executor" // TODO: figure out something better54 "go.k6.io/k6/lib/fsext"55 "go.k6.io/k6/lib/testutils"56 "go.k6.io/k6/lib/testutils/httpmultibin"57 "go.k6.io/k6/lib/testutils/mockoutput"58 "go.k6.io/k6/lib/types"59 "go.k6.io/k6/loader"60 "go.k6.io/k6/metrics"61 "go.k6.io/k6/output"62)63func TestRunnerNew(t *testing.T) {64 t.Parallel()65 t.Run("Valid", func(t *testing.T) {66 t.Parallel()67 r, err := getSimpleRunner(t, "/script.js", `68 var counter = 0;69 exports.default = function() { counter++; }70 `)71 assert.NoError(t, err)72 t.Run("NewVU", func(t *testing.T) {73 t.Parallel()74 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))75 assert.NoError(t, err)76 vuc, ok := initVU.(*VU)77 assert.True(t, ok)78 assert.Equal(t, int64(0), vuc.Runtime.Get("counter").Export())79 ctx, cancel := context.WithCancel(context.Background())80 defer cancel()81 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})82 t.Run("RunOnce", func(t *testing.T) {83 err = vu.RunOnce()84 assert.NoError(t, err)85 assert.Equal(t, int64(1), vuc.Runtime.Get("counter").Export())86 })87 })88 })89 t.Run("Invalid", func(t *testing.T) {90 t.Parallel()91 _, err := getSimpleRunner(t, "/script.js", `blarg`)92 assert.EqualError(t, err, "ReferenceError: blarg is not defined\n\tat file:///script.js:1:1(0)\n")93 })94}95func TestRunnerGetDefaultGroup(t *testing.T) {96 t.Parallel()97 r1, err := getSimpleRunner(t, "/script.js", `exports.default = function() {};`)98 if assert.NoError(t, err) {99 assert.NotNil(t, r1.GetDefaultGroup())100 }101 registry := metrics.NewRegistry()102 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)103 r2, err := NewFromArchive(104 &lib.RuntimeState{105 Logger: testutils.NewLogger(t),106 BuiltinMetrics: builtinMetrics,107 Registry: registry,108 }, r1.MakeArchive())109 if assert.NoError(t, err) {110 assert.NotNil(t, r2.GetDefaultGroup())111 }112}113func TestRunnerOptions(t *testing.T) {114 t.Parallel()115 r1, err := getSimpleRunner(t, "/script.js", `exports.default = function() {};`)116 require.NoError(t, err)117 registry := metrics.NewRegistry()118 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)119 r2, err := NewFromArchive(120 &lib.RuntimeState{121 Logger: testutils.NewLogger(t),122 BuiltinMetrics: builtinMetrics,123 Registry: registry,124 }, r1.MakeArchive())125 require.NoError(t, err)126 testdata := map[string]*Runner{"Source": r1, "Archive": r2}127 for name, r := range testdata {128 name, r := name, r129 t.Run(name, func(t *testing.T) {130 t.Parallel()131 assert.Equal(t, r.Bundle.Options, r.GetOptions())132 assert.Equal(t, null.NewBool(false, false), r.Bundle.Options.Paused)133 r.SetOptions(lib.Options{Paused: null.BoolFrom(true)})134 assert.Equal(t, r.Bundle.Options, r.GetOptions())135 assert.Equal(t, null.NewBool(true, true), r.Bundle.Options.Paused)136 r.SetOptions(lib.Options{Paused: null.BoolFrom(false)})137 assert.Equal(t, r.Bundle.Options, r.GetOptions())138 assert.Equal(t, null.NewBool(false, true), r.Bundle.Options.Paused)139 })140 }141}142func TestOptionsSettingToScript(t *testing.T) {143 t.Parallel()144 optionVariants := []string{145 "",146 "var options = null;",147 "var options = undefined;",148 "var options = {};",149 "var options = {teardownTimeout: '1s'};",150 }151 for i, variant := range optionVariants {152 variant := variant153 t.Run(fmt.Sprintf("Variant#%d", i), func(t *testing.T) {154 t.Parallel()155 data := variant + `156 exports.default = function() {157 if (!options) {158 throw new Error("Expected options to be defined!");159 }160 if (options.teardownTimeout != __ENV.expectedTeardownTimeout) {161 throw new Error("expected teardownTimeout to be " + __ENV.expectedTeardownTimeout + " but it was " + options.teardownTimeout);162 }163 };`164 r, err := getSimpleRunner(t, "/script.js", data,165 lib.RuntimeOptions{Env: map[string]string{"expectedTeardownTimeout": "4s"}})166 require.NoError(t, err)167 newOptions := lib.Options{TeardownTimeout: types.NullDurationFrom(4 * time.Second)}168 r.SetOptions(newOptions)169 require.Equal(t, newOptions, r.GetOptions())170 samples := make(chan metrics.SampleContainer, 100)171 initVU, err := r.NewVU(1, 1, samples)172 if assert.NoError(t, err) {173 ctx, cancel := context.WithCancel(context.Background())174 defer cancel()175 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})176 err := vu.RunOnce()177 assert.NoError(t, err)178 }179 })180 }181}182func TestOptionsPropagationToScript(t *testing.T) {183 t.Parallel()184 data := `185 var options = { setupTimeout: "1s", myOption: "test" };186 exports.options = options;187 exports.default = function() {188 if (options.external) {189 throw new Error("Unexpected property external!");190 }191 if (options.myOption != "test") {192 throw new Error("expected myOption to remain unchanged but it was '" + options.myOption + "'");193 }194 if (options.setupTimeout != __ENV.expectedSetupTimeout) {195 throw new Error("expected setupTimeout to be " + __ENV.expectedSetupTimeout + " but it was " + options.setupTimeout);196 }197 };`198 expScriptOptions := lib.Options{SetupTimeout: types.NullDurationFrom(1 * time.Second)}199 r1, err := getSimpleRunner(t, "/script.js", data,200 lib.RuntimeOptions{Env: map[string]string{"expectedSetupTimeout": "1s"}})201 require.NoError(t, err)202 require.Equal(t, expScriptOptions, r1.GetOptions())203 registry := metrics.NewRegistry()204 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)205 r2, err := NewFromArchive(206 &lib.RuntimeState{207 Logger: testutils.NewLogger(t),208 BuiltinMetrics: builtinMetrics,209 Registry: registry,210 RuntimeOptions: lib.RuntimeOptions{Env: map[string]string{"expectedSetupTimeout": "3s"}},211 }, r1.MakeArchive())212 require.NoError(t, err)213 require.Equal(t, expScriptOptions, r2.GetOptions())214 newOptions := lib.Options{SetupTimeout: types.NullDurationFrom(3 * time.Second)}215 require.NoError(t, r2.SetOptions(newOptions))216 require.Equal(t, newOptions, r2.GetOptions())217 testdata := map[string]*Runner{"Source": r1, "Archive": r2}218 for name, r := range testdata {219 r := r220 t.Run(name, func(t *testing.T) {221 t.Parallel()222 samples := make(chan metrics.SampleContainer, 100)223 initVU, err := r.NewVU(1, 1, samples)224 if assert.NoError(t, err) {225 ctx, cancel := context.WithCancel(context.Background())226 defer cancel()227 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})228 err := vu.RunOnce()229 assert.NoError(t, err)230 }231 })232 }233}234func TestMetricName(t *testing.T) {235 t.Parallel()236 script := `237 var Counter = require("k6/metrics").Counter;238 var myCounter = new Counter("not ok name @");239 exports.default = function(data) {240 myCounter.add(1);241 }242 `243 _, err := getSimpleRunner(t, "/script.js", script)244 require.Error(t, err)245}246func TestSetupDataIsolation(t *testing.T) {247 t.Parallel()248 script := `249 var Counter = require("k6/metrics").Counter;250 exports.options = {251 scenarios: {252 shared_iters: {253 executor: "shared-iterations",254 vus: 5,255 iterations: 500,256 },257 },258 teardownTimeout: "5s",259 setupTimeout: "5s",260 };261 var myCounter = new Counter("mycounter");262 exports.setup = function() {263 return { v: 0 };264 }265 exports.default = function(data) {266 if (data.v !== __ITER) {267 throw new Error("default: wrong data for iter " + __ITER + ": " + JSON.stringify(data));268 }269 data.v += 1;270 myCounter.add(1);271 }272 exports.teardown = function(data) {273 if (data.v !== 0) {274 throw new Error("teardown: wrong data: " + data.v);275 }276 myCounter.add(1);277 }278 `279 runner, err := getSimpleRunner(t, "/script.js", script)280 require.NoError(t, err)281 options := runner.GetOptions()282 require.Empty(t, options.Validate())283 registry := metrics.NewRegistry()284 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)285 execScheduler, err := local.NewExecutionScheduler(runner, builtinMetrics, testutils.NewLogger(t))286 require.NoError(t, err)287 mockOutput := mockoutput.New()288 engine, err := core.NewEngine(289 execScheduler, options, lib.RuntimeOptions{}, []output.Output{mockOutput}, testutils.NewLogger(t), registry,290 )291 require.NoError(t, err)292 require.NoError(t, engine.OutputManager.StartOutputs())293 defer engine.OutputManager.StopOutputs()294 ctx, cancel := context.WithCancel(context.Background())295 run, wait, err := engine.Init(ctx, ctx)296 require.NoError(t, err)297 require.Empty(t, runner.defaultGroup.Groups)298 errC := make(chan error)299 go func() { errC <- run() }()300 select {301 case <-time.After(10 * time.Second):302 cancel()303 t.Fatal("Test timed out")304 case err := <-errC:305 cancel()306 require.NoError(t, err)307 wait()308 require.False(t, engine.IsTainted())309 }310 require.Contains(t, runner.defaultGroup.Groups, "setup")311 require.Contains(t, runner.defaultGroup.Groups, "teardown")312 var count int313 for _, s := range mockOutput.Samples {314 if s.Metric.Name == "mycounter" {315 count += int(s.Value)316 }317 }318 require.Equal(t, 501, count, "mycounter should be the number of iterations + 1 for the teardown")319}320func testSetupDataHelper(t *testing.T, data string) {321 t.Helper()322 expScriptOptions := lib.Options{323 SetupTimeout: types.NullDurationFrom(1 * time.Second),324 TeardownTimeout: types.NullDurationFrom(1 * time.Second),325 }326 r1, err := getSimpleRunner(t, "/script.js", data) // TODO fix this327 require.NoError(t, err)328 require.Equal(t, expScriptOptions, r1.GetOptions())329 testdata := map[string]*Runner{"Source": r1}330 for name, r := range testdata {331 r := r332 t.Run(name, func(t *testing.T) {333 t.Parallel()334 ctx, cancel := context.WithCancel(context.Background())335 defer cancel()336 samples := make(chan metrics.SampleContainer, 100)337 if !assert.NoError(t, r.Setup(ctx, samples)) {338 return339 }340 initVU, err := r.NewVU(1, 1, samples)341 if assert.NoError(t, err) {342 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})343 err := vu.RunOnce()344 assert.NoError(t, err)345 }346 })347 }348}349func TestSetupDataReturnValue(t *testing.T) {350 t.Parallel()351 testSetupDataHelper(t, `352 exports.options = { setupTimeout: "1s", teardownTimeout: "1s" };353 exports.setup = function() {354 return 42;355 }356 exports.default = function(data) {357 if (data != 42) {358 throw new Error("default: wrong data: " + JSON.stringify(data))359 }360 };361 exports.teardown = function(data) {362 if (data != 42) {363 throw new Error("teardown: wrong data: " + JSON.stringify(data))364 }365 };`)366}367func TestSetupDataNoSetup(t *testing.T) {368 t.Parallel()369 testSetupDataHelper(t, `370 exports.options = { setupTimeout: "1s", teardownTimeout: "1s" };371 exports.default = function(data) {372 if (data !== undefined) {373 throw new Error("default: wrong data: " + JSON.stringify(data))374 }375 };376 exports.teardown = function(data) {377 if (data !== undefined) {378 console.log(data);379 throw new Error("teardown: wrong data: " + JSON.stringify(data))380 }381 };`)382}383func TestConsoleInInitContext(t *testing.T) {384 t.Parallel()385 r1, err := getSimpleRunner(t, "/script.js", `386 console.log("1");387 exports.default = function(data) {388 };389 `)390 require.NoError(t, err)391 testdata := map[string]*Runner{"Source": r1}392 for name, r := range testdata {393 r := r394 t.Run(name, func(t *testing.T) {395 t.Parallel()396 samples := make(chan metrics.SampleContainer, 100)397 initVU, err := r.NewVU(1, 1, samples)398 if assert.NoError(t, err) {399 ctx, cancel := context.WithCancel(context.Background())400 defer cancel()401 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})402 err := vu.RunOnce()403 assert.NoError(t, err)404 }405 })406 }407}408func TestSetupDataNoReturn(t *testing.T) {409 t.Parallel()410 testSetupDataHelper(t, `411 exports.options = { setupTimeout: "1s", teardownTimeout: "1s" };412 exports.setup = function() { }413 exports.default = function(data) {414 if (data !== undefined) {415 throw new Error("default: wrong data: " + JSON.stringify(data))416 }417 };418 exports.teardown = function(data) {419 if (data !== undefined) {420 throw new Error("teardown: wrong data: " + JSON.stringify(data))421 }422 };`)423}424func TestRunnerIntegrationImports(t *testing.T) {425 t.Parallel()426 t.Run("Modules", func(t *testing.T) {427 t.Parallel()428 modules := []string{429 "k6",430 "k6/http",431 "k6/metrics",432 "k6/html",433 }434 rtOpts := lib.RuntimeOptions{CompatibilityMode: null.StringFrom("extended")}435 for _, mod := range modules {436 mod := mod437 t.Run(mod, func(t *testing.T) {438 t.Run("Source", func(t *testing.T) {439 _, err := getSimpleRunner(t, "/script.js", fmt.Sprintf(`import "%s"; exports.default = function() {}`, mod), rtOpts)440 assert.NoError(t, err)441 })442 })443 }444 })445 t.Run("Files", func(t *testing.T) {446 t.Parallel()447 testdata := map[string]struct{ filename, path string }{448 "Absolute": {"/path/script.js", "/path/to/lib.js"},449 "Relative": {"/path/script.js", "./to/lib.js"},450 "Adjacent": {"/path/to/script.js", "./lib.js"},451 "STDIN-Absolute": {"-", "/path/to/lib.js"},452 "STDIN-Relative": {"-", "./path/to/lib.js"},453 }454 for name, data := range testdata {455 name, data := name, data456 t.Run(name, func(t *testing.T) {457 t.Parallel()458 fs := afero.NewMemMapFs()459 require.NoError(t, fs.MkdirAll("/path/to", 0o755))460 require.NoError(t, afero.WriteFile(fs, "/path/to/lib.js", []byte(`exports.default = "hi!";`), 0o644))461 r1, err := getSimpleRunner(t, data.filename, fmt.Sprintf(`462 var hi = require("%s").default;463 exports.default = function() {464 if (hi != "hi!") { throw new Error("incorrect value"); }465 }`, data.path), fs)466 require.NoError(t, err)467 registry := metrics.NewRegistry()468 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)469 r2, err := NewFromArchive(470 &lib.RuntimeState{471 Logger: testutils.NewLogger(t),472 BuiltinMetrics: builtinMetrics,473 Registry: registry,474 }, r1.MakeArchive())475 require.NoError(t, err)476 testdata := map[string]*Runner{"Source": r1, "Archive": r2}477 for name, r := range testdata {478 r := r479 t.Run(name, func(t *testing.T) {480 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))481 require.NoError(t, err)482 ctx, cancel := context.WithCancel(context.Background())483 defer cancel()484 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})485 err = vu.RunOnce()486 require.NoError(t, err)487 })488 }489 })490 }491 })492}493func TestVURunContext(t *testing.T) {494 t.Parallel()495 r1, err := getSimpleRunner(t, "/script.js", `496 exports.options = { vus: 10 };497 exports.default = function() { fn(); }498 `)499 require.NoError(t, err)500 r1.SetOptions(r1.GetOptions().Apply(lib.Options{Throw: null.BoolFrom(true)}))501 registry := metrics.NewRegistry()502 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)503 r2, err := NewFromArchive(504 &lib.RuntimeState{505 Logger: testutils.NewLogger(t),506 BuiltinMetrics: builtinMetrics,507 Registry: registry,508 }, r1.MakeArchive())509 require.NoError(t, err)510 testdata := map[string]*Runner{"Source": r1, "Archive": r2}511 for name, r := range testdata {512 r := r513 t.Run(name, func(t *testing.T) {514 t.Parallel()515 vu, err := r.newVU(1, 1, make(chan metrics.SampleContainer, 100))516 require.NoError(t, err)517 fnCalled := false518 vu.Runtime.Set("fn", func() {519 fnCalled = true520 require.NotNil(t, vu.moduleVUImpl.Runtime())521 require.Nil(t, vu.moduleVUImpl.InitEnv())522 state := vu.moduleVUImpl.State()523 require.NotNil(t, state)524 assert.Equal(t, null.IntFrom(10), state.Options.VUs)525 assert.Equal(t, null.BoolFrom(true), state.Options.Throw)526 assert.NotNil(t, state.Logger)527 assert.Equal(t, r.GetDefaultGroup(), state.Group)528 assert.Equal(t, vu.Transport, state.Transport)529 })530 ctx, cancel := context.WithCancel(context.Background())531 defer cancel()532 activeVU := vu.Activate(&lib.VUActivationParams{RunContext: ctx})533 err = activeVU.RunOnce()534 assert.NoError(t, err)535 assert.True(t, fnCalled, "fn() not called")536 })537 }538}539func TestVURunInterrupt(t *testing.T) {540 t.Parallel()541 r1, err := getSimpleRunner(t, "/script.js", `542 exports.default = function() { while(true) {} }543 `)544 require.NoError(t, err)545 require.NoError(t, r1.SetOptions(lib.Options{Throw: null.BoolFrom(true)}))546 registry := metrics.NewRegistry()547 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)548 r2, err := NewFromArchive(549 &lib.RuntimeState{550 Logger: testutils.NewLogger(t),551 BuiltinMetrics: builtinMetrics,552 Registry: registry,553 }, r1.MakeArchive())554 require.NoError(t, err)555 testdata := map[string]*Runner{"Source": r1, "Archive": r2}556 for name, r := range testdata {557 name, r := name, r558 t.Run(name, func(t *testing.T) {559 t.Parallel()560 samples := make(chan metrics.SampleContainer, 100)561 defer close(samples)562 go func() {563 for range samples {564 }565 }()566 vu, err := r.newVU(1, 1, samples)567 require.NoError(t, err)568 ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)569 defer cancel()570 activeVU := vu.Activate(&lib.VUActivationParams{RunContext: ctx})571 err = activeVU.RunOnce()572 assert.Error(t, err)573 assert.Contains(t, err.Error(), "context canceled")574 })575 }576}577func TestVURunInterruptDoesntPanic(t *testing.T) {578 t.Parallel()579 r1, err := getSimpleRunner(t, "/script.js", `580 exports.default = function() { while(true) {} }581 `)582 require.NoError(t, err)583 require.NoError(t, r1.SetOptions(lib.Options{Throw: null.BoolFrom(true)}))584 registry := metrics.NewRegistry()585 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)586 r2, err := NewFromArchive(587 &lib.RuntimeState{588 Logger: testutils.NewLogger(t),589 BuiltinMetrics: builtinMetrics,590 Registry: registry,591 }, r1.MakeArchive())592 require.NoError(t, err)593 testdata := map[string]*Runner{"Source": r1, "Archive": r2}594 for name, r := range testdata {595 r := r596 t.Run(name, func(t *testing.T) {597 t.Parallel()598 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)599 defer cancel()600 samples := make(chan metrics.SampleContainer, 100)601 defer close(samples)602 go func() {603 for range samples {604 }605 }()606 var wg sync.WaitGroup607 initVU, err := r.newVU(1, 1, samples)608 require.NoError(t, err)609 for i := 0; i < 1000; i++ {610 wg.Add(1)611 newCtx, newCancel := context.WithCancel(ctx)612 vu := initVU.Activate(&lib.VUActivationParams{613 RunContext: newCtx,614 DeactivateCallback: func(_ lib.InitializedVU) { wg.Done() },615 })616 ch := make(chan struct{})617 go func() {618 close(ch)619 vuErr := vu.RunOnce()620 assert.Error(t, vuErr)621 assert.Contains(t, vuErr.Error(), "context canceled")622 }()623 <-ch624 time.Sleep(time.Millisecond * 1) // NOTE: increase this in case of problems ;)625 newCancel()626 wg.Wait()627 }628 })629 }630}631func TestVUIntegrationGroups(t *testing.T) {632 t.Parallel()633 r1, err := getSimpleRunner(t, "/script.js", `634 var group = require("k6").group;635 exports.default = function() {636 fnOuter();637 group("my group", function() {638 fnInner();639 group("nested group", function() {640 fnNested();641 })642 });643 }644 `)645 require.NoError(t, err)646 registry := metrics.NewRegistry()647 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)648 r2, err := NewFromArchive(649 &lib.RuntimeState{650 Logger: testutils.NewLogger(t),651 BuiltinMetrics: builtinMetrics,652 Registry: registry,653 }, r1.MakeArchive())654 require.NoError(t, err)655 testdata := map[string]*Runner{"Source": r1, "Archive": r2}656 for name, r := range testdata {657 r := r658 t.Run(name, func(t *testing.T) {659 t.Parallel()660 vu, err := r.newVU(1, 1, make(chan metrics.SampleContainer, 100))661 require.NoError(t, err)662 fnOuterCalled := false663 fnInnerCalled := false664 fnNestedCalled := false665 vu.Runtime.Set("fnOuter", func() {666 fnOuterCalled = true667 assert.Equal(t, r.GetDefaultGroup(), vu.state.Group)668 })669 vu.Runtime.Set("fnInner", func() {670 fnInnerCalled = true671 g := vu.state.Group672 assert.Equal(t, "my group", g.Name)673 assert.Equal(t, r.GetDefaultGroup(), g.Parent)674 })675 vu.Runtime.Set("fnNested", func() {676 fnNestedCalled = true677 g := vu.state.Group678 assert.Equal(t, "nested group", g.Name)679 assert.Equal(t, "my group", g.Parent.Name)680 assert.Equal(t, r.GetDefaultGroup(), g.Parent.Parent)681 })682 ctx, cancel := context.WithCancel(context.Background())683 defer cancel()684 activeVU := vu.Activate(&lib.VUActivationParams{RunContext: ctx})685 err = activeVU.RunOnce()686 assert.NoError(t, err)687 assert.True(t, fnOuterCalled, "fnOuter() not called")688 assert.True(t, fnInnerCalled, "fnInner() not called")689 assert.True(t, fnNestedCalled, "fnNested() not called")690 })691 }692}693func TestVUIntegrationMetrics(t *testing.T) {694 t.Parallel()695 r1, err := getSimpleRunner(t, "/script.js", `696 var group = require("k6").group;697 var Trend = require("k6/metrics").Trend;698 var myMetric = new Trend("my_metric");699 exports.default = function() { myMetric.add(5); }700 `)701 require.NoError(t, err)702 registry := metrics.NewRegistry()703 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)704 r2, err := NewFromArchive(705 &lib.RuntimeState{706 Logger: testutils.NewLogger(t),707 BuiltinMetrics: builtinMetrics,708 Registry: registry,709 }, r1.MakeArchive())710 require.NoError(t, err)711 testdata := map[string]*Runner{"Source": r1, "Archive": r2}712 for name, r := range testdata {713 r := r714 t.Run(name, func(t *testing.T) {715 t.Parallel()716 samples := make(chan metrics.SampleContainer, 100)717 defer close(samples)718 vu, err := r.newVU(1, 1, samples)719 require.NoError(t, err)720 ctx, cancel := context.WithCancel(context.Background())721 defer cancel()722 activeVU := vu.Activate(&lib.VUActivationParams{RunContext: ctx})723 err = activeVU.RunOnce()724 assert.NoError(t, err)725 sampleCount := 0726 for i, sampleC := range metrics.GetBufferedSamples(samples) {727 for j, s := range sampleC.GetSamples() {728 sampleCount++729 switch i + j {730 case 0:731 assert.Equal(t, 5.0, s.Value)732 assert.Equal(t, "my_metric", s.Metric.Name)733 assert.Equal(t, metrics.Trend, s.Metric.Type)734 case 1:735 assert.Equal(t, 0.0, s.Value)736 assert.Equal(t, builtinMetrics.DataSent, s.Metric, "`data_sent` sample is before `data_received` and `iteration_duration`")737 case 2:738 assert.Equal(t, 0.0, s.Value)739 assert.Equal(t, builtinMetrics.DataReceived, s.Metric, "`data_received` sample is after `data_received`")740 case 3:741 assert.Equal(t, builtinMetrics.IterationDuration, s.Metric, "`iteration-duration` sample is after `data_received`")742 case 4:743 assert.Equal(t, builtinMetrics.Iterations, s.Metric, "`iterations` sample is after `iteration_duration`")744 assert.Equal(t, float64(1), s.Value)745 }746 }747 }748 assert.Equal(t, sampleCount, 5)749 })750 }751}752func TestVUIntegrationInsecureRequests(t *testing.T) {753 t.Parallel()754 testdata := map[string]struct {755 opts lib.Options756 errMsg string757 }{758 "Null": {759 lib.Options{},760 "x509: certificate has expired or is not yet valid",761 },762 "False": {763 lib.Options{InsecureSkipTLSVerify: null.BoolFrom(false)},764 "x509: certificate has expired or is not yet valid",765 },766 "True": {767 lib.Options{InsecureSkipTLSVerify: null.BoolFrom(true)},768 "",769 },770 }771 for name, data := range testdata {772 data := data773 t.Run(name, func(t *testing.T) {774 t.Parallel()775 r1, err := getSimpleRunner(t, "/script.js", `776 var http = require("k6/http");;777 exports.default = function() { http.get("https://expired.badssl.com/"); }778 `)779 require.NoError(t, err)780 require.NoError(t, r1.SetOptions(lib.Options{Throw: null.BoolFrom(true)}.Apply(data.opts)))781 registry := metrics.NewRegistry()782 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)783 r2, err := NewFromArchive(784 &lib.RuntimeState{785 Logger: testutils.NewLogger(t),786 BuiltinMetrics: builtinMetrics,787 Registry: registry,788 }, r1.MakeArchive())789 require.NoError(t, err)790 runners := map[string]*Runner{"Source": r1, "Archive": r2}791 for name, r := range runners {792 r := r793 t.Run(name, func(t *testing.T) {794 t.Parallel()795 r.Logger, _ = logtest.NewNullLogger()796 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))797 require.NoError(t, err)798 ctx, cancel := context.WithCancel(context.Background())799 defer cancel()800 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})801 err = vu.RunOnce()802 if data.errMsg != "" {803 require.Error(t, err)804 assert.Contains(t, err.Error(), data.errMsg)805 } else {806 assert.NoError(t, err)807 }808 })809 }810 })811 }812}813func TestVUIntegrationBlacklistOption(t *testing.T) {814 t.Parallel()815 r1, err := getSimpleRunner(t, "/script.js", `816 var http = require("k6/http");;817 exports.default = function() { http.get("http://10.1.2.3/"); }818 `)819 require.NoError(t, err)820 cidr, err := lib.ParseCIDR("10.0.0.0/8")821 require.NoError(t, err)822 require.NoError(t, r1.SetOptions(lib.Options{823 Throw: null.BoolFrom(true),824 BlacklistIPs: []*lib.IPNet{cidr},825 }))826 registry := metrics.NewRegistry()827 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)828 r2, err := NewFromArchive(829 &lib.RuntimeState{830 Logger: testutils.NewLogger(t),831 BuiltinMetrics: builtinMetrics,832 Registry: registry,833 }, r1.MakeArchive())834 require.NoError(t, err)835 runners := map[string]*Runner{"Source": r1, "Archive": r2}836 for name, r := range runners {837 r := r838 t.Run(name, func(t *testing.T) {839 t.Parallel()840 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))841 require.NoError(t, err)842 ctx, cancel := context.WithCancel(context.Background())843 defer cancel()844 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})845 err = vu.RunOnce()846 require.Error(t, err)847 assert.Contains(t, err.Error(), "IP (10.1.2.3) is in a blacklisted range (10.0.0.0/8)")848 })849 }850}851func TestVUIntegrationBlacklistScript(t *testing.T) {852 t.Parallel()853 r1, err := getSimpleRunner(t, "/script.js", `854 var http = require("k6/http");;855 exports.options = {856 throw: true,857 blacklistIPs: ["10.0.0.0/8"],858 };859 exports.default = function() { http.get("http://10.1.2.3/"); }860 `)861 require.NoError(t, err)862 registry := metrics.NewRegistry()863 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)864 r2, err := NewFromArchive(865 &lib.RuntimeState{866 Logger: testutils.NewLogger(t),867 BuiltinMetrics: builtinMetrics,868 Registry: registry,869 }, r1.MakeArchive())870 require.NoError(t, err)871 runners := map[string]*Runner{"Source": r1, "Archive": r2}872 for name, r := range runners {873 r := r874 t.Run(name, func(t *testing.T) {875 t.Parallel()876 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))877 require.NoError(t, err)878 ctx, cancel := context.WithCancel(context.Background())879 defer cancel()880 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})881 err = vu.RunOnce()882 require.Error(t, err)883 assert.Contains(t, err.Error(), "IP (10.1.2.3) is in a blacklisted range (10.0.0.0/8)")884 })885 }886}887func TestVUIntegrationBlockHostnamesOption(t *testing.T) {888 t.Parallel()889 r1, err := getSimpleRunner(t, "/script.js", `890 var http = require("k6/http");891 exports.default = function() { http.get("https://k6.io/"); }892 `)893 require.NoError(t, err)894 hostnames, err := types.NewNullHostnameTrie([]string{"*.io"})895 require.NoError(t, err)896 require.NoError(t, r1.SetOptions(lib.Options{897 Throw: null.BoolFrom(true),898 BlockedHostnames: hostnames,899 }))900 registry := metrics.NewRegistry()901 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)902 r2, err := NewFromArchive(903 &lib.RuntimeState{904 Logger: testutils.NewLogger(t),905 BuiltinMetrics: builtinMetrics,906 Registry: registry,907 }, r1.MakeArchive())908 require.NoError(t, err)909 runners := map[string]*Runner{"Source": r1, "Archive": r2}910 for name, r := range runners {911 r := r912 t.Run(name, func(t *testing.T) {913 t.Parallel()914 initVu, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))915 require.NoError(t, err)916 ctx, cancel := context.WithCancel(context.Background())917 defer cancel()918 vu := initVu.Activate(&lib.VUActivationParams{RunContext: ctx})919 err = vu.RunOnce()920 require.Error(t, err)921 assert.Contains(t, err.Error(), "hostname (k6.io) is in a blocked pattern (*.io)")922 })923 }924}925func TestVUIntegrationBlockHostnamesScript(t *testing.T) {926 t.Parallel()927 r1, err := getSimpleRunner(t, "/script.js", `928 var http = require("k6/http");929 exports.options = {930 throw: true,931 blockHostnames: ["*.io"],932 };933 exports.default = function() { http.get("https://k6.io/"); }934 `)935 require.NoError(t, err)936 registry := metrics.NewRegistry()937 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)938 r2, err := NewFromArchive(939 &lib.RuntimeState{940 Logger: testutils.NewLogger(t),941 BuiltinMetrics: builtinMetrics,942 Registry: registry,943 }, r1.MakeArchive())944 require.NoError(t, err)945 runners := map[string]*Runner{"Source": r1, "Archive": r2}946 for name, r := range runners {947 r := r948 t.Run(name, func(t *testing.T) {949 t.Parallel()950 initVu, err := r.NewVU(0, 0, make(chan metrics.SampleContainer, 100))951 require.NoError(t, err)952 ctx, cancel := context.WithCancel(context.Background())953 defer cancel()954 vu := initVu.Activate(&lib.VUActivationParams{RunContext: ctx})955 err = vu.RunOnce()956 require.Error(t, err)957 assert.Contains(t, err.Error(), "hostname (k6.io) is in a blocked pattern (*.io)")958 })959 }960}961func TestVUIntegrationHosts(t *testing.T) {962 t.Parallel()963 tb := httpmultibin.NewHTTPMultiBin(t)964 r1, err := getSimpleRunner(t, "/script.js",965 tb.Replacer.Replace(`966 var k6 = require("k6");967 var check = k6.check;968 var fail = k6.fail;969 var http = require("k6/http");;970 exports.default = function() {971 var res = http.get("http://test.loadimpact.com:HTTPBIN_PORT/");972 check(res, {973 "is correct IP": function(r) { return r.remote_ip === "127.0.0.1" }974 }) || fail("failed to override dns");975 }976 `))977 require.NoError(t, err)978 r1.SetOptions(lib.Options{979 Throw: null.BoolFrom(true),980 Hosts: map[string]*lib.HostAddress{981 "test.loadimpact.com": {IP: net.ParseIP("127.0.0.1")},982 },983 })984 registry := metrics.NewRegistry()985 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)986 r2, err := NewFromArchive(987 &lib.RuntimeState{988 Logger: testutils.NewLogger(t),989 BuiltinMetrics: builtinMetrics,990 Registry: registry,991 }, r1.MakeArchive())992 require.NoError(t, err)993 runners := map[string]*Runner{"Source": r1, "Archive": r2}994 for name, r := range runners {995 r := r996 t.Run(name, func(t *testing.T) {997 t.Parallel()998 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))999 require.NoError(t, err)1000 ctx, cancel := context.WithCancel(context.Background())1001 defer cancel()1002 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1003 err = vu.RunOnce()1004 require.NoError(t, err)1005 })1006 }1007}1008func TestVUIntegrationTLSConfig(t *testing.T) {1009 t.Parallel()1010 unsupportedVersionErrorMsg := "remote error: tls: handshake failure"1011 for _, tag := range build.Default.ReleaseTags {1012 if tag == "go1.12" {1013 unsupportedVersionErrorMsg = "tls: no supported versions satisfy MinVersion and MaxVersion"1014 break1015 }1016 }1017 testdata := map[string]struct {1018 opts lib.Options1019 errMsg string1020 }{1021 "NullCipherSuites": {1022 lib.Options{},1023 "",1024 },1025 "SupportedCipherSuite": {1026 lib.Options{TLSCipherSuites: &lib.TLSCipherSuites{tls.TLS_RSA_WITH_AES_128_GCM_SHA256}},1027 "",1028 },1029 "UnsupportedCipherSuite": {1030 lib.Options{TLSCipherSuites: &lib.TLSCipherSuites{tls.TLS_RSA_WITH_RC4_128_SHA}},1031 "remote error: tls: handshake failure",1032 },1033 "NullVersion": {1034 lib.Options{},1035 "",1036 },1037 "SupportedVersion": {1038 lib.Options{TLSVersion: &lib.TLSVersions{Min: tls.VersionTLS12, Max: tls.VersionTLS12}},1039 "",1040 },1041 "UnsupportedVersion": {1042 lib.Options{TLSVersion: &lib.TLSVersions{Min: tls.VersionSSL30, Max: tls.VersionSSL30}},1043 unsupportedVersionErrorMsg,1044 },1045 }1046 registry := metrics.NewRegistry()1047 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1048 for name, data := range testdata {1049 data := data1050 t.Run(name, func(t *testing.T) {1051 t.Parallel()1052 r1, err := getSimpleRunner(t, "/script.js", `1053 var http = require("k6/http");;1054 exports.default = function() { http.get("https://sha256.badssl.com/"); }1055 `)1056 require.NoError(t, err)1057 require.NoError(t, r1.SetOptions(lib.Options{Throw: null.BoolFrom(true)}.Apply(data.opts)))1058 r2, err := NewFromArchive(1059 &lib.RuntimeState{1060 Logger: testutils.NewLogger(t),1061 BuiltinMetrics: builtinMetrics,1062 Registry: registry,1063 }, r1.MakeArchive())1064 require.NoError(t, err)1065 runners := map[string]*Runner{"Source": r1, "Archive": r2}1066 for name, r := range runners {1067 r := r1068 t.Run(name, func(t *testing.T) {1069 t.Parallel()1070 r.Logger, _ = logtest.NewNullLogger()1071 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1072 require.NoError(t, err)1073 ctx, cancel := context.WithCancel(context.Background())1074 defer cancel()1075 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1076 err = vu.RunOnce()1077 if data.errMsg != "" {1078 require.Error(t, err)1079 assert.Contains(t, err.Error(), data.errMsg)1080 } else {1081 assert.NoError(t, err)1082 }1083 })1084 }1085 })1086 }1087}1088func TestVUIntegrationOpenFunctionError(t *testing.T) {1089 t.Parallel()1090 r, err := getSimpleRunner(t, "/script.js", `1091 exports.default = function() { open("/tmp/foo") }1092 `)1093 assert.NoError(t, err)1094 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1095 assert.NoError(t, err)1096 ctx, cancel := context.WithCancel(context.Background())1097 defer cancel()1098 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1099 err = vu.RunOnce()1100 assert.Error(t, err)1101 assert.Contains(t, err.Error(), "only available in the init stage")1102}1103func TestVUIntegrationOpenFunctionErrorWhenSneaky(t *testing.T) {1104 t.Parallel()1105 r, err := getSimpleRunner(t, "/script.js", `1106 var sneaky = open;1107 exports.default = function() { sneaky("/tmp/foo") }1108 `)1109 assert.NoError(t, err)1110 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1111 assert.NoError(t, err)1112 ctx, cancel := context.WithCancel(context.Background())1113 defer cancel()1114 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1115 err = vu.RunOnce()1116 assert.Error(t, err)1117 assert.Contains(t, err.Error(), "only available in the init stage")1118}1119func TestVUDoesOpenUnderV0Condition(t *testing.T) {1120 t.Parallel()1121 baseFS := afero.NewMemMapFs()1122 data := `1123 if (__VU == 0) {1124 let data = open("/home/somebody/test.json");1125 }1126 exports.default = function() {1127 console.log("hey")1128 }1129 `1130 require.NoError(t, afero.WriteFile(baseFS, "/home/somebody/test.json", []byte(`42`), os.ModePerm))1131 require.NoError(t, afero.WriteFile(baseFS, "/script.js", []byte(data), os.ModePerm))1132 fs := fsext.NewCacheOnReadFs(baseFS, afero.NewMemMapFs(), 0)1133 r, err := getSimpleRunner(t, "/script.js", data, fs)1134 require.NoError(t, err)1135 _, err = r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1136 assert.NoError(t, err)1137}1138func TestVUDoesNotOpenUnderConditions(t *testing.T) {1139 t.Parallel()1140 baseFS := afero.NewMemMapFs()1141 data := `1142 if (__VU > 0) {1143 let data = open("/home/somebody/test.json");1144 }1145 exports.default = function() {1146 console.log("hey")1147 }1148 `1149 require.NoError(t, afero.WriteFile(baseFS, "/home/somebody/test.json", []byte(`42`), os.ModePerm))1150 require.NoError(t, afero.WriteFile(baseFS, "/script.js", []byte(data), os.ModePerm))1151 fs := fsext.NewCacheOnReadFs(baseFS, afero.NewMemMapFs(), 0)1152 r, err := getSimpleRunner(t, "/script.js", data, fs)1153 require.NoError(t, err)1154 _, err = r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1155 assert.Error(t, err)1156 assert.Contains(t, err.Error(), "open() can't be used with files that weren't previously opened during initialization (__VU==0)")1157}1158func TestVUDoesNonExistingPathnUnderConditions(t *testing.T) {1159 t.Parallel()1160 baseFS := afero.NewMemMapFs()1161 data := `1162 if (__VU == 1) {1163 let data = open("/home/nobody");1164 }1165 exports.default = function() {1166 console.log("hey")1167 }1168 `1169 require.NoError(t, afero.WriteFile(baseFS, "/script.js", []byte(data), os.ModePerm))1170 fs := fsext.NewCacheOnReadFs(baseFS, afero.NewMemMapFs(), 0)1171 r, err := getSimpleRunner(t, "/script.js", data, fs)1172 require.NoError(t, err)1173 _, err = r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1174 assert.Error(t, err)1175 assert.Contains(t, err.Error(), "open() can't be used with files that weren't previously opened during initialization (__VU==0)")1176}1177func TestVUIntegrationCookiesReset(t *testing.T) {1178 t.Parallel()1179 tb := httpmultibin.NewHTTPMultiBin(t)1180 r1, err := getSimpleRunner(t, "/script.js", tb.Replacer.Replace(`1181 var http = require("k6/http");;1182 exports.default = function() {1183 var url = "HTTPBIN_URL";1184 var preRes = http.get(url + "/cookies");1185 if (preRes.status != 200) { throw new Error("wrong status (pre): " + preRes.status); }1186 if (preRes.json().k1 || preRes.json().k2) {1187 throw new Error("cookies persisted: " + preRes.body);1188 }1189 var res = http.get(url + "/cookies/set?k2=v2&k1=v1");1190 if (res.status != 200) { throw new Error("wrong status: " + res.status) }1191 if (res.json().k1 != "v1" || res.json().k2 != "v2") {1192 throw new Error("wrong cookies: " + res.body);1193 }1194 }1195 `))1196 require.NoError(t, err)1197 r1.SetOptions(lib.Options{1198 Throw: null.BoolFrom(true),1199 MaxRedirects: null.IntFrom(10),1200 Hosts: tb.Dialer.Hosts,1201 })1202 registry := metrics.NewRegistry()1203 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1204 r2, err := NewFromArchive(1205 &lib.RuntimeState{1206 Logger: testutils.NewLogger(t),1207 BuiltinMetrics: builtinMetrics,1208 Registry: registry,1209 }, r1.MakeArchive())1210 require.NoError(t, err)1211 runners := map[string]*Runner{"Source": r1, "Archive": r2}1212 for name, r := range runners {1213 r := r1214 t.Run(name, func(t *testing.T) {1215 t.Parallel()1216 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1217 require.NoError(t, err)1218 ctx, cancel := context.WithCancel(context.Background())1219 defer cancel()1220 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1221 for i := 0; i < 2; i++ {1222 err = vu.RunOnce()1223 assert.NoError(t, err)1224 }1225 })1226 }1227}1228func TestVUIntegrationCookiesNoReset(t *testing.T) {1229 t.Parallel()1230 tb := httpmultibin.NewHTTPMultiBin(t)1231 r1, err := getSimpleRunner(t, "/script.js", tb.Replacer.Replace(`1232 var http = require("k6/http");;1233 exports.default = function() {1234 var url = "HTTPBIN_URL";1235 if (__ITER == 0) {1236 var res = http.get(url + "/cookies/set?k2=v2&k1=v1");1237 if (res.status != 200) { throw new Error("wrong status: " + res.status) }1238 if (res.json().k1 != "v1" || res.json().k2 != "v2") {1239 throw new Error("wrong cookies: " + res.body);1240 }1241 }1242 if (__ITER == 1) {1243 var res = http.get(url + "/cookies");1244 if (res.status != 200) { throw new Error("wrong status (pre): " + res.status); }1245 if (res.json().k1 != "v1" || res.json().k2 != "v2") {1246 throw new Error("wrong cookies: " + res.body);1247 }1248 }1249 }1250 `))1251 require.NoError(t, err)1252 r1.SetOptions(lib.Options{1253 Throw: null.BoolFrom(true),1254 MaxRedirects: null.IntFrom(10),1255 Hosts: tb.Dialer.Hosts,1256 NoCookiesReset: null.BoolFrom(true),1257 })1258 registry := metrics.NewRegistry()1259 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1260 r2, err := NewFromArchive(1261 &lib.RuntimeState{1262 Logger: testutils.NewLogger(t),1263 BuiltinMetrics: builtinMetrics,1264 Registry: registry,1265 }, r1.MakeArchive())1266 require.NoError(t, err)1267 runners := map[string]*Runner{"Source": r1, "Archive": r2}1268 for name, r := range runners {1269 r := r1270 t.Run(name, func(t *testing.T) {1271 t.Parallel()1272 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1273 require.NoError(t, err)1274 ctx, cancel := context.WithCancel(context.Background())1275 defer cancel()1276 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1277 err = vu.RunOnce()1278 assert.NoError(t, err)1279 err = vu.RunOnce()1280 assert.NoError(t, err)1281 })1282 }1283}1284func TestVUIntegrationVUID(t *testing.T) {1285 t.Parallel()1286 r1, err := getSimpleRunner(t, "/script.js", `1287 exports.default = function() {1288 if (__VU != 1234) { throw new Error("wrong __VU: " + __VU); }1289 }`,1290 )1291 require.NoError(t, err)1292 r1.SetOptions(lib.Options{Throw: null.BoolFrom(true)})1293 registry := metrics.NewRegistry()1294 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1295 r2, err := NewFromArchive(1296 &lib.RuntimeState{1297 Logger: testutils.NewLogger(t),1298 BuiltinMetrics: builtinMetrics,1299 Registry: registry,1300 }, r1.MakeArchive())1301 require.NoError(t, err)1302 runners := map[string]*Runner{"Source": r1, "Archive": r2}1303 for name, r := range runners {1304 r := r1305 t.Run(name, func(t *testing.T) {1306 t.Parallel()1307 initVU, err := r.NewVU(1234, 1234, make(chan metrics.SampleContainer, 100))1308 require.NoError(t, err)1309 ctx, cancel := context.WithCancel(context.Background())1310 defer cancel()1311 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1312 err = vu.RunOnce()1313 assert.NoError(t, err)1314 })1315 }1316}1317/*1318CA key:1319-----BEGIN EC PRIVATE KEY-----1320MHcCAQEEIDEm8bxihqYfAsWP39o5DpkAksPBw+3rlDHNX+d69oYGoAoGCCqGSM491321AwEHoUQDQgAEeeuCFQsdraFJr8JaKbAKfjYpZ2U+p3r/OzcmAsjFO8EckmV9uFZs1322Gq3JurKi9Z3dDKQcwinHQ1malicbwWhamQ==1323-----END EC PRIVATE KEY-----1324*/1325func TestVUIntegrationClientCerts(t *testing.T) {1326 t.Parallel()1327 clientCAPool := x509.NewCertPool()1328 assert.True(t, clientCAPool.AppendCertsFromPEM(1329 []byte("-----BEGIN CERTIFICATE-----\n"+1330 "MIIBWzCCAQGgAwIBAgIJAIQMBgLi+DV6MAoGCCqGSM49BAMCMBAxDjAMBgNVBAMM\n"+1331 "BU15IENBMCAXDTIyMDEyMTEyMjkzNloYDzMwMjEwNTI0MTIyOTM2WjAQMQ4wDAYD\n"+1332 "VQQDDAVNeSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHnrghULHa2hSa/C\n"+1333 "WimwCn42KWdlPqd6/zs3JgLIxTvBHJJlfbhWbBqtybqyovWd3QykHMIpx0NZmpYn\n"+1334 "G8FoWpmjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\n"+1335 "DgQWBBSkukBA8lgFvvBJAYKsoSUR+PX71jAKBggqhkjOPQQDAgNIADBFAiEAiFF7\n"+1336 "Y54CMNRSBSVMgd4mQgrzJInRH88KpLsQ7VeOAaQCIEa0vaLln9zxIDZQKocml4Db\n"+1337 "AEJr8tDzMKIds6sRTBT4\n"+1338 "-----END CERTIFICATE-----"),1339 ))1340 serverCert, err := tls.X509KeyPair(1341 []byte("-----BEGIN CERTIFICATE-----\n"+1342 "MIIBcTCCARigAwIBAgIJAIP0njRt16gbMAoGCCqGSM49BAMCMBAxDjAMBgNVBAMM\n"+1343 "BU15IENBMCAXDTIyMDEyMTE1MTA0OVoYDzMwMjEwNTI0MTUxMDQ5WjAZMRcwFQYD\n"+1344 "VQQDDA4xMjcuMC4wLjE6Njk2OTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH8Y\n"+1345 "exy5LI9r+RNwVpf/5ZX86EigMYHp9YOyiUMmfUfvDig+BGhlwjm7Lh2941Gz4amO\n"+1346 "lpN2YAkcd0wnNLHkVOmjUDBOMA4GA1UdDwEB/wQEAwIBBjAMBgNVHRMBAf8EAjAA\n"+1347 "MB0GA1UdDgQWBBQ9cIYUwwzfzBXPyRGB5tNpAgHWujAPBgNVHREECDAGhwR/AAAB\n"+1348 "MAoGCCqGSM49BAMCA0cAMEQCIDjRZlg+jKgI9K99HOM2wS9+URr6R1/FYLZYBtMc\n"+1349 "pq3hAiB9NQxNqV459fgN0BpbiLrEvJjquRFoUr9BWsG+hHrHtQ==\n"+1350 "-----END CERTIFICATE-----\n"+1351 "-----BEGIN CERTIFICATE-----\n"+1352 "MIIBWzCCAQGgAwIBAgIJAIQMBgLi+DV6MAoGCCqGSM49BAMCMBAxDjAMBgNVBAMM\n"+1353 "BU15IENBMCAXDTIyMDEyMTEyMjkzNloYDzMwMjEwNTI0MTIyOTM2WjAQMQ4wDAYD\n"+1354 "VQQDDAVNeSBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHnrghULHa2hSa/C\n"+1355 "WimwCn42KWdlPqd6/zs3JgLIxTvBHJJlfbhWbBqtybqyovWd3QykHMIpx0NZmpYn\n"+1356 "G8FoWpmjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\n"+1357 "DgQWBBSkukBA8lgFvvBJAYKsoSUR+PX71jAKBggqhkjOPQQDAgNIADBFAiEAiFF7\n"+1358 "Y54CMNRSBSVMgd4mQgrzJInRH88KpLsQ7VeOAaQCIEa0vaLln9zxIDZQKocml4Db\n"+1359 "AEJr8tDzMKIds6sRTBT4\n"+1360 "-----END CERTIFICATE-----"),1361 []byte("-----BEGIN EC PRIVATE KEY-----\n"+1362 "MHcCAQEEIHNpjs0P9/ejoUYF5Agzf9clHR4PwBsVfZ+JgslfuBg1oAoGCCqGSM49\n"+1363 "AwEHoUQDQgAEfxh7HLksj2v5E3BWl//llfzoSKAxgen1g7KJQyZ9R+8OKD4EaGXC\n"+1364 "ObsuHb3jUbPhqY6Wk3ZgCRx3TCc0seRU6Q==\n"+1365 "-----END EC PRIVATE KEY-----"),1366 )1367 require.NoError(t, err)1368 testdata := map[string]struct {1369 withClientCert bool1370 withDomains bool1371 insecureSkipVerify bool1372 errMsg string1373 }{1374 "WithoutCert": {false, false, true, "remote error: tls: bad certificate"},1375 "WithCert": {true, true, true, ""},1376 "VerifyServerCert": {true, false, false, "certificate signed by unknown authority"},1377 "WithoutDomains": {true, false, true, ""},1378 }1379 listener, err := tls.Listen("tcp", "127.0.0.1:0", &tls.Config{1380 Certificates: []tls.Certificate{serverCert},1381 ClientAuth: tls.RequireAndVerifyClientCert,1382 ClientCAs: clientCAPool,1383 })1384 require.NoError(t, err)1385 srv := &http.Server{1386 Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {1387 _, _ = fmt.Fprintf(w, "ok")1388 }),1389 ErrorLog: stdlog.New(ioutil.Discard, "", 0),1390 }1391 go func() { _ = srv.Serve(listener) }()1392 t.Cleanup(func() { _ = listener.Close() })1393 for name, data := range testdata {1394 data := data1395 registry := metrics.NewRegistry()1396 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1397 t.Run(name, func(t *testing.T) {1398 t.Parallel()1399 r1, err := getSimpleRunner(t, "/script.js", fmt.Sprintf(`1400 var http = require("k6/http");1401 var k6 = require("k6");1402 var check = k6.check;1403 exports.default = function() {1404 const res = http.get("https://%s")1405 check(res, {1406 'is status 200': (r) => r.status === 200,1407 'verify resp': (r) => r.body.includes('ok'),1408 })1409 }`, listener.Addr().String()))1410 require.NoError(t, err)1411 opt := lib.Options{Throw: null.BoolFrom(true)}1412 if data.insecureSkipVerify {1413 opt.InsecureSkipTLSVerify = null.BoolFrom(true)1414 }1415 if data.withClientCert {1416 opt.TLSAuth = []*lib.TLSAuth{1417 {1418 TLSAuthFields: lib.TLSAuthFields{1419 Cert: "-----BEGIN CERTIFICATE-----\n" +1420 "MIIBVzCB/6ADAgECAgkAg/SeNG3XqB0wCgYIKoZIzj0EAwIwEDEOMAwGA1UEAwwF\n" +1421 "TXkgQ0EwIBcNMjIwMTIxMTUxMjM0WhgPMzAyMTA1MjQxNTEyMzRaMBExDzANBgNV\n" +1422 "BAMMBmNsaWVudDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKM7OJQMYG4KLtDA\n" +1423 "gZ8zOg2PimHMmQnjD2HtI4cSwIUJJnvHWLowbFe9fk6XeP9b3dK1ImUI++/EZdVr\n" +1424 "ABAcngejPzA9MA4GA1UdDwEB/wQEAwIBBjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQW\n" +1425 "BBSttJe1mcPEnBOZ6wvKPG4zL0m1CzAKBggqhkjOPQQDAgNHADBEAiBPSLgKA/r9\n" +1426 "u/FW6W+oy6Odm1kdNMGCI472iTn545GwJgIgb3UQPOUTOj0IN4JLJYfmYyXviqsy\n" +1427 "zk9eWNHFXDA9U6U=\n" +1428 "-----END CERTIFICATE-----",1429 Key: "-----BEGIN EC PRIVATE KEY-----\n" +1430 "MHcCAQEEINDaMGkOT3thu1A0LfLJr3Jd011/aEG6OArmEQaujwgpoAoGCCqGSM49\n" +1431 "AwEHoUQDQgAEozs4lAxgbgou0MCBnzM6DY+KYcyZCeMPYe0jhxLAhQkme8dYujBs\n" +1432 "V71+Tpd4/1vd0rUiZQj778Rl1WsAEByeBw==\n" +1433 "-----END EC PRIVATE KEY-----",1434 },1435 },1436 }1437 if data.withDomains {1438 opt.TLSAuth[0].TLSAuthFields.Domains = []string{"127.0.0.1"}1439 }1440 _, _ = opt.TLSAuth[0].Certificate()1441 }1442 require.NoError(t, r1.SetOptions(opt))1443 r2, err := NewFromArchive(1444 &lib.RuntimeState{1445 Logger: testutils.NewLogger(t),1446 BuiltinMetrics: builtinMetrics,1447 Registry: registry,1448 }, r1.MakeArchive())1449 require.NoError(t, err)1450 runners := map[string]*Runner{"Source": r1, "Archive": r2}1451 for name, r := range runners {1452 r := r1453 t.Run(name, func(t *testing.T) {1454 t.Parallel()1455 r.Logger, _ = logtest.NewNullLogger()1456 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))1457 if assert.NoError(t, err) {1458 ctx, cancel := context.WithCancel(context.Background())1459 defer cancel()1460 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1461 err := vu.RunOnce()1462 if len(data.errMsg) > 0 {1463 require.Error(t, err)1464 assert.Contains(t, err.Error(), data.errMsg)1465 } else {1466 assert.NoError(t, err)1467 }1468 }1469 })1470 }1471 })1472 }1473}1474func TestHTTPRequestInInitContext(t *testing.T) {1475 t.Parallel()1476 tb := httpmultibin.NewHTTPMultiBin(t)1477 _, err := getSimpleRunner(t, "/script.js", tb.Replacer.Replace(`1478 var k6 = require("k6");1479 var check = k6.check;1480 var fail = k6.fail;1481 var http = require("k6/http");;1482 var res = http.get("HTTPBIN_URL/");1483 exports.default = function() {1484 console.log(test);1485 }1486 `))1487 if assert.Error(t, err) {1488 assert.Contains(1489 t,1490 err.Error(),1491 k6http.ErrHTTPForbiddenInInitContext.Error())1492 }1493}1494func TestInitContextForbidden(t *testing.T) {1495 t.Parallel()1496 table := [...][3]string{1497 {1498 "http.request",1499 `var http = require("k6/http");;1500 var res = http.get("HTTPBIN_URL");1501 exports.default = function() { console.log("p"); }`,1502 k6http.ErrHTTPForbiddenInInitContext.Error(),1503 },1504 {1505 "http.batch",1506 `var http = require("k6/http");;1507 var res = http.batch("HTTPBIN_URL/something", "HTTPBIN_URL/else");1508 exports.default = function() { console.log("p"); }`,1509 k6http.ErrBatchForbiddenInInitContext.Error(),1510 },1511 {1512 "http.cookieJar",1513 `var http = require("k6/http");;1514 var jar = http.cookieJar();1515 exports.default = function() { console.log("p"); }`,1516 k6http.ErrJarForbiddenInInitContext.Error(),1517 },1518 {1519 "check",1520 `var check = require("k6").check;1521 check("test", {'is test': function(test) { return test == "test"}})1522 exports.default = function() { console.log("p"); }`,1523 k6.ErrCheckInInitContext.Error(),1524 },1525 {1526 "abortTest",1527 `var test = require("k6/execution").test;1528 test.abort();1529 exports.default = function() { console.log("p"); }`,1530 common.AbortTest,1531 },1532 {1533 "group",1534 `var group = require("k6").group;1535 group("group1", function () { console.log("group1");})1536 exports.default = function() { console.log("p"); }`,1537 k6.ErrGroupInInitContext.Error(),1538 },1539 {1540 "ws",1541 `var ws = require("k6/ws");1542 var url = "ws://echo.websocket.org";1543 var params = { "tags": { "my_tag": "hello" } };1544 var response = ws.connect(url, params, function (socket) {1545 socket.on('open', function open() {1546 console.log('connected');1547 })1548 });1549 exports.default = function() { console.log("p"); }`,1550 ws.ErrWSInInitContext.Error(),1551 },1552 {1553 "metric",1554 `var Counter = require("k6/metrics").Counter;1555 var counter = Counter("myCounter");1556 counter.add(1);1557 exports.default = function() { console.log("p"); }`,1558 k6metrics.ErrMetricsAddInInitContext.Error(),1559 },1560 }1561 tb := httpmultibin.NewHTTPMultiBin(t)1562 for _, test := range table {1563 test := test1564 t.Run(test[0], func(t *testing.T) {1565 t.Parallel()1566 _, err := getSimpleRunner(t, "/script.js", tb.Replacer.Replace(test[1]))1567 if assert.Error(t, err) {1568 assert.Contains(1569 t,1570 err.Error(),1571 test[2])1572 }1573 })1574 }1575}1576func TestArchiveRunningIntegrity(t *testing.T) {1577 t.Parallel()1578 fs := afero.NewMemMapFs()1579 data := `1580 var fput = open("/home/somebody/test.json");1581 exports.options = { setupTimeout: "10s", teardownTimeout: "10s" };1582 exports.setup = function () {1583 return JSON.parse(fput);1584 }1585 exports.default = function(data) {1586 if (data != 42) {1587 throw new Error("incorrect answer " + data);1588 }1589 }1590 `1591 require.NoError(t, afero.WriteFile(fs, "/home/somebody/test.json", []byte(`42`), os.ModePerm))1592 require.NoError(t, afero.WriteFile(fs, "/script.js", []byte(data), os.ModePerm))1593 r1, err := getSimpleRunner(t, "/script.js", data, fs)1594 require.NoError(t, err)1595 buf := bytes.NewBuffer(nil)1596 require.NoError(t, r1.MakeArchive().Write(buf))1597 arc, err := lib.ReadArchive(buf)1598 require.NoError(t, err)1599 registry := metrics.NewRegistry()1600 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1601 r2, err := NewFromArchive(1602 &lib.RuntimeState{1603 Logger: testutils.NewLogger(t),1604 BuiltinMetrics: builtinMetrics,1605 Registry: registry,1606 }, arc)1607 require.NoError(t, err)1608 runners := map[string]*Runner{"Source": r1, "Archive": r2}1609 for name, r := range runners {1610 r := r1611 t.Run(name, func(t *testing.T) {1612 t.Parallel()1613 var err error1614 ch := make(chan metrics.SampleContainer, 100)1615 ctx, cancel := context.WithCancel(context.Background())1616 defer cancel()1617 err = r.Setup(ctx, ch)1618 cancel()1619 require.NoError(t, err)1620 initVU, err := r.NewVU(1, 1, ch)1621 require.NoError(t, err)1622 ctx, cancel = context.WithCancel(context.Background())1623 defer cancel()1624 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1625 err = vu.RunOnce()1626 require.NoError(t, err)1627 })1628 }1629}1630func TestArchiveNotPanicking(t *testing.T) {1631 t.Parallel()1632 fs := afero.NewMemMapFs()1633 require.NoError(t, afero.WriteFile(fs, "/non/existent", []byte(`42`), os.ModePerm))1634 r1, err := getSimpleRunner(t, "/script.js", `1635 var fput = open("/non/existent");1636 exports.default = function(data) {}1637 `, fs)1638 require.NoError(t, err)1639 arc := r1.MakeArchive()1640 arc.Filesystems = map[string]afero.Fs{"file": afero.NewMemMapFs()}1641 registry := metrics.NewRegistry()1642 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1643 r2, err := NewFromArchive(1644 &lib.RuntimeState{1645 Logger: testutils.NewLogger(t),1646 BuiltinMetrics: builtinMetrics,1647 Registry: registry,1648 }, arc)1649 // we do want this to error here as this is where we find out that a given file is not in the1650 // archive1651 require.Error(t, err)1652 require.Nil(t, r2)1653}1654func TestStuffNotPanicking(t *testing.T) {1655 t.Parallel()1656 tb := httpmultibin.NewHTTPMultiBin(t)1657 r, err := getSimpleRunner(t, "/script.js", tb.Replacer.Replace(`1658 var http = require("k6/http");1659 var ws = require("k6/ws");1660 var group = require("k6").group;1661 var parseHTML = require("k6/html").parseHTML;1662 exports.options = { iterations: 1, vus: 1 };1663 exports.default = function() {1664 var doc = parseHTML(http.get("HTTPBIN_URL/html").body);1665 var testCases = [1666 function() { return group()},1667 function() { return group("test")},1668 function() { return group("test", "wat")},1669 function() { return doc.find('p').each()},1670 function() { return doc.find('p').each("wat")},1671 function() { return doc.find('p').map()},1672 function() { return doc.find('p').map("wat")},1673 function() { return ws.connect("WSBIN_URL/ws-echo")},1674 ];1675 testCases.forEach(function(fn, idx) {1676 var hasException;1677 try {1678 fn();1679 hasException = false;1680 } catch (e) {1681 hasException = true;1682 }1683 if (hasException === false) {1684 throw new Error("Expected test case #" + idx + " to return an error");1685 } else if (hasException === undefined) {1686 throw new Error("Something strange happened with test case #" + idx);1687 }1688 });1689 }1690 `))1691 require.NoError(t, err)1692 ch := make(chan metrics.SampleContainer, 1000)1693 initVU, err := r.NewVU(1, 1, ch)1694 require.NoError(t, err)1695 ctx, cancel := context.WithCancel(context.Background())1696 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1697 errC := make(chan error)1698 go func() { errC <- vu.RunOnce() }()1699 select {1700 case <-time.After(15 * time.Second):1701 cancel()1702 t.Fatal("Test timed out")1703 case err := <-errC:1704 cancel()1705 require.NoError(t, err)1706 }1707}1708func TestPanicOnSimpleHTML(t *testing.T) {1709 t.Parallel()1710 r, err := getSimpleRunner(t, "/script.js", `1711 var parseHTML = require("k6/html").parseHTML;1712 exports.options = { iterations: 1, vus: 1 };1713 exports.default = function() {1714 var doc = parseHTML("<html>");1715 var o = doc.find(".something").slice(0, 4).toArray()1716 };1717 `)1718 require.NoError(t, err)1719 ch := make(chan metrics.SampleContainer, 1000)1720 initVU, err := r.NewVU(1, 1, ch)1721 require.NoError(t, err)1722 ctx, cancel := context.WithCancel(context.Background())1723 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1724 errC := make(chan error)1725 go func() { errC <- vu.RunOnce() }()1726 select {1727 case <-time.After(15 * time.Second):1728 cancel()1729 t.Fatal("Test timed out")1730 case err := <-errC:1731 cancel()1732 require.NoError(t, err)1733 }1734}1735func TestSystemTags(t *testing.T) {1736 t.Parallel()1737 tb := httpmultibin.NewHTTPMultiBin(t)1738 // Handle paths with custom logic1739 tb.Mux.HandleFunc("/wrong-redirect", func(w http.ResponseWriter, r *http.Request) {1740 w.Header().Add("Location", "%")1741 w.WriteHeader(http.StatusTemporaryRedirect)1742 })1743 httpURL, err := url.Parse(tb.ServerHTTP.URL)1744 require.NoError(t, err)1745 testedSystemTags := []struct{ tag, exec, expVal string }{1746 {"proto", "http_get", "HTTP/1.1"},1747 {"status", "http_get", "200"},1748 {"method", "http_get", "GET"},1749 {"url", "http_get", tb.ServerHTTP.URL},1750 {"url", "https_get", tb.ServerHTTPS.URL},1751 {"ip", "http_get", httpURL.Hostname()},1752 {"name", "http_get", tb.ServerHTTP.URL},1753 {"group", "http_get", ""},1754 {"vu", "http_get", "8"},1755 {"vu", "noop", "9"},1756 {"iter", "http_get", "0"},1757 {"iter", "noop", "0"},1758 {"tls_version", "https_get", "tls1.3"},1759 {"ocsp_status", "https_get", "unknown"},1760 {"error", "bad_url_get", `dial: connection refused`},1761 {"error_code", "bad_url_get", "1212"},1762 {"scenario", "http_get", "default"},1763 // TODO: add more tests1764 }1765 for num, tc := range testedSystemTags {1766 num, tc := num, tc1767 t.Run(fmt.Sprintf("TC %d with only %s", num, tc.tag), func(t *testing.T) {1768 t.Parallel()1769 samples := make(chan metrics.SampleContainer, 100)1770 r, err := getSimpleRunner(t, "/script.js", tb.Replacer.Replace(`1771 var http = require("k6/http");1772 exports.http_get = function() {1773 http.get("HTTPBIN_IP_URL");1774 };1775 exports.https_get = function() {1776 http.get("HTTPSBIN_IP_URL");1777 };1778 exports.bad_url_get = function() {1779 http.get("http://127.0.0.1:1");1780 };1781 exports.noop = function() {};1782 `), lib.RuntimeOptions{CompatibilityMode: null.StringFrom("base")})1783 require.NoError(t, err)1784 require.NoError(t, r.SetOptions(r.GetOptions().Apply(lib.Options{1785 Throw: null.BoolFrom(false),1786 TLSVersion: &lib.TLSVersions{Max: tls.VersionTLS13},1787 SystemTags: metrics.ToSystemTagSet([]string{tc.tag}),1788 InsecureSkipTLSVerify: null.BoolFrom(true),1789 })))1790 ctx, cancel := context.WithCancel(context.Background())1791 defer cancel()1792 vu, err := r.NewVU(uint64(num), 0, samples)1793 require.NoError(t, err)1794 activeVU := vu.Activate(&lib.VUActivationParams{1795 RunContext: ctx,1796 Exec: tc.exec,1797 Scenario: "default",1798 })1799 require.NoError(t, activeVU.RunOnce())1800 bufSamples := metrics.GetBufferedSamples(samples)1801 require.NotEmpty(t, bufSamples)1802 for _, sample := range bufSamples[0].GetSamples() {1803 assert.NotEmpty(t, sample.Tags)1804 for emittedTag, emittedVal := range sample.Tags.CloneTags() {1805 assert.Equal(t, tc.tag, emittedTag)1806 assert.Equal(t, tc.expVal, emittedVal)1807 }1808 }1809 })1810 }1811}1812func TestVUPanic(t *testing.T) {1813 t.Parallel()1814 r1, err := getSimpleRunner(t, "/script.js", `1815 var group = require("k6").group;1816 exports.default = function() {1817 group("panic here", function() {1818 if (__ITER == 0) {1819 panic("here we panic");1820 }1821 console.log("here we don't");1822 })1823 }`,1824 )1825 require.NoError(t, err)1826 registry := metrics.NewRegistry()1827 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1828 r2, err := NewFromArchive(1829 &lib.RuntimeState{1830 Logger: testutils.NewLogger(t),1831 BuiltinMetrics: builtinMetrics,1832 Registry: registry,1833 }, r1.MakeArchive())1834 require.NoError(t, err)1835 runners := map[string]*Runner{"Source": r1, "Archive": r2}1836 for name, r := range runners {1837 r := r1838 t.Run(name, func(t *testing.T) {1839 t.Parallel()1840 initVU, err := r.NewVU(1, 1234, make(chan metrics.SampleContainer, 100))1841 require.NoError(t, err)1842 logger := logrus.New()1843 logger.SetLevel(logrus.InfoLevel)1844 logger.Out = ioutil.Discard1845 hook := testutils.SimpleLogrusHook{1846 HookedLevels: []logrus.Level{logrus.InfoLevel, logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel},1847 }1848 logger.AddHook(&hook)1849 ctx, cancel := context.WithCancel(context.Background())1850 defer cancel()1851 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})1852 vu.(*ActiveVU).Runtime.Set("panic", func(str string) { panic(str) })1853 vu.(*ActiveVU).state.Logger = logger1854 vu.(*ActiveVU).Console.logger = logger.WithField("source", "console")1855 err = vu.RunOnce()1856 require.Error(t, err)1857 assert.Contains(t, err.Error(), "a panic occurred during JS execution: here we panic")1858 entries := hook.Drain()1859 require.Len(t, entries, 1)1860 assert.Equal(t, logrus.ErrorLevel, entries[0].Level)1861 require.True(t, strings.HasPrefix(entries[0].Message, "panic: here we panic"))1862 // broken since goja@f3cfc97811c0b4d8337902c3e42fb2371ba1d524 see1863 // https://github.com/dop251/goja/issues/179#issuecomment-7835720201864 // require.True(t, strings.HasSuffix(entries[0].Message, "Goja stack:\nfile:///script.js:3:4(12)"))1865 err = vu.RunOnce()1866 assert.NoError(t, err)1867 entries = hook.Drain()1868 require.Len(t, entries, 1)1869 assert.Equal(t, logrus.InfoLevel, entries[0].Level)1870 require.Contains(t, entries[0].Message, "here we don't")1871 })1872 }1873}1874type multiFileTestCase struct {1875 fses map[string]afero.Fs1876 rtOpts lib.RuntimeOptions1877 cwd string1878 script string1879 expInitErr bool1880 expVUErr bool1881 samples chan metrics.SampleContainer1882}1883func runMultiFileTestCase(t *testing.T, tc multiFileTestCase, tb *httpmultibin.HTTPMultiBin) {1884 t.Helper()1885 logger := testutils.NewLogger(t)1886 registry := metrics.NewRegistry()1887 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)1888 runner, err := New(1889 &lib.RuntimeState{1890 Logger: logger,1891 BuiltinMetrics: builtinMetrics,1892 Registry: registry,1893 RuntimeOptions: tc.rtOpts,1894 },1895 &loader.SourceData{1896 URL: &url.URL{Path: tc.cwd + "/script.js", Scheme: "file"},1897 Data: []byte(tc.script),1898 },1899 tc.fses,1900 )1901 if tc.expInitErr {1902 require.Error(t, err)1903 return1904 }1905 require.NoError(t, err)1906 options := runner.GetOptions()1907 require.Empty(t, options.Validate())1908 vu, err := runner.NewVU(1, 1, tc.samples)1909 require.NoError(t, err)1910 jsVU, ok := vu.(*VU)1911 require.True(t, ok)1912 jsVU.state.Dialer = tb.Dialer1913 jsVU.state.TLSConfig = tb.TLSClientConfig1914 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)1915 defer cancel()1916 activeVU := vu.Activate(&lib.VUActivationParams{RunContext: ctx})1917 err = activeVU.RunOnce()1918 if tc.expVUErr {1919 require.Error(t, err)1920 } else {1921 require.NoError(t, err)1922 }1923 arc := runner.MakeArchive()1924 runnerFromArc, err := NewFromArchive(1925 &lib.RuntimeState{1926 Logger: logger,1927 BuiltinMetrics: builtinMetrics,1928 Registry: registry,1929 RuntimeOptions: tc.rtOpts,1930 }, arc)1931 require.NoError(t, err)1932 vuFromArc, err := runnerFromArc.NewVU(2, 2, tc.samples)1933 require.NoError(t, err)1934 jsVUFromArc, ok := vuFromArc.(*VU)1935 require.True(t, ok)1936 jsVUFromArc.state.Dialer = tb.Dialer1937 jsVUFromArc.state.TLSConfig = tb.TLSClientConfig1938 activeVUFromArc := jsVUFromArc.Activate(&lib.VUActivationParams{RunContext: ctx})1939 err = activeVUFromArc.RunOnce()1940 if tc.expVUErr {1941 require.Error(t, err)1942 return1943 }1944 require.NoError(t, err)1945}1946func TestComplicatedFileImportsForGRPC(t *testing.T) {1947 t.Parallel()1948 tb := httpmultibin.NewHTTPMultiBin(t)1949 tb.GRPCStub.UnaryCallFunc = func(ctx context.Context, sreq *grpc_testing.SimpleRequest) (1950 *grpc_testing.SimpleResponse, error,1951 ) {1952 return &grpc_testing.SimpleResponse{1953 Username: "foo",1954 }, nil1955 }1956 fs := afero.NewMemMapFs()1957 protoFile, err := ioutil.ReadFile("../vendor/google.golang.org/grpc/test/grpc_testing/test.proto")1958 require.NoError(t, err)1959 require.NoError(t, afero.WriteFile(fs, "/path/to/service.proto", protoFile, 0o644))1960 require.NoError(t, afero.WriteFile(fs, "/path/to/same-dir.proto", []byte(1961 `syntax = "proto3";package whatever;import "service.proto";`,1962 ), 0o644))1963 require.NoError(t, afero.WriteFile(fs, "/path/subdir.proto", []byte(1964 `syntax = "proto3";package whatever;import "to/service.proto";`,1965 ), 0o644))1966 require.NoError(t, afero.WriteFile(fs, "/path/to/abs.proto", []byte(1967 `syntax = "proto3";package whatever;import "/path/to/service.proto";`,1968 ), 0o644))1969 grpcTestCase := func(expInitErr, expVUErr bool, cwd, loadCode string) multiFileTestCase {1970 script := tb.Replacer.Replace(fmt.Sprintf(`1971 var grpc = require('k6/net/grpc');1972 var client = new grpc.Client();1973 %s // load statements1974 exports.default = function() {1975 client.connect('GRPCBIN_ADDR', {timeout: '3s'});1976 try {1977 var resp = client.invoke('grpc.testing.TestService/UnaryCall', {})1978 if (!resp.message || resp.error || resp.message.username !== 'foo') {1979 throw new Error('unexpected response message: ' + JSON.stringify(resp.message))1980 }1981 } finally {1982 client.close();1983 }1984 }1985 `, loadCode))1986 return multiFileTestCase{1987 fses: map[string]afero.Fs{"file": fs, "https": afero.NewMemMapFs()},1988 rtOpts: lib.RuntimeOptions{CompatibilityMode: null.NewString("base", true)},1989 samples: make(chan metrics.SampleContainer, 100),1990 cwd: cwd, expInitErr: expInitErr, expVUErr: expVUErr, script: script,1991 }1992 }1993 testCases := []multiFileTestCase{1994 grpcTestCase(false, true, "/", `/* no grpc loads */`), // exp VU error with no proto files loaded1995 // Init errors when the protobuf file can't be loaded1996 grpcTestCase(true, false, "/", `client.load(null, 'service.proto');`),1997 grpcTestCase(true, false, "/", `client.load(null, '/wrong/path/to/service.proto');`),1998 grpcTestCase(true, false, "/", `client.load(['/', '/path/'], 'service.proto');`),1999 // Direct imports of service.proto2000 grpcTestCase(false, false, "/", `client.load(null, '/path/to/service.proto');`), // full path should be fine2001 grpcTestCase(false, false, "/path/to/", `client.load([], 'service.proto');`), // file name from same folder2002 grpcTestCase(false, false, "/", `client.load(['./path//to/'], 'service.proto');`),2003 grpcTestCase(false, false, "/path/", `client.load(['./to/'], 'service.proto');`),2004 grpcTestCase(false, false, "/whatever", `client.load(['/path/to/'], 'service.proto');`), // with import paths2005 grpcTestCase(false, false, "/path", `client.load(['/', '/path/to/'], 'service.proto');`), // with import paths2006 grpcTestCase(false, false, "/whatever", `client.load(['../path/to/'], 'service.proto');`),2007 // Import another file that imports "service.proto" directly2008 grpcTestCase(true, false, "/", `client.load([], '/path/to/same-dir.proto');`),2009 grpcTestCase(true, false, "/path/", `client.load([], 'to/same-dir.proto');`),2010 grpcTestCase(true, false, "/", `client.load(['/path/'], 'to/same-dir.proto');`),2011 grpcTestCase(false, false, "/path/to/", `client.load([], 'same-dir.proto');`),2012 grpcTestCase(false, false, "/", `client.load(['/path/to/'], 'same-dir.proto');`),2013 grpcTestCase(false, false, "/whatever", `client.load(['/other', '/path/to/'], 'same-dir.proto');`),2014 grpcTestCase(false, false, "/", `client.load(['./path//to/'], 'same-dir.proto');`),2015 grpcTestCase(false, false, "/path/", `client.load(['./to/'], 'same-dir.proto');`),2016 grpcTestCase(false, false, "/whatever", `client.load(['../path/to/'], 'same-dir.proto');`),2017 // Import another file that imports "to/service.proto" directly2018 grpcTestCase(true, false, "/", `client.load([], '/path/to/subdir.proto');`),2019 grpcTestCase(false, false, "/path/", `client.load([], 'subdir.proto');`),2020 grpcTestCase(false, false, "/", `client.load(['/path/'], 'subdir.proto');`),2021 grpcTestCase(false, false, "/", `client.load(['./path/'], 'subdir.proto');`),2022 grpcTestCase(false, false, "/whatever", `client.load(['/other', '/path/'], 'subdir.proto');`),2023 grpcTestCase(false, false, "/whatever", `client.load(['../other', '../path/'], 'subdir.proto');`),2024 // Import another file that imports "/path/to/service.proto" directly2025 grpcTestCase(true, false, "/", `client.load(['/path'], '/path/to/abs.proto');`),2026 grpcTestCase(false, false, "/", `client.load([], '/path/to/abs.proto');`),2027 grpcTestCase(false, false, "/whatever", `client.load(['/'], '/path/to/abs.proto');`),2028 }2029 for i, tc := range testCases {2030 i, tc := i, tc2031 t.Run(fmt.Sprintf("TestCase_%d", i), func(t *testing.T) {2032 t.Parallel()2033 t.Logf(2034 "CWD: %s, expInitErr: %t, expVUErr: %t, script injected with: `%s`",2035 tc.cwd, tc.expInitErr, tc.expVUErr, tc.script,2036 )2037 runMultiFileTestCase(t, tc, tb)2038 })2039 }2040}2041func TestMinIterationDurationIsCancellable(t *testing.T) {2042 t.Parallel()2043 r, err := getSimpleRunner(t, "/script.js", `2044 exports.options = { iterations: 1, vus: 1, minIterationDuration: '1m' };2045 exports.default = function() { /* do nothing */ };2046 `)2047 require.NoError(t, err)2048 ch := make(chan metrics.SampleContainer, 1000)2049 initVU, err := r.NewVU(1, 1, ch)2050 require.NoError(t, err)2051 ctx, cancel := context.WithCancel(context.Background())2052 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})2053 errC := make(chan error)2054 go func() { errC <- vu.RunOnce() }()2055 time.Sleep(200 * time.Millisecond) // give it some time to actually start2056 cancel() // simulate the end of gracefulStop or a Ctrl+C event2057 select {2058 case <-time.After(3 * time.Second):2059 t.Fatal("Test timed out or minIterationDuration prevailed")2060 case err := <-errC:2061 require.NoError(t, err)2062 }2063}2064// nolint:paralleltest2065func TestForceHTTP1Feature(t *testing.T) {2066 cases := map[string]struct {2067 godebug string2068 expectedForceH1Result bool2069 protocol string2070 }{2071 "Force H1 Enabled. Checking for H1": {2072 godebug: "http2client=0,gctrace=1",2073 expectedForceH1Result: true,2074 protocol: "HTTP/1.1",2075 },2076 "Force H1 Disabled. Checking for H2": {2077 godebug: "test=0",2078 expectedForceH1Result: false,2079 protocol: "HTTP/2.0",2080 },2081 }2082 for name, tc := range cases {2083 t.Run(name, func(t *testing.T) {2084 err := os.Setenv("GODEBUG", tc.godebug)2085 require.NoError(t, err)2086 defer func() {2087 err = os.Unsetenv("GODEBUG")2088 require.NoError(t, err)2089 }()2090 assert.Equal(t, tc.expectedForceH1Result, forceHTTP1())2091 tb := httpmultibin.NewHTTPMultiBin(t)2092 data := fmt.Sprintf(`var k6 = require("k6");2093 var check = k6.check;2094 var fail = k6.fail;2095 var http = require("k6/http");;2096 exports.default = function() {2097 var res = http.get("HTTP2BIN_URL");2098 if (2099 !check(res, {2100 'checking to see if status was 200': (res) => res.status === 200,2101 'checking to see protocol': (res) => res.proto === '%s'2102 })2103 ) {2104 fail('test failed')2105 }2106 }`, tc.protocol)2107 r1, err := getSimpleRunner(t, "/script.js", tb.Replacer.Replace(data))2108 require.NoError(t, err)2109 err = r1.SetOptions(lib.Options{2110 Hosts: tb.Dialer.Hosts,2111 // We disable TLS verify so that we don't get a TLS handshake error since2112 // the certificates on the endpoint are not certified by a certificate authority2113 InsecureSkipTLSVerify: null.BoolFrom(true),2114 })2115 require.NoError(t, err)2116 registry := metrics.NewRegistry()2117 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)2118 r2, err := NewFromArchive(2119 &lib.RuntimeState{2120 Logger: testutils.NewLogger(t),2121 BuiltinMetrics: builtinMetrics,2122 Registry: registry,2123 }, r1.MakeArchive())2124 require.NoError(t, err)2125 runners := map[string]*Runner{"Source": r1, "Archive": r2}2126 for name, r := range runners {2127 r := r2128 t.Run(name, func(t *testing.T) {2129 initVU, err := r.NewVU(1, 1, make(chan metrics.SampleContainer, 100))2130 require.NoError(t, err)2131 ctx, cancel := context.WithCancel(context.Background())2132 defer cancel()2133 vu := initVU.Activate(&lib.VUActivationParams{RunContext: ctx})2134 err = vu.RunOnce()2135 require.NoError(t, err)2136 })2137 }2138 })2139 }2140}2141func TestExecutionInfo(t *testing.T) {2142 t.Parallel()2143 testCases := []struct {2144 name, script, expErr string2145 }{2146 {name: "vu_ok", script: `2147 var exec = require('k6/execution');2148 exports.default = function() {2149 if (exec.vu.idInInstance !== 1) throw new Error('unexpected VU ID: '+exec.vu.idInInstance);2150 if (exec.vu.idInTest !== 10) throw new Error('unexpected global VU ID: '+exec.vu.idInTest);2151 if (exec.vu.iterationInInstance !== 0) throw new Error('unexpected VU iteration: '+exec.vu.iterationInInstance);2152 if (exec.vu.iterationInScenario !== 0) throw new Error('unexpected scenario iteration: '+exec.vu.iterationInScenario);2153 }`},2154 {name: "vu_err", script: `2155 var exec = require('k6/execution');2156 exec.vu;2157 `, expErr: "getting VU information in the init context is not supported"},2158 {name: "scenario_ok", script: `2159 var exec = require('k6/execution');2160 var sleep = require('k6').sleep;2161 exports.default = function() {2162 var si = exec.scenario;2163 sleep(0.1);2164 if (si.name !== 'default') throw new Error('unexpected scenario name: '+si.name);2165 if (si.executor !== 'test-exec') throw new Error('unexpected executor: '+si.executor);2166 if (si.startTime > new Date().getTime()) throw new Error('unexpected startTime: '+si.startTime);2167 if (si.progress !== 0.1) throw new Error('unexpected progress: '+si.progress);2168 if (si.iterationInInstance !== 3) throw new Error('unexpected scenario local iteration: '+si.iterationInInstance);2169 if (si.iterationInTest !== 4) throw new Error('unexpected scenario local iteration: '+si.iterationInTest);2170 }`},2171 {name: "scenario_err", script: `2172 var exec = require('k6/execution');2173 exec.scenario;2174 `, expErr: "getting scenario information in the init context is not supported"},2175 {name: "test_ok", script: `2176 var exec = require('k6/execution');2177 exports.default = function() {2178 var ti = exec.instance;2179 if (ti.currentTestRunDuration !== 0) throw new Error('unexpected test duration: '+ti.currentTestRunDuration);2180 if (ti.vusActive !== 1) throw new Error('unexpected vusActive: '+ti.vusActive);2181 if (ti.vusInitialized !== 0) throw new Error('unexpected vusInitialized: '+ti.vusInitialized);2182 if (ti.iterationsCompleted !== 0) throw new Error('unexpected iterationsCompleted: '+ti.iterationsCompleted);2183 if (ti.iterationsInterrupted !== 0) throw new Error('unexpected iterationsInterrupted: '+ti.iterationsInterrupted);2184 }`},2185 {name: "test_err", script: `2186 var exec = require('k6/execution');2187 exec.instance;2188 `, expErr: "getting instance information in the init context is not supported"},2189 }2190 for _, tc := range testCases {2191 tc := tc2192 t.Run(tc.name, func(t *testing.T) {2193 t.Parallel()2194 r, err := getSimpleRunner(t, "/script.js", tc.script)2195 if tc.expErr != "" {2196 require.Error(t, err)2197 assert.Contains(t, err.Error(), tc.expErr)2198 return2199 }2200 require.NoError(t, err)2201 r.Bundle.Options.SystemTags = metrics.NewSystemTagSet(metrics.DefaultSystemTagSet)2202 samples := make(chan metrics.SampleContainer, 100)2203 initVU, err := r.NewVU(1, 10, samples)2204 require.NoError(t, err)2205 registry := metrics.NewRegistry()2206 builtinMetrics := metrics.RegisterBuiltinMetrics(registry)2207 execScheduler, err := local.NewExecutionScheduler(r, builtinMetrics, testutils.NewLogger(t))2208 require.NoError(t, err)2209 ctx, cancel := context.WithCancel(context.Background())2210 defer cancel()2211 ctx = lib.WithExecutionState(ctx, execScheduler.GetState())2212 ctx = lib.WithScenarioState(ctx, &lib.ScenarioState{2213 Name: "default",2214 Executor: "test-exec",2215 StartTime: time.Now(),2216 ProgressFn: func() (float64, []string) {2217 return 0.1, nil2218 },2219 })2220 vu := initVU.Activate(&lib.VUActivationParams{2221 RunContext: ctx,2222 Exec: "default",2223 GetNextIterationCounters: func() (uint64, uint64) { return 3, 4 },2224 })2225 execState := execScheduler.GetState()2226 execState.ModCurrentlyActiveVUsCount(+1)2227 err = vu.RunOnce()2228 assert.NoError(t, err)2229 })2230 }2231}...

Full Screen

Full Screen

module_loading_test.go

Source:module_loading_test.go Github

copy

Full Screen

...122 }123 })124 }125}126func TestLoadExportsIsUsableInModule(t *testing.T) {127 t.Parallel()128 fs := afero.NewMemMapFs()129 require.NoError(t, afero.WriteFile(fs, "/A.js", []byte(`130 export function A() {131 return "A";132 }133 export function B() {134 return exports.A() + "B";135 }136 `), os.ModePerm))137 r1, err := getSimpleRunner(t, "/script.js", `138 import { A, B } from "./A.js";139 export default function(data) {140 if (A() != "A") {...

Full Screen

Full Screen

metrics.go

Source:metrics.go Github

copy

Full Screen

...32 mExposuresStatsDeleteFailed = stats.Int64(cleanupMetricsPrefix+"exposures_stats_delete_failed",33 "Instances of exposures stats delete failures", stats.UnitDimensionless)34 mExposuresStatsDeleted = stats.Int64(cleanupMetricsPrefix+"exposures_stats_deleted",35 "Exposures stats deletions", stats.UnitDimensionless)36 mExportsSetupFailed = stats.Int64(cleanupMetricsPrefix+"exports_setup_failed",37 "Instances of export setup failures", stats.UnitDimensionless)38 mExportsCleanupBefore = stats.Int64(cleanupMetricsPrefix+"exports_cleanup_before",39 "Exports cleanup cutoff date", stats.UnitSeconds)40 mExportsDeleteFailed = stats.Int64(cleanupMetricsPrefix+"exports_delete_failed",41 "Instances of exports delete failures", stats.UnitDimensionless)42 mExportsDeleted = stats.Int64(cleanupMetricsPrefix+"exports_deleted",43 "Exports deletions", stats.UnitDimensionless)44)45func init() {46 observability.CollectViews([]*view.View{47 {48 Name: metrics.MetricRoot + "exposures_setup_failed_count",49 Description: "Total count of exposures setup failures",50 Measure: mExposuresSetupFailed,51 Aggregation: view.Sum(),52 },53 {54 Name: metrics.MetricRoot + "exposure_cleanup_before_latest",55 Description: "Last value of exposures cleanup cutoff date",56 Measure: mExposuresCleanupBefore,57 Aggregation: view.LastValue(),58 },59 {60 Name: metrics.MetricRoot + "exposure_cleanup_delete_failed_count",61 Description: "Total count of exposures delete failed",62 Measure: mExposuresDeleteFailed,63 Aggregation: view.Sum(),64 },65 {66 Name: metrics.MetricRoot + "exposures_deleted_count",67 Description: "Total count of exposures deletions",68 Measure: mExposuresDeleted,69 Aggregation: view.Sum(),70 },71 {72 Name: metrics.MetricRoot + "exposure_stats_cleanup_delete_failed_count",73 Description: "Total count of exposures stats delete failed",74 Measure: mExposuresStatsDeleteFailed,75 Aggregation: view.Sum(),76 },77 {78 Name: metrics.MetricRoot + "exposures_stats_deleted_count",79 Description: "Total count of stats exposures deletions",80 Measure: mExposuresStatsDeleted,81 Aggregation: view.Sum(),82 },83 {84 Name: metrics.MetricRoot + "exports_setup_failed_count",85 Description: "Total count of exports setup failures",86 Measure: mExportsSetupFailed,87 Aggregation: view.Sum(),88 },89 {90 Name: metrics.MetricRoot + "exports_cleanup_before_latest",91 Description: "Last value of exports cleanup cutoff date",92 Measure: mExportsCleanupBefore,93 Aggregation: view.Sum(),94 },95 {96 Name: metrics.MetricRoot + "exports_delete_failed_count",97 Description: "Total count of export deletion failures",98 Measure: mExportsDeleteFailed,99 Aggregation: view.Sum(),100 },101 {102 Name: metrics.MetricRoot + "exports_deleted_count",103 Description: "Total count of exports deletions",104 Measure: mExportsDeleted,105 Aggregation: view.Sum(),106 },107 }...)108}...

Full Screen

Full Screen

Exports

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 prometheus.MustRegister(prometheus.NewGoCollector())4 prometheus.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))5 http.Handle("/metrics", promhttp.Handler())6 log.Fatal(http.ListenAndServe(":8080", nil))7}8go_gc_duration_seconds{quantile="0"} 3.678e-059go_gc_duration_seconds{quantile="0.25"} 4.1445e-0510go_gc_duration_seconds{quantile="0.5"} 4.4142e-0511go_gc_duration_seconds{quantile="0.75"} 4.709e-0512go_gc_duration_seconds{quantile="1"} 0.00010510113go_info{version="go1.15.2"} 1

Full Screen

Full Screen

Exports

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 http.Handle("/metrics", promhttp.Handler())4 http.ListenAndServe(":8080", nil)5 fmt.Println("Server is running")6 requests := promauto.NewCounter(prometheus.CounterOpts{7 })8 requests.Inc()9}10import (11func main() {12 http.Handle("/metrics", promhttp.Handler())13 http.ListenAndServe(":8080", nil)14 fmt.Println("Server is running")15 requests := promauto.NewCounter(prometheus.CounterOpts{16 })17 requests.Inc()18}19import (20func main() {21 http.Handle("/metrics", promhttp.Handler())22 http.ListenAndServe(":8080", nil)23 fmt.Println("Server is running")24 requests := promauto.NewCounter(prometheus.CounterOpts{

Full Screen

Full Screen

Exports

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 counter := prometheus.NewCounter(prometheus.CounterOpts{4 })5 prometheus.MustRegister(counter)6 counter.Inc()7 gauge := prometheus.NewGauge(prometheus.GaugeOpts{8 })9 prometheus.MustRegister(gauge)10 gauge.Set(42)11 histogram := prometheus.NewHistogram(prometheus.HistogramOpts{12 Buckets: prometheus.LinearBuckets(5, 5, 5),13 })14 prometheus.MustRegister(histogram)15 histogram.Observe(5)16 summary := prometheus.NewSummary(prometheus.SummaryOpts{17 Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},18 })19 prometheus.MustRegister(summary)20 summary.Observe(5)21 gaugeVec := prometheus.NewGaugeVec(22 prometheus.GaugeOpts{23 },24 []string{"label1", "label2"},25 prometheus.MustRegister(gaugeVec)26 gaugeVec.WithLabelValues("label1", "

Full Screen

Full Screen

Exports

Using AI Code Generation

copy

Full Screen

1import (2var (3 requests = prometheus.NewCounterVec(4 prometheus.CounterOpts{5 },6 []string{"code"},7func init() {8 prometheus.MustRegister(requests)9}10func main() {11 http.Handle("/metrics", promhttp.Handler())12 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {13 requests.WithLabelValues("200").Inc()14 fmt.Fprintf(w, "Hello, World!")15 })16 log.Fatal(http.ListenAndServe(":8080", nil))17}18import (19var (20 requests = prometheus.NewCounterVec(21 prometheus.CounterOpts{22 },23 []string{"code"},24func main() {25 http.Handle("/metrics", promhttp.Handler())26 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {27 requests.WithLabelValues("200").Inc()28 fmt.Fprintf(w, "Hello, World!")29 })30 go func() {31 log.Fatal(http.ListenAndServe(":8080", nil))32 }()33 select {}34}35import (36var (37 requests = prometheus.NewCounterVec(38 prometheus.CounterOpts{39 },40 []string{"code"},41func main() {42 http.Handle("/metrics", promhttp.Handler())

Full Screen

Full Screen

Exports

Using AI Code Generation

copy

Full Screen

1import (2var (3 metrics = promauto.NewCounter(prometheus.CounterOpts{4 })5 metrics2 = promauto.NewGauge(prometheus.GaugeOpts{6 })7 metrics3 = promauto.NewHistogram(prometheus.HistogramOpts{8 Help: "Histogram of processing time (s)",9 })10func main() {11 go func() {12 for {13 metrics.Inc()14 metrics2.Inc()15 metrics3.Observe(0.1)16 time.Sleep(time.Second)17 }18 }()19 http.Handle("/metrics", promhttp.Handler())20 log.Fatal(http.ListenAndServe(":2112", nil))21}22import (23var (24 metrics = promauto.NewCounter(prometheus.CounterOpts{25 })26 metrics2 = promauto.NewGauge(prometheus.GaugeOpts{27 })28 metrics3 = promauto.NewHistogram(prometheus.HistogramOpts{29 Help: "Histogram of processing time (s)",30 })31func main() {32 go func() {33 for {34 metrics.Inc()35 metrics2.Inc()36 metrics3.Observe(0.1)37 time.Sleep(time.Second)38 }39 }()40 http.Handle("/metrics", promhttp

Full Screen

Full Screen

Exports

Using AI Code Generation

copy

Full Screen

1func main() {2 metrics.Exports()3}4func main() {5 metrics.Exports()6}7func main() {8 metrics.Exports()9}10func main() {11 metrics.Exports()12}13func main() {14 metrics.Exports()15}16func main() {17 metrics.Exports()18}19func main() {20 metrics.Exports()21}22func main() {23 metrics.Exports()24}25func main() {26 metrics.Exports()27}28func main() {29 metrics.Exports()30}31func main() {32 metrics.Exports()33}34func main() {35 metrics.Exports()36}37func main() {38 metrics.Exports()39}40func main() {41 metrics.Exports()42}43func main() {44 metrics.Exports()45}46func main() {47 metrics.Exports()48}49func main() {50 metrics.Exports()51}52func main() {53 metrics.Exports()54}

Full Screen

Full Screen

Exports

Using AI Code Generation

copy

Full Screen

1m := metrics.New()2m.Exports()3m := metrics.New()4m.Exports()5m := metrics.New()6m.Exports()7m := metrics.New()8m.Exports()9m := metrics.New()10m.Exports()11m := metrics.New()12m.Exports()13m := metrics.New()14m.Exports()15m := metrics.New()16m.Exports()17m := metrics.New()18m.Exports()19m := metrics.New()20m.Exports()21m := metrics.New()22m.Exports()23m := metrics.New()24m.Exports()25m := metrics.New()26m.Exports()27m := metrics.New()28m.Exports()29m := metrics.New()30m.Exports()31m := metrics.New()32m.Exports()33m := metrics.New()34m.Exports()35m := metrics.New()36m.Exports()37m := metrics.New()38m.Exports()

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run K6 automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful