func newMDServerLocalWithStorage(config Config, handleStorage, mdStorage, branchStorage, lockStorage storage.Storage) (*MDServerLocal, error) { handleDb, err := leveldb.Open(handleStorage, leveldbOptions) if err != nil { return nil, err } mdDb, err := leveldb.Open(mdStorage, leveldbOptions) if err != nil { return nil, err } branchDb, err := leveldb.Open(branchStorage, leveldbOptions) if err != nil { return nil, err } locksDb, err := leveldb.Open(lockStorage, leveldbOptions) if err != nil { return nil, err } log := config.MakeLogger("") mdserv := &MDServerLocal{config, handleDb, mdDb, branchDb, log, &sync.Mutex{}, locksDb, &sync.Mutex{}, make(map[TlfID]map[*MDServerLocal]chan<- error), make(map[TlfID]*MDServerLocal), new(bool), &sync.RWMutex{}} return mdserv, nil }
func BenchmarkRequest(b *testing.B) { db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel("/tmp", nil, "syncthing", "dev", db) m.AddRepo(config.RepositoryConfiguration{ID: "default", Directory: "testdata"}) m.ScanRepo("default") const n = 1000 files := make([]protocol.FileInfo, n) t := time.Now().Unix() for i := 0; i < n; i++ { files[i] = protocol.FileInfo{ Name: fmt.Sprintf("file%d", i), Modified: t, Blocks: []protocol.BlockInfo{{0, 100, []byte("some hash bytes")}}, } } fc := FakeConnection{ id: node1, requestData: []byte("some data to return"), } m.AddConnection(fc, fc) m.Index(node1, "default", files) b.ResetTimer() for i := 0; i < b.N; i++ { data, err := m.requestGlobal(node1, "default", files[i%n].Name, 0, 32, nil) if err != nil { b.Error(err) } if data == nil { b.Error("nil data") } } }
func Benchmark10kUpdateChg(b *testing.B) { var remote []protocol.FileInfo for i := 0; i < 10000; i++ { remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: 1000}) } ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { b.Fatal(err) } m := db.NewFileSet("test", ldb) m.Replace(remoteDevice0, remote) var local []protocol.FileInfo for i := 0; i < 10000; i++ { local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: 1000}) } m.ReplaceWithDelete(protocol.LocalDeviceID, local) b.ResetTimer() for i := 0; i < b.N; i++ { b.StopTimer() for j := range local { local[j].Version++ } b.StartTimer() m.Update(protocol.LocalDeviceID, local) } }
func TestUpdateToInvalid(t *testing.T) { ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } s := db.NewFileSet("test", ldb) localHave := fileList{ protocol.FileInfo{Name: "a", Version: protocol.Vector{{ID: myID, Value: 1000}}, Blocks: genBlocks(1)}, protocol.FileInfo{Name: "b", Version: protocol.Vector{{ID: myID, Value: 1001}}, Blocks: genBlocks(2)}, protocol.FileInfo{Name: "c", Version: protocol.Vector{{ID: myID, Value: 1002}}, Blocks: genBlocks(5), Flags: protocol.FlagInvalid}, protocol.FileInfo{Name: "d", Version: protocol.Vector{{ID: myID, Value: 1003}}, Blocks: genBlocks(7)}, } s.Replace(protocol.LocalDeviceID, localHave) have := fileList(haveList(s, protocol.LocalDeviceID)) sort.Sort(have) if fmt.Sprint(have) != fmt.Sprint(localHave) { t.Errorf("Have incorrect before invalidation;\n A: %v !=\n E: %v", have, localHave) } localHave[1] = protocol.FileInfo{Name: "b", Version: protocol.Vector{{ID: myID, Value: 1001}}, Flags: protocol.FlagInvalid} s.Update(protocol.LocalDeviceID, localHave[1:2]) have = fileList(haveList(s, protocol.LocalDeviceID)) sort.Sort(have) if fmt.Sprint(have) != fmt.Sprint(localHave) { t.Errorf("Have incorrect after invalidation;\n A: %v !=\n E: %v", have, localHave) } }
// Open will open and possibly create a datastore at the given directory. func OpenLeveldb(path string, create bool, kvOpts Options) (db Engine, err error) { goOpts := kvOpts.(*goKeyValueOptions) if goOpts == nil { err = fmt.Errorf("Nil pointer passed in as key-value options to Openleveldb()!") return } leveldb_stor, err := storage.OpenFile(path) if err != nil { return } // Set the CreateIfMissing flag. if create { goOpts.Options.Flag |= opt.OFCreateIfMissing goOpts.Options.Flag |= opt.OFErrorIfExist } // Open the leveldb leveldb_db, err := leveldb.Open(leveldb_stor, goOpts.Options) if err != nil { return } db = &goLDB{ directory: path, opts: *goOpts, // We want a copy at time of Open() stor: leveldb_stor, ldb: leveldb_db, } return }
func Benchmark10kGlobal(b *testing.B) { var remote []protocol.FileInfo for i := 0; i < 10000; i++ { remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}}) } ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { b.Fatal(err) } m := db.NewFileSet("test", ldb) m.Replace(remoteDevice0, remote) var local []protocol.FileInfo for i := 0; i < 2000; i++ { local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}}) } for i := 2000; i < 10000; i++ { local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{1, 980}}}) } m.Replace(protocol.LocalDeviceID, local) b.ResetTimer() for i := 0; i < b.N; i++ { fs := globalList(m) if l := len(fs); l != 10000 { b.Errorf("wrong length %d != 10k", l) } } }
func Benchmark10kUpdateSme(b *testing.B) { var remote []protocol.FileInfo for i := 0; i < 10000; i++ { remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: 1000}) } db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { b.Fatal(err) } m := files.NewSet("test", db) m.Replace(remoteNode0, remote) var local []protocol.FileInfo for i := 0; i < 10000; i++ { local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: 1000}) } m.ReplaceWithDelete(protocol.LocalNodeID, local) b.ResetTimer() for i := 0; i < b.N; i++ { m.Update(protocol.LocalNodeID, local) } }
func Benchmark10kHaveFullList(b *testing.B) { var remote []protocol.FileInfo for i := 0; i < 10000; i++ { remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: 1000}) } db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { b.Fatal(err) } m := files.NewSet("test", db) m.Replace(remoteNode0, remote) var local []protocol.FileInfo for i := 0; i < 2000; i++ { local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: 1000}) } for i := 2000; i < 10000; i++ { local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: 980}) } m.ReplaceWithDelete(protocol.LocalNodeID, local) b.ResetTimer() for i := 0; i < b.N; i++ { fs := haveList(m, protocol.LocalNodeID) if l := len(fs); l != 10000 { b.Errorf("wrong length %d != 10k", l) } } }
func TestLongPath(t *testing.T) { ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } s := db.NewFileSet("test", ldb) var b bytes.Buffer for i := 0; i < 100; i++ { b.WriteString("012345678901234567890123456789012345678901234567890") } name := b.String() // 5000 characters local := []protocol.FileInfo{ {Name: string(name), Version: protocol.Vector{{ID: myID, Value: 1000}}}, } s.Replace(protocol.LocalDeviceID, local) gf := globalList(s) if l := len(gf); l != 1 { t.Fatalf("Incorrect len %d != 1 for global list", l) } if gf[0].Name != local[0].Name { t.Errorf("Incorrect long filename;\n%q !=\n%q", gf[0].Name, local[0].Name) } }
func TestLocalVersion(t *testing.T) { ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } m := db.NewFileSet("test", ldb) local1 := []protocol.FileInfo{ {Name: "a", Version: protocol.Vector{{ID: myID, Value: 1000}}}, {Name: "b", Version: protocol.Vector{{ID: myID, Value: 1000}}}, {Name: "c", Version: protocol.Vector{{ID: myID, Value: 1000}}}, {Name: "d", Version: protocol.Vector{{ID: myID, Value: 1000}}}, } local2 := []protocol.FileInfo{ local1[0], // [1] deleted local1[2], {Name: "d", Version: protocol.Vector{{ID: myID, Value: 1002}}}, {Name: "e", Version: protocol.Vector{{ID: myID, Value: 1000}}}, } m.Replace(protocol.LocalDeviceID, local1) c0 := m.LocalVersion(protocol.LocalDeviceID) m.Replace(protocol.LocalDeviceID, local2) c1 := m.LocalVersion(protocol.LocalDeviceID) if !(c1 > c0) { t.Fatal("Local version number should have incremented") } }
func Benchmark10kUpdateSme(b *testing.B) { var remote []protocol.FileInfo for i := 0; i < 10000; i++ { remote = append(remote, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}}) } ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { b.Fatal(err) } m := db.NewFileSet("test", ldb) m.Replace(remoteDevice0, remote) var local []protocol.FileInfo for i := 0; i < 10000; i++ { local = append(local, protocol.FileInfo{Name: fmt.Sprintf("file%d", i), Version: protocol.Vector{{ID: myID, Value: 1000}}}) } m.Replace(protocol.LocalDeviceID, local) b.ResetTimer() for i := 0; i < b.N; i++ { m.Update(protocol.LocalDeviceID, local) } }
func TestNamespacedReset(t *testing.T) { ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } n1 := NewNamespacedKV(ldb, "foo") n1.PutString("test1", "yo1") n1.PutString("test2", "yo2") n1.PutString("test3", "yo3") if v, ok := n1.String("test1"); v != "yo1" || !ok { t.Errorf("Incorrect return v %q != \"yo1\" || ok %v != true", v, ok) } if v, ok := n1.String("test2"); v != "yo2" || !ok { t.Errorf("Incorrect return v %q != \"yo2\" || ok %v != true", v, ok) } if v, ok := n1.String("test3"); v != "yo3" || !ok { t.Errorf("Incorrect return v %q != \"yo3\" || ok %v != true", v, ok) } n1.Reset() if v, ok := n1.String("test1"); v != "" || ok { t.Errorf("Incorrect return v %q != \"\" || ok %v != false", v, ok) } if v, ok := n1.String("test2"); v != "" || ok { t.Errorf("Incorrect return v %q != \"\" || ok %v != false", v, ok) } if v, ok := n1.String("test3"); v != "" || ok { t.Errorf("Incorrect return v %q != \"\" || ok %v != false", v, ok) } }
// Make sure that the copier routine hashes the content when asked, and pulls // if it fails to find the block. func TestLastResortPulling(t *testing.T) { db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db) m.AddFolder(defaultFolderConfig) // Add a file to index (with the incorrect block representation, as content // doesn't actually match the block list) file := protocol.FileInfo{ Name: "empty", Flags: 0, Modified: 0, Blocks: []protocol.BlockInfo{blocks[0]}, } m.updateLocals("default", []protocol.FileInfo{file}) // Pretend that we are handling a new file of the same content but // with a different name (causing to copy that particular block) file.Name = "newfile" iterFn := func(folder, file string, index int32) bool { return true } // Check that that particular block is there if !m.finder.Iterate(blocks[0].Hash, iterFn) { t.Error("Expected block not found") } p := rwFolder{ folder: "default", dir: "testdata", model: m, } copyChan := make(chan copyBlocksState) pullChan := make(chan pullBlockState, 1) finisherChan := make(chan *sharedPullerState, 1) // Run a single copier routine go p.copierRoutine(copyChan, pullChan, finisherChan) p.handleFile(file, copyChan, finisherChan) // Copier should hash empty file, realise that the region it has read // doesn't match the hash which was advertised by the block map, fix it // and ask to pull the block. <-pullChan // Verify that it did fix the incorrect hash. if m.finder.Iterate(blocks[0].Hash, iterFn) { t.Error("Found unexpected block") } if !m.finder.Iterate(scanner.SHA256OfNothing, iterFn) { t.Error("Expected block not found") } (<-finisherChan).fd.Close() os.Remove(filepath.Join("testdata", defTempNamer.TempName("newfile"))) }
func setup() (*leveldb.DB, *BlockFinder) { // Setup db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { panic(err) } return db, NewBlockFinder(db) }
func (ulevel) OpenDatabase(name string, o level.UnderlyingOptions) (dtb level.UnderlyingDatabase, err error) { stor, err := storage.OpenFile(name) if err != nil { return } var dtbe *leveldb.DB dtbe, err = leveldb.Open(stor, o.(opts).Options) dtb = db{dtbe, stor} return }
// newMemoryNodeDB creates a new in-memory node database without a persistent // backend. func newMemoryNodeDB() (*nodeDB, error) { db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { return nil, err } return &nodeDB{ lvl: db, quit: make(chan struct{}), }, nil }
func TestHandleFileWithTemp(t *testing.T) { // After diff between required and existing we should: // Copy: 2, 5, 8 // Pull: 1, 3, 4, 6, 7 // After dropping out blocks already on the temp file we should: // Copy: 5, 8 // Pull: 1, 6 // Create existing file existingFile := protocol.FileInfo{ Name: "file", Flags: 0, Modified: 0, Blocks: []protocol.BlockInfo{ blocks[0], blocks[2], blocks[0], blocks[0], blocks[5], blocks[0], blocks[0], blocks[8], }, } // Create target file requiredFile := existingFile requiredFile.Blocks = blocks[1:] db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db) m.AddFolder(defaultFolderConfig) // Update index m.updateLocals("default", []protocol.FileInfo{existingFile}) p := rwFolder{ folder: "default", dir: "testdata", model: m, errors: make(map[string]string), errorsMut: sync.NewMutex(), } copyChan := make(chan copyBlocksState, 1) p.handleFile(requiredFile, copyChan, nil) // Receive the results toCopy := <-copyChan if len(toCopy.blocks) != 4 { t.Errorf("Unexpected count of copy blocks: %d != 4", len(toCopy.blocks)) } for i, eq := range []int{1, 5, 6, 8} { if string(toCopy.blocks[i].Hash) != string(blocks[eq].Hash) { t.Errorf("Block mismatch: %s != %s", toCopy.blocks[i].String(), blocks[eq].String()) } } }
func TestRequest(t *testing.T) { db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil) // device1 shares default, but device2 doesn't m.AddFolder(defaultFolderConfig) m.StartFolderRO("default") m.ServeBackground() m.ScanFolder("default") bs := make([]byte, protocol.BlockSize) // Existing, shared file bs = bs[:6] err := m.Request(device1, "default", "foo", 0, nil, 0, nil, bs) if err != nil { t.Error(err) } if bytes.Compare(bs, []byte("foobar")) != 0 { t.Errorf("Incorrect data from request: %q", string(bs)) } // Existing, nonshared file err = m.Request(device2, "default", "foo", 0, nil, 0, nil, bs) if err == nil { t.Error("Unexpected nil error on insecure file read") } // Nonexistent file err = m.Request(device1, "default", "nonexistent", 0, nil, 0, nil, bs) if err == nil { t.Error("Unexpected nil error on insecure file read") } // Shared folder, but disallowed file name err = m.Request(device1, "default", "../walk.go", 0, nil, 0, nil, bs) if err == nil { t.Error("Unexpected nil error on insecure file read") } // Negative offset err = m.Request(device1, "default", "foo", -4, nil, 0, nil, bs[:0]) if err == nil { t.Error("Unexpected nil error on insecure file read") } // Larger block than available bs = bs[:42] err = m.Request(device1, "default", "foo", 0, nil, 0, nil, bs) if err == nil { t.Error("Unexpected nil error on insecure file read") } }
func TestDeviceRename(t *testing.T) { ccm := protocol.ClusterConfigMessage{ ClientName: "syncthing", ClientVersion: "v0.9.4", } defer os.Remove("tmpconfig.xml") rawCfg := config.New(device1) rawCfg.Devices = []config.DeviceConfiguration{ { DeviceID: device1, }, } cfg := config.Wrap("tmpconfig.xml", rawCfg) db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", db) m.ServeBackground() if cfg.Devices()[device1].Name != "" { t.Errorf("Device already has a name") } m.ClusterConfig(device1, ccm) if cfg.Devices()[device1].Name != "" { t.Errorf("Device already has a name") } ccm.Options = []protocol.Option{ { Key: "name", Value: "tester", }, } m.ClusterConfig(device1, ccm) if cfg.Devices()[device1].Name != "tester" { t.Errorf("Device did not get a name") } ccm.Options[0].Value = "tester2" m.ClusterConfig(device1, ccm) if cfg.Devices()[device1].Name != "tester" { t.Errorf("Device name got overwritten") } cfgw, err := config.Load("tmpconfig.xml", protocol.LocalDeviceID) if err != nil { t.Error(err) return } if cfgw.Devices()[device1].Name != "tester" { t.Errorf("Device name not saved in config") } }
func BenchmarkIndex00100(b *testing.B) { db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(nil, "device", "syncthing", "dev", db) m.AddFolder(config.FolderConfiguration{ID: "default", Path: "testdata"}) m.ScanFolder("default") files := genFiles(100) b.ResetTimer() for i := 0; i < b.N; i++ { m.Index(device1, "default", files) } }
func BenchmarkIndex10000(b *testing.B) { db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel("/tmp", nil, "syncthing", "dev", db) m.AddRepo(config.RepositoryConfiguration{ID: "default", Directory: "testdata"}) m.ScanRepo("default") files := genFiles(10000) b.ResetTimer() for i := 0; i < b.N; i++ { m.Index(node1, "default", files) } }
func TestMain(m *testing.M) { ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { fmt.Printf("Unable to create levelDB database: %v\n", err) os.Exit(-1) } db = Wrap(ldb, NewConfig()) r := m.Run() db.Close() os.Exit(r) }
// Test that updating a file removes it's old blocks from the blockmap func TestCopierCleanup(t *testing.T) { iterFn := func(folder, file string, index uint32) bool { return true } fcfg := config.FolderConfiguration{ID: "default", Path: "testdata"} cfg := config.Configuration{Folders: []config.FolderConfiguration{fcfg}} db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(config.Wrap("/tmp/test", cfg), "device", "syncthing", "dev", db) m.AddFolder(fcfg) // Create a file file := protocol.FileInfo{ Name: "test", Flags: 0, Modified: 0, Blocks: []protocol.BlockInfo{blocks[0]}, } // Add file to index m.updateLocal("default", file) if !m.finder.Iterate(blocks[0].Hash, iterFn) { t.Error("Expected block not found") } file.Blocks = []protocol.BlockInfo{blocks[1]} file.Version++ // Update index (removing old blocks) m.updateLocal("default", file) if m.finder.Iterate(blocks[0].Hash, iterFn) { t.Error("Unexpected block found") } if !m.finder.Iterate(blocks[1].Hash, iterFn) { t.Error("Expected block not found") } file.Blocks = []protocol.BlockInfo{blocks[0]} file.Version++ // Update index (removing old blocks) m.updateLocal("default", file) if !m.finder.Iterate(blocks[0].Hash, iterFn) { t.Error("Unexpected block found") } if m.finder.Iterate(blocks[1].Hash, iterFn) { t.Error("Expected block not found") } }
func TestListDropRepo(t *testing.T) { db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } s0 := files.NewSet("test0", db) local1 := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000}, protocol.FileInfo{Name: "b", Version: 1000}, protocol.FileInfo{Name: "c", Version: 1000}, } s0.Replace(protocol.LocalNodeID, local1) s1 := files.NewSet("test1", db) local2 := []protocol.FileInfo{ protocol.FileInfo{Name: "d", Version: 1002}, protocol.FileInfo{Name: "e", Version: 1002}, protocol.FileInfo{Name: "f", Version: 1002}, } s1.Replace(remoteNode0, local2) // Check that we have both repos and their data is in the global list expectedRepoList := []string{"test0", "test1"} if actualRepoList := files.ListRepos(db); !reflect.DeepEqual(actualRepoList, expectedRepoList) { t.Fatalf("RepoList mismatch\nE: %v\nA: %v", expectedRepoList, actualRepoList) } if l := len(globalList(s0)); l != 3 { t.Errorf("Incorrect global length %d != 3 for s0", l) } if l := len(globalList(s1)); l != 3 { t.Errorf("Incorrect global length %d != 3 for s1", l) } // Drop one of them and check that it's gone. files.DropRepo(db, "test1") expectedRepoList = []string{"test0"} if actualRepoList := files.ListRepos(db); !reflect.DeepEqual(actualRepoList, expectedRepoList) { t.Fatalf("RepoList mismatch\nE: %v\nA: %v", expectedRepoList, actualRepoList) } if l := len(globalList(s0)); l != 3 { t.Errorf("Incorrect global length %d != 3 for s0", l) } if l := len(globalList(s1)); l != 0 { t.Errorf("Incorrect global length %d != 0 for s1", l) } }
// Test that updating a file removes it's old blocks from the blockmap func TestCopierCleanup(t *testing.T) { iterFn := func(folder, file string, index int32) bool { return true } db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db) m.AddFolder(defaultFolderConfig) // Create a file file := protocol.FileInfo{ Name: "test", Flags: 0, Modified: 0, Blocks: []protocol.BlockInfo{blocks[0]}, } // Add file to index m.updateLocals("default", []protocol.FileInfo{file}) if !m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Expected block not found") } file.Blocks = []protocol.BlockInfo{blocks[1]} file.Version = file.Version.Update(protocol.LocalDeviceID.Short()) // Update index (removing old blocks) m.updateLocals("default", []protocol.FileInfo{file}) if m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Unexpected block found") } if !m.finder.Iterate(folders, blocks[1].Hash, iterFn) { t.Error("Expected block not found") } file.Blocks = []protocol.BlockInfo{blocks[0]} file.Version = file.Version.Update(protocol.LocalDeviceID.Short()) // Update index (removing old blocks) m.updateLocals("default", []protocol.FileInfo{file}) if !m.finder.Iterate(folders, blocks[0].Hash, iterFn) { t.Error("Unexpected block found") } if m.finder.Iterate(folders, blocks[1].Hash, iterFn) { t.Error("Expected block not found") } }
func TestListDropFolder(t *testing.T) { ldb, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } s0 := db.NewFileSet("test0", ldb) local1 := []protocol.FileInfo{ {Name: "a", Version: protocol.Vector{{ID: myID, Value: 1000}}}, {Name: "b", Version: protocol.Vector{{ID: myID, Value: 1000}}}, {Name: "c", Version: protocol.Vector{{ID: myID, Value: 1000}}}, } s0.Replace(protocol.LocalDeviceID, local1) s1 := db.NewFileSet("test1", ldb) local2 := []protocol.FileInfo{ {Name: "d", Version: protocol.Vector{{ID: myID, Value: 1002}}}, {Name: "e", Version: protocol.Vector{{ID: myID, Value: 1002}}}, {Name: "f", Version: protocol.Vector{{ID: myID, Value: 1002}}}, } s1.Replace(remoteDevice0, local2) // Check that we have both folders and their data is in the global list expectedFolderList := []string{"test0", "test1"} if actualFolderList := db.ListFolders(ldb); !reflect.DeepEqual(actualFolderList, expectedFolderList) { t.Fatalf("FolderList mismatch\nE: %v\nA: %v", expectedFolderList, actualFolderList) } if l := len(globalList(s0)); l != 3 { t.Errorf("Incorrect global length %d != 3 for s0", l) } if l := len(globalList(s1)); l != 3 { t.Errorf("Incorrect global length %d != 3 for s1", l) } // Drop one of them and check that it's gone. db.DropFolder(ldb, "test1") expectedFolderList = []string{"test0"} if actualFolderList := db.ListFolders(ldb); !reflect.DeepEqual(actualFolderList, expectedFolderList) { t.Fatalf("FolderList mismatch\nE: %v\nA: %v", expectedFolderList, actualFolderList) } if l := len(globalList(s0)); l != 3 { t.Errorf("Incorrect global length %d != 3 for s0", l) } if l := len(globalList(s1)); l != 0 { t.Errorf("Incorrect global length %d != 0 for s1", l) } }
func TestHandleFile(t *testing.T) { // After the diff between required and existing we should: // Copy: 2, 5, 8 // Pull: 1, 3, 4, 6, 7 // Create existing file existingFile := protocol.FileInfo{ Name: "filex", Flags: 0, Modified: 0, Blocks: []protocol.BlockInfo{ blocks[0], blocks[2], blocks[0], blocks[0], blocks[5], blocks[0], blocks[0], blocks[8], }, } // Create target file requiredFile := existingFile requiredFile.Blocks = blocks[1:] db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(config.Wrap("/tmp/test", config.Configuration{}), "device", "syncthing", "dev", db) m.AddFolder(config.FolderConfiguration{ID: "default", Path: "testdata"}) // Update index m.updateLocal("default", existingFile) p := Puller{ folder: "default", dir: "testdata", model: m, } copyChan := make(chan copyBlocksState, 1) p.handleFile(requiredFile, copyChan, nil) // Receive the results toCopy := <-copyChan if len(toCopy.blocks) != 8 { t.Errorf("Unexpected count of copy blocks: %d != 8", len(toCopy.blocks)) } for i, block := range toCopy.blocks { if string(block.Hash) != string(blocks[i+1].Hash) { t.Errorf("Block mismatch: %s != %s", block.String(), blocks[i+1].String()) } } }
func (s MemStore) Open(path string, cfg *config.Config) (driver.IDB, error) { db := new(DB) db.path = path db.cfg = &cfg.LevelDB db.initOpts() var err error db.db, err = leveldb.Open(storage.NewMemStorage(), db.opts) if err != nil { return nil, err } return db, nil }
func benchmarkIndex(b *testing.B, nfiles int) { db, _ := leveldb.Open(storage.NewMemStorage(), nil) m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db) m.AddFolder(defaultFolderConfig) m.StartFolderRO("default") m.ServeBackground() files := genFiles(nfiles) m.Index(device1, "default", files, 0, nil) b.ResetTimer() for i := 0; i < b.N; i++ { m.Index(device1, "default", files, 0, nil) } b.ReportAllocs() }
func NewGoLevelDBStorageBackend(path string) StorageBackend { desc, err := desc.OpenFile(path) if err != nil { panic(err) } db, err := leveldb.Open(desc, &opt.Options{Flag: opt.OFCreateIfMissing}) if err != nil { panic(err) } ro := &opt.ReadOptions{} wo := &opt.WriteOptions{} return &GoLevelDBStorageBackend{store: db, ro: ro, wo: wo} }