syncthing/lib/db/blockmap_test.go

253 lines
4.7 KiB
Go
Raw Normal View History

2014-11-16 20:13:20 +00:00
// Copyright (C) 2014 The Syncthing Authors.
2014-10-06 20:57:33 +00:00
//
2015-03-07 20:36:35 +00:00
// 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/.
2014-10-06 20:57:33 +00:00
package db
2014-10-06 20:57:33 +00:00
import (
"testing"
2015-09-22 17:38:46 +00:00
"github.com/syncthing/syncthing/lib/protocol"
2014-10-06 20:57:33 +00:00
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/storage"
)
func genBlocks(n int) []protocol.BlockInfo {
b := make([]protocol.BlockInfo, n)
for i := range b {
h := make([]byte, 32)
for j := range h {
h[j] = byte(i + j)
}
b[i].Size = int32(i)
2014-10-06 20:57:33 +00:00
b[i].Hash = h
}
return b
}
var f1, f2, f3 protocol.FileInfo
2015-09-04 10:01:00 +00:00
var folders = []string{"folder1", "folder2"}
2014-10-06 20:57:33 +00:00
func init() {
blocks := genBlocks(30)
f1 = protocol.FileInfo{
Name: "f1",
Blocks: blocks[:10],
}
f2 = protocol.FileInfo{
Name: "f2",
Blocks: blocks[10:20],
}
f3 = protocol.FileInfo{
Name: "f3",
Blocks: blocks[20:],
}
}
func setup() (*leveldb.DB, *BlockFinder) {
// Setup
db, err := leveldb.Open(storage.NewMemStorage(), nil)
if err != nil {
panic(err)
}
2015-09-04 10:01:00 +00:00
return db, NewBlockFinder(db)
2014-10-06 20:57:33 +00:00
}
func dbEmpty(db *leveldb.DB) bool {
iter := db.NewIterator(nil, nil)
defer iter.Release()
if iter.Next() {
return false
}
return true
}
func TestBlockMapAddUpdateWipe(t *testing.T) {
db, f := setup()
if !dbEmpty(db) {
t.Fatal("db not empty")
}
m := NewBlockMap(db, "folder1")
f3.Flags |= protocol.FlagDirectory
err := m.Add([]protocol.FileInfo{f1, f2, f3})
if err != nil {
t.Fatal(err)
}
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
if folder != "folder1" || file != "f1" || index != 0 {
t.Fatal("Mismatch")
}
return true
})
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f2.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
if folder != "folder1" || file != "f2" || index != 0 {
t.Fatal("Mismatch")
}
return true
})
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f3.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
t.Fatal("Unexpected block")
return true
})
f3.Flags = f1.Flags
f1.Flags |= protocol.FlagDeleted
f2.Flags |= protocol.FlagInvalid
// Should remove
err = m.Update([]protocol.FileInfo{f1, f2, f3})
if err != nil {
t.Fatal(err)
}
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
t.Fatal("Unexpected block")
return false
})
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f2.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
t.Fatal("Unexpected block")
return false
})
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f3.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
if folder != "folder1" || file != "f3" || index != 0 {
t.Fatal("Mismatch")
}
return true
})
err = m.Drop()
if err != nil {
t.Fatal(err)
}
if !dbEmpty(db) {
t.Fatal("db not empty")
}
// Should not add
err = m.Add([]protocol.FileInfo{f1, f2})
if err != nil {
t.Fatal(err)
}
if !dbEmpty(db) {
t.Fatal("db not empty")
}
f1.Flags = 0
f2.Flags = 0
f3.Flags = 0
}
2014-10-24 21:23:19 +00:00
func TestBlockFinderLookup(t *testing.T) {
2014-10-06 20:57:33 +00:00
db, f := setup()
m1 := NewBlockMap(db, "folder1")
m2 := NewBlockMap(db, "folder2")
err := m1.Add([]protocol.FileInfo{f1})
if err != nil {
t.Fatal(err)
}
err = m2.Add([]protocol.FileInfo{f1})
if err != nil {
t.Fatal(err)
}
counter := 0
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
counter++
switch counter {
case 1:
if folder != "folder1" || file != "f1" || index != 0 {
t.Fatal("Mismatch")
}
case 2:
if folder != "folder2" || file != "f1" || index != 0 {
t.Fatal("Mismatch")
}
default:
t.Fatal("Unexpected block")
}
return false
})
2015-09-04 10:01:00 +00:00
2014-10-06 20:57:33 +00:00
if counter != 2 {
t.Fatal("Incorrect count", counter)
}
f1.Flags |= protocol.FlagDeleted
err = m1.Update([]protocol.FileInfo{f1})
if err != nil {
t.Fatal(err)
}
counter = 0
2015-09-04 10:01:00 +00:00
f.Iterate(folders, f1.Blocks[0].Hash, func(folder, file string, index int32) bool {
2014-10-06 20:57:33 +00:00
counter++
switch counter {
case 1:
if folder != "folder2" || file != "f1" || index != 0 {
t.Fatal("Mismatch")
}
default:
t.Fatal("Unexpected block")
}
return false
})
2015-09-04 10:01:00 +00:00
2014-10-06 20:57:33 +00:00
if counter != 1 {
t.Fatal("Incorrect count")
}
2014-10-24 21:23:19 +00:00
f1.Flags = 0
2014-10-06 20:57:33 +00:00
}
2014-10-24 22:20:08 +00:00
func TestBlockFinderFix(t *testing.T) {
db, f := setup()
iterFn := func(folder, file string, index int32) bool {
2014-10-24 22:20:08 +00:00
return true
}
m := NewBlockMap(db, "folder1")
err := m.Add([]protocol.FileInfo{f1})
if err != nil {
t.Fatal(err)
}
2015-09-04 10:01:00 +00:00
if !f.Iterate(folders, f1.Blocks[0].Hash, iterFn) {
2014-10-24 22:20:08 +00:00
t.Fatal("Block not found")
}
err = f.Fix("folder1", f1.Name, 0, f1.Blocks[0].Hash, f2.Blocks[0].Hash)
if err != nil {
t.Fatal(err)
}
2015-09-04 10:01:00 +00:00
if f.Iterate(folders, f1.Blocks[0].Hash, iterFn) {
2014-10-24 22:20:08 +00:00
t.Fatal("Unexpected block")
}
2015-09-04 10:01:00 +00:00
if !f.Iterate(folders, f2.Blocks[0].Hash, iterFn) {
2014-10-24 22:20:08 +00:00
t.Fatal("Block not found")
}
}