github.com/shrimpyuk/bor@v0.2.15-0.20220224151350-fb4ec6020bae/cmd/evm/t8n_test.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"reflect"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/docker/docker/pkg/reexec"
    12  	"github.com/ethereum/go-ethereum/internal/cmdtest"
    13  )
    14  
    15  func TestMain(m *testing.M) {
    16  	// Run the app if we've been exec'd as "ethkey-test" in runEthkey.
    17  	reexec.Register("evm-test", func() {
    18  		if err := app.Run(os.Args); err != nil {
    19  			fmt.Fprintln(os.Stderr, err)
    20  			os.Exit(1)
    21  		}
    22  		os.Exit(0)
    23  	})
    24  	// check if we have been reexec'd
    25  	if reexec.Init() {
    26  		return
    27  	}
    28  	os.Exit(m.Run())
    29  }
    30  
    31  type testT8n struct {
    32  	*cmdtest.TestCmd
    33  }
    34  
    35  type t8nInput struct {
    36  	inAlloc  string
    37  	inTxs    string
    38  	inEnv    string
    39  	stFork   string
    40  	stReward string
    41  }
    42  
    43  func (args *t8nInput) get(base string) []string {
    44  	var out []string
    45  	if opt := args.inAlloc; opt != "" {
    46  		out = append(out, "--input.alloc")
    47  		out = append(out, fmt.Sprintf("%v/%v", base, opt))
    48  	}
    49  	if opt := args.inTxs; opt != "" {
    50  		out = append(out, "--input.txs")
    51  		out = append(out, fmt.Sprintf("%v/%v", base, opt))
    52  	}
    53  	if opt := args.inEnv; opt != "" {
    54  		out = append(out, "--input.env")
    55  		out = append(out, fmt.Sprintf("%v/%v", base, opt))
    56  	}
    57  	if opt := args.stFork; opt != "" {
    58  		out = append(out, "--state.fork", opt)
    59  	}
    60  	if opt := args.stReward; opt != "" {
    61  		out = append(out, "--state.reward", opt)
    62  	}
    63  	return out
    64  }
    65  
    66  type t8nOutput struct {
    67  	alloc  bool
    68  	result bool
    69  	body   bool
    70  }
    71  
    72  func (args *t8nOutput) get() (out []string) {
    73  	if args.body {
    74  		out = append(out, "--output.body", "stdout")
    75  	} else {
    76  		out = append(out, "--output.body", "") // empty means ignore
    77  	}
    78  	if args.result {
    79  		out = append(out, "--output.result", "stdout")
    80  	} else {
    81  		out = append(out, "--output.result", "")
    82  	}
    83  	if args.alloc {
    84  		out = append(out, "--output.alloc", "stdout")
    85  	} else {
    86  		out = append(out, "--output.alloc", "")
    87  	}
    88  	return out
    89  }
    90  
    91  func TestT8n(t *testing.T) {
    92  	tt := new(testT8n)
    93  	tt.TestCmd = cmdtest.NewTestCmd(t, tt)
    94  	for i, tc := range []struct {
    95  		base        string
    96  		input       t8nInput
    97  		output      t8nOutput
    98  		expExitCode int
    99  		expOut      string
   100  	}{
   101  		{ // Test exit (3) on bad config
   102  			base: "./testdata/1",
   103  			input: t8nInput{
   104  				"alloc.json", "txs.json", "env.json", "Frontier+1346", "",
   105  			},
   106  			output:      t8nOutput{alloc: true, result: true},
   107  			expExitCode: 3,
   108  		},
   109  		{
   110  			base: "./testdata/1",
   111  			input: t8nInput{
   112  				"alloc.json", "txs.json", "env.json", "Byzantium", "",
   113  			},
   114  			output: t8nOutput{alloc: true, result: true},
   115  			expOut: "exp.json",
   116  		},
   117  		{ // blockhash test
   118  			base: "./testdata/3",
   119  			input: t8nInput{
   120  				"alloc.json", "txs.json", "env.json", "Berlin", "",
   121  			},
   122  			output: t8nOutput{alloc: true, result: true},
   123  			expOut: "exp.json",
   124  		},
   125  		{ // missing blockhash test
   126  			base: "./testdata/4",
   127  			input: t8nInput{
   128  				"alloc.json", "txs.json", "env.json", "Berlin", "",
   129  			},
   130  			output:      t8nOutput{alloc: true, result: true},
   131  			expExitCode: 4,
   132  		},
   133  		{ // Ommer test
   134  			base: "./testdata/5",
   135  			input: t8nInput{
   136  				"alloc.json", "txs.json", "env.json", "Byzantium", "0x80",
   137  			},
   138  			output: t8nOutput{alloc: true, result: true},
   139  			expOut: "exp.json",
   140  		},
   141  		{ // Sign json transactions
   142  			base: "./testdata/13",
   143  			input: t8nInput{
   144  				"alloc.json", "txs.json", "env.json", "London", "",
   145  			},
   146  			output: t8nOutput{body: true},
   147  			expOut: "exp.json",
   148  		},
   149  		{ // Already signed transactions
   150  			base: "./testdata/13",
   151  			input: t8nInput{
   152  				"alloc.json", "signed_txs.rlp", "env.json", "London", "",
   153  			},
   154  			output: t8nOutput{result: true},
   155  			expOut: "exp2.json",
   156  		},
   157  		{ // Difficulty calculation - no uncles
   158  			base: "./testdata/14",
   159  			input: t8nInput{
   160  				"alloc.json", "txs.json", "env.json", "London", "",
   161  			},
   162  			output: t8nOutput{result: true},
   163  			expOut: "exp.json",
   164  		},
   165  		{ // Difficulty calculation - with uncles
   166  			base: "./testdata/14",
   167  			input: t8nInput{
   168  				"alloc.json", "txs.json", "env.uncles.json", "London", "",
   169  			},
   170  			output: t8nOutput{result: true},
   171  			expOut: "exp2.json",
   172  		},
   173  	} {
   174  
   175  		args := []string{"t8n"}
   176  		args = append(args, tc.output.get()...)
   177  		args = append(args, tc.input.get(tc.base)...)
   178  		tt.Run("evm-test", args...)
   179  		tt.Logf("args: %v\n", strings.Join(args, " "))
   180  		// Compare the expected output, if provided
   181  		if tc.expOut != "" {
   182  			want, err := os.ReadFile(fmt.Sprintf("%v/%v", tc.base, tc.expOut))
   183  			if err != nil {
   184  				t.Fatalf("test %d: could not read expected output: %v", i, err)
   185  			}
   186  			have := tt.Output()
   187  			ok, err := cmpJson(have, want)
   188  			switch {
   189  			case err != nil:
   190  				t.Fatalf("test %d, json parsing failed: %v", i, err)
   191  			case !ok:
   192  				t.Fatalf("test %d: output wrong, have \n%v\nwant\n%v\n", i, string(have), string(want))
   193  			}
   194  		}
   195  		tt.WaitExit()
   196  		if have, want := tt.ExitStatus(), tc.expExitCode; have != want {
   197  			t.Fatalf("test %d: wrong exit code, have %d, want %d", i, have, want)
   198  		}
   199  	}
   200  }
   201  
   202  type t9nInput struct {
   203  	inTxs  string
   204  	stFork string
   205  }
   206  
   207  func (args *t9nInput) get(base string) []string {
   208  	var out []string
   209  	if opt := args.inTxs; opt != "" {
   210  		out = append(out, "--input.txs")
   211  		out = append(out, fmt.Sprintf("%v/%v", base, opt))
   212  	}
   213  	if opt := args.stFork; opt != "" {
   214  		out = append(out, "--state.fork", opt)
   215  	}
   216  	return out
   217  }
   218  
   219  func TestT9n(t *testing.T) {
   220  	tt := new(testT8n)
   221  	tt.TestCmd = cmdtest.NewTestCmd(t, tt)
   222  	for i, tc := range []struct {
   223  		base        string
   224  		input       t9nInput
   225  		expExitCode int
   226  		expOut      string
   227  	}{
   228  		{ // London txs on homestead
   229  			base: "./testdata/15",
   230  			input: t9nInput{
   231  				inTxs:  "signed_txs.rlp",
   232  				stFork: "Homestead",
   233  			},
   234  			expOut: "exp.json",
   235  		},
   236  		{ // London txs on London
   237  			base: "./testdata/15",
   238  			input: t9nInput{
   239  				inTxs:  "signed_txs.rlp",
   240  				stFork: "London",
   241  			},
   242  			expOut: "exp2.json",
   243  		},
   244  		{ // An RLP list (a blockheader really)
   245  			base: "./testdata/15",
   246  			input: t9nInput{
   247  				inTxs:  "blockheader.rlp",
   248  				stFork: "London",
   249  			},
   250  			expOut: "exp3.json",
   251  		},
   252  		{ // Transactions with too low gas
   253  			base: "./testdata/16",
   254  			input: t9nInput{
   255  				inTxs:  "signed_txs.rlp",
   256  				stFork: "London",
   257  			},
   258  			expOut: "exp.json",
   259  		},
   260  	} {
   261  
   262  		args := []string{"t9n"}
   263  		args = append(args, tc.input.get(tc.base)...)
   264  
   265  		tt.Run("evm-test", args...)
   266  		tt.Logf("args:\n go run . %v\n", strings.Join(args, " "))
   267  		// Compare the expected output, if provided
   268  		if tc.expOut != "" {
   269  			want, err := os.ReadFile(fmt.Sprintf("%v/%v", tc.base, tc.expOut))
   270  			if err != nil {
   271  				t.Fatalf("test %d: could not read expected output: %v", i, err)
   272  			}
   273  			have := tt.Output()
   274  			ok, err := cmpJson(have, want)
   275  			switch {
   276  			case err != nil:
   277  				t.Logf(string(have))
   278  				t.Fatalf("test %d, json parsing failed: %v", i, err)
   279  			case !ok:
   280  				t.Fatalf("test %d: output wrong, have \n%v\nwant\n%v\n", i, string(have), string(want))
   281  			}
   282  		}
   283  		tt.WaitExit()
   284  		if have, want := tt.ExitStatus(), tc.expExitCode; have != want {
   285  			t.Fatalf("test %d: wrong exit code, have %d, want %d", i, have, want)
   286  		}
   287  	}
   288  }
   289  
   290  // cmpJson compares the JSON in two byte slices.
   291  func cmpJson(a, b []byte) (bool, error) {
   292  	var j, j2 interface{}
   293  	if err := json.Unmarshal(a, &j); err != nil {
   294  		return false, err
   295  	}
   296  	if err := json.Unmarshal(b, &j2); err != nil {
   297  		return false, err
   298  	}
   299  	return reflect.DeepEqual(j2, j), nil
   300  }