diff --git a/README.md b/README.md index 1d63c73..3d1b4e1 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,14 @@ A framework to fuzz Ethereum Virtual Machine implementations. +FuzzyVM uses two different processes. +One process generates test cases and the other one executes them on different EVM implementations. +The traces of the EVM's are collected and compared against each other. +If a crasher is found, + ## Environment -You need to have golang < 1.15 installed as go version 1.15 includes some -changes that break go-fuzz. +You might need to have golang < 1.15 installed as go version 1.15 includes some +changes that might break go-fuzz. ## Install instructions @@ -21,3 +26,14 @@ go build ./FuzzyVM ``` +If the fuzzer breaks (or you shut it down) it might leave test cases laying around. +You can execute the test cases with `./FuzzyVM --exec`. + +It makes sense to create an initial corpus in order to improve the efficiency of the fuzzer. +You can generate corpus elements with `./FuzzyVM --corpus N`. + +## Config + +FuzzyVM has to be configured to know which EVMs it should use. +You can specify the paths to the EVMs in a config file. +An example for the config file can be found in `config.toml`. diff --git a/benchmark/linear.go b/benchmark/linear.go index f1c833b..35e50aa 100644 --- a/benchmark/linear.go +++ b/benchmark/linear.go @@ -6,6 +6,7 @@ import ( "github.com/MariusVanDerWijden/FuzzyVM/executor" "github.com/MariusVanDerWijden/FuzzyVM/generator" + "github.com/holiman/goevmlab/evms" ) // testGeneration generates N programs. @@ -32,13 +33,14 @@ func verify(N int) (time.Duration, error) { return time.Nanosecond, err } name = fmt.Sprintf("%v/%v.json", outDir, name) - out, err := executor.ExecuteTest(name) + exc := newExecutor() + out, err := exc.ExecuteTest(name) if err != nil { return time.Nanosecond, err } start := time.Now() for i := 0; i < N; i++ { - if !executor.Verify(name, out) { + if !exc.Verify(name, out) { return time.Nanosecond, fmt.Errorf("Verification failed: %v", name) } } @@ -56,10 +58,10 @@ func execution(N int) (time.Duration, error) { return time.Nanosecond, err } name = fmt.Sprintf("%v.json", name) - executor.PrintTrace = false + exc := newExecutor() start := time.Now() for i := 0; i < N; i++ { - executor.ExecuteFullTest(outDir, crashers, name, false) + exc.ExecuteFullTest(outDir, crashers, name, false) } return time.Since(start), nil } @@ -87,10 +89,15 @@ func execMultiple(N int, threadlimit int) (time.Duration, error) { } names = append(names, fmt.Sprintf("%v.json", name)) } - executor.PrintTrace = false + exc := newExecutor() start := time.Now() - if err := executor.Execute(outDir, crashers, threadlimit); err != nil { + if err := exc.Execute(outDir, crashers, threadlimit); err != nil { return time.Nanosecond, err } return time.Since(start), nil } + +func newExecutor() *executor.Executor { + // TODO add meaningful vms for benchmarks + return executor.NewExecutor([]evms.Evm{}, false) +} diff --git a/config.go b/config.go new file mode 100644 index 0000000..58b694c --- /dev/null +++ b/config.go @@ -0,0 +1,94 @@ +// Copyright 2020 Marius van der Wijden +// This file is part of the fuzzy-vm library. +// +// The fuzzy-vm library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The fuzzy-vm library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the fuzzy-vm library. If not, see . + +package main + +import ( + "bufio" + "errors" + "fmt" + "os" + "reflect" + "unicode" + + "github.com/holiman/goevmlab/evms" + "github.com/naoina/toml" +) + +func getVMsFromConfig(file string) ([]evms.Evm, error) { + conf, err := loadConfig(file) + if err != nil { + return []evms.Evm{}, err + } + var vms []evms.Evm + for _, s := range conf.Geth { + vms = append(vms, evms.NewGethEVM(s)) + } + for _, s := range conf.Nethermind { + vms = append(vms, evms.NewNethermindVM(s)) + } + for _, s := range conf.Besu { + vms = append(vms, evms.NewBesuVM(s)) + } + for _, s := range conf.OpenEthereum { + vms = append(vms, evms.NewParityVM(s)) + } + for _, s := range conf.Aleth { + vms = append(vms, evms.NewAlethVM(s)) + } + return vms, nil +} + +type config struct { + Geth []string + Besu []string + OpenEthereum []string + Nethermind []string + Aleth []string +} + +func loadConfig(file string) (*config, error) { + f, err := os.Open(file) + if err != nil { + return nil, err + } + defer f.Close() + + conf := &config{} + err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(conf) + // Add file name to errors that have a line number. + if _, ok := err.(*toml.LineError); ok { + err = errors.New(file + ", " + err.Error()) + } + return conf, err +} + +// These settings ensure that TOML keys use the same names as Go struct fields. +var tomlSettings = toml.Config{ + NormFieldName: func(rt reflect.Type, key string) string { + return key + }, + FieldToKey: func(rt reflect.Type, field string) string { + return field + }, + MissingField: func(rt reflect.Type, field string) error { + link := "" + if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" { + link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name()) + } + return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link) + }, +} diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..22bd372 --- /dev/null +++ b/config.toml @@ -0,0 +1,5 @@ +Geth = ["/home/matematik/ethereum/FuzzyVM/vms/geth-evm", "/home/matematik/ethereum/FuzzyVM/vms/turbogeth-evm"] +OpenEthereum = ["/home/matematik/ethereum/FuzzyVM/vms/openethereum-evm"] +Nethermind = ["/home/matematik/ethereum/neth_test/nethermind/src/Nethermind/Nethermind.State.Test.Runner/bin/Release/netcoreapp3.1/nethtest"] +Besu = ["/home/matematik/ethereum/besu/ethereum/evmtool/build/install/evmtool/bin/evm"] +Aleth = [] \ No newline at end of file diff --git a/executor/executor.go b/executor/executor.go index dcb9cb2..af141e7 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -31,19 +31,22 @@ import ( "github.com/pkg/errors" ) -var ( - vms = []evms.Evm{ - evms.NewGethEVM("/home/matematik/ethereum/FuzzyVM/vms/geth-evm"), - evms.NewParityVM("/home/matematik/ethereum/FuzzyVM/vms/openethereum-evm"), - evms.NewNethermindVM("/home/matematik/ethereum/neth_test/nethermind/src/Nethermind/Nethermind.State.Test.Runner/bin/Release/netcoreapp3.1/nethtest"), - evms.NewBesuVM("/home/matematik/ethereum/besu/ethereum/evmtool/build/install/evmtool/bin/evm"), - evms.NewGethEVM("/home/matematik/ethereum/FuzzyVM/vms/turbogeth-evm"), +var PrintTrace = true + +type Executor struct { + Vms []evms.Evm + PrintTrace bool +} + +func NewExecutor(vms []evms.Evm, printTrace bool) *Executor { + return &Executor{ + Vms: vms, + PrintTrace: printTrace, } - PrintTrace = true -) +} // Execute runs all tests in `dirName` and saves crashers in `outDir` -func Execute(dirName, outDir string, threadlimit int) error { +func (e *Executor) Execute(dirName, outDir string, threadlimit int) error { infos, err := ioutil.ReadDir(dirName) if err != nil { return err @@ -59,7 +62,7 @@ func Execute(dirName, outDir string, threadlimit int) error { meter.Mark(1) name := info.Name() job := func() { - if err := ExecuteFullTest(dirName, outDir, name, true); err != nil { + if err := e.ExecuteFullTest(dirName, outDir, name, true); err != nil { err := errors.Wrap(err, fmt.Sprintf("in file: %v", name)) fmt.Println(err) //errChan <- err @@ -81,7 +84,7 @@ func Execute(dirName, outDir string, threadlimit int) error { } // ExecuteFullTest executes a single test. -func ExecuteFullTest(dirName, outDir, filename string, doPurge bool) error { +func (e *Executor) ExecuteFullTest(dirName, outDir, filename string, doPurge bool) error { var ( testFile = fmt.Sprintf("%v/%v", dirName, filename) testName = strings.TrimRight(filename, ".json") @@ -89,17 +92,17 @@ func ExecuteFullTest(dirName, outDir, filename string, doPurge bool) error { outputs [][]byte err error ) - outputs, err = ExecuteTest(testFile) + outputs, err = e.ExecuteTest(testFile) if err != nil { return err } - return verifyAndPurge(traceFile, testName, outDir, testFile, outputs, doPurge) + return e.verifyAndPurge(traceFile, testName, outDir, testFile, outputs, doPurge) } -func verifyAndPurge(traceFile, testName, outDir, testFile string, outputs [][]byte, doPurge bool) error { - if !Verify(traceFile, outputs) { +func (e *Executor) verifyAndPurge(traceFile, testName, outDir, testFile string, outputs [][]byte, doPurge bool) error { + if !e.Verify(traceFile, outputs) { fmt.Printf("Test %v failed, dumping\n", testName) - if err := dump(testName, outDir, vms, outputs); err != nil { + if err := dump(testName, outDir, e.Vms, outputs); err != nil { return err } } else { @@ -109,17 +112,17 @@ func verifyAndPurge(traceFile, testName, outDir, testFile string, outputs [][]by fmt.Printf("Purging failed: %v\n", err) } } else if PrintTrace { - printOutputs(outputs) + e.printOutputs(outputs) } } return nil } // ExecuteTest executes a state test. -func ExecuteTest(testName string) ([][]byte, error) { +func (e *Executor) ExecuteTest(testName string) ([][]byte, error) { var buf [][]byte var buffer bytes.Buffer - for _, vm := range vms { + for _, vm := range e.Vms { buffer.Reset() if _, err := vm.RunStateTest(testName, &buffer, false); err != nil { return nil, err @@ -130,7 +133,7 @@ func ExecuteTest(testName string) ([][]byte, error) { } // Verify checks if the traces match the default trace. -func Verify(traceName string, outputs [][]byte) bool { +func (e *Executor) Verify(traceName string, outputs [][]byte) bool { var ioReaders []io.Reader for _, out := range outputs { ioReaders = append(ioReaders, bytes.NewReader(out)) @@ -143,7 +146,7 @@ func Verify(traceName string, outputs [][]byte) bool { } ioReaders = append(ioReaders, bytes.NewBuffer(ref)) */ - return evms.CompareFiles(vms, ioReaders) + return evms.CompareFiles(e.Vms, ioReaders) } // dump writes outputs to a file in case of a verification problem @@ -168,11 +171,11 @@ func purge(filename, tracename string) error { } // printOutputs prints out the produced traces -func printOutputs(outputs [][]byte) { +func (e *Executor) printOutputs(outputs [][]byte) { fmt.Println("TRACES:") fmt.Println("--------------") for i, out := range outputs { - fmt.Printf("%v: \n", vms[i].Name()) + fmt.Printf("%v: \n", e.Vms[i].Name()) fmt.Print(string(out)) fmt.Println("--------------") } diff --git a/flags.go b/flags.go index 1751d44..af386a2 100644 --- a/flags.go +++ b/flags.go @@ -64,4 +64,9 @@ var ( Name: "corpus", Usage: "Number of corpus elements that should be created", } + configFileFlag = cli.StringFlag{ + Name: "config", + Usage: "Path to the config file required to run FuzzyVM", + Value: "config.toml", + } ) diff --git a/generator/basic_strategies.go b/generator/basic_strategies.go index 8278381..46f649f 100644 --- a/generator/basic_strategies.go +++ b/generator/basic_strategies.go @@ -17,27 +17,16 @@ package generator import ( - "math/big" - - "github.com/MariusVanDerWijden/FuzzyVM/filler" - "github.com/MariusVanDerWijden/FuzzyVM/generator/precompiles" - "github.com/ethereum/go-ethereum/common" "github.com/holiman/goevmlab/ops" ) var basicStrategies = []Strategy{ new(opcodeGenerator), - new(jumpdestGenerator), - new(jumpGenerator), new(memStorageGenerator), new(mstoreGenerator), new(sstoreGenerator), new(returnDataGenerator), new(returnGenerator), - new(createCallRNGGenerator), - new(createCallGenerator), - new(randomCallGenerator), - new(callPrecompileGenerator), new(pushGenerator), } @@ -58,52 +47,6 @@ func (*opcodeGenerator) Importance() int { return 10 } -type jumpdestGenerator struct{} - -func (*jumpdestGenerator) Execute(env Environment) { - switch env.f.Byte() % 10 { - case 0: - // Set a jumpdest label - env.jumptable.Push(env.p.Label(), env.p.Label()) - case 1: - // Set the jumpdest randomly - env.jumptable.Push(uint64(env.f.Uint16()), env.p.Label()) - default: - // Set a jumpdest - env.jumptable.Push(env.p.Jumpdest(), env.p.Label()) - } -} - -func (*jumpdestGenerator) Importance() int { - return 5 -} - -type jumpGenerator struct{} - -func (*jumpGenerator) Execute(env Environment) { - if env.f.Bool() { - // Jump to a label - jumpdest := env.jumptable.Pop(env.p.Label()) - env.p.Jump(jumpdest) - } else { - // Jumpi to a label - var ( - jumpdest = env.jumptable.Pop(env.p.Label()) - shouldJump = env.f.Bool() - condition = big.NewInt(0) - ) - if shouldJump { - condition = env.f.BigInt() - } - // jumps if condition != 0 - env.p.JumpIf(jumpdest, condition) - } -} - -func (*jumpGenerator) Importance() int { - return 7 -} - type memStorageGenerator struct{} func (*memStorageGenerator) Execute(env Environment) { @@ -177,88 +120,6 @@ func (*returnGenerator) Importance() int { return 1 } -type createCallRNGGenerator struct{} - -func (*createCallRNGGenerator) Execute(env Environment) { - // Create and call a random program - var ( - code = env.f.ByteSlice256() - isCreate2 = env.f.Bool() - callOp = ops.OpCode(env.f.Byte()) - ) - env.p.CreateAndCall(code, isCreate2, callOp) -} - -func (*createCallRNGGenerator) Importance() int { - return 4 -} - -type createCallGenerator struct{} - -func (*createCallGenerator) Execute(env Environment) { - // Prevent to deep recursion - if recursionLevel > maxRecursionLevel { - return - } - recursionLevel++ - // Create and call a meaningful program - var ( - seedLen = env.f.Uint16() - seed = env.f.ByteSlice(int(seedLen)) - newFiller = filler.NewFiller(seed) - _, code = GenerateProgram(newFiller) - isCreate2 = env.f.Bool() - callOp = ops.OpCode(env.f.Byte()) - ) - env.p.CreateAndCall(code, isCreate2, callOp) - // Decreasing recursion level generates to heavy test cases, - // so once we reach maxRecursionLevel we don't create new CreateAndCalls. - - // recursionLevel-- -} - -func (*createCallGenerator) Importance() int { - return 5 -} - -type randomCallGenerator struct{} - -func (*randomCallGenerator) Execute(env Environment) { - // Call a random address - var addr common.Address - if env.f.Bool() { - // call a precompile - addr = common.BigToAddress(new(big.Int).Mod(env.f.BigInt16(), big.NewInt(20))) - } else { - addr = common.BytesToAddress(env.f.ByteSlice(20)) - } - - c := precompiles.CallObj{ - Gas: env.f.GasInt(), - Address: addr, - Value: env.f.BigInt16(), - InOffset: uint32(env.f.Uint16()), - InSize: uint32(env.f.Uint16()), - OutOffset: uint32(env.f.Uint16()), - OutSize: uint32(env.f.Uint16()), - } - precompiles.CallRandomizer(env.p, env.f, c) -} - -func (*randomCallGenerator) Importance() int { - return 4 -} - -type callPrecompileGenerator struct{} - -func (*callPrecompileGenerator) Execute(env Environment) { - precompiles.CallPrecompile(env.p, env.f) -} - -func (*callPrecompileGenerator) Importance() int { - return 8 -} - type pushGenerator struct{} func (*pushGenerator) Execute(env Environment) { diff --git a/generator/call_strategies.go b/generator/call_strategies.go new file mode 100644 index 0000000..088d1d0 --- /dev/null +++ b/generator/call_strategies.go @@ -0,0 +1,115 @@ +// Copyright 2021 Marius van der Wijden +// This file is part of the fuzzy-vm library. +// +// The fuzzy-vm library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The fuzzy-vm library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the fuzzy-vm library. If not, see . + +package generator + +import ( + "math/big" + + "github.com/MariusVanDerWijden/FuzzyVM/filler" + "github.com/MariusVanDerWijden/FuzzyVM/generator/precompiles" + "github.com/ethereum/go-ethereum/common" + "github.com/holiman/goevmlab/ops" +) + +var callStrategies = []Strategy{ + new(createCallRNGGenerator), + new(createCallGenerator), + new(randomCallGenerator), + new(callPrecompileGenerator), +} + +type createCallRNGGenerator struct{} + +func (*createCallRNGGenerator) Execute(env Environment) { + // Create and call a random program + var ( + code = env.f.ByteSlice256() + isCreate2 = env.f.Bool() + callOp = ops.OpCode(env.f.Byte()) + ) + env.p.CreateAndCall(code, isCreate2, callOp) +} + +func (*createCallRNGGenerator) Importance() int { + return 4 +} + +type createCallGenerator struct{} + +func (*createCallGenerator) Execute(env Environment) { + // Prevent to deep recursion + if recursionLevel > maxRecursionLevel { + return + } + recursionLevel++ + // Create and call a meaningful program + var ( + seedLen = env.f.Uint16() + seed = env.f.ByteSlice(int(seedLen)) + newFiller = filler.NewFiller(seed) + _, code = GenerateProgram(newFiller) + isCreate2 = env.f.Bool() + callOp = ops.OpCode(env.f.Byte()) + ) + env.p.CreateAndCall(code, isCreate2, callOp) + // Decreasing recursion level generates to heavy test cases, + // so once we reach maxRecursionLevel we don't create new CreateAndCalls. + + // recursionLevel-- +} + +func (*createCallGenerator) Importance() int { + return 5 +} + +type randomCallGenerator struct{} + +func (*randomCallGenerator) Execute(env Environment) { + // Call a random address + var addr common.Address + if env.f.Bool() { + // call a precompile + addr = common.BigToAddress(new(big.Int).Mod(env.f.BigInt16(), big.NewInt(20))) + } else { + addr = common.BytesToAddress(env.f.ByteSlice(20)) + } + + c := precompiles.CallObj{ + Gas: env.f.GasInt(), + Address: addr, + Value: env.f.BigInt16(), + InOffset: uint32(env.f.Uint16()), + InSize: uint32(env.f.Uint16()), + OutOffset: uint32(env.f.Uint16()), + OutSize: uint32(env.f.Uint16()), + } + precompiles.CallRandomizer(env.p, env.f, c) +} + +func (*randomCallGenerator) Importance() int { + return 4 +} + +type callPrecompileGenerator struct{} + +func (*callPrecompileGenerator) Execute(env Environment) { + precompiles.CallPrecompile(env.p, env.f) +} + +func (*callPrecompileGenerator) Importance() int { + return 8 +} diff --git a/generator/jump_strategies.go b/generator/jump_strategies.go new file mode 100644 index 0000000..dcc6a18 --- /dev/null +++ b/generator/jump_strategies.go @@ -0,0 +1,70 @@ +// Copyright 2021 Marius van der Wijden +// This file is part of the fuzzy-vm library. +// +// The fuzzy-vm library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The fuzzy-vm library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the fuzzy-vm library. If not, see . + +package generator + +import "math/big" + +var jumpStrategies = []Strategy{ + new(jumpdestGenerator), + new(jumpGenerator), +} + +type jumpdestGenerator struct{} + +func (*jumpdestGenerator) Execute(env Environment) { + switch env.f.Byte() % 10 { + case 0: + // Set a jumpdest label + env.jumptable.Push(env.p.Label(), env.p.Label()) + case 1: + // Set the jumpdest randomly + env.jumptable.Push(uint64(env.f.Uint16()), env.p.Label()) + default: + // Set a jumpdest + env.jumptable.Push(env.p.Jumpdest(), env.p.Label()) + } +} + +func (*jumpdestGenerator) Importance() int { + return 5 +} + +type jumpGenerator struct{} + +func (*jumpGenerator) Execute(env Environment) { + if env.f.Bool() { + // Jump to a label + jumpdest := env.jumptable.Pop(env.p.Label()) + env.p.Jump(jumpdest) + } else { + // Jumpi to a label + var ( + jumpdest = env.jumptable.Pop(env.p.Label()) + shouldJump = env.f.Bool() + condition = big.NewInt(0) + ) + if shouldJump { + condition = env.f.BigInt() + } + // jumps if condition != 0 + env.p.JumpIf(jumpdest, condition) + } +} + +func (*jumpGenerator) Importance() int { + return 7 +} diff --git a/go.mod b/go.mod index 52564a1..a5aec58 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/ethereum/go-ethereum v1.10.2 github.com/holiman/goevmlab v0.0.0-20210406174504-acc14986d1a1 github.com/korovkin/limiter v0.0.0-20190919045942-dac5a6b2a536 + github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/pkg/errors v0.9.1 gopkg.in/urfave/cli.v1 v1.20.0 ) diff --git a/go.sum b/go.sum index b3382ca..62a9beb 100644 --- a/go.sum +++ b/go.sum @@ -35,7 +35,6 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/MariusVanDerWijden/go-ethereum v1.8.22/go.mod h1:ebrf7+OjOOcr3sIpE3bNWHVHvUvpIiEk07dr3G9wrAw= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -59,7 +58,6 @@ github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8 github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= -github.com/aristanetworks/goarista v0.0.0-20201012165903-2cb20defcd66/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -84,16 +82,11 @@ github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx2 github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= -github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= @@ -127,14 +120,12 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813 h1:NgO45/5mBLRVfiXerEFzH6ikcZ7DNRPS639xFg3ENzU= github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= @@ -145,7 +136,6 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.23/go.mod h1:JIfVb6esrqALTExdz9hRYvrP0xBDf6wCncIu1hNwHpM= github.com/ethereum/go-ethereum v1.9.25/go.mod h1:vMkFiYLHI4tgPw4k2j4MHKoovchFE8plZ0M9VMk4/oM= github.com/ethereum/go-ethereum v1.10.1/go.mod h1:E5e/zvdfUVr91JZ0AwjyuJM3x+no51zZJRz61orLLSk= github.com/ethereum/go-ethereum v1.10.2 h1:qRDI7ztIBsAFH0ULVjU+twnRUYV2ApT0XJBdxxaSNzk= @@ -164,7 +154,6 @@ github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= -github.com/gdamore/tcell v1.4.0/go.mod h1:vxEiSDZdW3L+Uhjii9c3375IlDmR05bzxY404ZVSMo0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= @@ -210,7 +199,6 @@ github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.2-0.20200707131729-196ae77b8a26/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 h1:ur2rms48b3Ep1dxh7aUV2FZEQ8jEVO2F6ILKx8ofkAg= github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -293,7 +281,6 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -334,6 +321,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.8/go.mod h1:gNcbPWNEWRe4lm+bycKqxUYoH5uoVje5SkOJ3uoLer8= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= @@ -350,7 +338,6 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -372,14 +359,15 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -388,7 +376,6 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -440,7 +427,6 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rivo/tview v0.0.0-20200712113419-c65badfc3d92/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84= -github.com/rivo/tview v0.0.0-20200915114512-42866ecf6ca6/go.mod h1:xV4Aw4WIX8cmhg71U7MUHBdpIQ7zSEXdRruGHLaEAOc= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -458,8 +444,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v2.20.7+incompatible h1:Ymv4OD12d6zm+2yONe39VSmp2XooJe8za7ngOLW/o/w= github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ= -github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -524,15 +508,11 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= -golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -562,7 +542,6 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -630,9 +609,7 @@ golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210105210732-16f7687f5001/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/main.go b/main.go index b3f809e..502f61f 100644 --- a/main.go +++ b/main.go @@ -49,6 +49,7 @@ func initApp() *cli.App { execNoGen, benchFlag, corpusFlag, + configFileFlag, } return app } @@ -67,15 +68,25 @@ func main() { } func mainLoop(c *cli.Context) { - execThreads := c.GlobalInt(execThreadsFlag.Name) + var ( + execThreads = c.GlobalInt(execThreadsFlag.Name) + configFile = c.GlobalString(configFileFlag.Name) + ) + + vms, err := getVMsFromConfig(configFile) + if err != nil { + panic(err) + } + exec := executor.NewExecutor(vms, true) + if c.GlobalBool(buildFlag.Name) { if err := startBuilder(); err != nil { panic(err) } } else if c.GlobalString(retestFlag.Name) != "" { - retest(c) + retest(c, exec) } else if c.GlobalBool(execNoGen.Name) { - if err := executor.Execute(dirName, outDir, execThreads); err != nil { + if err := exec.Execute(dirName, outDir, execThreads); err != nil { panic(err) } } else if c.GlobalInt(benchFlag.Name) != 0 { @@ -83,7 +94,7 @@ func mainLoop(c *cli.Context) { } else if c.GlobalInt(corpusFlag.Name) != 0 { createCorpus(c.GlobalInt(corpusFlag.Name)) } else { - generatorLoop(c) + generatorLoop(c, exec) } } @@ -100,14 +111,14 @@ func startBuilder() error { return cmd.Run() } -func retest(c *cli.Context) { +func retest(c *cli.Context, exec *executor.Executor) { p := c.GlobalString(retestFlag.Name) dir := path.Dir(p) test := path.Base(p) - executor.ExecuteFullTest(dirName, dir, test, false) + exec.ExecuteFullTest(dirName, dir, test, false) } -func generatorLoop(c *cli.Context) { +func generatorLoop(c *cli.Context, exec *executor.Executor) { var ( genThreads = c.GlobalInt(genThreadsFlag.Name) execThreads = c.GlobalInt(execThreadsFlag.Name) @@ -123,7 +134,7 @@ func generatorLoop(c *cli.Context) { // Sleep a bit to ensure some tests have been generated. time.Sleep(30 * time.Second) fmt.Println("Starting executor") - if err := executor.Execute(dirName, outDir, execThreads); err != nil { + if err := exec.Execute(dirName, outDir, execThreads); err != nil { errChan <- err } errChan <- nil