Эх сурвалжийг харах

cmd/geth: improve the JS tests

These changes ensure that the JS tests run without networking
and fixes the block chain export and its associated test.
Felix Lange 10 жил өмнө
parent
commit
e1f616fadf
2 өөрчлөгдсөн 71 нэмэгдсэн , 209 устгасан
  1. 3 22
      cmd/geth/admin.go
  2. 68 187
      cmd/geth/js_test.go

+ 3 - 22
cmd/geth/admin.go

@@ -3,7 +3,6 @@ package main
 import (
 	"errors"
 	"fmt"
-	"os"
 	"time"
 
 	"github.com/ethereum/go-ethereum/cmd/utils"
@@ -318,7 +317,7 @@ func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
 		fmt.Printf("Could not create the account: %v", err)
 		return otto.UndefinedValue()
 	}
-	return js.re.ToVal(common.Bytes2Hex(acct.Address))
+	return js.re.ToVal("0x" + common.Bytes2Hex(acct.Address))
 }
 
 func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value {
@@ -334,33 +333,15 @@ func (js *jsre) importChain(call otto.FunctionCall) otto.Value {
 		fmt.Println("err: require file name")
 		return otto.FalseValue()
 	}
-
 	fn, err := call.Argument(0).ToString()
 	if err != nil {
 		fmt.Println(err)
 		return otto.FalseValue()
 	}
-
-	var fh *os.File
-	fh, err = os.OpenFile(fn, os.O_RDONLY, os.ModePerm)
-	if err != nil {
-		fmt.Println(err)
+	if err := utils.ImportChain(js.ethereum.ChainManager(), fn); err != nil {
+		fmt.Println("Import error: ", err)
 		return otto.FalseValue()
 	}
-	defer fh.Close()
-
-	var blocks types.Blocks
-	if err = rlp.Decode(fh, &blocks); err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
-	js.ethereum.ChainManager().Reset()
-	if err = js.ethereum.ChainManager().InsertChain(blocks); err != nil {
-		fmt.Println(err)
-		return otto.FalseValue()
-	}
-
 	return otto.TrueValue()
 }
 

+ 68 - 187
cmd/geth/js_test.go

@@ -3,260 +3,141 @@ package main
 import (
 	"fmt"
 	"io/ioutil"
+	"path/filepath"
 	"os"
 	"path"
 	"testing"
 
-	"github.com/robertkrimen/otto"
-
 	"github.com/ethereum/go-ethereum/accounts"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/eth"
+	"runtime"
+	"regexp"
+	"strconv"
 )
 
 var port = 30300
 
-func testJEthRE(t *testing.T) (repl *jsre, ethereum *eth.Ethereum, err error) {
-	os.RemoveAll("/tmp/eth/")
-	err = os.MkdirAll("/tmp/eth/keys/e273f01c99144c438695e10f24926dc1f9fbf62d/", os.ModePerm)
-	if err != nil {
-		t.Errorf("%v", err)
-		return
-	}
-	err = os.MkdirAll("/tmp/eth/data", os.ModePerm)
+func testJEthRE(t *testing.T) (*jsre, *eth.Ethereum) {
+	tmp, err := ioutil.TempDir("", "geth-test")
 	if err != nil {
-		t.Errorf("%v", err)
-		return
+		t.Fatal(err)
 	}
-	// FIXME: this does not work ATM
-	ks := crypto.NewKeyStorePlain("/tmp/eth/keys")
-	ioutil.WriteFile("/tmp/eth/keys/e273f01c99144c438695e10f24926dc1f9fbf62d/e273f01c99144c438695e10f24926dc1f9fbf62d",
-		[]byte(`{"Id":"RhRXD+fNRKS4jx+7ZfEsNA==","Address":"4nPwHJkUTEOGleEPJJJtwfn79i0=","PrivateKey":"h4ACVpe74uIvi5Cg/2tX/Yrm2xdr3J7QoMbMtNX2CNc="}`), os.ModePerm)
+	defer os.RemoveAll(tmp)
 
-	port++
-	ethereum, err = eth.New(&eth.Config{
-		DataDir:        "/tmp/eth",
+	ks := crypto.NewKeyStorePlain(filepath.Join(tmp, "keys"))
+	ethereum, err := eth.New(&eth.Config{
+		DataDir:        tmp,
 		AccountManager: accounts.NewManager(ks),
-		Port:           fmt.Sprintf("%d", port),
-		MaxPeers:       10,
+		MaxPeers:       0,
 		Name:           "test",
 	})
-
 	if err != nil {
-		t.Errorf("%v", err)
-		return
+		t.Fatal("%v", err)
 	}
 	assetPath := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext")
-	repl = newJSRE(ethereum, assetPath, false)
-	return
+	repl := newJSRE(ethereum, assetPath, false)
+	return repl, ethereum
 }
 
 func TestNodeInfo(t *testing.T) {
-	repl, ethereum, err := testJEthRE(t)
-	if err != nil {
-		t.Errorf("error creating jsre, got %v", err)
-		return
-	}
-	err = ethereum.Start()
-	if err != nil {
-		t.Errorf("error starting ethereum: %v", err)
-		return
+	repl, ethereum := testJEthRE(t)
+	if err := ethereum.Start(); err != nil {
+		t.Fatalf("error starting ethereum: %v", err)
 	}
 	defer ethereum.Stop()
 
-	val, err := repl.re.Run("admin.nodeInfo()")
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-	exp, err := val.Export()
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-	nodeInfo, ok := exp.(*eth.NodeInfo)
-	if !ok {
-		t.Errorf("expected nodeInfo, got %v", err)
-	}
-	exp = "test"
-	got := nodeInfo.Name
-	if exp != got {
-		t.Errorf("expected %v, got %v", exp, got)
-	}
-	exp = 30301
-	port := nodeInfo.DiscPort
-	if exp != port {
-		t.Errorf("expected %v, got %v", exp, port)
-	}
-	exp = 30301
-	port = nodeInfo.TCPPort
-	if exp != port {
-		t.Errorf("expected %v, got %v", exp, port)
-	}
+	want := `{"DiscPort":0,"IP":"0.0.0.0","ListenAddr":"","Name":"test","NodeID":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","NodeUrl":"enode://00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@0.0.0.0:0","TCPPort":0,"Td":"0"}`
+	checkEvalJSON(t, repl, `admin.nodeInfo()`, want)
 }
 
 func TestAccounts(t *testing.T) {
-	repl, ethereum, err := testJEthRE(t)
-	if err != nil {
-		t.Errorf("error creating jsre, got %v", err)
-		return
-	}
-	err = ethereum.Start()
-	if err != nil {
-		t.Errorf("error starting ethereum: %v", err)
-		return
+	repl, ethereum := testJEthRE(t)
+	if err := ethereum.Start(); err != nil {
+		t.Fatalf("error starting ethereum: %v", err)
 	}
 	defer ethereum.Stop()
 
-	val, err := repl.re.Run("eth.coinbase")
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-
-	pp, err := repl.re.PrettyPrint(val)
-	if err != nil {
-		t.Errorf("%v", err)
-	}
-
-	if !val.IsString() {
-		t.Errorf("incorrect type, expected string, got %v: %v", val, pp)
-	}
-	strVal, _ := val.ToString()
-	expected := "0xe273f01c99144c438695e10f24926dc1f9fbf62d"
-	if strVal != expected {
-		t.Errorf("incorrect result, expected %s, got %v", expected, strVal)
-	}
+	checkEvalJSON(t, repl, `eth.accounts`, `[]`)
+	checkEvalJSON(t, repl, `eth.coinbase`, `"0x"`)
 
-	val, err = repl.re.Run(`admin.newAccount("password")`)
+	val, err := repl.re.Run(`admin.newAccount("password")`)
 	if err != nil {
 		t.Errorf("expected no error, got %v", err)
 	}
-	addr, err := val.ToString()
-	if err != nil {
-		t.Errorf("expected string, got %v", err)
-	}
-
-	val, err = repl.re.Run("eth.accounts")
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-	exp, err := val.Export()
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-	interfaceAddr, ok := exp.([]interface{})
-	if !ok {
-		t.Errorf("expected []string, got %T", exp)
-	}
-
-	addrs := make([]string, len(interfaceAddr))
-	for i, addr := range interfaceAddr {
-		var ok bool
-		if addrs[i], ok = addr.(string); !ok {
-			t.Errorf("expected addrs[%d] to be string. Got %T instead", i, addr)
-		}
-	}
-
-	if len(addrs) != 2 || (addr != addrs[0][2:] && addr != addrs[1][2:]) {
-		t.Errorf("expected addrs == [<default>, <new>], got %v (%v)", addrs, addr)
+	addr := val.String()
+	if !regexp.MustCompile(`0x[0-9a-f]{40}`).MatchString(addr) {
+		t.Errorf("address not hex: %q", addr)
 	}
 
+	checkEvalJSON(t, repl, `eth.accounts`, `["` + addr + `"]`)
+	checkEvalJSON(t, repl, `eth.coinbase`, `"` + addr + `"`)
 }
 
 func TestBlockChain(t *testing.T) {
-	repl, ethereum, err := testJEthRE(t)
-	if err != nil {
-		t.Errorf("error creating jsre, got %v", err)
-		return
-	}
-	err = ethereum.Start()
-	if err != nil {
-		t.Errorf("error starting ethereum: %v", err)
-		return
+	repl, ethereum := testJEthRE(t)
+	if err := ethereum.Start(); err != nil {
+		t.Fatalf("error starting ethereum: %v", err)
 	}
 	defer ethereum.Stop()
 
-	// should get current block
-	val0, err := repl.re.Run("admin.debug.dumpBlock()")
+	// get current block dump before export/import.
+	val, err := repl.re.Run("JSON.stringify(admin.debug.dumpBlock())")
 	if err != nil {
 		t.Errorf("expected no error, got %v", err)
 	}
+	beforeExport := val.String()
 
-	fn := "/tmp/eth/data/blockchain.0"
-	_, err = repl.re.Run("admin.export(\"" + fn + "\")")
+	// do the export
+	tmp, err := ioutil.TempDir("", "geth-test-export")
 	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-	if _, err = os.Stat(fn); err != nil {
-		t.Errorf("expected no error on file, got %v", err)
+		t.Fatal(err)
 	}
+	defer os.RemoveAll(tmp)
+	tmpfile := filepath.Join(tmp, "export.chain")
+	tmpfileq := strconv.Quote(tmpfile)
 
-	_, err = repl.re.Run("admin.import(\"" + fn + "\")")
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
+	checkEvalJSON(t, repl, `admin.export(` + tmpfileq + `)`, `true`)
+	if _, err := os.Stat(tmpfile); err != nil {
+		t.Fatal(err)
 	}
 
-	var val1 otto.Value
-
-	// should get current block
-	val1, err = repl.re.Run("admin.debug.dumpBlock()")
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-
-	// FIXME: neither != , nor reflect.DeepEqual works, doing string comparison
-	v0 := fmt.Sprintf("%v", val0)
-	v1 := fmt.Sprintf("%v", val1)
-	if v0 != v1 {
-		t.Errorf("expected same head after export-import, got %v (!=%v)", v1, v0)
-	}
+	// check import, verify that dumpBlock gives the same result.
+	checkEvalJSON(t, repl, `admin.import(` + tmpfileq + `)`, `true`)
+	checkEvalJSON(t, repl, `admin.debug.dumpBlock()`, beforeExport)
 }
 
 func TestMining(t *testing.T) {
-	repl, ethereum, err := testJEthRE(t)
-	if err != nil {
-		t.Errorf("error creating jsre, got %v", err)
-		return
-	}
-	err = ethereum.Start()
-	if err != nil {
-		t.Errorf("error starting ethereum: %v", err)
-		return
+	repl, ethereum := testJEthRE(t)
+	if err := ethereum.Start(); err != nil {
+		t.Fatalf("error starting ethereum: %v", err)
 	}
 	defer ethereum.Stop()
 
-	val, err := repl.re.Run("eth.mining")
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
-	}
-	var mining bool
-	mining, err = val.ToBoolean()
-	if err != nil {
-		t.Errorf("expected boolean, got %v", err)
-	}
-	if mining {
-		t.Errorf("expected false (not mining), got true")
-	}
-
+	checkEvalJSON(t, repl, `eth.mining`, `false`)
 }
 
 func TestRPC(t *testing.T) {
-	repl, ethereum, err := testJEthRE(t)
-	if err != nil {
-		t.Errorf("error creating jsre, got %v", err)
-		return
-	}
-	err = ethereum.Start()
-	if err != nil {
+	repl, ethereum := testJEthRE(t)
+	if err := ethereum.Start(); err != nil {
 		t.Errorf("error starting ethereum: %v", err)
 		return
 	}
 	defer ethereum.Stop()
 
-	val, err := repl.re.Run(`admin.startRPC("127.0.0.1", 5004)`)
-	if err != nil {
-		t.Errorf("expected no error, got %v", err)
+	checkEvalJSON(t, repl, `admin.startRPC("127.0.0.1", 5004)`, `true`)
+}
+
+func checkEvalJSON(t *testing.T, re *jsre, expr, want string) error {
+	val, err := re.re.Run("JSON.stringify("+ expr + ")")
+	if err == nil && val.String() != want {
+		err = fmt.Errorf("Output mismatch for `%s`:\ngot:  %s\nwant: %s", expr, val.String(), want)
 	}
-	success, _ := val.ToBoolean()
-	if !success {
-		t.Errorf("expected true (started), got false")
+	if err != nil {
+		_, file, line, _ := runtime.Caller(1)
+		file = path.Base(file)
+		fmt.Printf("\t%s:%d: %v\n", file, line, err)
+		t.Fail()
 	}
+	return err
 }