graphmanager_edges_test.go 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package graph
  11. import (
  12. "errors"
  13. "fmt"
  14. "strings"
  15. "testing"
  16. "devt.de/krotik/eliasdb/graph/data"
  17. "devt.de/krotik/eliasdb/graph/graphstorage"
  18. "devt.de/krotik/eliasdb/graph/util"
  19. "devt.de/krotik/eliasdb/hash"
  20. "devt.de/krotik/eliasdb/storage"
  21. )
  22. func TestSimpleGraphStorage(t *testing.T) {
  23. if !RunDiskStorageTests {
  24. return
  25. }
  26. dgs, err := graphstorage.NewDiskGraphStorage(GraphManagerTestDBDir3, false)
  27. if err != nil {
  28. t.Error(err)
  29. return
  30. }
  31. gm := newGraphManagerNoRules(dgs)
  32. node1 := data.NewGraphNode()
  33. node1.SetAttr("key", "123")
  34. node1.SetAttr("kind", "mykind")
  35. node1.SetAttr("Name", "Node1")
  36. gm.StoreNode("main", node1)
  37. node2 := data.NewGraphNode()
  38. node2.SetAttr("key", "456")
  39. node2.SetAttr("kind", "mykind")
  40. node2.SetAttr("Name", "Node2")
  41. gm.StoreNode("main", node2)
  42. node3 := data.NewGraphNode()
  43. node3.SetAttr("key", "789")
  44. node3.SetAttr("kind", "mykind")
  45. node3.SetAttr("Name", "Node3")
  46. gm.StoreNode("main", node3)
  47. edge := data.NewGraphEdge()
  48. edge.SetAttr("key", "abc")
  49. edge.SetAttr("kind", "myedge")
  50. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  51. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  52. edge.SetAttr(data.EdgeEnd1Role, "node1")
  53. edge.SetAttr(data.EdgeEnd1Cascading, true)
  54. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  55. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  56. edge.SetAttr(data.EdgeEnd2Role, "node2")
  57. edge.SetAttr(data.EdgeEnd2Cascading, false)
  58. err = gm.StoreEdge("main", edge)
  59. if err != nil {
  60. t.Error(err)
  61. }
  62. if gm.EdgeCount("myedge") != 1 {
  63. t.Error("Unexpected edge count")
  64. return
  65. }
  66. // Check that the correct data has been written
  67. edgeTree, _ := gm.getEdgeStorageHTree("main", "myedge", false)
  68. keyAttrs := PrefixNSAttrs + edge.Key()
  69. val, err := edgeTree.Get([]byte(keyAttrs))
  70. if err != nil || val == nil {
  71. t.Error("Unexpected result:", val, val)
  72. return
  73. }
  74. if res := len(val.([]string)); res != 8 {
  75. t.Error("Unexpected number of stored attributes:", res)
  76. }
  77. keyAttr := PrefixNSAttr + edge.Key() + gm.nm.Encode32(data.EdgeEnd2Key, false)
  78. if val, err := edgeTree.Get([]byte(keyAttr)); err != nil || val != node2.Key() {
  79. t.Error("Unexpected result:", err, val)
  80. return
  81. }
  82. _, nodeTree, _ := gm.getNodeStorageHTree("main", "mykind", false)
  83. specMap, err := nodeTree.Get([]byte(PrefixNSSpecs + node2.Key()))
  84. if err != nil || specMap == nil {
  85. t.Error("Unexpected result:", specMap, err)
  86. }
  87. if len(specMap.(map[string]string)) != 1 {
  88. t.Error("Unexpected size of spec map")
  89. return
  90. }
  91. if _, ok := specMap.(map[string]string)[gm.nm.Encode16(edge.End2Role(), false)+gm.nm.Encode16(edge.Kind(), false)+
  92. gm.nm.Encode16(edge.End1Role(), false)+gm.nm.Encode16(edge.End1Kind(), false)]; !ok {
  93. t.Error("Unexpected content of spec map")
  94. return
  95. }
  96. fetchedEdge, err := gm.FetchEdge("main", edge.Key(), edge.Kind())
  97. if err != nil {
  98. t.Error(err)
  99. return
  100. }
  101. if !data.NodeCompare(edge, fetchedEdge, nil) {
  102. t.Error("Fetched edge should contain the same data as the stored edge")
  103. return
  104. }
  105. // Try to change one of the endpoints
  106. edge.SetAttr(data.EdgeEnd1Key, node3.Key())
  107. err = gm.StoreEdge("main", edge)
  108. if err.Error() != "GraphError: Invalid data (Cannot update endpoints or spec of existing edge: abc)" {
  109. t.Error(err)
  110. return
  111. }
  112. // Try again to make sure it was not updated
  113. edge.SetAttr(data.EdgeEnd1Key, node3.Key())
  114. err = gm.StoreEdge("main", edge)
  115. if err.Error() != "GraphError: Invalid data (Cannot update endpoints or spec of existing edge: abc)" {
  116. t.Error(err)
  117. }
  118. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  119. edge.SetAttr("Name", "Test")
  120. err = gm.StoreEdge("main", edge)
  121. if err != nil {
  122. t.Error(err)
  123. return
  124. }
  125. fetchedEdge, err = gm.FetchEdge("main", edge.Key(), edge.Kind())
  126. if err != nil {
  127. t.Error(err)
  128. return
  129. }
  130. if fetchedEdge.Attr("Name") != "Test" {
  131. t.Error("Unexpected attribute value")
  132. return
  133. }
  134. if gm.EdgeCount("myedge") != 1 {
  135. t.Error("Unexpected edge count")
  136. return
  137. }
  138. // Store more edges
  139. edge2 := data.NewGraphEdge()
  140. edge2.SetAttr("key", "def")
  141. edge2.SetAttr("kind", "myedge")
  142. edge2.SetAttr(data.EdgeEnd1Key, node1.Key())
  143. edge2.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  144. edge2.SetAttr(data.EdgeEnd1Role, "node1")
  145. edge2.SetAttr(data.EdgeEnd1Cascading, true)
  146. edge2.SetAttr(data.EdgeEnd2Key, node3.Key())
  147. edge2.SetAttr(data.EdgeEnd2Kind, node3.Kind())
  148. edge2.SetAttr(data.EdgeEnd2Role, "node2")
  149. edge2.SetAttr(data.EdgeEnd2Cascading, false)
  150. err = gm.StoreEdge("main", edge2)
  151. if err != nil {
  152. t.Error(err)
  153. return
  154. }
  155. // Spec map has still one entry
  156. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node1.Key()))
  157. if err != nil || specMap == nil {
  158. t.Error("Unexpected result:", specMap, err)
  159. }
  160. if len(specMap.(map[string]string)) != 1 {
  161. t.Error("Unexpected size of spec map")
  162. return
  163. }
  164. if gm.EdgeCount("myedge") != 2 {
  165. t.Error("Unexpected edge count")
  166. return
  167. }
  168. edge2.SetAttr("key", "ghi")
  169. err = gm.StoreEdge("main", edge2)
  170. if err != nil {
  171. t.Error(err)
  172. return
  173. }
  174. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node1.Key()))
  175. if err != nil || specMap == nil {
  176. t.Error("Unexpected result:", specMap, err)
  177. }
  178. spec1 := gm.nm.Encode16(edge.End1Role(), true) + gm.nm.Encode16(edge.Kind(), true) +
  179. gm.nm.Encode16(edge.End2Role(), true) + gm.nm.Encode16(edge.End2Kind(), true)
  180. edgeInfo1Key := PrefixNSEdge + edge.End1Key() + spec1
  181. obj, err := nodeTree.Get([]byte(edgeInfo1Key))
  182. targetMap := obj.(map[string]*edgeTargetInfo)
  183. // There should be 3 entries in the target map at this point
  184. if len(targetMap) != 3 {
  185. t.Error("Unexpected size of target map")
  186. return
  187. }
  188. testInfo := targetMap["def"]
  189. if !testInfo.CascadeToTarget {
  190. t.Error("Edge should cascade to target from end1")
  191. return
  192. }
  193. if testInfo.TargetNodeKey != node3.Key() {
  194. t.Error("Edge should go to node3")
  195. return
  196. }
  197. if testInfo.TargetNodeKind != node3.Kind() {
  198. t.Error("Edge should go to node3")
  199. return
  200. }
  201. if len(specMap.(map[string]string)) != 1 {
  202. t.Error("Unexpected size of spec map")
  203. return
  204. }
  205. // At this point there are 3 relationships in the db:
  206. // node1 -> node2 [abc]
  207. // node1 -> node3 [def]
  208. // node1 -> node3 [ghi]
  209. if gm.EdgeCount("myedge") != 3 {
  210. t.Error("Unexpected edge count")
  211. return
  212. }
  213. // Test index lookup
  214. iq, _ := gm.EdgeIndexQuery("main", "myedge")
  215. res, _ := iq.LookupValue("Name", "test")
  216. if fmt.Sprint(res) != "["+edge.Key()+"]" {
  217. t.Error("Unexpected result:", res)
  218. return
  219. }
  220. // Test removal
  221. removedEdge, err := gm.RemoveEdge("main", edge.Key(), edge.Kind())
  222. if !data.NodeCompare(edge, removedEdge, nil) {
  223. t.Error("Unexpected result")
  224. return
  225. }
  226. if gm.EdgeCount("myedge") != 2 {
  227. t.Error("Unexpected edge count")
  228. return
  229. }
  230. // Check that the correct data has been removed
  231. edgeTree, _ = gm.getEdgeStorageHTree("main", "myedge", false)
  232. keyAttrs = PrefixNSAttrs + edge.Key()
  233. val, err = edgeTree.Get([]byte(keyAttrs))
  234. if err != nil || val != nil {
  235. t.Error("Unexpected result:", val, val)
  236. return
  237. }
  238. // Check that the spec entry is still there
  239. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node1.Key()))
  240. if err != nil || specMap == nil {
  241. t.Error("Unexpected result:", specMap, err)
  242. return
  243. }
  244. if len(specMap.(map[string]string)) != 1 {
  245. t.Error("Unexpected size of spec map")
  246. return
  247. }
  248. obj, err = nodeTree.Get([]byte(edgeInfo1Key))
  249. targetMap = obj.(map[string]*edgeTargetInfo)
  250. // There should be 2 entries in the target map at this point
  251. if len(targetMap) != 2 {
  252. t.Error("Unexpected size of target map")
  253. return
  254. }
  255. removedEdge, err = gm.RemoveEdge("main", edge2.Key(), edge2.Kind())
  256. if !data.NodeCompare(edge2, removedEdge, nil) {
  257. t.Error("Unexpected result")
  258. return
  259. }
  260. if gm.EdgeCount("myedge") != 1 {
  261. t.Error("Unexpected edge count")
  262. return
  263. }
  264. // Check that the spec entry is still there
  265. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node1.Key()))
  266. if err != nil || specMap == nil {
  267. t.Error("Unexpected result:", specMap, err)
  268. return
  269. }
  270. if len(specMap.(map[string]string)) != 1 {
  271. t.Error("Unexpected size of spec map")
  272. return
  273. }
  274. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node3.Key()))
  275. if err != nil || specMap == nil {
  276. t.Error("Unexpected result:", specMap, err)
  277. return
  278. }
  279. if len(specMap.(map[string]string)) != 1 {
  280. t.Error("Unexpected size of spec map")
  281. return
  282. }
  283. obj, err = nodeTree.Get([]byte(edgeInfo1Key))
  284. targetMap = obj.(map[string]*edgeTargetInfo)
  285. // There should be 1 entries in the target map at this point
  286. if len(targetMap) != 1 {
  287. t.Error("Unexpected size of target map")
  288. return
  289. }
  290. edge2.SetAttr(data.NodeKey, "def")
  291. removedEdge, err = gm.RemoveEdge("main", edge2.Key(), edge2.Kind())
  292. if !data.NodeCompare(edge2, removedEdge, nil) {
  293. t.Error("Unexpected result")
  294. return
  295. }
  296. if gm.EdgeCount("myedge") != 0 {
  297. t.Error("Unexpected edge count")
  298. return
  299. }
  300. // Check that the spec entry has been removed
  301. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node1.Key()))
  302. if err != nil || specMap != nil {
  303. t.Error("Unexpected result:", specMap, err)
  304. return
  305. }
  306. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node2.Key()))
  307. if err != nil || specMap != nil {
  308. t.Error("Unexpected result:", specMap, err)
  309. return
  310. }
  311. specMap, err = nodeTree.Get([]byte(PrefixNSSpecs + node3.Key()))
  312. if err != nil || specMap != nil {
  313. t.Error("Unexpected result:", specMap, err)
  314. return
  315. }
  316. // Check that the target map has been removed
  317. obj, err = nodeTree.Get([]byte(edgeInfo1Key))
  318. if err != nil || obj != nil {
  319. t.Error("Unexpected result:", specMap, err)
  320. return
  321. }
  322. it := hash.NewHTreeIterator(edgeTree)
  323. if it.HasNext() {
  324. t.Error("Tree iterator should find no elements in the tree")
  325. return
  326. }
  327. dgs.Close()
  328. }
  329. func TestSimpleGraphStorageErrorCases(t *testing.T) {
  330. node1 := data.NewGraphNode()
  331. node1.SetAttr("key", "123")
  332. node1.SetAttr("kind", "mykind")
  333. node1.SetAttr("Name", "Node1")
  334. node2 := data.NewGraphNode()
  335. node2.SetAttr("key", "456")
  336. node2.SetAttr("kind", "mynewkind")
  337. node2.SetAttr("Name", "Node2")
  338. // Creeate storage and insert test nodes
  339. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  340. gm := newGraphManagerNoRules(mgs)
  341. gm.StoreNode("main", node1)
  342. gm.StoreNode("main", node2)
  343. edge := data.NewGraphEdge()
  344. edge.SetAttr("key", "abc")
  345. edge.SetAttr("kind", "myedge")
  346. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  347. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  348. edge.SetAttr(data.EdgeEnd1Role, "node1-")
  349. edge.SetAttr(data.EdgeEnd1Cascading, true)
  350. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  351. edge.SetAttr(data.EdgeEnd2Kind, "xxx")
  352. edge.SetAttr(data.EdgeEnd2Role, "node2-")
  353. edge.SetAttr(data.NodeName, "Edge name")
  354. _, _, err := gm.Traverse("main", node1.Key(), node2.Kind(), "abc", false)
  355. if err.Error() != "GraphError: Invalid data (Invalid spec: abc)" {
  356. t.Error("Unexpected store result:", err)
  357. return
  358. }
  359. _, _, err = gm.Traverse("main", node1.Key(), node2.Kind(), ":::abc", false)
  360. if err.Error() != "GraphError: Invalid data (Invalid spec: :::abc - spec needs to be fully specified for direct traversal)" {
  361. t.Error("Unexpected store result:", err)
  362. return
  363. }
  364. _, _, err = gm.TraverseMulti("main", node1.Key(), node2.Kind(), "abc", false)
  365. if err.Error() != "GraphError: Invalid data (Invalid spec: abc)" {
  366. t.Error("Unexpected store result:", err)
  367. return
  368. }
  369. if err := gm.StoreEdge("main", edge); err.Error() !=
  370. "GraphError: Invalid data (Edge role node1- is not alphanumeric - can only contain [a-zA-Z0-9_])" {
  371. t.Error("Unexpected store result:", err)
  372. return
  373. }
  374. edge.SetAttr(data.EdgeEnd1Role, "node1")
  375. if err := gm.StoreEdge("main", edge); err.Error() !=
  376. "GraphError: Invalid data (Edge role node2- is not alphanumeric - can only contain [a-zA-Z0-9_])" {
  377. t.Error("Unexpected store result:", err)
  378. return
  379. }
  380. edge.SetAttr(data.EdgeEnd2Role, "node2")
  381. if err := gm.StoreEdge("main", edge); err.Error() !=
  382. "GraphError: Invalid data (Edge is missing a cascading value for end2)" {
  383. t.Error("Unexpected store result:", err)
  384. return
  385. }
  386. edge.SetAttr(data.EdgeEnd2Cascading, false)
  387. if err := gm.StoreEdge("main", edge); err.Error() != "GraphError: Invalid data (Can't store edge to non-existing node kind: xxx)" {
  388. t.Error("Unexpected store result:", err)
  389. return
  390. }
  391. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  392. edge.SetAttr(data.EdgeEnd1Kind, "xxx")
  393. if err := gm.StoreEdge("main", edge); err.Error() != "GraphError: Invalid data (Can't store edge to non-existing node kind: xxx)" {
  394. t.Error("Unexpected store result:", err)
  395. return
  396. }
  397. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  398. edge.SetAttr(data.EdgeEnd1Key, "xxx")
  399. if err := gm.StoreEdge("main", edge); err.Error() != "GraphError: Invalid data (Can't find edge endpoint: xxx (mykind))" {
  400. t.Error("Unexpected store result:", err)
  401. return
  402. }
  403. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  404. edge.SetAttr(data.EdgeEnd2Key, "xxx")
  405. if err := gm.StoreEdge("main", edge); err.Error() != "GraphError: Invalid data (Can't find edge endpoint: xxx (mynewkind))" {
  406. t.Error("Unexpected store result:", err)
  407. return
  408. }
  409. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  410. // Test storage access failures
  411. sm := gm.gs.StorageManager("main"+"myedge"+StorageSuffixEdgesIndex, false)
  412. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  413. if err := gm.StoreEdge("main", edge); err == nil {
  414. t.Error("Unexpected store result:", err)
  415. return
  416. }
  417. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); err == nil {
  418. t.Error("Unexpected store result:", err)
  419. return
  420. }
  421. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  422. sm.(*storage.MemoryStorageManager).AccessMap[2] = storage.AccessInsertError
  423. if err := gm.StoreEdge("main", edge); err == nil {
  424. t.Error("Unexpected store result:", err)
  425. return
  426. }
  427. delete(sm.(*storage.MemoryStorageManager).AccessMap, 2)
  428. // Reset storage and insert test nodes
  429. mgs = graphstorage.NewMemoryGraphStorage("mystorage")
  430. gm = newGraphManagerNoRules(mgs)
  431. gm.StoreNode("main", node1)
  432. gm.StoreNode("main", node2)
  433. // Test high level errors
  434. sm = gm.gs.StorageManager("main"+"mykind"+StorageSuffixNodes, false)
  435. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  436. if err := gm.StoreEdge("main", edge); err == nil {
  437. t.Error("Unexpected store result:", err)
  438. return
  439. }
  440. if _, _, err := gm.Traverse("main", "bla", "mykind", "", false); err == nil {
  441. t.Error("Unexpected store result:", err)
  442. return
  443. }
  444. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  445. sm = gm.gs.StorageManager("main"+"myedge"+StorageSuffixEdges, false)
  446. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  447. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); err == nil {
  448. t.Error("Unexpected store result:", err)
  449. return
  450. }
  451. if _, err := gm.FetchEdge("main", edge.Key(), edge.Kind()); err == nil {
  452. t.Error("Unexpected store result:", err)
  453. return
  454. }
  455. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  456. sm = gm.gs.StorageManager("main"+"mynewkind"+StorageSuffixNodes, false)
  457. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  458. if err := gm.StoreEdge("main", edge); err == nil {
  459. t.Error("Unexpected store result:", err)
  460. return
  461. }
  462. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  463. graphstorage.MgsRetFlushMain = &util.GraphError{Type: util.ErrFlushing, Detail: errors.New("Test").Error()}
  464. if err := gm.StoreEdge("main", edge); err == nil {
  465. t.Error("Unexpected store result:", err)
  466. return
  467. }
  468. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); err == nil {
  469. t.Error("Unexpected store result:", err)
  470. return
  471. }
  472. graphstorage.MgsRetFlushMain = nil
  473. // Finally insert the edge
  474. if err := gm.StoreEdge("main", edge); err != nil {
  475. t.Error("Unexpected store result:", err)
  476. return
  477. }
  478. sm = gm.gs.StorageManager("main"+"myedge"+StorageSuffixEdges, false)
  479. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  480. traverseSpec := edge.End2Role() + ":" + edge.Kind() + ":" + edge.End1Role() + ":" + edge.End1Kind()
  481. _, _, err = gm.Traverse("main", edge.End2Key(), edge.End2Kind(), traverseSpec, true)
  482. if !strings.Contains(err.Error(), "Slot not found") {
  483. t.Error("Unexpected store result:", err)
  484. return
  485. }
  486. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  487. sm = gm.gs.StorageManager("main"+"myedge"+StorageSuffixEdgesIndex, false)
  488. sm.(*storage.MemoryStorageManager).AccessMap[5] = storage.AccessInsertError
  489. edge.SetAttr("name", "New edge name")
  490. if err := gm.StoreEdge("main", edge); err == nil {
  491. t.Error("Unexpected store result:", err)
  492. return
  493. }
  494. delete(sm.(*storage.MemoryStorageManager).AccessMap, 5)
  495. resetStorage := func() {
  496. mgs = graphstorage.NewMemoryGraphStorage("mystorage")
  497. gm = newGraphManagerNoRules(mgs)
  498. gm.StoreNode("main", node1)
  499. gm.StoreNode("main", node2)
  500. gm.StoreEdge("main", edge)
  501. }
  502. // Test low level errors
  503. spec1 := gm.nm.Encode16(edge.End1Role(), true) + gm.nm.Encode16(edge.Kind(), true) +
  504. gm.nm.Encode16(edge.End2Role(), true) + gm.nm.Encode16(edge.End2Kind(), true)
  505. spec2 := gm.nm.Encode16(edge.End2Role(), true) + gm.nm.Encode16(edge.Kind(), true) +
  506. gm.nm.Encode16(edge.End1Role(), true) + gm.nm.Encode16(edge.End1Kind(), true)
  507. specsNode1Key := PrefixNSSpecs + edge.End1Key()
  508. edgeInfo1Key := PrefixNSEdge + edge.End1Key() + spec1
  509. specsNode2Key := PrefixNSSpecs + edge.End2Key()
  510. edgeInfo2Key := PrefixNSEdge + edge.End2Key() + spec2
  511. resetStorage()
  512. // Test error case of index lookup
  513. sm = gm.gs.StorageManager("main"+edge.Kind()+StorageSuffixEdgesIndex, false)
  514. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  515. if _, err := gm.EdgeIndexQuery("main", "myedge"); err == nil {
  516. t.Error(err)
  517. return
  518. }
  519. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  520. _, nodeTree, _ := gm.getNodeStorageHTree("main", edge.End2Kind(), false)
  521. _, loc, _ := nodeTree.GetValueAndLocation([]byte(specsNode2Key))
  522. sm = gm.gs.StorageManager("main"+edge.End2Kind()+StorageSuffixNodes, false)
  523. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessCacheAndFetchError
  524. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Slot not found") {
  525. t.Error("Unexpected store result:", err)
  526. return
  527. }
  528. if err := gm.StoreEdge("main", edge); !strings.Contains(err.Error(), "Slot not found") {
  529. t.Error("Unexpected store result:", err)
  530. return
  531. }
  532. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  533. resetStorage()
  534. _, nodeTree, _ = gm.getNodeStorageHTree("main", edge.End1Kind(), false)
  535. _, _ = nodeTree.Remove([]byte(specsNode1Key))
  536. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Expected spec entry is missing") {
  537. t.Error("Unexpected store result:", err)
  538. return
  539. }
  540. resetStorage()
  541. _, nodeTree, _ = gm.getNodeStorageHTree("main", edge.End2Kind(), false)
  542. _, loc, _ = nodeTree.GetValueAndLocation([]byte(specsNode2Key))
  543. sm = gm.gs.StorageManager("main"+edge.End2Kind()+StorageSuffixNodes, false)
  544. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessFreeError
  545. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Slot not found") {
  546. t.Error("Unexpected store result:", err)
  547. return
  548. }
  549. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  550. resetStorage()
  551. _, nodeTree, _ = gm.getNodeStorageHTree("main", edge.End1Kind(), false)
  552. val, loc, _ := nodeTree.GetValueAndLocation([]byte(specsNode1Key))
  553. val.(map[string]string)["test2"] = "test3"
  554. sm = gm.gs.StorageManager("main"+edge.End1Kind()+StorageSuffixNodes, false)
  555. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessUpdateError
  556. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Slot not found") {
  557. t.Error("Unexpected store result:", err)
  558. return
  559. }
  560. if err := gm.StoreEdge("main", edge); !strings.Contains(err.Error(), "Slot not found") {
  561. t.Error("Unexpected store result:", err)
  562. return
  563. }
  564. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  565. resetStorage()
  566. _, nodeTree, _ = gm.getNodeStorageHTree("main", edge.End2Kind(), false)
  567. _, loc, _ = nodeTree.GetValueAndLocation([]byte(edgeInfo2Key))
  568. sm = gm.gs.StorageManager("main"+edge.End2Kind()+StorageSuffixNodes, false)
  569. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessCacheAndFetchError
  570. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Slot not found") {
  571. t.Error("Unexpected store result:", err)
  572. return
  573. }
  574. if err := gm.StoreEdge("main", edge); !strings.Contains(err.Error(), "Slot not found") {
  575. t.Error("Unexpected store result:", err)
  576. return
  577. }
  578. traverseSpec = edge.End2Role() + ":" + edge.Kind() + ":" + edge.End1Role() + ":" + edge.End1Kind()
  579. _, _, err = gm.Traverse("main", edge.End2Key(), edge.End2Kind(), traverseSpec, false)
  580. if !strings.Contains(err.Error(), "Slot not found") {
  581. t.Error("Unexpected store result:", err)
  582. return
  583. }
  584. traverseSpec = ":" + edge.Kind() + ":" + edge.End1Role() + ":" + edge.End1Kind()
  585. _, _, err = gm.TraverseMulti("main", edge.End2Key(), edge.End2Kind(), traverseSpec, false)
  586. if !strings.Contains(err.Error(), "Slot not found") {
  587. t.Error("Unexpected store result:", err)
  588. return
  589. }
  590. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  591. resetStorage()
  592. _, nodeTree, _ = gm.getNodeStorageHTree("main", edge.End1Kind(), false)
  593. _, _ = nodeTree.Remove([]byte(edgeInfo1Key))
  594. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Expected edgeTargetInfo entry is missing") {
  595. t.Error("Unexpected store result:", err)
  596. return
  597. }
  598. resetStorage()
  599. _, nodeTree, _ = gm.getNodeStorageHTree("main", edge.End2Kind(), false)
  600. _, loc, _ = nodeTree.GetValueAndLocation([]byte(edgeInfo2Key))
  601. sm = gm.gs.StorageManager("main"+edge.End2Kind()+StorageSuffixNodes, false)
  602. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessFreeError
  603. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Slot not found") {
  604. t.Error("Unexpected store result:", err)
  605. return
  606. }
  607. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  608. resetStorage()
  609. nodeattTree, nodeTree, _ := gm.getNodeStorageHTree("main", edge.End1Kind(), false)
  610. val, loc, _ = nodeTree.GetValueAndLocation([]byte(edgeInfo1Key))
  611. val.(map[string]*edgeTargetInfo)["test2"] = nil
  612. sm = gm.gs.StorageManager("main"+edge.End1Kind()+StorageSuffixNodes, false)
  613. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessUpdateError
  614. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Slot not found") {
  615. t.Error("Unexpected store result:", err)
  616. return
  617. }
  618. if err := gm.StoreEdge("main", edge); !strings.Contains(err.Error(), "Slot not found") {
  619. t.Error("Unexpected store result:", err)
  620. return
  621. }
  622. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  623. _, loc, _ = nodeattTree.GetValueAndLocation([]byte(PrefixNSAttrs + edge.End1Key()))
  624. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessCacheAndFetchError
  625. traverseSpec = edge.End2Role() + ":" + edge.Kind() + ":" + edge.End1Role() + ":" + edge.End1Kind()
  626. _, _, err = gm.Traverse("main", edge.End2Key(), edge.End2Kind(), traverseSpec, true)
  627. if !strings.Contains(err.Error(), "Slot not found") {
  628. t.Error("Unexpected store result:", err)
  629. return
  630. }
  631. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  632. mgs = graphstorage.NewMemoryGraphStorage("mystorage")
  633. gm = newGraphManagerNoRules(mgs)
  634. gm.StoreNode("main", node1)
  635. gm.StoreNode("main", node2)
  636. sm = gm.gs.StorageManager("main"+edge.Kind()+StorageSuffixEdges, true)
  637. sm.(*storage.MemoryStorageManager).AccessMap[11] = storage.AccessInsertError
  638. if err := gm.StoreEdge("main", edge); !strings.Contains(err.Error(), "Could not write graph information") {
  639. t.Error("Unexpected store result:", err)
  640. return
  641. }
  642. delete(sm.(*storage.MemoryStorageManager).AccessMap, 11)
  643. resetStorage()
  644. sm = gm.gs.StorageManager("main"+edge.Kind()+StorageSuffixEdges, false)
  645. sm.(*storage.MemoryStorageManager).AccessMap[11] = storage.AccessCacheAndFetchError
  646. traverseSpec = edge.End1Role() + ":" + edge.Kind() + ":" + edge.End2Role() + ":" + edge.End2Kind()
  647. _, _, err = gm.Traverse("main", edge.End1Key(), edge.End1Kind(), traverseSpec, true)
  648. if !strings.Contains(err.Error(), "Slot not found") {
  649. t.Error("Unexpected store result:", err)
  650. return
  651. }
  652. sm.(*storage.MemoryStorageManager).AccessMap[11] = storage.AccessFreeError
  653. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Could not write graph information") {
  654. t.Error("Unexpected store result:", err)
  655. return
  656. }
  657. delete(sm.(*storage.MemoryStorageManager).AccessMap, 11)
  658. resetStorage()
  659. sm = gm.gs.StorageManager("main"+edge.End1Kind()+StorageSuffixNodes, false)
  660. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  661. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Failed to access graph storage component") {
  662. t.Error("Unexpected store result:", err)
  663. return
  664. }
  665. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  666. resetStorage()
  667. sm = gm.gs.StorageManager("main"+edge.End2Kind()+StorageSuffixNodes, false)
  668. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  669. traverseSpec = edge.End1Role() + ":" + edge.Kind() + ":" + edge.End2Role() + ":" + edge.End2Kind()
  670. _, _, err = gm.Traverse("main", edge.End1Key(), edge.End1Kind(), traverseSpec, true)
  671. if !strings.Contains(err.Error(), "Slot not found") {
  672. t.Error("Unexpected store result:", err)
  673. return
  674. }
  675. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Failed to access graph storage component") {
  676. t.Error("Unexpected store result:", err)
  677. return
  678. }
  679. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  680. resetStorage()
  681. sm = gm.gs.StorageManager("main"+edge.Kind()+StorageSuffixEdgesIndex, false)
  682. sm.(*storage.MemoryStorageManager).AccessMap[2] = storage.AccessFreeError
  683. if _, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); !strings.Contains(err.Error(), "Index error") {
  684. t.Error("Unexpected store result:", err)
  685. return
  686. }
  687. delete(sm.(*storage.MemoryStorageManager).AccessMap, 2)
  688. // Test removal of non-existing edge
  689. resetStorage()
  690. if obj, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); obj == nil || err != nil {
  691. t.Error("Unexpected store result:", obj, err)
  692. return
  693. }
  694. if obj, err := gm.RemoveEdge("main", edge.Key(), edge.Kind()); obj != nil || err != nil {
  695. t.Error("Unexpected store result:", obj, err)
  696. return
  697. }
  698. }
  699. func TestEdgeOperations(t *testing.T) {
  700. node1 := data.NewGraphNode()
  701. node1.SetAttr("key", "123")
  702. node1.SetAttr("kind", "mykind")
  703. node1.SetAttr("Name", "Node1")
  704. node2 := data.NewGraphNode()
  705. node2.SetAttr("key", "456")
  706. node2.SetAttr("kind", "mynewkind")
  707. node2.SetAttr("Name", "Node2")
  708. constructEdge := func(kind string) data.Edge {
  709. edge := data.NewGraphEdge()
  710. edge.SetAttr("key", "abc")
  711. edge.SetAttr("kind", kind)
  712. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  713. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  714. edge.SetAttr(data.EdgeEnd1Role, "node1")
  715. edge.SetAttr(data.EdgeEnd1Cascading, true)
  716. edge.SetAttr(data.EdgeEnd1CascadingLast, true)
  717. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  718. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  719. edge.SetAttr(data.EdgeEnd2Role, "node2")
  720. edge.SetAttr(data.EdgeEnd2Cascading, false)
  721. edge.SetAttr(data.NodeName, "Edge "+kind)
  722. return edge
  723. }
  724. // Creeate storage and insert test nodes
  725. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  726. gm := newGraphManagerNoRules(mgs)
  727. if err := gm.StoreNode("main", node1); err != nil {
  728. t.Error(err)
  729. }
  730. if err := gm.StoreNode("main", node2); err != nil {
  731. t.Error(err)
  732. }
  733. edge1 := constructEdge("myedge")
  734. if err := gm.StoreEdge("main", edge1); err != nil {
  735. t.Error(err)
  736. }
  737. edge2 := constructEdge("myotheredge")
  738. if err := gm.StoreEdge("main", edge2); err != nil {
  739. t.Error(err)
  740. }
  741. specs, err := gm.FetchNodeEdgeSpecs("main", node1.Key(), node1.Kind())
  742. if err != nil {
  743. t.Error(err)
  744. return
  745. }
  746. if fmt.Sprint(specs) != "[node1:myedge:node2:mynewkind node1:myotheredge:node2:mynewkind]" {
  747. t.Error("Unexpected specs result:", specs)
  748. return
  749. }
  750. sm := gm.gs.StorageManager("main"+node1.Kind()+StorageSuffixNodes, false)
  751. sm.(*storage.MemoryStorageManager).AccessMap[1] = storage.AccessCacheAndFetchError
  752. _, err = gm.FetchNodeEdgeSpecs("main", node1.Key(), node1.Kind())
  753. if err.Error() != "GraphError: Failed to access graph storage component (Slot not found (mystorage/mainmykind.nodes - Location:1))" {
  754. t.Error("Unexpected error:", err)
  755. return
  756. }
  757. _, _, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(), ":::", false)
  758. if err.Error() != "GraphError: Failed to access graph storage component (Slot not found (mystorage/mainmykind.nodes - Location:1))" {
  759. t.Error("Unexpected error:", err)
  760. return
  761. }
  762. delete(sm.(*storage.MemoryStorageManager).AccessMap, 1)
  763. _, tree, _ := gm.getNodeStorageHTree("main", node1.Kind(), false)
  764. _, loc, _ := tree.GetValueAndLocation([]byte(PrefixNSSpecs + node1.Key()))
  765. sm.(*storage.MemoryStorageManager).AccessMap[loc] = storage.AccessCacheAndFetchError
  766. _, err = gm.FetchNodeEdgeSpecs("main", node1.Key(), node1.Kind())
  767. if !strings.Contains(err.Error(), "Slot not found") {
  768. t.Error("Unexpected error:", err)
  769. return
  770. }
  771. delete(sm.(*storage.MemoryStorageManager).AccessMap, loc)
  772. nodes, edges, err := gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  773. "node1:myotheredge:node2:mynewkind", false)
  774. if err != nil {
  775. t.Error(err)
  776. return
  777. }
  778. if len(nodes) != 1 || len(edges) != 1 {
  779. t.Error("Unexpected result:", nodes, edges)
  780. return
  781. }
  782. if !data.NodeCompare(edges[0], edge2, []string{data.NodeKey, data.NodeKind,
  783. data.EdgeEnd1Key, data.EdgeEnd1Kind, data.EdgeEnd1Role, data.EdgeEnd1Cascading,
  784. data.EdgeEnd2Key, data.EdgeEnd2Kind, data.EdgeEnd2Role, data.EdgeEnd2Cascading}) {
  785. t.Error("Edges should match:", edge2, edges[0])
  786. return
  787. }
  788. if !data.NodeCompare(nodes[0], node2, []string{data.NodeKey, data.NodeKind}) {
  789. t.Error("Nodes should match:", node2, nodes[0])
  790. return
  791. }
  792. // Now lookup from the other side
  793. nodes2, edges2, err := gm.Traverse("main", node2.Key(), node2.Kind(),
  794. "node2:myotheredge:node1:mykind", false)
  795. if err != nil {
  796. t.Error(err)
  797. return
  798. }
  799. if len(nodes2) != 1 || len(edges2) != 1 {
  800. t.Error("Unexpected result:", nodes2, edges2)
  801. return
  802. }
  803. if !data.NodeCompare(nodes2[0], node1, []string{data.NodeKey, data.NodeKind}) {
  804. t.Error("Nodes should match:", node1, nodes2[0])
  805. return
  806. }
  807. if !data.NodeCompare(edges2[0], edge2, []string{data.NodeKey, data.NodeKind}) {
  808. t.Error("Edges should match:", edge2, edges2[0])
  809. return
  810. }
  811. // Check that the correct ends have been set
  812. if edges2[0].End1Key() != node2.Key() {
  813. t.Error("Unexpected value in traversed edge")
  814. return
  815. } else if edges2[0].End1Kind() != node2.Kind() {
  816. t.Error("Unexpected value in traversed edge")
  817. return
  818. } else if edges2[0].End1Role() != "node2" {
  819. t.Error("Unexpected value in traversed edge")
  820. return
  821. } else if edges2[0].End1IsCascading() != false {
  822. t.Error("Unexpected value in traversed edge")
  823. return
  824. } else if edges2[0].End1IsCascadingLast() != false {
  825. t.Error("Unexpected value in traversed edge")
  826. return
  827. }
  828. if edges2[0].End2Key() != node1.Key() {
  829. t.Error("Unexpected value in traversed edge")
  830. return
  831. } else if edges2[0].End2Kind() != node1.Kind() {
  832. t.Error("Unexpected value in traversed edge")
  833. return
  834. } else if edges2[0].End2Role() != "node1" {
  835. t.Error("Unexpected value in traversed edge")
  836. return
  837. } else if edges2[0].End2IsCascading() != true {
  838. t.Error("Unexpected value in traversed edge")
  839. return
  840. } else if edges2[0].End2IsCascadingLast() != true {
  841. t.Error("Unexpected value in traversed edge")
  842. return
  843. }
  844. // Lookup from the other side getting all attributes
  845. nodes2, edges2, err = gm.Traverse("main", node2.Key(), node2.Kind(),
  846. "node2:myotheredge:node1:mykind", true)
  847. if err != nil {
  848. t.Error(err)
  849. return
  850. }
  851. if len(nodes2) != 1 || len(edges2) != 1 {
  852. t.Error("Unexpected result:", nodes2, edges2)
  853. return
  854. }
  855. if !data.NodeCompare(nodes2[0], node1, []string{data.NodeKey, data.NodeKind, data.NodeName}) {
  856. t.Error("Nodes should match:", node1, nodes2[0])
  857. return
  858. }
  859. if !data.NodeCompare(edges2[0], edge2, []string{data.NodeKey, data.NodeKind, data.NodeName}) {
  860. t.Error("Edges should match:", edge2, edges2[0])
  861. return
  862. }
  863. // Check that the correct ends have been set
  864. if edges2[0].End1Key() != node2.Key() {
  865. t.Error("Unexpected value in traversed edge")
  866. return
  867. } else if edges2[0].End1Kind() != node2.Kind() {
  868. t.Error("Unexpected value in traversed edge")
  869. return
  870. } else if edges2[0].End1Role() != "node2" {
  871. t.Error("Unexpected value in traversed edge")
  872. return
  873. } else if edges2[0].End1IsCascading() != false {
  874. t.Error("Unexpected value in traversed edge")
  875. return
  876. }
  877. if edges2[0].End2Key() != node1.Key() {
  878. t.Error("Unexpected value in traversed edge")
  879. return
  880. } else if edges2[0].End2Kind() != node1.Kind() {
  881. t.Error("Unexpected value in traversed edge")
  882. return
  883. } else if edges2[0].End2Role() != "node1" {
  884. t.Error("Unexpected value in traversed edge")
  885. return
  886. } else if edges2[0].End2IsCascading() != true {
  887. t.Error("Unexpected value in traversed edge")
  888. return
  889. }
  890. // Lookup from the original side with all attributes
  891. nodes, edges, err = gm.Traverse("main", node1.Key(), node1.Kind(),
  892. "node1:myotheredge:node2:mynewkind", true)
  893. if err != nil {
  894. t.Error(err)
  895. return
  896. }
  897. if len(nodes) != 1 || len(edges) != 1 {
  898. t.Error("Unexpected result:", nodes, edges)
  899. return
  900. }
  901. if !data.NodeCompare(nodes[0], node2, nil) {
  902. t.Error("Nodes should match:", node2, nodes[0])
  903. return
  904. }
  905. if !data.NodeCompare(edges[0], edge2, nil) {
  906. t.Error("Edges should match:", edge2, edges[0])
  907. return
  908. }
  909. nodes, edges, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  910. ":::", false)
  911. if err != nil {
  912. t.Error(err)
  913. return
  914. }
  915. if len(nodes) != 2 || len(edges) != 2 {
  916. t.Error("Unexpected result:", nodes, edges)
  917. return
  918. } else if nodes[0].Key() != node2.Key() || nodes[1].Key() != node2.Key() {
  919. t.Error("Unexpected result:", nodes, edges)
  920. return
  921. } else if edges[0].Key() != edge1.Key() || edges[1].Key() != edge2.Key() {
  922. t.Error("Unexpected result:", nodes, edges)
  923. return
  924. }
  925. nodes, edges, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  926. "node1::node2:mynewkind", false)
  927. if err != nil {
  928. t.Error(err)
  929. return
  930. }
  931. if len(nodes) != 2 || len(edges) != 2 {
  932. t.Error("Unexpected result:", nodes, edges)
  933. return
  934. } else if nodes[0].Key() != node2.Key() || nodes[1].Key() != node2.Key() {
  935. t.Error("Unexpected result:", nodes, edges)
  936. return
  937. } else if edges[0].Key() != edge1.Key() || edges[1].Key() != edge2.Key() {
  938. t.Error("Unexpected result:", nodes, edges)
  939. return
  940. }
  941. nodes, edges, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  942. "node1:myotheredge::mynewkind", false)
  943. if err != nil {
  944. t.Error(err)
  945. return
  946. }
  947. if len(nodes) != 1 || len(edges) != 1 {
  948. t.Error("Unexpected result:", nodes, edges)
  949. return
  950. } else if nodes[0].Key() != node2.Key() {
  951. t.Error("Unexpected result:", nodes, edges)
  952. return
  953. } else if edges[0].Key() != edge2.Key() {
  954. t.Error("Unexpected result:", nodes, edges)
  955. return
  956. }
  957. nodes, edges, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  958. "node2:myotheredge:node2:mynewkind", false)
  959. if err != nil {
  960. t.Error(err)
  961. return
  962. } else if len(nodes) != 0 || len(edges) != 0 {
  963. t.Error("Unexpected result:", nodes, edges)
  964. return
  965. }
  966. nodes, edges, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  967. "node1:myotheredge2:node2:mynewkind", false)
  968. if err != nil {
  969. t.Error(err)
  970. return
  971. } else if len(nodes) != 0 || len(edges) != 0 {
  972. t.Error("Unexpected result:", nodes, edges)
  973. return
  974. }
  975. nodes, edges, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  976. "node1:myotheredge:node3:mynewkind", false)
  977. if err != nil {
  978. t.Error(err)
  979. return
  980. } else if len(nodes) != 0 || len(edges) != 0 {
  981. t.Error("Unexpected result:", nodes, edges)
  982. return
  983. }
  984. nodes, edges, err = gm.TraverseMulti("main", node1.Key(), node1.Kind(),
  985. "node1:myotheredge:node2:mynewkind2", false)
  986. if err != nil {
  987. t.Error(err)
  988. return
  989. } else if len(nodes) != 0 || len(edges) != 0 {
  990. t.Error("Unexpected result:", nodes, edges)
  991. return
  992. }
  993. }