From 33513be9401c4b5dafa78ca7b99dde450e9c74ed Mon Sep 17 00:00:00 2001 From: Mihail Stoykov Date: Tue, 11 Feb 2020 16:05:32 +0200 Subject: [PATCH] Copy __ENV so that 2 VUs don't share the same one as in #799(which was about the same issue with setup data), we don't actually have problems with a VU seeing changes from previous iterations. It will be too expensive to constantly copy, it won't panic and there are no issues with distributed execution. --- js/bundle.go | 6 +++++- js/bundle_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/js/bundle.go b/js/bundle.go index 112cdf10a371..e25915831a20 100644 --- a/js/bundle.go +++ b/js/bundle.go @@ -255,7 +255,11 @@ func (b *Bundle) instantiate(rt *goja.Runtime, init *InitContext) error { _ = module.Set("exports", exports) rt.Set("module", module) - rt.Set("__ENV", b.Env) + env := make(map[string]string, len(b.Env)) + for key, value := range b.Env { + env[key] = value + } + rt.Set("__ENV", env) rt.Set("console", common.Bind(rt, newConsole(), init.ctxPtr)) *init.ctxPtr = common.WithRuntime(context.Background(), rt) diff --git a/js/bundle_test.go b/js/bundle_test.go index de35935d2c75..b6b76a509ef9 100644 --- a/js/bundle_test.go +++ b/js/bundle_test.go @@ -740,6 +740,48 @@ func TestBundleEnv(t *testing.T) { } } +func TestBundleNotSharable(t *testing.T) { + data := ` + export default function() { + if (__ITER == 0) { + if (typeof __ENV.something !== "undefined") { + throw new Error("invalid something: " + __ENV.something + " should be undefined"); + } + __ENV.something = __VU; + } else if (__ENV.something != __VU) { + throw new Error("invalid something: " + __ENV.something+ " should be "+ __VU); + } + } + ` + b1, err := getSimpleBundle("/script.js", data) + if !assert.NoError(t, err) { + return + } + + b2, err := NewBundleFromArchive(b1.makeArchive(), lib.RuntimeOptions{}) + if !assert.NoError(t, err) { + return + } + + bundles := map[string]*Bundle{"Source": b1, "Archive": b2} + vus, iters := 10, 1000 + for name, b := range bundles { + b := b + t.Run(name, func(t *testing.T) { + for i := 0; i < vus; i++ { + bi, err := b.Instantiate() + bi.Runtime.Set("__VU", i) + require.NoError(t, err) + for j := 0; j < iters; j++ { + bi.Runtime.Set("__ITER", j) + _, err := bi.Default(goja.Undefined()) + assert.NoError(t, err) + } + } + }) + } +} + func TestBundleMakeArchive(t *testing.T) { testCases := []struct { cm compiler.CompatibilityMode