This PR does two things, because one lead to the other: - Move the leveldb specific stuff into a small "backend" package that defines a backend interface and the leveldb implementation. This allows, potentially, in the future, switching the db implementation so another KV store should we wish to do so. - Add proper error handling all along the way. The db and backend packages are now errcheck clean. However, I drew the line at modifying the FileSet API in order to keep this manageable and not continue refactoring all of the rest of Syncthing. As such, the FileSet methods still panic on database errors, except for the "database is closed" error which is instead handled by silently returning as quickly as possible, with the assumption that we're anyway "on the way out".
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
// Copyright (C) 2018 The Syncthing Authors.
|
|
//
|
|
// 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 https://mozilla.org/MPL/2.0/.
|
|
|
|
package db
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/syncthing/syncthing/lib/db/backend"
|
|
)
|
|
|
|
func TestSmallIndex(t *testing.T) {
|
|
db := NewLowlevel(backend.OpenMemory())
|
|
idx := newSmallIndex(db, []byte{12, 34})
|
|
|
|
// ID zero should be unallocated
|
|
if val, ok := idx.Val(0); ok || val != nil {
|
|
t.Fatal("Unexpected return for nonexistent ID 0")
|
|
}
|
|
|
|
// A new key should get ID zero
|
|
if id, err := idx.ID([]byte("hello")); err != nil {
|
|
t.Fatal(err)
|
|
} else if id != 0 {
|
|
t.Fatal("Expected 0, not", id)
|
|
}
|
|
// Looking up ID zero should work
|
|
if val, ok := idx.Val(0); !ok || string(val) != "hello" {
|
|
t.Fatalf(`Expected true, "hello", not %v, %q`, ok, val)
|
|
}
|
|
|
|
// Delete the key
|
|
idx.Delete([]byte("hello"))
|
|
|
|
// Next ID should be one
|
|
if id, err := idx.ID([]byte("key2")); err != nil {
|
|
t.Fatal(err)
|
|
} else if id != 1 {
|
|
t.Fatal("Expected 1, not", id)
|
|
}
|
|
|
|
// Now lets create a new index instance based on what's actually serialized to the database.
|
|
idx = newSmallIndex(db, []byte{12, 34})
|
|
|
|
// Status should be about the same as before.
|
|
if val, ok := idx.Val(0); ok || val != nil {
|
|
t.Fatal("Unexpected return for deleted ID 0")
|
|
}
|
|
if id, err := idx.ID([]byte("key2")); err != nil {
|
|
t.Fatal(err)
|
|
} else if id != 1 {
|
|
t.Fatal("Expected 1, not", id)
|
|
}
|
|
|
|
// Setting "hello" again should get us ID 2, not 0 as it was originally.
|
|
if id, err := idx.ID([]byte("hello")); err != nil {
|
|
t.Fatal(err)
|
|
} else if id != 2 {
|
|
t.Fatal("Expected 2, not", id)
|
|
}
|
|
}
|