graphmanager_nodes_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  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. "strconv"
  15. "strings"
  16. "testing"
  17. "devt.de/krotik/eliasdb/graph/data"
  18. "devt.de/krotik/eliasdb/graph/graphstorage"
  19. "devt.de/krotik/eliasdb/graph/util"
  20. "devt.de/krotik/eliasdb/hash"
  21. "devt.de/krotik/eliasdb/storage"
  22. )
  23. func TestSimpleNodeStorage(t *testing.T) {
  24. if !RunDiskStorageTests {
  25. return
  26. }
  27. dgs, err := graphstorage.NewDiskGraphStorage(GraphManagerTestDBDir2, false)
  28. if err != nil {
  29. t.Error(err)
  30. return
  31. }
  32. gm := newGraphManagerNoRules(dgs)
  33. node1 := data.NewGraphNode()
  34. node1.SetAttr("key", "123")
  35. node1.SetAttr("kind", "mykind")
  36. node1.SetAttr("Name", "Some name")
  37. node1.SetAttr("To Delete", "Some data")
  38. if cnt := gm.NodeCount("mykind"); cnt != 0 {
  39. t.Error("Invalid node count:", cnt)
  40. return
  41. }
  42. if err := gm.StoreNode("main", node1); err != nil {
  43. t.Error(err)
  44. return
  45. }
  46. if cnt := gm.NodeCount("mykind"); cnt != 1 {
  47. t.Error("Invalid node count:", cnt)
  48. return
  49. }
  50. if gm.IsValidAttr("123") {
  51. t.Error("123 should not be a valid attribute")
  52. }
  53. if !gm.IsValidAttr("Name") {
  54. t.Error("Name should be a valid attribute")
  55. }
  56. if !gm.IsValidAttr(data.NodeKey) {
  57. t.Error("key should be a valid attribute")
  58. }
  59. if !gm.IsValidAttr(data.NodeKind) {
  60. t.Error("kind should be a valid attribute")
  61. }
  62. if !gm.IsValidAttr(data.EdgeEnd1Cascading) {
  63. t.Error("end1cascading should be a valid attribute")
  64. }
  65. node2 := data.NewGraphNode()
  66. node2.SetAttr("key", "456")
  67. node2.SetAttr("kind", "mykind")
  68. node2.SetAttr("Name", "Node2")
  69. node2.SetAttr("Data", "word1, word2, word3!")
  70. node1 = data.NewGraphNode()
  71. node1.SetAttr("key", "123")
  72. node1.SetAttr("kind", "mykind")
  73. node1.SetAttr("Name", "Some new name")
  74. node1.SetAttr("Data", "word4, word5, word6!")
  75. if err := gm.StoreNode("main", node1); err != nil {
  76. t.Error(err)
  77. return
  78. }
  79. if err := gm.StoreNode("main", node2); err != nil {
  80. t.Error(err)
  81. return
  82. }
  83. if cnt := gm.NodeCount("mykind"); cnt != 2 {
  84. t.Error("Invalid node count:", cnt)
  85. return
  86. }
  87. // Get only part of a node
  88. fnode1, err := gm.FetchNodePart("main", "123", "mykind", []string{"Data"})
  89. if err != nil {
  90. t.Error(err)
  91. return
  92. }
  93. // Check we got only the attributes we asked for
  94. if res := len(fnode1.Data()); res != 3 {
  95. t.Error("Unexpected number of attributes:", res)
  96. return
  97. }
  98. if fnode1.Key() != "123" || fnode1.Kind() != "mykind" {
  99. t.Error("Unexpected result:", fnode1)
  100. return
  101. }
  102. if fnode1.Attr("Data") != "word4, word5, word6!" {
  103. t.Error("Unexpected result:", fnode1)
  104. return
  105. }
  106. // Get the full node
  107. fnode2, err := gm.FetchNode("main", "123", "mykind")
  108. if err != nil {
  109. t.Error(err)
  110. return
  111. }
  112. // Check we got everything back
  113. if res := len(fnode2.Data()); res != 4 {
  114. t.Error("Unexpected number of attributes:", res)
  115. return
  116. }
  117. if fnode2.Key() != "123" || fnode2.Kind() != "mykind" {
  118. t.Error("Unexpected result:", fnode1)
  119. return
  120. }
  121. if fnode2.Attr("Name") != "Some new name" {
  122. t.Error("Unexpected result:", fnode1)
  123. return
  124. }
  125. if fnode2.Attr("Data") != "word4, word5, word6!" {
  126. t.Error("Unexpected result:", fnode1)
  127. return
  128. }
  129. dgs.Close()
  130. // Check that we can do the lookup with a new graph storage
  131. dgs2, err := graphstorage.NewDiskGraphStorage(GraphManagerTestDBDir2, false)
  132. if err != nil {
  133. t.Error(err)
  134. return
  135. }
  136. gm2 := newGraphManagerNoRules(dgs2)
  137. // Do an index lookup
  138. iq, err := gm2.NodeIndexQuery("main", "mykind")
  139. if err != nil {
  140. t.Error(err)
  141. return
  142. }
  143. res, err := iq.LookupWord("Data", "word5")
  144. if err != nil {
  145. t.Error(err)
  146. return
  147. }
  148. if fmt.Sprint(res) != "map[123:[2]]" {
  149. t.Error("Unexpected result:", res)
  150. return
  151. }
  152. fnode3, err := gm2.FetchNode("main", "123", "mykind")
  153. if err != nil {
  154. t.Error(err)
  155. return
  156. }
  157. // Check we got everything back
  158. if res := len(fnode3.Data()); res != 4 {
  159. t.Error("Unexpected number of attributes:", res)
  160. return
  161. }
  162. res2, err := iq.LookupPhrase("Data", "-....word5 ...word6")
  163. if err != nil {
  164. t.Error(err)
  165. return
  166. }
  167. if fmt.Sprint(res2) != "[123]" {
  168. t.Error("Unexpected result:", res)
  169. return
  170. }
  171. // Delete the nodes
  172. fnode4, err := gm2.RemoveNode("main", "123", "mykind")
  173. if err != nil {
  174. t.Error(err)
  175. return
  176. }
  177. if res := len(fnode4.Data()); res != 4 {
  178. t.Error("Unexpected number of attributes:", res)
  179. return
  180. }
  181. // Check that the node no longer exists
  182. fnode4, err = gm2.FetchNode("main", "123", "mykind")
  183. if err != nil || fnode4 != nil {
  184. t.Error("Unexpected lookup result:", fnode4, err)
  185. return
  186. }
  187. if cnt := gm2.NodeCount("mykind"); cnt != 1 {
  188. t.Error("Invalid node count:", cnt)
  189. return
  190. }
  191. _, err = gm2.RemoveNode("main", "456", "mykind")
  192. if err != nil {
  193. t.Error(err)
  194. return
  195. }
  196. if cnt := gm2.NodeCount("mykind"); cnt != 0 {
  197. t.Error("Invalid node count:", cnt)
  198. return
  199. }
  200. // Check that all datastructures are empty
  201. tree, _, _ := gm2.getNodeStorageHTree("main", "mykind", false)
  202. it := hash.NewHTreeIterator(tree)
  203. if it.HasNext() {
  204. t.Error("Node storage tree should be empty at this point")
  205. return
  206. }
  207. tree, _ = gm2.getNodeIndexHTree("main", "mykind", false)
  208. it = hash.NewHTreeIterator(tree)
  209. if it.HasNext() {
  210. t.Error("Node storage tree should be empty at this point")
  211. return
  212. }
  213. dgs2.Close()
  214. }
  215. func TestSimpleNodeUpdate(t *testing.T) {
  216. if !RunDiskStorageTests {
  217. return
  218. }
  219. dgs, err := graphstorage.NewDiskGraphStorage(GraphManagerTestDBDir2, false)
  220. if err != nil {
  221. t.Error(err)
  222. return
  223. }
  224. gm := newGraphManagerNoRules(dgs)
  225. node1 := data.NewGraphNode()
  226. node1.SetAttr("key", "nodeToUpdate")
  227. node1.SetAttr("kind", "nodeupdatekind")
  228. // Check that an update can do an actual insert
  229. err = gm.UpdateNode("main", node1)
  230. if err != nil {
  231. t.Error(err)
  232. return
  233. }
  234. // Check that we can lookup the node just by asking for the kind attribute
  235. n, err := gm.FetchNodePart("main", node1.Key(), node1.Kind(), []string{"kind"})
  236. if err != nil {
  237. t.Error(err)
  238. }
  239. if !data.NodeCompare(node1, n, nil) {
  240. t.Error("Nodes should match")
  241. return
  242. }
  243. node1.SetAttr("Name", "Some name")
  244. node1.SetAttr("Name2", "Some name2")
  245. node1.SetAttr("Name3", "Some name3")
  246. node1.SetAttr("Name4", "Some name4")
  247. err = gm.UpdateNode("main", node1)
  248. if err != nil {
  249. t.Error(err)
  250. return
  251. }
  252. fetchedNode, _ := gm.FetchNode("main", "nodeToUpdate", "nodeupdatekind")
  253. if !data.NodeCompare(node1, fetchedNode, nil) {
  254. t.Error("Node should have been stored completely")
  255. return
  256. }
  257. node2 := data.NewGraphNode()
  258. node2.SetAttr("key", "nodeToUpdate")
  259. node2.SetAttr("kind", "nodeupdatekind")
  260. node2.SetAttr("Name", "Some new name")
  261. node2.SetAttr("NewField", "Some new field value")
  262. err = gm.UpdateNode("main", node2)
  263. if err != nil {
  264. t.Error(err)
  265. return
  266. }
  267. fetchedNode, _ = gm.FetchNode("main", "nodeToUpdate", "nodeupdatekind")
  268. if len(fetchedNode.Data()) != len(node1.Data())+1 {
  269. t.Error("Unexpected number of attributes")
  270. return
  271. }
  272. if !data.NodeCompare(data.NodeMerge(node1, node2), fetchedNode, nil) {
  273. t.Error("Node should have been stored completely")
  274. return
  275. }
  276. dgs.Close()
  277. }
  278. func TestSimpleNodeStorageErrorCases(t *testing.T) {
  279. mgs := graphstorage.NewMemoryGraphStorage("mystorage")
  280. gm := newGraphManagerNoRules(mgs)
  281. if _, err := gm.FetchNodePart("in valid", "testkey", "testkind", nil); err.Error() !=
  282. "GraphError: Invalid data (Partition name in valid is not alphanumeric - can only contain [a-zA-Z0-9_])" {
  283. t.Error("Unexpected error:", err)
  284. return
  285. }
  286. if res, err := gm.FetchNodePart("testpart", "testkey", "testkind", nil); res != nil || err != nil {
  287. t.Error("Unexpected result:", res, err)
  288. return
  289. }
  290. if _, err := gm.NodeIndexQuery("in valid", "testkind"); err.Error() !=
  291. "GraphError: Invalid data (Partition name in valid is not alphanumeric - can only contain [a-zA-Z0-9_])" {
  292. t.Error("Unexpected error:", err)
  293. return
  294. }
  295. if _, err := gm.NodeIndexQuery("testpart", "testkind-"); err.Error() !=
  296. "GraphError: Invalid data (Node kind testkind- is not alphanumeric - can only contain [a-zA-Z0-9_])" {
  297. t.Error("Unexpected error:", err)
  298. return
  299. }
  300. if _, err := gm.RemoveNode("in valid", "testkey", "testkind"); err.Error() !=
  301. "GraphError: Invalid data (Partition name in valid is not alphanumeric - can only contain [a-zA-Z0-9_])" {
  302. t.Error("Unexpected error:", err)
  303. return
  304. }
  305. if res, err := gm.RemoveNode("testpart", "testkey", "testkind"); res != nil || err != nil {
  306. t.Error("Unexpected result:", res, err)
  307. return
  308. }
  309. if res, err := gm.NodeIndexQuery("testpart", "testkind"); res != nil || err != nil {
  310. t.Error("Unexpected result:", res, err)
  311. return
  312. }
  313. if res, err := gm.NodeIndexQuery("testpart", "testkind"); res != nil || err != nil {
  314. t.Error("Unexpected result:", res, err)
  315. return
  316. }
  317. attTree, valTree, _ := gm.getNodeStorageHTree("testpart", "testkind", true)
  318. if res, err := gm.readNode("123", "testkind", nil, attTree, valTree); res != nil || err != nil {
  319. t.Error("Unexpected result:", res, err)
  320. return
  321. }
  322. node1 := data.NewGraphNode()
  323. node1.SetAttr("key", "123")
  324. node1.SetAttr("kind", "testkind")
  325. node1.SetAttr("Name", "Some name")
  326. if err := gm.StoreNode("testpart", node1); err != nil {
  327. t.Error(err)
  328. return
  329. }
  330. msm := mgs.StorageManager("testpart"+"testkind"+StorageSuffixNodes,
  331. true).(*storage.MemoryStorageManager)
  332. msm.AccessMap[4] = storage.AccessCacheAndFetchError
  333. if res, err := gm.readNode("123", "testkind", nil, attTree, valTree); res != nil ||
  334. err.Error() != "GraphError: Could not read graph information "+
  335. "(Slot not found (mystorage/testparttestkind.nodes - Location:4))" {
  336. t.Error("Unexpected result:", res, err)
  337. return
  338. }
  339. if res, err := gm.writeNode(node1, true, attTree, valTree, nodeAttributeFilter); res != nil ||
  340. err.Error() != "GraphError: Could not read graph information "+
  341. "(Slot not found (mystorage/testparttestkind.nodes - Location:4))" {
  342. t.Error("Unexpected result:", res, err)
  343. return
  344. }
  345. if res, err := gm.RemoveNode("testpart", "123", "testkind"); res != nil ||
  346. err.Error() != "GraphError: Could not write graph information "+
  347. "(Slot not found (mystorage/testparttestkind.nodes - Location:4))" {
  348. t.Error("Unexpected result:", res, err)
  349. return
  350. }
  351. delete(msm.AccessMap, 4)
  352. if res, err := gm.RemoveNode("testpart", "1234", "testkind"); res != nil || err != nil {
  353. t.Error("Unexpected result:", res, err)
  354. return
  355. }
  356. msm.AccessMap[3] = storage.AccessCacheAndFetchError
  357. if res, err := gm.readNode("123", "testkind", nil, attTree, valTree); res != nil ||
  358. err.Error() != "GraphError: Could not read graph information "+
  359. "(Slot not found (mystorage/testparttestkind.nodes - Location:3))" {
  360. t.Error("Unexpected result:", res, err)
  361. return
  362. }
  363. if res, err := gm.readNode("123", "testkind", []string{"Name"}, attTree, valTree); res != nil ||
  364. err.Error() != "GraphError: Could not read graph information "+
  365. "(Slot not found (mystorage/testparttestkind.nodes - Location:3))" {
  366. t.Error("Unexpected result:", res, err)
  367. return
  368. }
  369. delete(msm.AccessMap, 3)
  370. node2 := data.NewGraphNode()
  371. node2.SetAttr("key", "")
  372. node2.SetAttr("kind", "testkind")
  373. node2.SetAttr("Name", "Some name2")
  374. if err := gm.StoreNode("testpart", node2); err.Error() !=
  375. "GraphError: Invalid data (Node is missing a key value)" {
  376. t.Error(err)
  377. return
  378. }
  379. node2.SetAttr("key", "456")
  380. // Test edge to test common error cases with nodes
  381. edge := data.NewGraphEdge()
  382. edge.SetAttr("key", "abc")
  383. edge.SetAttr("kind", "myedge")
  384. edge.SetAttr(data.EdgeEnd1Key, node1.Key())
  385. edge.SetAttr(data.EdgeEnd1Kind, node1.Kind())
  386. edge.SetAttr(data.EdgeEnd1Role, "node1")
  387. edge.SetAttr(data.EdgeEnd1Cascading, false)
  388. edge.SetAttr(data.EdgeEnd2Key, node2.Key())
  389. edge.SetAttr(data.EdgeEnd2Kind, node2.Kind())
  390. edge.SetAttr(data.EdgeEnd2Role, "node2")
  391. edge.SetAttr(data.EdgeEnd2Cascading, false)
  392. if err := gm.StoreNode("testpart ", node2); err.Error() !=
  393. "GraphError: Invalid data (Partition name testpart is not alphanumeric - can only contain [a-zA-Z0-9_])" {
  394. t.Error(err)
  395. return
  396. }
  397. delete(mgs.MainDB(), MainDBNodeCount+"testkind")
  398. sm := mgs.StorageManager("testpart"+node2.Kind()+StorageSuffixNodes, false).(*storage.MemoryStorageManager)
  399. sm.AccessMap[1] = storage.AccessCacheAndFetchError
  400. if err := gm.StoreNode("testpart", node2); err.Error() !=
  401. "GraphError: Failed to access graph storage component (Slot not found (mystorage/testparttestkind.nodes - Location:1))" {
  402. t.Error(err)
  403. return
  404. }
  405. delete(sm.AccessMap, 1)
  406. sm = mgs.StorageManager("testpart"+edge.Kind()+StorageSuffixEdges, true).(*storage.MemoryStorageManager)
  407. sm.AccessMap[1] = storage.AccessCacheAndFetchError
  408. sm.SetRoot(RootIDNodeHTree, 1)
  409. if err := gm.StoreEdge("testpart", edge); err.Error() !=
  410. "GraphError: Failed to access graph storage component (Slot not found (mystorage/testpartmyedge.edges - Location:1))" {
  411. t.Error(err)
  412. return
  413. }
  414. delete(sm.AccessMap, 1)
  415. msm.AccessMap[5] = storage.AccessInsertError
  416. if err := gm.StoreNode("testpart", node2); err.Error() !=
  417. "GraphError: Could not write graph information (Record is already in-use (<memory> - ))" {
  418. t.Error(err)
  419. return
  420. }
  421. delete(msm.AccessMap, 5)
  422. msm.AccessMap[5] = storage.AccessInsertError
  423. if err := gm.StoreNode("testpart", node2); err.Error() !=
  424. "GraphError: Could not write graph information (Record is already in-use (<memory> - ))" {
  425. t.Error(err)
  426. return
  427. }
  428. delete(msm.AccessMap, 5)
  429. node2.SetAttr("key", "123")
  430. node2.SetAttr("Name", nil)
  431. msm.AccessMap[3] = storage.AccessFreeError
  432. if err := gm.StoreNode("testpart", node2); err.Error() !=
  433. "GraphError: Could not write graph information (Slot not found (mystorage/testparttestkind.nodes - Location:3))" {
  434. t.Error(err)
  435. return
  436. }
  437. delete(msm.AccessMap, 3)
  438. node2.SetAttr("key", "456")
  439. node2.SetAttr("Name", "A new name")
  440. graphstorage.MgsRetFlushMain = &util.GraphError{Type: util.ErrFlushing, Detail: errors.New("Test").Error()}
  441. if err := gm.StoreNode("testpart", node2); err.Error() !=
  442. "GraphError: Failed to flush changes (Test)" {
  443. t.Error(err)
  444. return
  445. }
  446. graphstorage.MgsRetFlushMain = nil
  447. is := gm.gs.StorageManager("testpart"+"testkind"+StorageSuffixNodesIndex,
  448. false).(*storage.MemoryStorageManager)
  449. for i := 0; i < 10; i++ {
  450. is.AccessMap[uint64(i)] = storage.AccessInsertError
  451. }
  452. node2.SetAttr("key", "789")
  453. if err := gm.StoreNode("testpart", node2); err.Error() !=
  454. "GraphError: Index error (Record is already in-use (<memory> - ))" {
  455. t.Error(err)
  456. return
  457. }
  458. node2.SetAttr("key", "123")
  459. if err := gm.StoreNode("testpart", node2); err.Error() !=
  460. "GraphError: Index error (Record is already in-use (<memory> - ))" {
  461. t.Error(err)
  462. return
  463. }
  464. for i := 0; i < 10; i++ {
  465. is.AccessMap[uint64(i)] = storage.AccessUpdateError
  466. }
  467. if res, err := gm.RemoveNode("testpart", "789", "testkind"); !strings.Contains(err.Error(),
  468. "GraphError: Index error (Slot not found (mystorage/testparttestkind.nodeidx") {
  469. t.Error("Unexpected result:", res, err)
  470. return
  471. }
  472. for i := 0; i < 10; i++ {
  473. delete(is.AccessMap, uint64(i))
  474. }
  475. msm.AccessMap[9] = storage.AccessCacheAndFetchError
  476. // This call does delete the node by blowing
  477. // away the attribute list - the node is removed though its attribute
  478. // values remain in the datastore
  479. if res, err := gm.deleteNode("123", "testkind", attTree, valTree); err.Error() !=
  480. "GraphError: Could not write graph information "+
  481. "(Slot not found (mystorage/testparttestkind.nodes - Location:9))" {
  482. t.Error("Unexpected result:", res, err)
  483. return
  484. }
  485. delete(msm.AccessMap, 9)
  486. if res, err := gm.FetchNodePart("testpart", "123", "testkind", nil); res != nil || err != nil {
  487. t.Error("Unexpected result:", res, err)
  488. return
  489. }
  490. gm.StoreNode("testpart", node2)
  491. graphstorage.MgsRetFlushMain = &util.GraphError{Type: util.ErrFlushing, Detail: errors.New("Test").Error()}
  492. if _, err := gm.RemoveNode("testpart", node2.Key(), node2.Kind()); err.Error() !=
  493. "GraphError: Failed to flush changes (Test)" {
  494. t.Error(err)
  495. return
  496. }
  497. graphstorage.MgsRetFlushMain = nil
  498. }
  499. func TestGraphManagerDiskStorage(t *testing.T) {
  500. if !RunDiskStorageTests {
  501. return
  502. }
  503. dgs, err := graphstorage.NewDiskGraphStorage(GraphManagerTestDBDir1, false)
  504. if err != nil {
  505. t.Error(err)
  506. return
  507. }
  508. gm := newGraphManagerNoRules(dgs)
  509. if gm.Name() != "Graph "+GraphManagerTestDBDir1 {
  510. t.Error("Unexpected name:", gm.Name())
  511. return
  512. }
  513. sm := dgs.StorageManager("my1", true)
  514. htree, err := gm.getHTree(sm, RootIDNodeHTree)
  515. if err != nil {
  516. t.Error(err)
  517. return
  518. }
  519. htree.Put([]byte("test1"), "testvalue1")
  520. dgs.Close()
  521. dgs2, err := graphstorage.NewDiskGraphStorage(GraphManagerTestDBDir1, false)
  522. if err != nil {
  523. t.Error(err)
  524. return
  525. }
  526. dgs2.MainDB()[MainDBVersion] = strconv.Itoa(VERSION + 1)
  527. dgs2.FlushMain()
  528. testVersionPanic(t, dgs2)
  529. dgs2.MainDB()[MainDBVersion] = strconv.Itoa(VERSION)
  530. dgs2.FlushMain()
  531. // This should now succeed
  532. newGraphManagerNoRules(dgs2)
  533. dgs2.MainDB()[MainDBVersion] = strconv.Itoa(VERSION - 1)
  534. dgs2.FlushMain()
  535. gm = newGraphManagerNoRules(dgs2)
  536. if dgs2.MainDB()[MainDBVersion] != strconv.Itoa(VERSION) {
  537. t.Error("Version should have been corrected")
  538. return
  539. }
  540. sm2 := dgs2.StorageManager("my1", true)
  541. htree2, err := gm.getHTree(sm2, RootIDNodeHTree)
  542. if err != nil {
  543. t.Error(err)
  544. return
  545. }
  546. if val, err := htree2.Get([]byte("test1")); val != "testvalue1" || err != nil {
  547. t.Error("Unexpected result:", val, err)
  548. return
  549. }
  550. dgs2.Close()
  551. // Test error cases
  552. msm := storage.NewMemoryStorageManager("mytest")
  553. msm.AccessMap[1] = storage.AccessInsertError
  554. _, err = gm.getHTree(msm, RootIDNodeHTree)
  555. if err.(*util.GraphError).Type != util.ErrAccessComponent {
  556. t.Error(err)
  557. return
  558. }
  559. delete(msm.AccessMap, 1)
  560. msm.SetRoot(RootIDNodeHTree, 2)
  561. msm.AccessMap[2] = storage.AccessInsertError
  562. _, err = gm.getHTree(msm, RootIDNodeHTree)
  563. if err.(*util.GraphError).Type != util.ErrAccessComponent {
  564. t.Error(err)
  565. return
  566. }
  567. delete(msm.AccessMap, 2)
  568. }
  569. func testVersionPanic(t *testing.T, gs graphstorage.Storage) {
  570. defer func() {
  571. if r := recover(); r == nil {
  572. t.Error("Opening a graph with a newer version did not cause a panic.")
  573. }
  574. }()
  575. newGraphManagerNoRules(gs)
  576. }