123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- * 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 cluster
- import (
- "errors"
- "math"
- "testing"
- "devt.de/krotik/eliasdb/hash"
- "devt.de/krotik/eliasdb/storage"
- )
- func TestAddressTableClusterLoc(t *testing.T) {
- // Set a low distribution range
- defaultDistributionRange = 3
- defer func() { defaultDistributionRange = math.MaxUint64 }()
- // Test an inoperable cluster
- cluster1, ms1 := createCluster(1, 1)
- cluster1[0].distributionTable = nil
- cluster1[0].distributionTableError = errors.New("testerror")
- _, err := ms1[0].at.NewClusterLoc("test1")
- if err.Error() != "Storage is currently disabled on member: TestClusterMember-0 (testerror)" {
- t.Error("Unexpected result:", err)
- return
- }
- // Test normal number sequence
- cluster1, ms1 = createCluster(1, 1)
- loc, err := ms1[0].at.NewClusterLoc("test1")
- if loc != 1 || err != nil {
- t.Error("Unexpected result:", loc, err)
- return
- }
- ms1[0].at.SetTransClusterLoc("test1", loc, 123, 1)
- // Starting an unrelated counter should have no effect
- loc, err = ms1[0].at.NewClusterLoc("test2")
- if loc != 1 || err != nil {
- t.Error("Unexpected result:", loc, err)
- return
- }
- delete(ms1[0].at.newlocCounters, "test1")
- // Advance the counter
- loc, err = ms1[0].at.NewClusterLoc("test1")
- if loc != 2 || err != nil {
- t.Error("Unexpected result:", loc, err)
- return
- }
- ms1[0].at.SetTransClusterLoc("test1", loc, 123, 1)
- loc, err = ms1[0].at.NewClusterLoc("test1")
- if loc != 3 || err != nil {
- t.Error("Unexpected result:", loc, err)
- return
- }
- // Not filling the location 3
- // The next call should find the free location 3
- loc, err = ms1[0].at.NewClusterLoc("test1")
- if loc != 3 || err != nil {
- t.Error("Unexpected result:", loc, err)
- return
- }
- ms1[0].at.SetTransClusterLoc("test1", loc, 123, 1)
- // Now we are full the next call should error
- loc, err = ms1[0].at.NewClusterLoc("test1")
- if err.Error() != "Could not find any free storage location on this member" {
- t.Error("Unexpected result:", loc, err)
- return
- }
- // Change distribution table - test member which is in the middle of the cluster
- defaultDistributionRange = 120
- dd, _ := NewDistributionTable([]string{"aa", cluster1[0].MemberManager.Name(), "bb"}, 1)
- cluster1[0].distributionTable = dd
- cluster1[0].distributionTableError = nil
- start, end := cluster1[0].distributionTable.MemberRange(cluster1[0].MemberManager.Name())
- if start != 40 || end != 79 {
- t.Error("Unexpected range:", start, end)
- return
- }
- loc, err = ms1[0].at.NewClusterLoc("test1")
- if loc != 40 || err != nil {
- t.Error("Unexpected result:", loc, err)
- return
- }
- ms1[0].at.SetTransClusterLoc("test1", loc, 123, 1)
- // Simulate a lookup failure
- for i := 40; i < 70; i++ {
- ms1[0].at.SetTransClusterLoc("test1", uint64(i), 123, 1)
- }
- // Get the translation location for cluster location 6
- _, loc, _ = ms1[0].at.translation.GetValueAndLocation(transKey("test1", 69))
- msm := ms1[0].at.sm.(*storage.MemoryStorageManager)
- msm.AccessMap[loc] = storage.AccessCacheAndFetchSeriousError
- loc, err = ms1[0].at.NewClusterLoc("test1")
- if err.Error() != "Record is already in-use (<memory> - )" {
- t.Error("Unexpected result:", loc, err)
- return
- }
- delete(msm.AccessMap, loc)
- // Recreate the member address table
- ms1[0].at, err = newMemberAddressTable(cluster1[0], ms1[0].at.sm)
- if err != nil {
- t.Error("Could not recreate MemberAddressTable:", err)
- return
- }
- // Now check the translation lookup
- if tr, ok, err := ms1[0].at.TransClusterLoc("test1", 50); tr.Loc != 123 || tr.Ver != 1 || !ok || err != nil {
- t.Error("Unexpected translation:", tr, ok, err)
- return
- }
- if tr, ok, err := ms1[0].at.TransClusterLoc("test1", 150); tr != nil || ok || err != nil {
- t.Error("Unexpected translation:", tr, ok, err)
- return
- }
- if tr, ok, err := ms1[0].at.SetTransClusterLoc("test1", 50, 555, 2); tr.Loc != 123 || tr.Ver != 1 || !ok || err != nil {
- t.Error("Unexpected translation:", tr, ok, err)
- return
- }
- if tr, ok, err := ms1[0].at.TransClusterLoc("test1", 50); tr.Loc != 555 || tr.Ver != 2 || !ok || err != nil {
- t.Error("Unexpected translation:", tr, ok, err)
- return
- }
- if tr, ok, err := ms1[0].at.RemoveTransClusterLoc("test1", 50); tr.Loc != 555 || tr.Ver != 2 || !ok || err != nil {
- t.Error("Unexpected translation:", tr, ok, err)
- return
- }
- if tr, ok, err := ms1[0].at.TransClusterLoc("test1", 50); tr != nil || ok || err != nil {
- t.Error("Unexpected translation:", tr, ok, err)
- return
- }
- if tr, ok, err := ms1[0].at.RemoveTransClusterLoc("test1", 50); tr != nil || ok || err != nil {
- t.Error("Unexpected translation:", tr, ok, err)
- return
- }
- }
- func TestAddressTableTransfer(t *testing.T) {
- _, ms1 := createCluster(1, 1)
- // Test storing transfer requests
- ms1[0].at.AddTransferRequest([]string{"a,b"}, nil)
- ms1[0].at.AddTransferRequest([]string{"c,d"}, nil)
- ms1[0].at.AddTransferRequest([]string{"e,f"}, nil)
- counter := 0
- it := hash.NewHTreeIterator(ms1[0].at.transfer)
- for ; it.HasNext(); it.Next() {
- counter++
- }
- // Check that we have 3 entries
- if counter != 3 {
- t.Error("Unexpected counter value:", counter)
- return
- }
- }
|