htree_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 hash
  11. import (
  12. "flag"
  13. "fmt"
  14. "os"
  15. "testing"
  16. "devt.de/krotik/common/fileutil"
  17. "devt.de/krotik/eliasdb/storage"
  18. "devt.de/krotik/eliasdb/storage/file"
  19. )
  20. const DBDIR = "htreetest"
  21. func TestMain(m *testing.M) {
  22. flag.Parse()
  23. // Setup
  24. if res, _ := fileutil.PathExists(DBDIR); res {
  25. os.RemoveAll(DBDIR)
  26. }
  27. err := os.Mkdir(DBDIR, 0770)
  28. if err != nil {
  29. fmt.Print("Could not create test directory:", err.Error())
  30. os.Exit(1)
  31. }
  32. // Run the tests
  33. res := m.Run()
  34. // Teardown
  35. err = os.RemoveAll(DBDIR)
  36. if err != nil {
  37. fmt.Print("Could not remove test directory:", err.Error())
  38. }
  39. os.Exit(res)
  40. }
  41. func TestHTreeSerialization(t *testing.T) {
  42. sm := storage.NewDiskStorageManager(DBDIR+"/test1", false, false, false, false)
  43. htree, err := NewHTree(sm)
  44. if err != nil {
  45. t.Error(err)
  46. return
  47. }
  48. loc := htree.Location()
  49. htree.Put([]byte("test"), "testvalue1")
  50. sm.Close()
  51. sm2 := storage.NewDiskStorageManager(DBDIR+"/test1", false, false, false, false)
  52. htree2, _ := LoadHTree(sm2, loc)
  53. if res, err := htree2.Get([]byte("test")); res != "testvalue1" || err != nil {
  54. t.Error("Unexpected result:", res, err)
  55. return
  56. }
  57. sm2.Close()
  58. }
  59. func TestHTree(t *testing.T) {
  60. sm := storage.NewMemoryStorageManager("testsm")
  61. sm.AccessMap[1] = storage.AccessInsertError
  62. if _, err := NewHTree(sm); err != file.ErrAlreadyInUse {
  63. t.Error("Unexpected new tree result:", err)
  64. return
  65. }
  66. delete(sm.AccessMap, 1)
  67. htree, _ := NewHTree(sm)
  68. page := htree.Root
  69. if loc := page.Location(); loc != 1 {
  70. t.Error("Unexpected root location:", loc)
  71. return
  72. }
  73. // Fill up the tree
  74. page.Put([]byte("testkey1"), "test1")
  75. page.Put([]byte("testkey2"), "test2")
  76. page.Put([]byte("testkey3"), "test3")
  77. page.Put([]byte("testkey4"), "test4")
  78. page.Put([]byte("testkey5"), "test5")
  79. page.Put([]byte("testkey6"), "test6")
  80. page.Put([]byte("testkey7"), "test7")
  81. page.Put([]byte("testkey8"), "test8")
  82. page.Put([]byte("testkey9"), "test9")
  83. page.Put([]byte("testkey10"), "test10")
  84. if page.Location() != 1 {
  85. t.Error("Unexpected location for tree")
  86. return
  87. }
  88. // Reload HTree
  89. htreeCached, _ := LoadHTree(sm, page.Location())
  90. sm.AccessMap[1] = storage.AccessCacheAndFetchError
  91. if _, err := LoadHTree(sm, page.Location()); err != storage.ErrSlotNotFound {
  92. t.Error("Unexpected tree load result:", err)
  93. return
  94. }
  95. delete(sm.AccessMap, 1)
  96. sm.AccessMap[1] = storage.AccessNotInCache
  97. htreeFetched, _ := LoadHTree(sm, page.Location())
  98. delete(sm.AccessMap, 1)
  99. if htreeCached.Location() != htreeFetched.Location() {
  100. t.Error("Trees have different locations:", htreeCached.Location(), htreeFetched.Location())
  101. return
  102. }
  103. sm.AccessMap[8] = storage.AccessNotInCache
  104. if res, err := htree.Get([]byte("testkey5")); res != "test5" || err != nil {
  105. t.Error("Unexpected get result:", res, err)
  106. return
  107. }
  108. if res, loc, err := htree.GetValueAndLocation([]byte("testkey5")); res != "test5" || loc == 0 || err != nil {
  109. t.Error("Unexpected get result:", res, loc, err)
  110. return
  111. }
  112. if res, loc, err := htree.GetValueAndLocation([]byte("testkey99")); res != nil || loc != 0 || err != nil {
  113. t.Error("Unexpected get result:", res, loc, err)
  114. return
  115. }
  116. delete(sm.AccessMap, 1)
  117. // Test proxy functions
  118. if res, err := htree.Exists([]byte("testkey6")); res != true || err != nil {
  119. t.Error("Unexpected exist result:", res, err)
  120. return
  121. }
  122. if res, err := htree.Put([]byte("testkey6"), "test7"); res != "test6" || err != nil {
  123. t.Error("Unexpected exist result:", res, err)
  124. return
  125. }
  126. if res, err := htree.Remove([]byte("testkey6")); res != "test7" || err != nil {
  127. t.Error("Unexpected exist result:", res, err)
  128. return
  129. }
  130. if res, err := htree.Exists([]byte("testkey6")); res != false || err != nil {
  131. t.Error("Unexpected exist result:", res, err)
  132. return
  133. }
  134. }