node_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*
  2. * Rufs - Remote Union File System
  3. *
  4. * Copyright 2017 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package node
  11. import (
  12. "crypto/tls"
  13. "flag"
  14. "fmt"
  15. "io"
  16. "io/ioutil"
  17. "log"
  18. "os"
  19. "path"
  20. "testing"
  21. "time"
  22. "devt.de/krotik/common/cryptutil"
  23. "devt.de/krotik/common/fileutil"
  24. )
  25. var consoleOutput = false
  26. var liveOutput = false
  27. type LogWriter struct {
  28. w io.Writer
  29. }
  30. func (l LogWriter) Write(p []byte) (n int, err error) {
  31. if liveOutput {
  32. fmt.Print(string(p))
  33. }
  34. return l.w.Write(p)
  35. }
  36. const certdir = "certs"
  37. func TestMain(m *testing.M) {
  38. flag.Parse()
  39. // Create output capture file
  40. outFile, err := os.Create("out.txt")
  41. if err != nil {
  42. panic(err)
  43. }
  44. if res, _ := fileutil.PathExists(certdir); res {
  45. os.RemoveAll(certdir)
  46. }
  47. err = os.Mkdir(certdir, 0770)
  48. if err != nil {
  49. fmt.Print("Could not create test directory:", err.Error())
  50. os.Exit(1)
  51. }
  52. // Ensure logging is directed to the file
  53. log.SetOutput(LogWriter{outFile})
  54. // Run the tests
  55. res := m.Run()
  56. log.SetOutput(os.Stderr)
  57. // Collected output
  58. outFile.Sync()
  59. outFile.Close()
  60. stdout, err := ioutil.ReadFile("out.txt")
  61. if err != nil {
  62. panic(err)
  63. }
  64. // Handle collected output
  65. if consoleOutput {
  66. fmt.Println(string(stdout))
  67. }
  68. os.RemoveAll("out.txt")
  69. err = os.RemoveAll(certdir)
  70. if err != nil {
  71. fmt.Print("Could not remove test directory:", err.Error())
  72. }
  73. os.Exit(res)
  74. }
  75. /*
  76. createNodeNetwork creates a network of n nodes.
  77. */
  78. func createNodeNetwork(n int) []*RufsNode {
  79. var mms []*RufsNode
  80. for i := 0; i < n; i++ {
  81. host := fmt.Sprintf("localhost:%v", 9020+i)
  82. // Generate a certificate and private key
  83. certFile := fmt.Sprintf("cert-%v.pem", i)
  84. keyFile := fmt.Sprintf("key-%v.pem", i)
  85. err := cryptutil.GenCert(certdir, certFile, keyFile, host, "", 365*24*time.Hour, true, 2048, "")
  86. if err != nil {
  87. panic(err)
  88. }
  89. cert, err := tls.LoadX509KeyPair(path.Join(certdir, certFile), path.Join(certdir, keyFile))
  90. if err != nil {
  91. panic(err)
  92. }
  93. mms = append(mms, NewNode(host,
  94. fmt.Sprintf("TestNode-%v", i), "test123", &cert, nil))
  95. }
  96. return mms
  97. }
  98. func TestReconnect(t *testing.T) {
  99. // Debug logging
  100. // liveOutput = true
  101. // LogDebug = LogInfo
  102. // defer func() { liveOutput = false }()
  103. // Send a simple ping
  104. nnet2 := createNodeNetwork(2)
  105. nnet2[0].Start(nnet2[0].Client.cert) // Start the server with the client certificate
  106. nnet2[1].Start(nnet2[1].Client.cert) // Start the server with the client certificate
  107. defer nnet2[0].Shutdown()
  108. defer nnet2[1].Shutdown()
  109. var ctrlReceived map[string]string
  110. var dataReceived string
  111. nnet2[1].DataHandler = func(ctrl map[string]string, data []byte) ([]byte, error) {
  112. dataReceived = string(data)
  113. ctrlReceived = ctrl
  114. return []byte("testack"), nil
  115. }
  116. // Register peer 1 on peer 0
  117. nnet2[0].Client.RegisterPeer(nnet2[1].name, nnet2[1].Client.rpc, nnet2[1].SSLFingerprint())
  118. // Send data successful
  119. datares, err := nnet2[0].Client.SendData(nnet2[1].name, map[string]string{
  120. "foo": "bar",
  121. }, []byte("testmsg"))
  122. if dataReceived != "testmsg" || fmt.Sprint(ctrlReceived) != "map[foo:bar]" ||
  123. string(datares) != "testack" || err != nil {
  124. t.Error("Unexpected result: ", ctrlReceived, dataReceived, datares, err)
  125. return
  126. }
  127. ctrlReceived = nil
  128. dataReceived = ""
  129. // Shutdown peer 1
  130. nnet2[1].Shutdown()
  131. datares, err = nnet2[0].Client.SendData(nnet2[1].name, map[string]string{
  132. "foo": "bar",
  133. }, []byte("testmsg"))
  134. if err == nil || err.Error() != "RufsError: Remote error (Unknown target node)" {
  135. t.Error("Unexpected result: ", ctrlReceived, dataReceived, datares, err)
  136. return
  137. }
  138. ctrlReceived = nil
  139. dataReceived = ""
  140. // Start again
  141. nnet2[1].Start(nnet2[1].Client.cert)
  142. datares, err = nnet2[0].Client.SendData(nnet2[1].name, map[string]string{
  143. "foo": "bar",
  144. }, []byte("testmsg"))
  145. if dataReceived != "testmsg" || fmt.Sprint(ctrlReceived) != "map[foo:bar]" ||
  146. string(datares) != "testack" || err != nil {
  147. t.Error("Unexpected result: ", ctrlReceived, dataReceived, datares, err)
  148. return
  149. }
  150. }
  151. func Test2NodeNetwork(t *testing.T) {
  152. // Debug logging
  153. // liveOutput = true
  154. // LogDebug = LogInfo
  155. // defer func() { liveOutput = false }()
  156. // Send a simple ping
  157. nnet2 := createNodeNetwork(2)
  158. nnet2[0].Start(nnet2[0].Client.cert) // Start the server with the client certificate
  159. nnet2[1].Start(nnet2[1].Client.cert) // Start the server with the client certificate
  160. defer nnet2[0].Shutdown()
  161. defer nnet2[1].Shutdown()
  162. // Check we are using the same certificates
  163. if nnet2[0].Client.SSLFingerprint() != nnet2[0].SSLFingerprint() {
  164. t.Errorf("Unexpected result:\n#%v\n#%v", nnet2[0].Client.SSLFingerprint(), nnet2[0].SSLFingerprint())
  165. return
  166. }
  167. res, rfp, err := nnet2[0].Client.SendPing(nnet2[1].name, nnet2[1].Client.rpc)
  168. if fmt.Sprint(res) != "[Pong]" || rfp != nnet2[1].SSLFingerprint() || err != nil {
  169. t.Error("Unexpected result:", res, err)
  170. return
  171. }
  172. if res := nnet2[1].Name(); res != "TestNode-1" {
  173. t.Error("Unexpected result:", res)
  174. return
  175. }
  176. // Send a data request
  177. var ctrlReceived map[string]string
  178. var dataReceived string
  179. var datares []byte
  180. nnet2[1].DataHandler = func(ctrl map[string]string, data []byte) ([]byte, error) {
  181. dataReceived = string(data)
  182. ctrlReceived = ctrl
  183. return []byte("testack"), nil
  184. }
  185. _, err = nnet2[0].Client.SendData(nnet2[1].name, map[string]string{
  186. "foo": "bar",
  187. }, []byte("testmsg"))
  188. if err == nil || err.Error() != "Unknown peer: TestNode-1" {
  189. t.Error("Unexpected result: ", err)
  190. return
  191. }
  192. // Register the peer
  193. if err := nnet2[0].Client.RegisterPeer(nnet2[1].name, "", ""); err.Error() != "RPC interface must not be empty" {
  194. t.Error("Unexpected result: ", err)
  195. return
  196. }
  197. nnet2[0].Client.RegisterPeer(nnet2[1].name, nnet2[1].Client.rpc, nnet2[1].SSLFingerprint())
  198. if err := nnet2[0].Client.RegisterPeer(nnet2[1].name, nnet2[1].Client.rpc, ""); err.Error() != "Peer already registered: TestNode-1" {
  199. t.Error("Unexpected result: ", err)
  200. return
  201. }
  202. peers, peerFps := nnet2[0].Client.Peers()
  203. if res := fmt.Sprint(peers); res != "[TestNode-1]" && peerFps[0] == nnet2[1].SSLFingerprint() {
  204. t.Error("Unexpected result: ", res)
  205. return
  206. }
  207. // Send the data request
  208. datares, err = nnet2[0].Client.SendData(nnet2[1].name, map[string]string{
  209. "foo": "bar",
  210. }, []byte("testmsg"))
  211. if dataReceived != "testmsg" || fmt.Sprint(ctrlReceived) != "map[foo:bar]" ||
  212. string(datares) != "testack" || err != nil {
  213. t.Error("Unexpected result: ", ctrlReceived, dataReceived, datares, err)
  214. return
  215. }
  216. // Close connection and send data again (connection should be automatically reconnected)
  217. nnet2[0].Client.conns[nnet2[1].name].Close()
  218. datares, err = nnet2[0].Client.SendData(nnet2[1].name, map[string]string{
  219. "foo": "bar",
  220. }, []byte("testmsg"))
  221. if dataReceived != "testmsg" || fmt.Sprint(ctrlReceived) != "map[foo:bar]" ||
  222. string(datares) != "testack" || err != nil {
  223. t.Error("Unexpected result: ", ctrlReceived, dataReceived, datares, err)
  224. return
  225. }
  226. nnet2[0].Client.RemovePeer(nnet2[1].name)
  227. nnet2[0].Client.RegisterPeer(nnet2[1].name, nnet2[1].Client.rpc, "123")
  228. res, rfp, err = nnet2[0].Client.SendPing(nnet2[1].name, nnet2[1].Client.rpc)
  229. if fmt.Sprint(res) != "[]" || rfp != "" || err == nil ||
  230. err.Error() != "RufsError: Unexpected SSL certificate from target node (TestNode-1)" {
  231. t.Error("Unexpected result:", res, rfp, err)
  232. return
  233. }
  234. // Test error response
  235. nnet2[0].Client.RemovePeer(nnet2[1].name)
  236. _, err = nnet2[0].Client.SendData(nnet2[1].name, map[string]string{
  237. "foo": "bar",
  238. }, []byte("testmsg"))
  239. if err == nil || err.Error() != "Unknown peer: TestNode-1" {
  240. t.Error("Unexpected result: ", err)
  241. return
  242. }
  243. nnet2[0].Client.RegisterPeer(nnet2[1].name, nnet2[1].Client.rpc, "")
  244. res, rfp, err = nnet2[0].Client.SendPing("", "localhost")
  245. if err == nil || rfp != "" {
  246. t.Error("Unexpected result:", res, rfp, err)
  247. return
  248. }
  249. rres, err := nnet2[0].Client.SendRequest("", RPCPing, nil)
  250. if err == nil || err.Error() != "RufsError: Unknown target node" {
  251. t.Error("Unexpected result:", rres, err)
  252. return
  253. }
  254. rres, err = nnet2[0].Client.SendRequest(nnet2[1].name, "foo", nil)
  255. if err == nil || err.Error() != "RufsError: Remote error (rpc: can't find method RufsServer.foo)" {
  256. t.Error("Unexpected result:", rres, err)
  257. return
  258. }
  259. nnet2[1].DataHandler = func(ctrl map[string]string, data []byte) ([]byte, error) {
  260. return nil, fmt.Errorf("Testerror")
  261. }
  262. datares, err = nnet2[0].Client.SendData(nnet2[1].name, nil, []byte("testmsg"))
  263. if err == nil || err.Error() != "RufsError: Remote error (Testerror)" {
  264. t.Error("Unexpected result: ", dataReceived, datares, err)
  265. return
  266. }
  267. nnet2[1].DataHandler = func(ctrl map[string]string, data []byte) ([]byte, error) {
  268. return nil, &Error{ErrNodeComm, "Testerror2", false}
  269. }
  270. datares, err = nnet2[0].Client.SendData(nnet2[1].name, nil, []byte("testmsg"))
  271. if err == nil || err.Error() != "RufsError: Network error (Testerror2)" {
  272. t.Error("Unexpected result: ", dataReceived, datares, err)
  273. return
  274. }
  275. }
  276. func TestNodeErrors(t *testing.T) {
  277. // Debug logging
  278. //liveOutput = true
  279. //LogDebug = LogInfo
  280. // defer func() { liveOutput = false }()
  281. n := NewNode(fmt.Sprintf("localhost:%v", 9019), "TestNode", "test123", nil, nil)
  282. n.Start(nil)
  283. if err := n.Start(nil); err.Error() != "Cannot start node TestNode twice" {
  284. t.Error("Unexpected result: ", err)
  285. return
  286. }
  287. cl := NewClient("test123", nil)
  288. res, rfp, err := cl.SendPing("TestNode", fmt.Sprintf("localhost:%v", 9019))
  289. if fmt.Sprint(res) != "[Pong]" || err != nil || rfp != "" {
  290. t.Error("Unexpected result:", res, rfp, err)
  291. return
  292. }
  293. // Now corrupt the token of the Client
  294. cl.token.NodeAuth = "123"
  295. _, _, err = cl.SendPing("TestNode", fmt.Sprintf("localhost:%v", 9019))
  296. if err == nil || err.Error() != "RufsError: Remote error (Invalid node token)" {
  297. t.Error("Unexpected result: ", err)
  298. return
  299. }
  300. cl.RegisterPeer("TestNode", fmt.Sprintf("localhost:%v", 9019), "")
  301. _, err = cl.SendData("TestNode", nil, nil)
  302. if err == nil || err.Error() != "RufsError: Remote error (Invalid node token)" {
  303. t.Error("Unexpected result: ", err)
  304. return
  305. }
  306. cl.Shutdown()
  307. n.Shutdown()
  308. if err := n.Shutdown(); err != nil {
  309. t.Error("Unexpected result: ", err)
  310. return
  311. }
  312. n = NewNode(fmt.Sprintf("fff"), "TestNode", "test123", nil, nil)
  313. if err := n.Start(nil); err == nil {
  314. t.Error("Unexpected result: ", err)
  315. return
  316. }
  317. }