From eeb439f548e47c934c420b8efe709369760a9027 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Tue, 29 Aug 2023 20:39:27 +0300 Subject: [PATCH] internal: avoid race access to config.Version by tests Network server constructor reads config.Version variable, and testcli.DeployContract writes dummy config.Version which causes race in tests. Avoid this race by moving config.Version initialisation to a separate package and perform it inside test packages init(). Close #3011, close #3017. Signed-off-by: Anna Shaleva --- cli/app/main_test.go | 3 ++- cli/nep_test/nep11_test.go | 4 ++++ cli/smartcontract/contract_test.go | 31 ++++-------------------------- cli/vm/cli_test.go | 6 ++++-- internal/testchain/transaction.go | 3 ++- internal/testcli/executor.go | 1 - internal/versionutil/init.go | 14 ++++++++++++++ pkg/compiler/compiler_test.go | 7 ++++--- 8 files changed, 34 insertions(+), 35 deletions(-) create mode 100644 internal/versionutil/init.go diff --git a/cli/app/main_test.go b/cli/app/main_test.go index b4452921b..a8521f3a2 100644 --- a/cli/app/main_test.go +++ b/cli/app/main_test.go @@ -4,11 +4,12 @@ import ( "testing" "github.com/nspcc-dev/neo-go/internal/testcli" + "github.com/nspcc-dev/neo-go/internal/versionutil" "github.com/nspcc-dev/neo-go/pkg/config" ) func TestCLIVersion(t *testing.T) { - config.Version = "0.90.0-test" // Zero-length version string disables '--version' completely. + config.Version = versionutil.TestVersion // Zero-length version string disables '--version' completely. e := testcli.NewExecutor(t, false) e.Run(t, "neo-go", "--version") e.CheckNextLine(t, "^NeoGo") diff --git a/cli/nep_test/nep11_test.go b/cli/nep_test/nep11_test.go index a8ea2741f..334a27dd7 100644 --- a/cli/nep_test/nep11_test.go +++ b/cli/nep_test/nep11_test.go @@ -14,6 +14,7 @@ import ( "testing" "github.com/nspcc-dev/neo-go/internal/testcli" + "github.com/nspcc-dev/neo-go/internal/versionutil" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/encoding/address" @@ -29,6 +30,9 @@ const ( nftOwnerAddr = "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB" nftOwnerWallet = "../../examples/my_wallet.json" nftOwnerPass = "qwerty" + + // Keep contract NEFs consistent between runs. + _ = versionutil.TestVersion ) func TestNEP11Import(t *testing.T) { diff --git a/cli/smartcontract/contract_test.go b/cli/smartcontract/contract_test.go index 0699c0526..4b53e7fba 100644 --- a/cli/smartcontract/contract_test.go +++ b/cli/smartcontract/contract_test.go @@ -13,6 +13,7 @@ import ( "github.com/nspcc-dev/neo-go/cli/smartcontract" "github.com/nspcc-dev/neo-go/internal/random" "github.com/nspcc-dev/neo-go/internal/testcli" + "github.com/nspcc-dev/neo-go/internal/versionutil" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/core/interop/storage" "github.com/nspcc-dev/neo-go/pkg/core/state" @@ -31,6 +32,9 @@ import ( "gopkg.in/yaml.v3" ) +// Keep contract NEFs consistent between runs. +const _ = versionutil.TestVersion + func TestCalcHash(t *testing.T) { tmpDir := t.TempDir() e := testcli.NewExecutor(t, false) @@ -97,9 +101,6 @@ func TestCalcHash(t *testing.T) { } func TestContractBindings(t *testing.T) { - // For proper nef generation. - config.Version = "v0.98.1-test" - // For proper contract init. The actual version as it will be replaced. smartcontract.ModVersion = "v0.0.0" @@ -210,9 +211,6 @@ func ToMap(a []testcontract.MyPair) map[int]string { } func TestContractInitAndCompile(t *testing.T) { - // For proper nef generation. - config.Version = "v0.98.1-test" - // For proper contract init. The actual version as it will be replaced. smartcontract.ModVersion = "v0.0.0" @@ -310,9 +308,6 @@ func TestDeployBigContract(t *testing.T) { e := testcli.NewExecutorWithConfig(t, true, true, func(c *config.Config) { c.ApplicationConfiguration.RPC.MaxGasInvoke = fixedn.Fixed8(1) }) - - // For proper nef generation. - config.Version = "0.90.0-test" tmpDir := t.TempDir() nefName := filepath.Join(tmpDir, "deploy.nef") @@ -331,9 +326,6 @@ func TestDeployBigContract(t *testing.T) { func TestContractDeployWithData(t *testing.T) { eCompile := testcli.NewExecutor(t, false) - - // For proper nef generation. - config.Version = "0.90.0-test" tmpDir := t.TempDir() nefName := filepath.Join(tmpDir, "deploy.nef") @@ -408,9 +400,6 @@ func TestContractDeployWithData(t *testing.T) { func TestDeployWithSigners(t *testing.T) { e := testcli.NewExecutor(t, true) - - // For proper nef generation. - config.Version = "0.90.0-test" tmpDir := t.TempDir() nefName := filepath.Join(tmpDir, "deploy.nef") @@ -472,9 +461,6 @@ func TestDeployWithSigners(t *testing.T) { func TestContractManifestGroups(t *testing.T) { e := testcli.NewExecutor(t, true) - - // For proper nef generation. - config.Version = "0.90.0-test" tmpDir := t.TempDir() _, err := wallet.NewWalletFromFile(testcli.TestWalletPath) @@ -631,9 +617,6 @@ func TestContract_TestInvokeScript(t *testing.T) { func TestComlileAndInvokeFunction(t *testing.T) { e := testcli.NewExecutor(t, true) - - // For proper nef generation. - config.Version = "0.90.0-test" tmpDir := t.TempDir() nefName := filepath.Join(tmpDir, "deploy.nef") @@ -963,9 +946,6 @@ func TestComlileAndInvokeFunction(t *testing.T) { func TestContractInspect(t *testing.T) { e := testcli.NewExecutor(t, false) - - // For proper nef generation. - config.Version = "0.90.0-test" const srcPath = "testdata/deploy/main.go" tmpDir := t.TempDir() @@ -1000,9 +980,6 @@ func TestCompileExamples(t *testing.T) { infos, err := os.ReadDir(examplePath) require.NoError(t, err) - // For proper nef generation. - config.Version = "0.90.0-test" - e := testcli.NewExecutor(t, false) for _, info := range infos { diff --git a/cli/vm/cli_test.go b/cli/vm/cli_test.go index 20b5e6d3b..bef78e711 100644 --- a/cli/vm/cli_test.go +++ b/cli/vm/cli_test.go @@ -22,6 +22,7 @@ import ( "github.com/nspcc-dev/neo-go/cli/paramcontext" "github.com/nspcc-dev/neo-go/internal/basicchain" "github.com/nspcc-dev/neo-go/internal/random" + "github.com/nspcc-dev/neo-go/internal/versionutil" "github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config/netmode" @@ -44,6 +45,9 @@ import ( "go.uber.org/atomic" ) +// Keep contract NEFs consistent between runs. +const _ = versionutil.TestVersion + type readCloser struct { sync.Mutex bytes.Buffer @@ -351,8 +355,6 @@ go 1.18`) // via `loadnef` command. It returns the name of manifest and NEF files ready to be used in CLI // commands. func prepareLoadnefSrc(t *testing.T, tmpDir, src string) (string, string) { - config.Version = "0.92.0-test" - nefFile, di, err := compiler.CompileWithOptions("test.go", strings.NewReader(src), nil) require.NoError(t, err) filename := filepath.Join(tmpDir, "vmtestcontract.nef") diff --git a/internal/testchain/transaction.go b/internal/testchain/transaction.go index cce8dd49c..43b817d98 100644 --- a/internal/testchain/transaction.go +++ b/internal/testchain/transaction.go @@ -7,6 +7,7 @@ import ( "strings" clisc "github.com/nspcc-dev/neo-go/cli/smartcontract" + "github.com/nspcc-dev/neo-go/internal/versionutil" "github.com/nspcc-dev/neo-go/pkg/compiler" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/core/block" @@ -61,7 +62,7 @@ func NewTransferFromOwner(bc Ledger, contractHash, to util.Uint160, amount int64 // the filename without '.go' suffix. func NewDeployTx(bc Ledger, name string, sender util.Uint160, r gio.Reader, confFile *string) (*transaction.Transaction, util.Uint160, []byte, error) { // nef.NewFile() cares about version a lot. - config.Version = "0.90.0-test" + config.Version = versionutil.TestVersion o := &compiler.Options{ Name: strings.TrimSuffix(name, ".go"), diff --git a/internal/testcli/executor.go b/internal/testcli/executor.go index 20fa01a64..d6cc9da1e 100644 --- a/internal/testcli/executor.go +++ b/internal/testcli/executor.go @@ -340,7 +340,6 @@ func (e *Executor) CheckScriptDump(t *testing.T, scriptSize int) { } func DeployContract(t *testing.T, e *Executor, inPath, configPath, wallet, address, pass string) util.Uint160 { - config.Version = "0.90.0-test" // Contracts are compiled and we want NEFs to not change from run to run. tmpDir := t.TempDir() nefName := filepath.Join(tmpDir, "contract.nef") manifestName := filepath.Join(tmpDir, "contract.manifest.json") diff --git a/internal/versionutil/init.go b/internal/versionutil/init.go new file mode 100644 index 000000000..9de3f5298 --- /dev/null +++ b/internal/versionutil/init.go @@ -0,0 +1,14 @@ +package versionutil + +import "github.com/nspcc-dev/neo-go/pkg/config" + +// TestVersion is a NeoGo version that should be used to keep all +// compiled NEFs the same from run to run for tests. +const TestVersion = "0.90.0-test" + +// init sets config.Version to a dummy TestVersion value to keep contract NEFs +// consistent between test runs for those packages who import it. For test usage +// only! +func init() { + config.Version = TestVersion +} diff --git a/pkg/compiler/compiler_test.go b/pkg/compiler/compiler_test.go index 89a5d431b..6cbbacc1f 100644 --- a/pkg/compiler/compiler_test.go +++ b/pkg/compiler/compiler_test.go @@ -9,8 +9,8 @@ import ( "testing" "github.com/nspcc-dev/neo-go/internal/random" + "github.com/nspcc-dev/neo-go/internal/versionutil" "github.com/nspcc-dev/neo-go/pkg/compiler" - "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/interop/native/neo" "github.com/nspcc-dev/neo-go/pkg/smartcontract" @@ -23,14 +23,15 @@ const examplePath = "../../examples" const exampleCompilePath = "testdata/compile" const exampleSavePath = exampleCompilePath + "/save" +// Keep contract NEFs consistent between runs. +const _ = versionutil.TestVersion + type compilerTestCase struct { name string function func(*testing.T) } func TestCompiler(t *testing.T) { - // CompileAndSave uses config.Version for proper .nef generation. - config.Version = "0.90.0-test" testCases := []compilerTestCase{ { name: "TestCompileDirectory",