1 package integration
2 3 import (
4 "bytes"
5 "fmt"
6 "os"
7 "runtime/debug"
8 "testing"
9 10 "github.com/p9c/p9/cmd/node/integration/rpctest"
11 "github.com/p9c/p9/pkg/chaincfg"
12 )
13 14 func testGetBestBlock(r *rpctest.Harness, t *testing.T) {
15 _, prevbestHeight, e := r.Node.GetBestBlock()
16 if e != nil {
17 t.Fatalf("Call to `getbestblock` failed: %v", e)
18 }
19 // Create a new block connecting to the current tip.
20 generatedBlockHashes, e := r.Node.Generate(1)
21 if e != nil {
22 t.Fatalf("Unable to generate block: %v", e)
23 }
24 bestHash, bestHeight, e := r.Node.GetBestBlock()
25 if e != nil {
26 t.Fatalf("Call to `getbestblock` failed: %v", e)
27 }
28 // Hash should be the same as the newly submitted block.
29 if !bytes.Equal(bestHash[:], generatedBlockHashes[0][:]) {
30 t.Fatalf(
31 "Block hashes do not match. Returned hash %v, wanted "+
32 "hash %v", bestHash, generatedBlockHashes[0][:],
33 )
34 }
35 // Block height should now reflect newest height.
36 if bestHeight != prevbestHeight+1 {
37 t.Fatalf(
38 "Block heights do not match. Got %v, wanted %v",
39 bestHeight, prevbestHeight+1,
40 )
41 }
42 }
43 44 func testGetBlockCount(r *rpctest.Harness, t *testing.T) {
45 // Save the current count.
46 currentCount, e := r.Node.GetBlockCount()
47 if e != nil {
48 t.Fatalf("Unable to get block count: %v", e)
49 }
50 if _, e = r.Node.Generate(1); E.Chk(e) {
51 t.Fatalf("Unable to generate block: %v", e)
52 }
53 // Count should have increased by one.
54 newCount, e := r.Node.GetBlockCount()
55 if e != nil {
56 t.Fatalf("Unable to get block count: %v", e)
57 }
58 if newCount != currentCount+1 {
59 t.Fatalf(
60 "Block count incorrect. Got %v should be %v",
61 newCount, currentCount+1,
62 )
63 }
64 }
65 66 func testGetBlockHash(r *rpctest.Harness, t *testing.T) {
67 // Create a new block connecting to the current tip.
68 generatedBlockHashes, e := r.Node.Generate(1)
69 if e != nil {
70 t.Fatalf("Unable to generate block: %v", e)
71 }
72 info, e := r.Node.GetInfo()
73 if e != nil {
74 t.Fatalf("call to getinfo cailed: %v", e)
75 }
76 blockHash, e := r.Node.GetBlockHash(int64(info.Blocks))
77 if e != nil {
78 t.Fatalf("Call to `getblockhash` failed: %v", e)
79 }
80 // Block hashes should match newly created block.
81 if !bytes.Equal(generatedBlockHashes[0][:], blockHash[:]) {
82 83 t.Fatalf(
84 "Block hashes do not match. Returned hash %v, wanted "+
85 "hash %v", blockHash, generatedBlockHashes[0][:],
86 )
87 }
88 }
89 90 var rpcTestCases = []rpctest.HarnessTestCase{
91 testGetBestBlock,
92 testGetBlockCount,
93 testGetBlockHash,
94 }
95 var primaryHarness *rpctest.Harness
96 97 func TestMain(m *testing.M) {
98 var e error
99 // In order to properly test scenarios on as if we were on mainnet, ensure that non-standard transactions aren't
100 // accepted into the mempool or relayed.
101 podCfg := []string{"--rejectnonstd"}
102 primaryHarness, e = rpctest.New(&chaincfg.SimNetParams, nil, podCfg)
103 if e != nil {
104 fmt.Println("unable to create primary harness: ", e)
105 os.Exit(1)
106 }
107 // Initialize the primary mining node with a chain of length 125, providing 25 mature coinbases to allow spending
108 // from for testing purposes.
109 if e := primaryHarness.SetUp(true, 25); E.Chk(e) {
110 fmt.Println("unable to setup test chain: ", e)
111 // Even though the harness was not fully setup, it still needs to be torn down to ensure all resources such as
112 // temp directories are cleaned up. The error is intentionally ignored since this is already an error path and
113 // nothing else could be done about it anyways.
114 _ = primaryHarness.TearDown()
115 os.Exit(1)
116 }
117 exitCode := m.Run()
118 // Clean up any active harnesses that are still currently running. This includes removing all temporary directories,
119 // and shutting down any created processes.
120 if e := rpctest.TearDownAll(); E.Chk(e) {
121 fmt.Println("unable to tear down all harnesses: ", e)
122 os.Exit(1)
123 }
124 os.Exit(exitCode)
125 }
126 127 func TestRpcServer(t *testing.T) {
128 var currentTestNum int
129 defer func() {
130 // If one of the integration tests caused a panic within the main goroutine, then tear down all the harnesses in
131 // order to avoid any leaked pod processes.
132 if r := recover(); r != nil {
133 fmt.Println("recovering from test panic: ", r)
134 if e := rpctest.TearDownAll(); E.Chk(e) {
135 fmt.Println("unable to tear down all harnesses: ", e)
136 }
137 t.Fatalf("test #%v panicked: %s", currentTestNum, debug.Stack())
138 }
139 }()
140 for _, testCase := range rpcTestCases {
141 testCase(primaryHarness, t)
142 currentTestNum++
143 }
144 }
145