/* * EliasDB * * Copyright 2016 Matthias Ladkau. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package hash import ( "flag" "fmt" "os" "testing" "devt.de/krotik/common/fileutil" "devt.de/krotik/eliasdb/storage" "devt.de/krotik/eliasdb/storage/file" ) const DBDIR = "htreetest" func TestMain(m *testing.M) { flag.Parse() // Setup if res, _ := fileutil.PathExists(DBDIR); res { os.RemoveAll(DBDIR) } err := os.Mkdir(DBDIR, 0770) if err != nil { fmt.Print("Could not create test directory:", err.Error()) os.Exit(1) } // Run the tests res := m.Run() // Teardown err = os.RemoveAll(DBDIR) if err != nil { fmt.Print("Could not remove test directory:", err.Error()) } os.Exit(res) } func TestHTreeSerialization(t *testing.T) { sm := storage.NewDiskStorageManager(DBDIR+"/test1", false, false, false, false) htree, err := NewHTree(sm) if err != nil { t.Error(err) return } loc := htree.Location() htree.Put([]byte("test"), "testvalue1") sm.Close() sm2 := storage.NewDiskStorageManager(DBDIR+"/test1", false, false, false, false) htree2, _ := LoadHTree(sm2, loc) if res, err := htree2.Get([]byte("test")); res != "testvalue1" || err != nil { t.Error("Unexpected result:", res, err) return } sm2.Close() } func TestHTree(t *testing.T) { sm := storage.NewMemoryStorageManager("testsm") sm.AccessMap[1] = storage.AccessInsertError _, err := NewHTree(sm) if sfe, ok := err.(*file.StorageFileError); !ok || sfe.Type != file.ErrAlreadyInUse { t.Error("Unexpected new tree result:", err) return } delete(sm.AccessMap, 1) htree, _ := NewHTree(sm) page := htree.Root if loc := page.Location(); loc != 1 { t.Error("Unexpected root location:", loc) return } // Fill up the tree page.Put([]byte("testkey1"), "test1") page.Put([]byte("testkey2"), "test2") page.Put([]byte("testkey3"), "test3") page.Put([]byte("testkey4"), "test4") page.Put([]byte("testkey5"), "test5") page.Put([]byte("testkey6"), "test6") page.Put([]byte("testkey7"), "test7") page.Put([]byte("testkey8"), "test8") page.Put([]byte("testkey9"), "test9") page.Put([]byte("testkey10"), "test10") if page.Location() != 1 { t.Error("Unexpected location for tree") return } // Reload HTree htreeCached, _ := LoadHTree(sm, page.Location()) sm.AccessMap[1] = storage.AccessCacheAndFetchError if _, err := LoadHTree(sm, page.Location()); err.(*storage.ManagerError).Type != storage.ErrSlotNotFound { t.Error("Unexpected tree load result:", err) return } delete(sm.AccessMap, 1) sm.AccessMap[1] = storage.AccessNotInCache htreeFetched, _ := LoadHTree(sm, page.Location()) delete(sm.AccessMap, 1) if htreeCached.Location() != htreeFetched.Location() { t.Error("Trees have different locations:", htreeCached.Location(), htreeFetched.Location()) return } sm.AccessMap[8] = storage.AccessNotInCache if res, err := htree.Get([]byte("testkey5")); res != "test5" || err != nil { t.Error("Unexpected get result:", res, err) return } if res, loc, err := htree.GetValueAndLocation([]byte("testkey5")); res != "test5" || loc == 0 || err != nil { t.Error("Unexpected get result:", res, loc, err) return } if res, loc, err := htree.GetValueAndLocation([]byte("testkey99")); res != nil || loc != 0 || err != nil { t.Error("Unexpected get result:", res, loc, err) return } delete(sm.AccessMap, 1) // Test proxy functions if res, err := htree.Exists([]byte("testkey6")); res != true || err != nil { t.Error("Unexpected exist result:", res, err) return } if res, err := htree.Put([]byte("testkey6"), "test7"); res != "test6" || err != nil { t.Error("Unexpected exist result:", res, err) return } if res, err := htree.Remove([]byte("testkey6")); res != "test7" || err != nil { t.Error("Unexpected exist result:", res, err) return } if res, err := htree.Exists([]byte("testkey6")); res != false || err != nil { t.Error("Unexpected exist result:", res, err) return } }