runtime_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  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 interpreter
  11. import (
  12. "errors"
  13. "fmt"
  14. "strings"
  15. "testing"
  16. "devt.de/krotik/eliasdb/eql/parser"
  17. "devt.de/krotik/eliasdb/graph"
  18. "devt.de/krotik/eliasdb/graph/data"
  19. "devt.de/krotik/eliasdb/graph/graphstorage"
  20. "devt.de/krotik/eliasdb/graph/util"
  21. "devt.de/krotik/eliasdb/hash"
  22. "devt.de/krotik/eliasdb/storage"
  23. )
  24. type testNodeInfo struct {
  25. *defaultNodeInfo
  26. }
  27. func (ni *testNodeInfo) SummaryAttributes(kind string) []string {
  28. return []string{"key"}
  29. }
  30. /*
  31. Helper function to run a search and check against a result.
  32. */
  33. func runSearch(query string, expectedResult string, rt parser.RuntimeProvider) error {
  34. ast, err := parser.ParseWithRuntime("test", query, rt)
  35. if err != nil {
  36. return err
  37. }
  38. res, err := ast.Runtime.Eval()
  39. if err != nil {
  40. return err
  41. }
  42. res.(*SearchResult).StableSort()
  43. if fmt.Sprint(res) != expectedResult {
  44. return errors.New(fmt.Sprint("Unexpected search result:", res, err))
  45. }
  46. return nil
  47. }
  48. func TestLookup(t *testing.T) {
  49. gm, _ := simpleGraph()
  50. rt := NewLookupRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  51. if err := runSearch("lookup mynode '000', '123'", `
  52. Labels: Mynode Key, Name
  53. Format: auto, auto
  54. Data: 1:n:key, 1:n:Name
  55. 000, Node0
  56. 123, Node1
  57. `[1:], rt); err != nil {
  58. t.Error(err)
  59. return
  60. }
  61. if err := runSearch("lookup mynode '000', '123' where true", `
  62. Labels: Mynode Key, Name
  63. Format: auto, auto
  64. Data: 1:n:key, 1:n:Name
  65. 000, Node0
  66. 123, Node1
  67. `[1:], rt); err != nil {
  68. t.Error(err)
  69. return
  70. }
  71. }
  72. func TestMultiKindTraversal(t *testing.T) {
  73. gm := multiKindGraph()
  74. rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  75. // Test simple traversal and setting of primary kind
  76. if err := runSearch("get mynode0 traverse :::", `
  77. Labels: Mynode0 Key, Name, Type, Key, Kind, Name
  78. Format: auto, auto, auto, auto, auto, auto
  79. Data: 1:n:key, 1:n:Name, 1:n:Type, 2:n:key, 2:n:kind, 2:n:name
  80. 000, Node0, root, 123, mynode1, <not set>
  81. 000, Node0, root, 456, mynode2, <not set>
  82. `[1:], rt); err != nil {
  83. t.Error(err)
  84. return
  85. }
  86. // Test simple traversal and access the edge
  87. if err := runSearch("get mynode0 traverse :myedge:: end show mynode0:key, 2:n:key, 2:e:key, myedge:name", `
  88. Labels: Mynode0 Key, Key, Key, Myedge Name
  89. Format: auto, auto, auto, auto
  90. Data: 1:n:key, 2:n:key, 2:e:key, 2:e:name
  91. 000, 123, abc1, edge:abc1
  92. 000, 456, abc2, edge:abc2
  93. `[1:], rt); err != nil {
  94. t.Error(err)
  95. return
  96. }
  97. // Test primary kind
  98. ast, err := parser.ParseWithRuntime("test", "get mynode0 traverse ::: end primary mynode2", rt)
  99. if err != nil {
  100. t.Error(err)
  101. return
  102. }
  103. res, err := ast.Runtime.Eval()
  104. if err != nil {
  105. t.Error(err)
  106. return
  107. }
  108. if pk := res.(*SearchResult).ResPrimaryKind; pk != "mynode2" {
  109. t.Error("Unexpected primary kind:", pk)
  110. return
  111. }
  112. ast, err = parser.ParseWithRuntime("test", "get mynode0 traverse ::: end primary bla", rt)
  113. if err != nil {
  114. t.Error(err)
  115. return
  116. }
  117. _, err = ast.Runtime.Eval()
  118. if err.Error() != "EQL error in test: Unknown node kind (bla) (Line:1 Pos:38)" {
  119. t.Error(err)
  120. return
  121. }
  122. }
  123. func TestErrors(t *testing.T) {
  124. gm, mgs := simpleGraph()
  125. rt := NewGetRuntimeProvider("test", "main", gm, NewDefaultNodeInfo(gm))
  126. // Test simple eval error
  127. generalProviderMap[parser.NodeGET] = invalidRuntimeInst
  128. if err := runSearch("get mynode", "", rt); err.Error() !=
  129. "EQL error in test: Invalid construct (get) (Line:1 Pos:1)" {
  130. t.Error(err)
  131. delete(generalProviderMap, parser.NodeGET)
  132. return
  133. }
  134. invast, err := parser.ParseWithRuntime("test", "get mynode", rt)
  135. if err != nil {
  136. t.Error(err)
  137. return
  138. }
  139. _, err = invast.Runtime.(*invalidRuntime).CondEval(nil, nil)
  140. if err.Error() != "EQL error in test: Invalid construct (get) (Line:1 Pos:1)" {
  141. t.Error(err)
  142. return
  143. }
  144. delete(generalProviderMap, parser.NodeGET)
  145. // Test validation errors
  146. if err := runSearch("get mynode show x traverse :::", "", rt); err.Error() !=
  147. "EQL error in test: Invalid construct (traversals must be before show clause) (Line:1 Pos:19)" {
  148. t.Error(err)
  149. return
  150. }
  151. if err := runSearch("get mynode traverse ::", "", rt); err.Error() !=
  152. "EQL error in test: Invalid traversal spec (::) (Line:1 Pos:12)" {
  153. t.Error(err)
  154. return
  155. }
  156. if err := runSearch("get mynode show mynode0:bla", "", rt); err.Error() !=
  157. "EQL error in test: Invalid construct (Cannot determine data position for kind: mynode0) (Line:1 Pos:17)" {
  158. t.Error(err)
  159. return
  160. }
  161. if err := runSearch("get mynode show 0:n:bla", "", rt); err.Error() !=
  162. "EQL error in test: Invalid construct (Invalid data index: 0:n:bla (index must be greater than 0)) (Line:1 Pos:17)" {
  163. t.Error(err)
  164. return
  165. }
  166. if err := runSearch("get mynode show a:n:bla", "", rt); err.Error() !=
  167. "EQL error in test: Invalid construct (Invalid data index: a:n:bla (strconv.Atoi: parsing \"a\": invalid syntax)) (Line:1 Pos:17)" {
  168. t.Error(err)
  169. return
  170. }
  171. if err := runSearch("get mynode show 1:b:bla", "", rt); err.Error() !=
  172. "EQL error in test: Invalid construct (Invalid data source 'b' (either n - Node or e - Edge)) (Line:1 Pos:17)" {
  173. t.Error(err)
  174. return
  175. }
  176. if err := runSearch("get mynode show 2:n:bla", "", rt); err.Error() !=
  177. "EQL error in test: Invalid column data spec (Data index out of range: 2) (Line:1 Pos:17)" {
  178. t.Error(err)
  179. return
  180. }
  181. // Test datastore errors
  182. msm := mgs.StorageManager("main"+"mynode"+graph.StorageSuffixNodes, false).(*storage.MemoryStorageManager)
  183. msm.AccessMap[1] = storage.AccessCacheAndFetchError
  184. if err := runSearch("get mynode", "", rt); err.Error() !=
  185. "GraphError: Failed to access graph storage component (Slot not found (mystorage/mainmynode.nodes - Location:1))" {
  186. t.Error(err)
  187. return
  188. }
  189. delete(msm.AccessMap, 1)
  190. // Test nextStartKey error
  191. msm.AccessMap[1] = storage.AccessCacheAndFetchSeriousError
  192. if _, err := rt.nextStartKey(); err.Error() != "GraphError: Could not read graph information (Record is already in-use (? - ))" {
  193. t.Error(err)
  194. return
  195. }
  196. delete(msm.AccessMap, 1)
  197. // Test FetchNodePart error
  198. msm.AccessMap[3] = storage.AccessCacheAndFetchError
  199. if err := runSearch("get mynode", "", rt); err.Error() !=
  200. "GraphError: Could not read graph information (Slot not found (mystorage/mainmynode.nodes - Location:3))" {
  201. t.Error(err)
  202. return
  203. }
  204. delete(msm.AccessMap, 3)
  205. // Test TraverseMulti errors
  206. msm = mgs.StorageManager("main"+"mynewnode"+graph.StorageSuffixNodes, false).(*storage.MemoryStorageManager)
  207. msm.AccessMap[5] = storage.AccessCacheAndFetchError // Node 3 attribute lookup
  208. if err := runSearch("get mynode traverse :::mynewnode traverse :::mynewnode end end", "", rt); err.Error() !=
  209. "GraphError: Could not read graph information (Slot not found (mystorage/mainmynewnode.nodes - Location:5))" {
  210. t.Error(err)
  211. return
  212. }
  213. delete(msm.AccessMap, 5)
  214. msm.AccessMap[11] = storage.AccessCacheAndFetchError // Traversal spec error
  215. if err := runSearch("get mynode traverse :::mynewnode traverse :::mynewnode end end", "", rt); err.Error() !=
  216. "GraphError: Could not read graph information (Slot not found (mystorage/mainmynewnode.nodes - Location:11))" {
  217. t.Error(err)
  218. return
  219. }
  220. delete(msm.AccessMap, 11)
  221. msm = mgs.StorageManager("main"+"myedge"+graph.StorageSuffixEdges, false).(*storage.MemoryStorageManager)
  222. msmtree, _ := hash.LoadHTree(msm, msm.Root(graph.RootIDNodeHTree))
  223. nm := util.NewNamesManager(mgs.MainDB())
  224. _, slot, _ := msmtree.GetValueAndLocation([]byte(graph.PrefixNSAttr + "abc2" + nm.Encode32("name", false)))
  225. msm.AccessMap[slot] = storage.AccessCacheAndFetchError // Edge attribute
  226. if err := runSearch("get mynode traverse :::mynewnode end show 1:n:key, 2:n:key, 2:e:key, 2:e:name", "", rt); strings.HasPrefix(err.Error(),
  227. "GraphError: Could not read graph information (Slot not found (mystorage/mainmynewnode.nodes - ") {
  228. t.Error(err)
  229. return
  230. }
  231. delete(msm.AccessMap, slot)
  232. // Test unknown ast node
  233. ast, err := parser.ParseWithRuntime("test", "get mynode show x", rt)
  234. if err != nil {
  235. t.Error(err)
  236. return
  237. }
  238. unknownASTNode := &parser.ASTNode{}
  239. unknownASTNode.Name = "Unknown"
  240. unknownASTNode.Token = &parser.LexToken{}
  241. ast.Children[1].Children = append(ast.Children[1].Children, unknownASTNode)
  242. if err = ast.Runtime.Validate(); err.Error() != "EQL error in test: Invalid construct (Unknown)" {
  243. t.Error(err)
  244. return
  245. }
  246. ast, err = parser.ParseWithRuntime("test", "get mynode show x as y", rt)
  247. if err != nil {
  248. t.Error(err)
  249. return
  250. }
  251. ast.Children[1].Children[0].Children = append(ast.Children[1].Children[0].Children, unknownASTNode)
  252. if err = ast.Runtime.Validate(); err.Error() != "EQL error in test: Invalid construct (Unknown)" {
  253. t.Error(err)
  254. return
  255. }
  256. ast, err = parser.ParseWithRuntime("test", "get mynode traverse ::: traverse ::: end end", rt)
  257. if err != nil {
  258. t.Error(err)
  259. return
  260. }
  261. ast.Children[1].Children[1].Children = append(ast.Children[1].Children[1].Children, unknownASTNode)
  262. if err = ast.Runtime.Validate(); err.Error() != "EQL error in test: Invalid construct (Unknown)" {
  263. t.Error(err)
  264. return
  265. }
  266. ast, err = parser.ParseWithRuntime("test", "get mynode", rt)
  267. if err != nil {
  268. t.Error(err)
  269. return
  270. }
  271. ast.Children = append(ast.Children, unknownASTNode)
  272. if err = ast.Runtime.Validate(); err.Error() != "EQL error in test: Invalid construct (Unknown)" {
  273. t.Error(err)
  274. return
  275. }
  276. ast.Children = ast.Children[:1]
  277. // Test add row errors
  278. if err = ast.Runtime.Validate(); err != nil {
  279. t.Error(err)
  280. return
  281. }
  282. ast.Runtime.(*getRuntime).rtp.colData[0] = "uu"
  283. res := newSearchResult(ast.Runtime.(*getRuntime).rtp.eqlRuntimeProvider, "")
  284. if err = res.addRow([]data.Node{data.NewGraphNode()}, nil); err.Error() !=
  285. "EQL result error in test: Invalid column data spec (Column data spec must have 3 items: uu)" {
  286. t.Error(err)
  287. return
  288. }
  289. ast.Runtime.(*getRuntime).rtp.colData[0] = "0:p:test"
  290. res = newSearchResult(ast.Runtime.(*getRuntime).rtp.eqlRuntimeProvider, "")
  291. if err = res.addRow([]data.Node{data.NewGraphNode()}, nil); err.Error() !=
  292. "EQL result error in test: Invalid column data spec (Invalid data source 'p' (either n - Node or e - Edge))" {
  293. t.Error(err)
  294. return
  295. }
  296. ast.Runtime.(*getRuntime).rtp.colData[0] = "0:e:test"
  297. allowMultiEval = true
  298. if _, err = ast.Runtime.Eval(); err.Error() !=
  299. "EQL result error in test: Invalid column data spec (Invalid data index: 0:e:test)" {
  300. t.Error(err)
  301. return
  302. }
  303. allowMultiEval = false
  304. ast.Runtime.(*getRuntime).rtp.colData[0] = "1:e:test"
  305. i := 0
  306. oldNextStartKey := ast.Runtime.(*getRuntime).rtp.nextStartKey
  307. ast.Runtime.(*getRuntime).rtp.nextStartKey = func() (string, error) {
  308. i++
  309. if i == 3 {
  310. return "", errors.New("testerror")
  311. }
  312. return "000", nil
  313. }
  314. allowMultiEval = true
  315. if _, err = ast.Runtime.Eval(); err.Error() != "testerror" {
  316. t.Error(err)
  317. return
  318. }
  319. allowMultiEval = false
  320. ast.Runtime.(*getRuntime).rtp.nextStartKey = oldNextStartKey
  321. // Test valid result
  322. r, err := ast.Runtime.Eval()
  323. if err != nil || fmt.Sprint(r) != `
  324. Labels: Mynode Key, Name
  325. Format: auto, auto
  326. Data: 1:n:key, 1:n:Name
  327. 123, Node1
  328. 000, Node0
  329. `[1:] {
  330. t.Error(r, err)
  331. return
  332. }
  333. }
  334. func TestBasicTraversalAndShow(t *testing.T) {
  335. gm, _ := simpleGraph()
  336. rt := NewGetRuntimeProvider("test", "main", gm, &testNodeInfo{&defaultNodeInfo{gm}})
  337. // Test unknown initial kind
  338. ast, err := parser.ParseWithRuntime("test", "get mymissingnode", rt)
  339. if err != nil {
  340. t.Error(err)
  341. return
  342. }
  343. if _, err := ast.Runtime.Eval(); err.Error() !=
  344. "EQL error in test: Unknown node kind (mymissingnode) (Line:1 Pos:5)" {
  345. t.Error(err)
  346. return
  347. }
  348. // Test simple query with traversals
  349. ast, err = parser.ParseWithRuntime("test", `
  350. get mynode
  351. traverse :::mynewnode
  352. traverse :::mynewnode
  353. end
  354. end
  355. traverse :::mynewnode
  356. end`, rt)
  357. if err != nil {
  358. t.Error(err)
  359. return
  360. }
  361. // Expected result explanation:
  362. // Row 1 - Node 000 is alone so no traversals possible
  363. // Row 2, 3, 4, 5 - there are two edges from 123 to 456 so possible traversals are doubled
  364. // 456 is also connected to 789 and 789-2
  365. // Node 123 has also a direct connection to xxx
  366. // 6 and 7 are duplicated because of the two edges from 123 to 456
  367. // 8 is the last combination of twice traversing from 123 to xxx
  368. expectedResult := `
  369. Labels: Mynode Key, Mynewnode Key, Mynewnode Key, Mynewnode Key
  370. Format: auto, auto, auto, auto
  371. Data: 1:n:key, 2:n:key, 3:n:key, 4:n:key
  372. 123, 456, 789-2, 456
  373. 123, 456, 789-2, 456
  374. 123, 456, 789, 456
  375. 123, 456, 789, 456
  376. 123, xxx ⌘, 789, 456
  377. 123, xxx ⌘, 789, 456
  378. 123, xxx ⌘, 789, xxx ⌘
  379. `[1:]
  380. res, err := ast.Runtime.Eval()
  381. if err != nil {
  382. t.Error(err)
  383. return
  384. }
  385. res.(*SearchResult).StableSort()
  386. if fmt.Sprint(res) != expectedResult {
  387. t.Error("Unexpected search result:", res, err)
  388. return
  389. }
  390. // Test showing empty traversals
  391. grt := ast.Runtime.(*getRuntime).rtp
  392. ast.Runtime.Validate()
  393. allowMultiEval = true
  394. grt.eqlRuntimeProvider.allowNilTraversal = true
  395. res, err = ast.Runtime.Eval()
  396. if err != nil {
  397. t.Error(err)
  398. return
  399. }
  400. res.(*SearchResult).StableSort()
  401. expectedResult = `
  402. Labels: Mynode Key, Mynewnode Key, Mynewnode Key, Mynewnode Key
  403. Format: auto, auto, auto, auto
  404. Data: 1:n:key, 2:n:key, 3:n:key, 4:n:key
  405. 000, <not set>, <not set>, <not set>
  406. 123, 456, 789-2, 456
  407. 123, 456, 789-2, 456
  408. 123, 456, 789, 456
  409. 123, 456, 789, 456
  410. 123, xxx ⌘, 789, 456
  411. 123, xxx ⌘, 789, 456
  412. 123, xxx ⌘, 789, xxx ⌘
  413. `[1:]
  414. if fmt.Sprint(res) != expectedResult {
  415. t.Error("Unexpected search result:", res, err)
  416. return
  417. }
  418. allowMultiEval = false
  419. // Test showing the traversal attributes in reverse order
  420. ast, err = parser.ParseWithRuntime("test", `
  421. get mynode
  422. traverse :::mynewnode
  423. traverse :::mynewnode
  424. end
  425. end
  426. show 3:n:key AS key1,
  427. 2:n:key FORMAT keystring1,
  428. key as key3 FORMAT x`, rt)
  429. if err != nil {
  430. t.Error(err)
  431. return
  432. }
  433. // Expected result explanation:
  434. // Row 1, 2, 3, 4 - there are two edges from 123 to 456 so possible traversals are doubled
  435. // 456 is also connected to 789 and 789-2
  436. // Row 5 - Node 123 has also a direct connection to xxx
  437. // Row 6 - Node 000 is alone so no traversals possible
  438. expectedResult = `
  439. Labels: key1, Key, key3
  440. Format: auto, keystring1, x
  441. Data: 3:n:key, 2:n:key, 1:n:key
  442. 789-2, 456, 123
  443. 789-2, 456, 123
  444. 789, 456, 123
  445. 789, 456, 123
  446. 789, xxx ⌘, 123
  447. `[1:]
  448. res, err = ast.Runtime.Eval()
  449. if err != nil {
  450. t.Error(err)
  451. return
  452. }
  453. res.(*SearchResult).StableSort()
  454. if fmt.Sprint(res) != expectedResult {
  455. t.Error("Unexpected search result:", res, err)
  456. return
  457. }
  458. }
  459. func simpleGraph() (*graph.Manager, *graphstorage.MemoryGraphStorage) {
  460. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  461. gm := graph.NewGraphManager(mgs)
  462. constructEdge := func(key string, node1 data.Node, node2 data.Node) data.Edge {
  463. edge := data.NewGraphEdge()
  464. edge.SetAttr("key", key)
  465. edge.SetAttr("kind", "myedge")
  466. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  467. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  468. edge.SetAttr(data.EdgeEnd1Role, "node1")
  469. edge.SetAttr(data.EdgeEnd1Cascading, true)
  470. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  471. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  472. edge.SetAttr(data.EdgeEnd2Role, "node2")
  473. edge.SetAttr(data.EdgeEnd2Cascading, false)
  474. edge.SetAttr(data.NodeName, "Edge1"+key)
  475. return edge
  476. }
  477. node0 := data.NewGraphNode()
  478. node0.SetAttr("key", "000")
  479. node0.SetAttr("kind", "mynode")
  480. node0.SetAttr("Name", "Node0")
  481. gm.StoreNode("main", node0)
  482. node1 := data.NewGraphNode()
  483. node1.SetAttr("key", "123")
  484. node1.SetAttr("kind", "mynode")
  485. node1.SetAttr("Name", "Node1")
  486. gm.StoreNode("main", node1)
  487. node2 := data.NewGraphNode()
  488. node2.SetAttr("key", "456")
  489. node2.SetAttr("kind", "mynewnode")
  490. node2.SetAttr("Na me", "Node2")
  491. gm.StoreNode("main", node2)
  492. node3 := data.NewGraphNode()
  493. node3.SetAttr("key", "789")
  494. node3.SetAttr("kind", "mynewnode")
  495. node3.SetAttr("Name", "Node3")
  496. gm.StoreNode("main", node3)
  497. node33 := data.NewGraphNode()
  498. node33.SetAttr("key", "789-2")
  499. node33.SetAttr("kind", "mynewnode")
  500. node33.SetAttr("Name", "Node3-2")
  501. gm.StoreNode("main", node33)
  502. node4 := data.NewGraphNode()
  503. node4.SetAttr("key", "xxx \xe2\x8c\x98")
  504. node4.SetAttr("kind", "mynewnode")
  505. node4.SetAttr("Nam \xe2\x8c\x98 e", "Node4")
  506. gm.StoreNode("main", node4)
  507. gm.StoreEdge("main", constructEdge("abc2", node1, node2))
  508. gm.StoreEdge("main", constructEdge("abc3", node1, node2))
  509. gm.StoreEdge("main", constructEdge("abc1", node2, node3))
  510. gm.StoreEdge("main", constructEdge("abc4", node2, node33))
  511. gm.StoreEdge("main", constructEdge("abc0", node3, node4))
  512. gm.StoreEdge("main", constructEdge("abc99", node4, node1))
  513. return gm, mgs.(*graphstorage.MemoryGraphStorage)
  514. }
  515. func multiKindGraph() *graph.Manager {
  516. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  517. gm := graph.NewGraphManager(mgs)
  518. constructEdge := func(key string, node1 data.Node, node2 data.Node) data.Edge {
  519. edge := data.NewGraphEdge()
  520. edge.SetAttr("key", key)
  521. edge.SetAttr("kind", "myedge")
  522. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  523. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  524. edge.SetAttr(data.EdgeEnd1Role, "src")
  525. edge.SetAttr(data.EdgeEnd1Cascading, true)
  526. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  527. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  528. edge.SetAttr(data.EdgeEnd2Role, "dest")
  529. edge.SetAttr(data.EdgeEnd2Cascading, false)
  530. edge.SetAttr(data.NodeName, "edge:"+key)
  531. return edge
  532. }
  533. node0 := data.NewGraphNode()
  534. node0.SetAttr("key", "000")
  535. node0.SetAttr("kind", "mynode0")
  536. node0.SetAttr("Name", "Node0")
  537. node0.SetAttr("Type", "root")
  538. gm.StoreNode("main", node0)
  539. node1 := data.NewGraphNode()
  540. node1.SetAttr("key", "123")
  541. node1.SetAttr("kind", "mynode1")
  542. gm.StoreNode("main", node1)
  543. node2 := data.NewGraphNode()
  544. node2.SetAttr("key", "456")
  545. node2.SetAttr("kind", "mynode2")
  546. gm.StoreNode("main", node2)
  547. node3 := data.NewGraphNode()
  548. node3.SetAttr("key", "789")
  549. node3.SetAttr("kind", "mynode3")
  550. gm.StoreNode("main", node3)
  551. gm.StoreEdge("main", constructEdge("abc1", node0, node1))
  552. gm.StoreEdge("main", constructEdge("abc2", node0, node2))
  553. gm.StoreEdge("main", constructEdge("abc3", node2, node3))
  554. return gm
  555. }
  556. func dataNodes() *graph.Manager {
  557. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  558. gm := graph.NewGraphManager(mgs)
  559. node0 := data.NewGraphNode()
  560. node0.SetAttr("key", "000")
  561. node0.SetAttr("kind", "mynode")
  562. node0.SetAttr("name", "Node0")
  563. node0.SetAttr("type", "type1")
  564. gm.StoreNode("main", node0)
  565. node1 := data.NewGraphNode()
  566. node1.SetAttr("key", "123")
  567. node1.SetAttr("kind", "mynode")
  568. node1.SetAttr("name", "Node1")
  569. node1.SetAttr("nested.nest1.nest2.atom1", 1.46)
  570. node1.SetAttr("type", "type1")
  571. gm.StoreNode("main", node1)
  572. node2 := data.NewGraphNode()
  573. node2.SetAttr("key", "456")
  574. node2.SetAttr("kind", "mynode")
  575. node2.SetAttr("name", "Node2")
  576. node2.SetAttr("type", "type2")
  577. node2.SetAttr("nested", map[string]interface{}{
  578. "nest1": map[string]interface{}{
  579. "nest2": map[string]interface{}{
  580. "atom1": 1.45,
  581. },
  582. },
  583. })
  584. gm.StoreNode("main", node2)
  585. return gm
  586. }