common_test.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. package controller
  2. import (
  3. "encoding/json"
  4. "testing"
  5. "time"
  6. "github.com/gravitl/netmaker/database"
  7. "github.com/gravitl/netmaker/models"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. type NodeValidationTC struct {
  11. testname string
  12. node models.Node
  13. errorMessage string
  14. }
  15. type NodeValidationUpdateTC struct {
  16. testname string
  17. node models.NodeUpdate
  18. errorMessage string
  19. }
  20. func createTestNode(t *testing.T) models.Node {
  21. createnode := models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.0.0.1", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet"}
  22. node, err := CreateNode(createnode, "skynet")
  23. assert.Nil(t, err)
  24. return node
  25. }
  26. func TestCreateNode(t *testing.T) {
  27. deleteNet(t)
  28. createNet()
  29. createnode := models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.0.0.1", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet"}
  30. err := ValidateNodeCreate("skynet", createnode)
  31. assert.Nil(t, err)
  32. node, err := CreateNode(createnode, "skynet")
  33. assert.Nil(t, err)
  34. assert.Equal(t, "10.0.0.1", node.Endpoint)
  35. assert.Equal(t, "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", node.PublicKey)
  36. assert.Equal(t, "01:02:03:04:05:06", node.MacAddress)
  37. assert.Equal(t, int32(51821), node.ListenPort)
  38. assert.NotNil(t, node.Name)
  39. assert.Equal(t, "skynet", node.Network)
  40. assert.Equal(t, "nm-skynet", node.Interface)
  41. }
  42. func TestDeleteNode(t *testing.T) {
  43. deleteNet(t)
  44. createNet()
  45. node := createTestNode(t)
  46. t.Run("NodeExists", func(t *testing.T) {
  47. err := DeleteNode(node.MacAddress, node.Network)
  48. assert.Nil(t, err)
  49. })
  50. t.Run("NonExistantNode", func(t *testing.T) {
  51. err := DeleteNode(node.MacAddress, node.Network)
  52. assert.Nil(t, err)
  53. })
  54. }
  55. func TestGetNode(t *testing.T) {
  56. deleteNet(t)
  57. createNet()
  58. node := createTestNode(t)
  59. t.Run("NodeExists", func(t *testing.T) {
  60. response, err := GetNode(node.MacAddress, node.Network)
  61. assert.Nil(t, err)
  62. assert.Equal(t, "10.0.0.1", response.Endpoint)
  63. assert.Equal(t, "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", response.PublicKey)
  64. assert.Equal(t, "01:02:03:04:05:06", response.MacAddress)
  65. assert.Equal(t, int32(51821), response.ListenPort)
  66. assert.NotNil(t, response.Name)
  67. assert.Equal(t, "skynet", response.Network)
  68. assert.Equal(t, "nm-skynet", response.Interface)
  69. })
  70. t.Run("BadMac", func(t *testing.T) {
  71. response, err := GetNode("01:02:03:04:05:07", node.Network)
  72. assert.NotNil(t, err)
  73. assert.Equal(t, models.Node{}, response)
  74. assert.Equal(t, "mongo: no documents in result", err.Error())
  75. })
  76. t.Run("BadNetwork", func(t *testing.T) {
  77. response, err := GetNode(node.MacAddress, "badnet")
  78. assert.NotNil(t, err)
  79. assert.Equal(t, models.Node{}, response)
  80. assert.Equal(t, "mongo: no documents in result", err.Error())
  81. })
  82. t.Run("NoNode", func(t *testing.T) {
  83. _ = DeleteNode("01:02:03:04:05:06", "skynet")
  84. response, err := GetNode(node.MacAddress, node.Network)
  85. assert.NotNil(t, err)
  86. assert.Equal(t, models.Node{}, response)
  87. assert.Equal(t, "mongo: no documents in result", err.Error())
  88. })
  89. }
  90. func TestGetPeerList(t *testing.T) {
  91. deleteNet(t)
  92. createNet()
  93. _ = createTestNode(t)
  94. //createnode := models.Node{PublicKey: "RM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.0.0.2", MacAddress: "02:02:03:04:05:06", Password: "password", Network: "skynet"}
  95. //_, _ = CreateNode(createnode, "skynet")
  96. t.Run("PeerExist", func(t *testing.T) {
  97. peers, err := GetPeersList("skynet")
  98. assert.Nil(t, err)
  99. assert.NotEqual(t, []models.PeersResponse(nil), peers)
  100. t.Log(peers)
  101. })
  102. t.Run("NoNodes", func(t *testing.T) {
  103. _ = DeleteNode("01:02:03:04:05:06", "skynet")
  104. peers, err := GetPeersList("skynet")
  105. assert.Nil(t, err)
  106. assert.Equal(t, []models.PeersResponse(nil), peers)
  107. t.Log(peers)
  108. })
  109. }
  110. func TestNodeCheckIn(t *testing.T) {
  111. deleteNet(t)
  112. createNet()
  113. node := createTestNode(t)
  114. time.Sleep(time.Second * 1)
  115. expectedResponse := models.CheckInResponse{false, false, false, false, false, "", false}
  116. t.Run("BadNet", func(t *testing.T) {
  117. response, err := NodeCheckIn(node, "badnet")
  118. assert.NotNil(t, err)
  119. assert.Contains(t, err.Error(), "Couldnt retrieve Network badnet: ")
  120. assert.Equal(t, expectedResponse, response)
  121. })
  122. t.Run("BadNode", func(t *testing.T) {
  123. badnode := models.Node{PublicKey: "RM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.0.0.2", MacAddress: "02:02:03:04:05:06", Password: "password", Network: "skynet"}
  124. response, err := NodeCheckIn(badnode, "skynet")
  125. assert.NotNil(t, err)
  126. assert.Contains(t, err.Error(), "Couldnt Get Node 02:02:03:04:05:06")
  127. assert.Equal(t, expectedResponse, response)
  128. })
  129. t.Run("NoUpdatesNeeded", func(t *testing.T) {
  130. expectedResponse := models.CheckInResponse{true, false, false, false, false, "", false}
  131. response, err := NodeCheckIn(node, node.Network)
  132. assert.Nil(t, err)
  133. assert.Equal(t, expectedResponse, response)
  134. })
  135. t.Run("NodePending", func(t *testing.T) {
  136. // create Pending Node
  137. createnode := models.Node{PublicKey: "RM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.0.0.2", MacAddress: "01:02:03:04:05:07", Password: "password", Network: "skynet", IsPending: true}
  138. pendingNode, _ := CreateNode(createnode, "skynet")
  139. expectedResponse.IsPending = true
  140. response, err := NodeCheckIn(pendingNode, "skynet")
  141. assert.NotNil(t, err)
  142. assert.Contains(t, err.Error(), "Node checking in is still pending: 01:02:03:04:05:07")
  143. assert.Equal(t, expectedResponse, response)
  144. })
  145. t.Run("ConfigUpdateRequired", func(t *testing.T) {
  146. err := TimestampNode(node, false, false, true)
  147. assert.Nil(t, err)
  148. expectedResponse.NeedConfigUpdate = true
  149. expectedResponse.Success = true
  150. response, err := NodeCheckIn(node, "skynet")
  151. assert.Nil(t, err)
  152. assert.Equal(t, true, response.Success)
  153. assert.Equal(t, true, response.NeedConfigUpdate)
  154. })
  155. t.Run("PeerUpdateRequired", func(t *testing.T) {
  156. var nodeUpdate models.NodeUpdate
  157. newtime := time.Now().Add(time.Hour * -24).Unix()
  158. nodeUpdate.LastPeerUpdate = newtime
  159. _, err := UpdateNode(nodeUpdate, node)
  160. assert.Nil(t, err)
  161. response, err := NodeCheckIn(node, "skynet")
  162. assert.Nil(t, err)
  163. assert.Equal(t, true, response.Success)
  164. assert.Equal(t, true, response.NeedPeerUpdate)
  165. })
  166. t.Run("KeyUpdateRequired", func(t *testing.T) {
  167. var network models.Network
  168. newtime := time.Now().Add(time.Hour * 24).Unix()
  169. t.Log(newtime, time.Now().Unix())
  170. //this is cheating; but can't find away to update timestamp through existing api
  171. record, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, "skynet")
  172. assert.Nil(t, err)
  173. err = json.Unmarshal([]byte(record), &network)
  174. assert.Nil(t, err)
  175. network.KeyUpdateTimeStamp = newtime
  176. response, err := NodeCheckIn(node, "skynet")
  177. assert.Nil(t, err)
  178. assert.Equal(t, true, response.Success)
  179. assert.Equal(t, true, response.NeedKeyUpdate)
  180. })
  181. t.Run("DeleteNeeded", func(t *testing.T) {
  182. var nodeUpdate models.NodeUpdate
  183. newtime := time.Now().Add(time.Hour * -24).Unix()
  184. nodeUpdate.ExpirationDateTime = newtime
  185. _, err := UpdateNode(nodeUpdate, node)
  186. assert.Nil(t, err)
  187. response, err := NodeCheckIn(node, "skynet")
  188. assert.Nil(t, err)
  189. assert.Equal(t, true, response.Success)
  190. assert.Equal(t, true, response.NeedDelete)
  191. })
  192. }
  193. func TestSetNetworkNodesLastModified(t *testing.T) {
  194. deleteNet(t)
  195. createNet()
  196. t.Run("InvalidNetwork", func(t *testing.T) {
  197. err := SetNetworkNodesLastModified("badnet")
  198. assert.NotNil(t, err)
  199. assert.Equal(t, "mongo: no documents in result", err.Error())
  200. })
  201. t.Run("NetworkExists", func(t *testing.T) {
  202. err := SetNetworkNodesLastModified("skynet")
  203. assert.Nil(t, err)
  204. })
  205. }
  206. func TestTimestampNode(t *testing.T) {
  207. deleteNet(t)
  208. createNet()
  209. node := createTestNode(t)
  210. time.Sleep(time.Second * 1)
  211. before, err := GetNode(node.MacAddress, node.Network)
  212. assert.Nil(t, err)
  213. t.Run("UpdateCheckIn", func(t *testing.T) {
  214. err = TimestampNode(node, true, false, false)
  215. assert.Nil(t, err)
  216. after, err := GetNode(node.MacAddress, node.Network)
  217. assert.Nil(t, err)
  218. assert.Greater(t, after.LastCheckIn, before.LastCheckIn)
  219. })
  220. t.Run("UpdatePeers", func(t *testing.T) {
  221. err = TimestampNode(node, false, true, false)
  222. assert.Nil(t, err)
  223. after, err := GetNode(node.MacAddress, node.Network)
  224. assert.Nil(t, err)
  225. assert.Greater(t, after.LastPeerUpdate, before.LastPeerUpdate)
  226. })
  227. t.Run("UpdateLastModified", func(t *testing.T) {
  228. err = TimestampNode(node, false, false, true)
  229. assert.Nil(t, err)
  230. after, err := GetNode(node.MacAddress, node.Network)
  231. assert.Nil(t, err)
  232. assert.Greater(t, after.LastModified, before.LastModified)
  233. })
  234. t.Run("InvalidNode", func(t *testing.T) {
  235. node.MacAddress = "01:02:03:04:05:08"
  236. err = TimestampNode(node, true, true, true)
  237. assert.NotNil(t, err)
  238. assert.Equal(t, "mongo: no documents in result", err.Error())
  239. })
  240. }
  241. func TestUpdateNode(t *testing.T) {
  242. deleteNet(t)
  243. createNet()
  244. node := createTestNode(t)
  245. var update models.NodeUpdate
  246. update.MacAddress = "01:02:03:04:05:06"
  247. update.Name = "helloworld"
  248. newnode, err := UpdateNode(update, node)
  249. assert.Nil(t, err)
  250. assert.Equal(t, update.Name, newnode.Name)
  251. }
  252. func TestValidateNodeCreate(t *testing.T) {
  253. cases := []NodeValidationTC{
  254. // NodeValidationTC{
  255. // testname: "EmptyAddress",
  256. // node: models.Node{
  257. // Address: "",
  258. // },
  259. // errorMessage: "Field validation for 'Endpoint' failed on the 'address_check' tag",
  260. // },
  261. NodeValidationTC{
  262. testname: "BadAddress",
  263. node: models.Node{
  264. Address: "256.0.0.1",
  265. },
  266. errorMessage: "Field validation for 'Address' failed on the 'ipv4' tag",
  267. },
  268. NodeValidationTC{
  269. testname: "BadAddress6",
  270. node: models.Node{
  271. Address6: "2607::abcd:efgh::1",
  272. },
  273. errorMessage: "Field validation for 'Address6' failed on the 'ipv6' tag",
  274. },
  275. NodeValidationTC{
  276. testname: "BadLocalAddress",
  277. node: models.Node{
  278. LocalAddress: "10.0.200.300",
  279. },
  280. errorMessage: "Field validation for 'LocalAddress' failed on the 'ip' tag",
  281. },
  282. NodeValidationTC{
  283. testname: "InvalidName",
  284. node: models.Node{
  285. Name: "mynode*",
  286. },
  287. errorMessage: "Field validation for 'Name' failed on the 'in_charset' tag",
  288. },
  289. NodeValidationTC{
  290. testname: "NameTooLong",
  291. node: models.Node{
  292. Name: "mynodexmynode",
  293. },
  294. errorMessage: "Field validation for 'Name' failed on the 'max' tag",
  295. },
  296. NodeValidationTC{
  297. testname: "ListenPortMin",
  298. node: models.Node{
  299. ListenPort: 1023,
  300. },
  301. errorMessage: "Field validation for 'ListenPort' failed on the 'min' tag",
  302. },
  303. NodeValidationTC{
  304. testname: "ListenPortMax",
  305. node: models.Node{
  306. ListenPort: 65536,
  307. },
  308. errorMessage: "Field validation for 'ListenPort' failed on the 'max' tag",
  309. },
  310. NodeValidationTC{
  311. testname: "PublicKeyEmpty",
  312. node: models.Node{
  313. PublicKey: "",
  314. },
  315. errorMessage: "Field validation for 'PublicKey' failed on the 'required' tag",
  316. },
  317. NodeValidationTC{
  318. testname: "PublicKeyInvalid",
  319. node: models.Node{
  320. PublicKey: "junk%key",
  321. },
  322. errorMessage: "Field validation for 'PublicKey' failed on the 'base64' tag",
  323. },
  324. NodeValidationTC{
  325. testname: "EndpointInvalid",
  326. node: models.Node{
  327. Endpoint: "10.2.0.300",
  328. },
  329. errorMessage: "Field validation for 'Endpoint' failed on the 'ip' tag",
  330. },
  331. NodeValidationTC{
  332. testname: "EndpointEmpty",
  333. node: models.Node{
  334. Endpoint: "",
  335. },
  336. errorMessage: "Field validation for 'Endpoint' failed on the 'required' tag",
  337. },
  338. NodeValidationTC{
  339. testname: "PersistentKeepaliveMax",
  340. node: models.Node{
  341. PersistentKeepalive: 1001,
  342. },
  343. errorMessage: "Field validation for 'PersistentKeepalive' failed on the 'max' tag",
  344. },
  345. NodeValidationTC{
  346. testname: "MacAddressInvalid",
  347. node: models.Node{
  348. MacAddress: "01:02:03:04:05",
  349. },
  350. errorMessage: "Field validation for 'MacAddress' failed on the 'mac' tag",
  351. },
  352. NodeValidationTC{
  353. testname: "MacAddressMissing",
  354. node: models.Node{
  355. MacAddress: "",
  356. },
  357. errorMessage: "Field validation for 'MacAddress' failed on the 'required' tag",
  358. },
  359. NodeValidationTC{
  360. testname: "EmptyPassword",
  361. node: models.Node{
  362. Password: "",
  363. },
  364. errorMessage: "Field validation for 'Password' failed on the 'required' tag",
  365. },
  366. NodeValidationTC{
  367. testname: "ShortPassword",
  368. node: models.Node{
  369. Password: "1234",
  370. },
  371. errorMessage: "Field validation for 'Password' failed on the 'min' tag",
  372. },
  373. NodeValidationTC{
  374. testname: "NoNetwork",
  375. node: models.Node{
  376. Network: "badnet",
  377. },
  378. errorMessage: "Field validation for 'Network' failed on the 'network_exists' tag",
  379. },
  380. }
  381. for _, tc := range cases {
  382. t.Run(tc.testname, func(t *testing.T) {
  383. err := ValidateNodeCreate("skynet", tc.node)
  384. assert.NotNil(t, err)
  385. assert.Contains(t, err.Error(), tc.errorMessage)
  386. })
  387. }
  388. t.Run("MacAddresUnique", func(t *testing.T) {
  389. createNet()
  390. node := models.Node{MacAddress: "01:02:03:04:05:06", Network: "skynet"}
  391. _, err := CreateNode(node, "skynet")
  392. assert.Nil(t, err)
  393. err = ValidateNodeCreate("skynet", node)
  394. assert.NotNil(t, err)
  395. assert.Contains(t, err.Error(), "Field validation for 'MacAddress' failed on the 'macaddress_unique' tag")
  396. })
  397. t.Run("EmptyAddress", func(t *testing.T) {
  398. node := models.Node{Address: ""}
  399. err := ValidateNodeCreate("skynet", node)
  400. assert.NotNil(t, err)
  401. assert.NotContains(t, err.Error(), "Field validation for 'Address' failed on the 'ipv4' tag")
  402. })
  403. }
  404. func TestValidateNodeUpdate(t *testing.T) {
  405. //cases
  406. cases := []NodeValidationUpdateTC{
  407. NodeValidationUpdateTC{
  408. testname: "BadAddress",
  409. node: models.NodeUpdate{
  410. Address: "256.0.0.1",
  411. },
  412. errorMessage: "Field validation for 'Address' failed on the 'ip' tag",
  413. },
  414. NodeValidationUpdateTC{
  415. testname: "BadAddress6",
  416. node: models.NodeUpdate{
  417. Address6: "2607::abcd:efgh::1",
  418. },
  419. errorMessage: "Field validation for 'Address6' failed on the 'ipv6' tag",
  420. },
  421. NodeValidationUpdateTC{
  422. testname: "BadLocalAddress",
  423. node: models.NodeUpdate{
  424. LocalAddress: "10.0.200.300",
  425. },
  426. errorMessage: "Field validation for 'LocalAddress' failed on the 'ip' tag",
  427. },
  428. NodeValidationUpdateTC{
  429. testname: "InvalidName",
  430. node: models.NodeUpdate{
  431. Name: "mynode*",
  432. },
  433. errorMessage: "Field validation for 'Name' failed on the 'in_charset' tag",
  434. },
  435. NodeValidationUpdateTC{
  436. testname: "NameTooLong",
  437. node: models.NodeUpdate{
  438. Name: "mynodexmynode",
  439. },
  440. errorMessage: "Field validation for 'Name' failed on the 'max' tag",
  441. },
  442. NodeValidationUpdateTC{
  443. testname: "ListenPortMin",
  444. node: models.NodeUpdate{
  445. ListenPort: 1023,
  446. },
  447. errorMessage: "Field validation for 'ListenPort' failed on the 'min' tag",
  448. },
  449. NodeValidationUpdateTC{
  450. testname: "ListenPortMax",
  451. node: models.NodeUpdate{
  452. ListenPort: 65536,
  453. },
  454. errorMessage: "Field validation for 'ListenPort' failed on the 'max' tag",
  455. },
  456. NodeValidationUpdateTC{
  457. testname: "PublicKeyInvalid",
  458. node: models.NodeUpdate{
  459. PublicKey: "bad&key",
  460. },
  461. errorMessage: "Field validation for 'PublicKey' failed on the 'base64' tag",
  462. },
  463. NodeValidationUpdateTC{
  464. testname: "EndpointInvalid",
  465. node: models.NodeUpdate{
  466. Endpoint: "10.2.0.300",
  467. },
  468. errorMessage: "Field validation for 'Endpoint' failed on the 'ip' tag",
  469. },
  470. NodeValidationUpdateTC{
  471. testname: "PersistentKeepaliveMax",
  472. node: models.NodeUpdate{
  473. PersistentKeepalive: 1001,
  474. },
  475. errorMessage: "Field validation for 'PersistentKeepalive' failed on the 'max' tag",
  476. },
  477. NodeValidationUpdateTC{
  478. testname: "MacAddressInvalid",
  479. node: models.NodeUpdate{
  480. MacAddress: "01:02:03:04:05",
  481. },
  482. errorMessage: "Field validation for 'MacAddress' failed on the 'mac' tag",
  483. },
  484. NodeValidationUpdateTC{
  485. testname: "MacAddressMissing",
  486. node: models.NodeUpdate{
  487. MacAddress: "",
  488. },
  489. errorMessage: "Field validation for 'MacAddress' failed on the 'required' tag",
  490. },
  491. NodeValidationUpdateTC{
  492. testname: "ShortPassword",
  493. node: models.NodeUpdate{
  494. Password: "1234",
  495. },
  496. errorMessage: "Field validation for 'Password' failed on the 'min' tag",
  497. },
  498. NodeValidationUpdateTC{
  499. testname: "NoNetwork",
  500. node: models.NodeUpdate{
  501. Network: "badnet",
  502. },
  503. errorMessage: "Field validation for 'Network' failed on the 'network_exists' tag",
  504. },
  505. }
  506. for _, tc := range cases {
  507. t.Run(tc.testname, func(t *testing.T) {
  508. err := ValidateNodeUpdate("skynet", tc.node)
  509. assert.NotNil(t, err)
  510. assert.Contains(t, err.Error(), tc.errorMessage)
  511. })
  512. }
  513. }