node_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package node
  17. import (
  18. "errors"
  19. "io/ioutil"
  20. "os"
  21. "reflect"
  22. "testing"
  23. "time"
  24. "github.com/ethereum/go-ethereum/crypto"
  25. "github.com/ethereum/go-ethereum/p2p"
  26. "github.com/ethereum/go-ethereum/rpc"
  27. )
  28. var (
  29. testNodeKey, _ = crypto.GenerateKey()
  30. )
  31. func testNodeConfig() *Config {
  32. return &Config{
  33. Name: "test node",
  34. P2P: p2p.Config{PrivateKey: testNodeKey},
  35. }
  36. }
  37. // Tests that an empty protocol stack can be started, restarted and stopped.
  38. func TestNodeLifeCycle(t *testing.T) {
  39. stack, err := New(testNodeConfig())
  40. if err != nil {
  41. t.Fatalf("failed to create protocol stack: %v", err)
  42. }
  43. // Ensure that a stopped node can be stopped again
  44. for i := 0; i < 3; i++ {
  45. if err := stack.Stop(); err != ErrNodeStopped {
  46. t.Fatalf("iter %d: stop failure mismatch: have %v, want %v", i, err, ErrNodeStopped)
  47. }
  48. }
  49. // Ensure that a node can be successfully started, but only once
  50. if err := stack.Start(); err != nil {
  51. t.Fatalf("failed to start node: %v", err)
  52. }
  53. if err := stack.Start(); err != ErrNodeRunning {
  54. t.Fatalf("start failure mismatch: have %v, want %v ", err, ErrNodeRunning)
  55. }
  56. // Ensure that a node can be restarted arbitrarily many times
  57. for i := 0; i < 3; i++ {
  58. if err := stack.Restart(); err != nil {
  59. t.Fatalf("iter %d: failed to restart node: %v", i, err)
  60. }
  61. }
  62. // Ensure that a node can be stopped, but only once
  63. if err := stack.Stop(); err != nil {
  64. t.Fatalf("failed to stop node: %v", err)
  65. }
  66. if err := stack.Stop(); err != ErrNodeStopped {
  67. t.Fatalf("stop failure mismatch: have %v, want %v ", err, ErrNodeStopped)
  68. }
  69. }
  70. // Tests that if the data dir is already in use, an appropriate error is returned.
  71. func TestNodeUsedDataDir(t *testing.T) {
  72. // Create a temporary folder to use as the data directory
  73. dir, err := ioutil.TempDir("", "")
  74. if err != nil {
  75. t.Fatalf("failed to create temporary data directory: %v", err)
  76. }
  77. defer os.RemoveAll(dir)
  78. // Create a new node based on the data directory
  79. original, err := New(&Config{DataDir: dir})
  80. if err != nil {
  81. t.Fatalf("failed to create original protocol stack: %v", err)
  82. }
  83. if err := original.Start(); err != nil {
  84. t.Fatalf("failed to start original protocol stack: %v", err)
  85. }
  86. defer original.Stop()
  87. // Create a second node based on the same data directory and ensure failure
  88. duplicate, err := New(&Config{DataDir: dir})
  89. if err != nil {
  90. t.Fatalf("failed to create duplicate protocol stack: %v", err)
  91. }
  92. if err := duplicate.Start(); err != ErrDatadirUsed {
  93. t.Fatalf("duplicate datadir failure mismatch: have %v, want %v", err, ErrDatadirUsed)
  94. }
  95. }
  96. // Tests whether services can be registered and duplicates caught.
  97. func TestServiceRegistry(t *testing.T) {
  98. stack, err := New(testNodeConfig())
  99. if err != nil {
  100. t.Fatalf("failed to create protocol stack: %v", err)
  101. }
  102. // Register a batch of unique services and ensure they start successfully
  103. services := []ServiceConstructor{NewNoopServiceA, NewNoopServiceB, NewNoopServiceC}
  104. for i, constructor := range services {
  105. if err := stack.Register(constructor); err != nil {
  106. t.Fatalf("service #%d: registration failed: %v", i, err)
  107. }
  108. }
  109. if err := stack.Start(); err != nil {
  110. t.Fatalf("failed to start original service stack: %v", err)
  111. }
  112. if err := stack.Stop(); err != nil {
  113. t.Fatalf("failed to stop original service stack: %v", err)
  114. }
  115. // Duplicate one of the services and retry starting the node
  116. if err := stack.Register(NewNoopServiceB); err != nil {
  117. t.Fatalf("duplicate registration failed: %v", err)
  118. }
  119. if err := stack.Start(); err == nil {
  120. t.Fatalf("duplicate service started")
  121. } else {
  122. if _, ok := err.(*DuplicateServiceError); !ok {
  123. t.Fatalf("duplicate error mismatch: have %v, want %v", err, DuplicateServiceError{})
  124. }
  125. }
  126. }
  127. // Tests that registered services get started and stopped correctly.
  128. func TestServiceLifeCycle(t *testing.T) {
  129. stack, err := New(testNodeConfig())
  130. if err != nil {
  131. t.Fatalf("failed to create protocol stack: %v", err)
  132. }
  133. // Register a batch of life-cycle instrumented services
  134. services := map[string]InstrumentingWrapper{
  135. "A": InstrumentedServiceMakerA,
  136. "B": InstrumentedServiceMakerB,
  137. "C": InstrumentedServiceMakerC,
  138. }
  139. started := make(map[string]bool)
  140. stopped := make(map[string]bool)
  141. for id, maker := range services {
  142. id := id // Closure for the constructor
  143. constructor := func(*ServiceContext) (Service, error) {
  144. return &InstrumentedService{
  145. startHook: func(*p2p.Server) { started[id] = true },
  146. stopHook: func() { stopped[id] = true },
  147. }, nil
  148. }
  149. if err := stack.Register(maker(constructor)); err != nil {
  150. t.Fatalf("service %s: registration failed: %v", id, err)
  151. }
  152. }
  153. // Start the node and check that all services are running
  154. if err := stack.Start(); err != nil {
  155. t.Fatalf("failed to start protocol stack: %v", err)
  156. }
  157. for id := range services {
  158. if !started[id] {
  159. t.Fatalf("service %s: freshly started service not running", id)
  160. }
  161. if stopped[id] {
  162. t.Fatalf("service %s: freshly started service already stopped", id)
  163. }
  164. }
  165. // Stop the node and check that all services have been stopped
  166. if err := stack.Stop(); err != nil {
  167. t.Fatalf("failed to stop protocol stack: %v", err)
  168. }
  169. for id := range services {
  170. if !stopped[id] {
  171. t.Fatalf("service %s: freshly terminated service still running", id)
  172. }
  173. }
  174. }
  175. // Tests that services are restarted cleanly as new instances.
  176. func TestServiceRestarts(t *testing.T) {
  177. stack, err := New(testNodeConfig())
  178. if err != nil {
  179. t.Fatalf("failed to create protocol stack: %v", err)
  180. }
  181. // Define a service that does not support restarts
  182. var (
  183. running bool
  184. started int
  185. )
  186. constructor := func(*ServiceContext) (Service, error) {
  187. running = false
  188. return &InstrumentedService{
  189. startHook: func(*p2p.Server) {
  190. if running {
  191. panic("already running")
  192. }
  193. running = true
  194. started++
  195. },
  196. }, nil
  197. }
  198. // Register the service and start the protocol stack
  199. if err := stack.Register(constructor); err != nil {
  200. t.Fatalf("failed to register the service: %v", err)
  201. }
  202. if err := stack.Start(); err != nil {
  203. t.Fatalf("failed to start protocol stack: %v", err)
  204. }
  205. defer stack.Stop()
  206. if !running || started != 1 {
  207. t.Fatalf("running/started mismatch: have %v/%d, want true/1", running, started)
  208. }
  209. // Restart the stack a few times and check successful service restarts
  210. for i := 0; i < 3; i++ {
  211. if err := stack.Restart(); err != nil {
  212. t.Fatalf("iter %d: failed to restart stack: %v", i, err)
  213. }
  214. }
  215. if !running || started != 4 {
  216. t.Fatalf("running/started mismatch: have %v/%d, want true/4", running, started)
  217. }
  218. }
  219. // Tests that if a service fails to initialize itself, none of the other services
  220. // will be allowed to even start.
  221. func TestServiceConstructionAbortion(t *testing.T) {
  222. stack, err := New(testNodeConfig())
  223. if err != nil {
  224. t.Fatalf("failed to create protocol stack: %v", err)
  225. }
  226. // Define a batch of good services
  227. services := map[string]InstrumentingWrapper{
  228. "A": InstrumentedServiceMakerA,
  229. "B": InstrumentedServiceMakerB,
  230. "C": InstrumentedServiceMakerC,
  231. }
  232. started := make(map[string]bool)
  233. for id, maker := range services {
  234. id := id // Closure for the constructor
  235. constructor := func(*ServiceContext) (Service, error) {
  236. return &InstrumentedService{
  237. startHook: func(*p2p.Server) { started[id] = true },
  238. }, nil
  239. }
  240. if err := stack.Register(maker(constructor)); err != nil {
  241. t.Fatalf("service %s: registration failed: %v", id, err)
  242. }
  243. }
  244. // Register a service that fails to construct itself
  245. failure := errors.New("fail")
  246. failer := func(*ServiceContext) (Service, error) {
  247. return nil, failure
  248. }
  249. if err := stack.Register(failer); err != nil {
  250. t.Fatalf("failer registration failed: %v", err)
  251. }
  252. // Start the protocol stack and ensure none of the services get started
  253. for i := 0; i < 100; i++ {
  254. if err := stack.Start(); err != failure {
  255. t.Fatalf("iter %d: stack startup failure mismatch: have %v, want %v", i, err, failure)
  256. }
  257. for id := range services {
  258. if started[id] {
  259. t.Fatalf("service %s: started should not have", id)
  260. }
  261. delete(started, id)
  262. }
  263. }
  264. }
  265. // Tests that if a service fails to start, all others started before it will be
  266. // shut down.
  267. func TestServiceStartupAbortion(t *testing.T) {
  268. stack, err := New(testNodeConfig())
  269. if err != nil {
  270. t.Fatalf("failed to create protocol stack: %v", err)
  271. }
  272. // Register a batch of good services
  273. services := map[string]InstrumentingWrapper{
  274. "A": InstrumentedServiceMakerA,
  275. "B": InstrumentedServiceMakerB,
  276. "C": InstrumentedServiceMakerC,
  277. }
  278. started := make(map[string]bool)
  279. stopped := make(map[string]bool)
  280. for id, maker := range services {
  281. id := id // Closure for the constructor
  282. constructor := func(*ServiceContext) (Service, error) {
  283. return &InstrumentedService{
  284. startHook: func(*p2p.Server) { started[id] = true },
  285. stopHook: func() { stopped[id] = true },
  286. }, nil
  287. }
  288. if err := stack.Register(maker(constructor)); err != nil {
  289. t.Fatalf("service %s: registration failed: %v", id, err)
  290. }
  291. }
  292. // Register a service that fails to start
  293. failure := errors.New("fail")
  294. failer := func(*ServiceContext) (Service, error) {
  295. return &InstrumentedService{
  296. start: failure,
  297. }, nil
  298. }
  299. if err := stack.Register(failer); err != nil {
  300. t.Fatalf("failer registration failed: %v", err)
  301. }
  302. // Start the protocol stack and ensure all started services stop
  303. for i := 0; i < 100; i++ {
  304. if err := stack.Start(); err != failure {
  305. t.Fatalf("iter %d: stack startup failure mismatch: have %v, want %v", i, err, failure)
  306. }
  307. for id := range services {
  308. if started[id] && !stopped[id] {
  309. t.Fatalf("service %s: started but not stopped", id)
  310. }
  311. delete(started, id)
  312. delete(stopped, id)
  313. }
  314. }
  315. }
  316. // Tests that even if a registered service fails to shut down cleanly, it does
  317. // not influece the rest of the shutdown invocations.
  318. func TestServiceTerminationGuarantee(t *testing.T) {
  319. stack, err := New(testNodeConfig())
  320. if err != nil {
  321. t.Fatalf("failed to create protocol stack: %v", err)
  322. }
  323. // Register a batch of good services
  324. services := map[string]InstrumentingWrapper{
  325. "A": InstrumentedServiceMakerA,
  326. "B": InstrumentedServiceMakerB,
  327. "C": InstrumentedServiceMakerC,
  328. }
  329. started := make(map[string]bool)
  330. stopped := make(map[string]bool)
  331. for id, maker := range services {
  332. id := id // Closure for the constructor
  333. constructor := func(*ServiceContext) (Service, error) {
  334. return &InstrumentedService{
  335. startHook: func(*p2p.Server) { started[id] = true },
  336. stopHook: func() { stopped[id] = true },
  337. }, nil
  338. }
  339. if err := stack.Register(maker(constructor)); err != nil {
  340. t.Fatalf("service %s: registration failed: %v", id, err)
  341. }
  342. }
  343. // Register a service that fails to shot down cleanly
  344. failure := errors.New("fail")
  345. failer := func(*ServiceContext) (Service, error) {
  346. return &InstrumentedService{
  347. stop: failure,
  348. }, nil
  349. }
  350. if err := stack.Register(failer); err != nil {
  351. t.Fatalf("failer registration failed: %v", err)
  352. }
  353. // Start the protocol stack, and ensure that a failing shut down terminates all
  354. for i := 0; i < 100; i++ {
  355. // Start the stack and make sure all is online
  356. if err := stack.Start(); err != nil {
  357. t.Fatalf("iter %d: failed to start protocol stack: %v", i, err)
  358. }
  359. for id := range services {
  360. if !started[id] {
  361. t.Fatalf("iter %d, service %s: service not running", i, id)
  362. }
  363. if stopped[id] {
  364. t.Fatalf("iter %d, service %s: service already stopped", i, id)
  365. }
  366. }
  367. // Stop the stack, verify failure and check all terminations
  368. err := stack.Stop()
  369. if err, ok := err.(*StopError); !ok {
  370. t.Fatalf("iter %d: termination failure mismatch: have %v, want StopError", i, err)
  371. } else {
  372. failer := reflect.TypeOf(&InstrumentedService{})
  373. if err.Services[failer] != failure {
  374. t.Fatalf("iter %d: failer termination failure mismatch: have %v, want %v", i, err.Services[failer], failure)
  375. }
  376. if len(err.Services) != 1 {
  377. t.Fatalf("iter %d: failure count mismatch: have %d, want %d", i, len(err.Services), 1)
  378. }
  379. }
  380. for id := range services {
  381. if !stopped[id] {
  382. t.Fatalf("iter %d, service %s: service not terminated", i, id)
  383. }
  384. delete(started, id)
  385. delete(stopped, id)
  386. }
  387. }
  388. }
  389. // TestServiceRetrieval tests that individual services can be retrieved.
  390. func TestServiceRetrieval(t *testing.T) {
  391. // Create a simple stack and register two service types
  392. stack, err := New(testNodeConfig())
  393. if err != nil {
  394. t.Fatalf("failed to create protocol stack: %v", err)
  395. }
  396. if err := stack.Register(NewNoopService); err != nil {
  397. t.Fatalf("noop service registration failed: %v", err)
  398. }
  399. if err := stack.Register(NewInstrumentedService); err != nil {
  400. t.Fatalf("instrumented service registration failed: %v", err)
  401. }
  402. // Make sure none of the services can be retrieved until started
  403. var noopServ *NoopService
  404. if err := stack.Service(&noopServ); err != ErrNodeStopped {
  405. t.Fatalf("noop service retrieval mismatch: have %v, want %v", err, ErrNodeStopped)
  406. }
  407. var instServ *InstrumentedService
  408. if err := stack.Service(&instServ); err != ErrNodeStopped {
  409. t.Fatalf("instrumented service retrieval mismatch: have %v, want %v", err, ErrNodeStopped)
  410. }
  411. // Start the stack and ensure everything is retrievable now
  412. if err := stack.Start(); err != nil {
  413. t.Fatalf("failed to start stack: %v", err)
  414. }
  415. defer stack.Stop()
  416. if err := stack.Service(&noopServ); err != nil {
  417. t.Fatalf("noop service retrieval mismatch: have %v, want %v", err, nil)
  418. }
  419. if err := stack.Service(&instServ); err != nil {
  420. t.Fatalf("instrumented service retrieval mismatch: have %v, want %v", err, nil)
  421. }
  422. }
  423. // Tests that all protocols defined by individual services get launched.
  424. func TestProtocolGather(t *testing.T) {
  425. stack, err := New(testNodeConfig())
  426. if err != nil {
  427. t.Fatalf("failed to create protocol stack: %v", err)
  428. }
  429. // Register a batch of services with some configured number of protocols
  430. services := map[string]struct {
  431. Count int
  432. Maker InstrumentingWrapper
  433. }{
  434. "Zero Protocols": {0, InstrumentedServiceMakerA},
  435. "Single Protocol": {1, InstrumentedServiceMakerB},
  436. "Many Protocols": {25, InstrumentedServiceMakerC},
  437. }
  438. for id, config := range services {
  439. protocols := make([]p2p.Protocol, config.Count)
  440. for i := 0; i < len(protocols); i++ {
  441. protocols[i].Name = id
  442. protocols[i].Version = uint(i)
  443. }
  444. constructor := func(*ServiceContext) (Service, error) {
  445. return &InstrumentedService{
  446. protocols: protocols,
  447. }, nil
  448. }
  449. if err := stack.Register(config.Maker(constructor)); err != nil {
  450. t.Fatalf("service %s: registration failed: %v", id, err)
  451. }
  452. }
  453. // Start the services and ensure all protocols start successfully
  454. if err := stack.Start(); err != nil {
  455. t.Fatalf("failed to start protocol stack: %v", err)
  456. }
  457. defer stack.Stop()
  458. protocols := stack.Server().Protocols
  459. if len(protocols) != 26 {
  460. t.Fatalf("mismatching number of protocols launched: have %d, want %d", len(protocols), 26)
  461. }
  462. for id, config := range services {
  463. for ver := 0; ver < config.Count; ver++ {
  464. launched := false
  465. for i := 0; i < len(protocols); i++ {
  466. if protocols[i].Name == id && protocols[i].Version == uint(ver) {
  467. launched = true
  468. break
  469. }
  470. }
  471. if !launched {
  472. t.Errorf("configured protocol not launched: %s v%d", id, ver)
  473. }
  474. }
  475. }
  476. }
  477. // Tests that all APIs defined by individual services get exposed.
  478. func TestAPIGather(t *testing.T) {
  479. stack, err := New(testNodeConfig())
  480. if err != nil {
  481. t.Fatalf("failed to create protocol stack: %v", err)
  482. }
  483. // Register a batch of services with some configured APIs
  484. calls := make(chan string, 1)
  485. makeAPI := func(result string) *OneMethodAPI {
  486. return &OneMethodAPI{fun: func() { calls <- result }}
  487. }
  488. services := map[string]struct {
  489. APIs []rpc.API
  490. Maker InstrumentingWrapper
  491. }{
  492. "Zero APIs": {
  493. []rpc.API{}, InstrumentedServiceMakerA},
  494. "Single API": {
  495. []rpc.API{
  496. {Namespace: "single", Version: "1", Service: makeAPI("single.v1"), Public: true},
  497. }, InstrumentedServiceMakerB},
  498. "Many APIs": {
  499. []rpc.API{
  500. {Namespace: "multi", Version: "1", Service: makeAPI("multi.v1"), Public: true},
  501. {Namespace: "multi.v2", Version: "2", Service: makeAPI("multi.v2"), Public: true},
  502. {Namespace: "multi.v2.nested", Version: "2", Service: makeAPI("multi.v2.nested"), Public: true},
  503. }, InstrumentedServiceMakerC},
  504. }
  505. for id, config := range services {
  506. config := config
  507. constructor := func(*ServiceContext) (Service, error) {
  508. return &InstrumentedService{apis: config.APIs}, nil
  509. }
  510. if err := stack.Register(config.Maker(constructor)); err != nil {
  511. t.Fatalf("service %s: registration failed: %v", id, err)
  512. }
  513. }
  514. // Start the services and ensure all API start successfully
  515. if err := stack.Start(); err != nil {
  516. t.Fatalf("failed to start protocol stack: %v", err)
  517. }
  518. defer stack.Stop()
  519. // Connect to the RPC server and verify the various registered endpoints
  520. client, err := stack.Attach()
  521. if err != nil {
  522. t.Fatalf("failed to connect to the inproc API server: %v", err)
  523. }
  524. defer client.Close()
  525. tests := []struct {
  526. Method string
  527. Result string
  528. }{
  529. {"single_theOneMethod", "single.v1"},
  530. {"multi_theOneMethod", "multi.v1"},
  531. {"multi.v2_theOneMethod", "multi.v2"},
  532. {"multi.v2.nested_theOneMethod", "multi.v2.nested"},
  533. }
  534. for i, test := range tests {
  535. if err := client.Call(nil, test.Method); err != nil {
  536. t.Errorf("test %d: API request failed: %v", i, err)
  537. }
  538. select {
  539. case result := <-calls:
  540. if result != test.Result {
  541. t.Errorf("test %d: result mismatch: have %s, want %s", i, result, test.Result)
  542. }
  543. case <-time.After(time.Second):
  544. t.Fatalf("test %d: rpc execution timeout", i)
  545. }
  546. }
  547. }