htree_test.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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. _, err := NewHTree(sm)
  63. if sfe, ok := err.(*file.StorageFileError); !ok || sfe.Type != file.ErrAlreadyInUse {
  64. t.Error("Unexpected new tree result:", err)
  65. return
  66. }
  67. delete(sm.AccessMap, 1)
  68. htree, _ := NewHTree(sm)
  69. page := htree.Root
  70. if loc := page.Location(); loc != 1 {
  71. t.Error("Unexpected root location:", loc)
  72. return
  73. }
  74. // Fill up the tree
  75. page.Put([]byte("testkey1"), "test1")
  76. page.Put([]byte("testkey2"), "test2")
  77. page.Put([]byte("testkey3"), "test3")
  78. page.Put([]byte("testkey4"), "test4")
  79. page.Put([]byte("testkey5"), "test5")
  80. page.Put([]byte("testkey6"), "test6")
  81. page.Put([]byte("testkey7"), "test7")
  82. page.Put([]byte("testkey8"), "test8")
  83. page.Put([]byte("testkey9"), "test9")
  84. page.Put([]byte("testkey10"), "test10")
  85. if page.Location() != 1 {
  86. t.Error("Unexpected location for tree")
  87. return
  88. }
  89. // Reload HTree
  90. htreeCached, _ := LoadHTree(sm, page.Location())
  91. sm.AccessMap[1] = storage.AccessCacheAndFetchError
  92. if _, err := LoadHTree(sm, page.Location()); err.(*storage.ManagerError).Type != storage.ErrSlotNotFound {
  93. t.Error("Unexpected tree load result:", err)
  94. return
  95. }
  96. delete(sm.AccessMap, 1)
  97. sm.AccessMap[1] = storage.AccessNotInCache
  98. htreeFetched, _ := LoadHTree(sm, page.Location())
  99. delete(sm.AccessMap, 1)
  100. if htreeCached.Location() != htreeFetched.Location() {
  101. t.Error("Trees have different locations:", htreeCached.Location(), htreeFetched.Location())
  102. return
  103. }
  104. sm.AccessMap[8] = storage.AccessNotInCache
  105. if res, err := htree.Get([]byte("testkey5")); res != "test5" || err != nil {
  106. t.Error("Unexpected get result:", res, err)
  107. return
  108. }
  109. if res, loc, err := htree.GetValueAndLocation([]byte("testkey5")); res != "test5" || loc == 0 || err != nil {
  110. t.Error("Unexpected get result:", res, loc, err)
  111. return
  112. }
  113. if res, loc, err := htree.GetValueAndLocation([]byte("testkey99")); res != nil || loc != 0 || err != nil {
  114. t.Error("Unexpected get result:", res, loc, err)
  115. return
  116. }
  117. delete(sm.AccessMap, 1)
  118. // Test proxy functions
  119. if res, err := htree.Exists([]byte("testkey6")); res != true || err != nil {
  120. t.Error("Unexpected exist result:", res, err)
  121. return
  122. }
  123. if res, err := htree.Put([]byte("testkey6"), "test7"); res != "test6" || err != nil {
  124. t.Error("Unexpected exist result:", res, err)
  125. return
  126. }
  127. if res, err := htree.Remove([]byte("testkey6")); res != "test7" || err != nil {
  128. t.Error("Unexpected exist result:", res, err)
  129. return
  130. }
  131. if res, err := htree.Exists([]byte("testkey6")); res != false || err != nil {
  132. t.Error("Unexpected exist result:", res, err)
  133. return
  134. }
  135. }