// Copyright 2015 The go-expanse Authors // This file is part of go-expanse. // // go-expanse is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // go-expanse 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with go-expanse. If not, see . package main import ( "fmt" "os" "github.com/codegangsta/cli" "github.com/expanse-project/go-expanse/cmd/utils" "github.com/expanse-project/go-expanse/common" "github.com/expanse-project/go-expanse/exp" "github.com/expanse-project/go-expanse/ethdb" "github.com/expanse-project/go-expanse/tests" ) var blocktestCommand = cli.Command{ Action: runBlockTest, Name: "blocktest", Usage: `loads a block test file`, Description: ` The first argument should be a block test file. The second argument is the name of a block test from the file. The block test will be loaded into an in-memory database. If loading succeeds, the RPC server is started. Clients will be able to interact with the chain defined by the test. `, } func runBlockTest(ctx *cli.Context) { var ( file, testname string rpc bool ) args := ctx.Args() switch { case len(args) == 1: file = args[0] case len(args) == 2: file, testname = args[0], args[1] case len(args) == 3: file, testname = args[0], args[1] rpc = true default: utils.Fatalf(`Usage: expanse blocktest [ [ "rpc" ] ]`) } bt, err := tests.LoadBlockTests(file) if err != nil { utils.Fatalf("%v", err) } // run all tests if no test name is specified if testname == "" { ecode := 0 for name, test := range bt { fmt.Printf("----------------- Running Block Test %q\n", name) expanse, err := runOneBlockTest(ctx, test) if err != nil { fmt.Println(err) fmt.Println("FAIL") ecode = 1 } if expanse != nil { expanse.Stop() expanse.WaitForShutdown() } } os.Exit(ecode) return } // otherwise, run the given test test, ok := bt[testname] if !ok { utils.Fatalf("Test file does not contain test named %q", testname) } expanse, err := runOneBlockTest(ctx, test) if err != nil { utils.Fatalf("%v", err) } defer expanse.Stop() if rpc { fmt.Println("Block Test post state validated, starting RPC interface.") startEth(ctx, expanse) utils.StartRPC(expanse, ctx) expanse.WaitForShutdown() } } func runOneBlockTest(ctx *cli.Context, test *tests.BlockTest) (*exp.Expanse, error) { cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) cfg.NewDB = func(path string) (common.Database, error) { return ethdb.NewMemDatabase() } cfg.MaxPeers = 0 // disable network cfg.Shh = false // disable whisper cfg.NAT = nil // disable port mapping expanse, err := exp.New(cfg) if err != nil { return nil, err } // if err := expanse.Start(); err != nil { // return nil, err // } // import the genesis block expanse.ResetWithGenesisBlock(test.Genesis) // import pre accounts statedb, err := test.InsertPreState(expanse) if err != nil { return expanse, fmt.Errorf("InsertPreState: %v", err) } if err := test.TryBlocksInsert(expanse.ChainManager()); err != nil { return expanse, fmt.Errorf("Block Test load error: %v", err) } if err := test.ValidatePostState(statedb); err != nil { return expanse, fmt.Errorf("post state validation failed: %v", err) } return expanse, nil }