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(remoteNode, 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 TestChanges(t *testing.T) { m := files.NewSet() local1 := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1000}, scanner.File{Name: "c", Version: 1000}, scanner.File{Name: "d", Version: 1000}, } local2 := []scanner.File{ local1[0], // [1] deleted local1[2], scanner.File{Name: "d", Version: 1002}, scanner.File{Name: "e", Version: 1000}, } m.ReplaceWithDelete(cid.LocalID, local1) c0 := m.Changes(cid.LocalID) m.ReplaceWithDelete(cid.LocalID, local2) c1 := m.Changes(cid.LocalID) if !(c1 > c0) { t.Fatal("Change number should have incremented") } m.ReplaceWithDelete(cid.LocalID, local2) c2 := m.Changes(cid.LocalID) if c2 != c1 { t.Fatal("Change number should be unchanged") } }
func main() { log.SetFlags(0) log.SetOutput(os.Stdout) repo := flag.String("repo", "default", "Repository ID") node := flag.String("node", "", "Node ID (blank for global)") flag.Parse() db, err := leveldb.OpenFile(flag.Arg(0), nil) if err != nil { log.Fatal(err) } fs := files.NewSet(*repo, db) if *node == "" { log.Printf("*** Global index for repo %q", *repo) fs.WithGlobal(func(f protocol.FileInfo) bool { fmt.Println(f) fmt.Println("\t", fs.Availability(f.Name)) return true }) } else { n, err := protocol.NodeIDFromString(*node) if err != nil { log.Fatal(err) } log.Printf("*** Have index for repo %q node %q", *repo, n) fs.WithHave(n, func(f protocol.FileInfo) bool { fmt.Println(f) return true }) } }
func TestGlobalReset(t *testing.T) { m := files.NewSet() local := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1000}, scanner.File{Name: "c", Version: 1000}, scanner.File{Name: "d", Version: 1000}, } remote := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1001}, scanner.File{Name: "c", Version: 1002}, scanner.File{Name: "e", Version: 1000}, } m.ReplaceWithDelete(cid.LocalID, local) g := m.Global() sort.Sort(fileList(g)) if !reflect.DeepEqual(g, local) { t.Errorf("Global incorrect;\n%v !=\n%v", g, local) } m.Replace(1, remote) m.Replace(1, nil) g = m.Global() sort.Sort(fileList(g)) if !reflect.DeepEqual(g, local) { t.Errorf("Global incorrect;\n%v !=\n%v", g, local) } }
func TestNeed(t *testing.T) { m := files.NewSet() local := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1000}, scanner.File{Name: "c", Version: 1000}, scanner.File{Name: "d", Version: 1000}, } remote := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1001}, scanner.File{Name: "c", Version: 1002}, scanner.File{Name: "e", Version: 1000}, } shouldNeed := []scanner.File{ scanner.File{Name: "b", Version: 1001}, scanner.File{Name: "c", Version: 1002}, scanner.File{Name: "e", Version: 1000}, } m.ReplaceWithDelete(cid.LocalID, local) m.Replace(1, remote) need := m.Need(0) sort.Sort(fileList(need)) sort.Sort(fileList(shouldNeed)) if !reflect.DeepEqual(need, shouldNeed) { t.Errorf("Need incorrect;\n%v !=\n%v", need, shouldNeed) } }
func Benchmark10kGlobal(b *testing.B) { var remote []scanner.File for i := 0; i < 10000; i++ { remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000}) } m := files.NewSet() m.Replace(cid.LocalID+1, remote) var local []scanner.File for i := 0; i < 2000; i++ { local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000}) } for i := 2000; i < 10000; i++ { local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 980}) } m.ReplaceWithDelete(cid.LocalID, local) b.ResetTimer() for i := 0; i < b.N; i++ { fs := m.Global() if l := len(fs); l != 10000 { b.Errorf("wrong length %d != 10k", l) } } }
func Benchmark10kUpdateChg(b *testing.B) { var remote []scanner.File for i := 0; i < 10000; i++ { remote = append(remote, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000}) } m := files.NewSet() m.Replace(1, remote) var local []scanner.File for i := 0; i < 10000; i++ { local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000}) } m.ReplaceWithDelete(cid.LocalID, local) b.ResetTimer() for i := 0; i < b.N; i++ { b.StopTimer() for j := range local { local[j].Version++ } b.StartTimer() m.Update(cid.LocalID, local) } }
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: 1000}) } db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { b.Fatal(err) } m := files.NewSet("test", db) m.Replace(remoteNode, 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 := globalList(m) if l := len(fs); l != 10000 { b.Errorf("wrong length %d != 10k", l) } } }
func Benchmark10kReplace(b *testing.B) { var local []scanner.File for i := 0; i < 10000; i++ { local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000}) } b.ResetTimer() for i := 0; i < b.N; i++ { m := files.NewSet() m.ReplaceWithDelete(cid.LocalID, local) } }
func (m *Model) AddRepo(id, dir string, nodes []NodeConfiguration) { if m.started { panic("cannot add repo to started model") } if len(id) == 0 { panic("cannot add empty repo id") } m.rmut.Lock() m.repoDirs[id] = dir m.repoFiles[id] = files.NewSet() m.repoNodes[id] = make([]string, len(nodes)) for i, node := range nodes { m.repoNodes[id][i] = node.NodeID m.nodeRepos[node.NodeID] = append(m.nodeRepos[node.NodeID], id) } m.addedRepo = true m.rmut.Unlock() }
func TestGlobalReset(t *testing.T) { db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } m := files.NewSet("test", db) local := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000}, protocol.FileInfo{Name: "b", Version: 1000}, protocol.FileInfo{Name: "c", Version: 1000}, protocol.FileInfo{Name: "d", Version: 1000}, } remote := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000}, protocol.FileInfo{Name: "b", Version: 1001}, protocol.FileInfo{Name: "c", Version: 1002}, protocol.FileInfo{Name: "e", Version: 1000}, } m.ReplaceWithDelete(protocol.LocalNodeID, local) g := globalList(m) sort.Sort(fileList(g)) if fmt.Sprint(g) != fmt.Sprint(local) { t.Errorf("Global incorrect;\n%v !=\n%v", g, local) } m.Replace(remoteNode, remote) m.Replace(remoteNode, nil) g = globalList(m) sort.Sort(fileList(g)) if fmt.Sprint(g) != fmt.Sprint(local) { t.Errorf("Global incorrect;\n%v !=\n%v", g, local) } }
func TestNeed(t *testing.T) { db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } m := files.NewSet("test", db) local := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000}, protocol.FileInfo{Name: "b", Version: 1000}, protocol.FileInfo{Name: "c", Version: 1000}, protocol.FileInfo{Name: "d", Version: 1000}, } remote := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000}, protocol.FileInfo{Name: "b", Version: 1001}, protocol.FileInfo{Name: "c", Version: 1002}, protocol.FileInfo{Name: "e", Version: 1000}, } shouldNeed := []protocol.FileInfo{ protocol.FileInfo{Name: "b", Version: 1001}, protocol.FileInfo{Name: "c", Version: 1002}, protocol.FileInfo{Name: "e", Version: 1000}, } m.ReplaceWithDelete(protocol.LocalNodeID, local) m.Replace(remoteNode, remote) need := needList(m, protocol.LocalNodeID) sort.Sort(fileList(need)) sort.Sort(fileList(shouldNeed)) if fmt.Sprint(need) != fmt.Sprint(shouldNeed) { t.Errorf("Need incorrect;\n%v !=\n%v", need, shouldNeed) } }
func (m *Model) AddRepo(cfg config.RepositoryConfiguration) { if m.started { panic("cannot add repo to started model") } if len(cfg.ID) == 0 { panic("cannot add empty repo id") } m.rmut.Lock() m.repoCfgs[cfg.ID] = cfg m.repoFiles[cfg.ID] = files.NewSet(cfg.ID, m.db) m.suppressor[cfg.ID] = &suppressor{threshold: int64(m.cfg.Options.MaxChangeKbps)} m.repoNodes[cfg.ID] = make([]protocol.NodeID, len(cfg.Nodes)) for i, node := range cfg.Nodes { m.repoNodes[cfg.ID][i] = node.NodeID m.nodeRepos[node.NodeID] = append(m.nodeRepos[node.NodeID], cfg.ID) } m.addedRepo = true m.rmut.Unlock() }
func TestChanges(t *testing.T) { db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } m := files.NewSet("test", db) local1 := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000}, protocol.FileInfo{Name: "b", Version: 1000}, protocol.FileInfo{Name: "c", Version: 1000}, protocol.FileInfo{Name: "d", Version: 1000}, } local2 := []protocol.FileInfo{ local1[0], // [1] deleted local1[2], protocol.FileInfo{Name: "d", Version: 1002}, protocol.FileInfo{Name: "e", Version: 1000}, } m.ReplaceWithDelete(protocol.LocalNodeID, local1) c0 := m.Changes(protocol.LocalNodeID) m.ReplaceWithDelete(protocol.LocalNodeID, local2) c1 := m.Changes(protocol.LocalNodeID) if !(c1 > c0) { t.Fatal("Change number should have incremented") } m.ReplaceWithDelete(protocol.LocalNodeID, local2) c2 := m.Changes(protocol.LocalNodeID) if c2 != c1 { t.Fatal("Change number should be unchanged") } }
func TestLocalDeleted(t *testing.T) { m := files.NewSet() lamport.Default = lamport.Clock{} local1 := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1000}, scanner.File{Name: "c", Version: 1000}, scanner.File{Name: "d", Version: 1000}, scanner.File{Name: "z", Version: 1000, Flags: protocol.FlagDirectory}, } m.ReplaceWithDelete(cid.LocalID, local1) m.ReplaceWithDelete(cid.LocalID, []scanner.File{ local1[0], // [1] removed local1[2], local1[3], local1[4], }) m.ReplaceWithDelete(cid.LocalID, []scanner.File{ local1[0], local1[2], // [3] removed local1[4], }) m.ReplaceWithDelete(cid.LocalID, []scanner.File{ local1[0], local1[2], // [4] removed }) expectedGlobal1 := []scanner.File{ local1[0], scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted}, local1[2], scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted}, scanner.File{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory}, } g := m.Global() sort.Sort(fileList(g)) sort.Sort(fileList(expectedGlobal1)) if !reflect.DeepEqual(g, expectedGlobal1) { t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal1) } m.ReplaceWithDelete(cid.LocalID, []scanner.File{ local1[0], // [2] removed }) expectedGlobal2 := []scanner.File{ local1[0], scanner.File{Name: "b", Version: 1001, Flags: protocol.FlagDeleted}, scanner.File{Name: "c", Version: 1004, Flags: protocol.FlagDeleted}, scanner.File{Name: "d", Version: 1002, Flags: protocol.FlagDeleted}, scanner.File{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory}, } g = m.Global() sort.Sort(fileList(g)) sort.Sort(fileList(expectedGlobal2)) if !reflect.DeepEqual(g, expectedGlobal2) { t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal2) } }
func TestGlobalSet(t *testing.T) { lamport.Default = lamport.Clock{} db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } m := files.NewSet("test", db) local0 := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000, Blocks: genBlocks(1)}, protocol.FileInfo{Name: "b", Version: 1000, Blocks: genBlocks(2)}, protocol.FileInfo{Name: "c", Version: 1000, Blocks: genBlocks(3)}, protocol.FileInfo{Name: "d", Version: 1000, Blocks: genBlocks(4)}, protocol.FileInfo{Name: "z", Version: 1000, Blocks: genBlocks(8)}, } local1 := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000, Blocks: genBlocks(1)}, protocol.FileInfo{Name: "b", Version: 1000, Blocks: genBlocks(2)}, protocol.FileInfo{Name: "c", Version: 1000, Blocks: genBlocks(3)}, protocol.FileInfo{Name: "d", Version: 1000, Blocks: genBlocks(4)}, } localTot := []protocol.FileInfo{ local0[0], local0[1], local0[2], local0[3], protocol.FileInfo{Name: "z", Version: 1001, Flags: protocol.FlagDeleted}, } remote0 := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000, Blocks: genBlocks(1)}, protocol.FileInfo{Name: "b", Version: 1000, Blocks: genBlocks(2)}, protocol.FileInfo{Name: "c", Version: 1002, Blocks: genBlocks(5)}, } remote1 := []protocol.FileInfo{ protocol.FileInfo{Name: "b", Version: 1001, Blocks: genBlocks(6)}, protocol.FileInfo{Name: "e", Version: 1000, Blocks: genBlocks(7)}, } remoteTot := []protocol.FileInfo{ remote0[0], remote1[0], remote0[2], remote1[1], } expectedGlobal := []protocol.FileInfo{ remote0[0], remote1[0], remote0[2], localTot[3], remote1[1], localTot[4], } expectedLocalNeed := []protocol.FileInfo{ remote1[0], remote0[2], remote1[1], } expectedRemoteNeed := []protocol.FileInfo{ local0[3], } m.ReplaceWithDelete(protocol.LocalNodeID, local0) m.ReplaceWithDelete(protocol.LocalNodeID, local1) m.Replace(remoteNode, remote0) m.Update(remoteNode, remote1) g := globalList(m) sort.Sort(fileList(g)) if fmt.Sprint(g) != fmt.Sprint(expectedGlobal) { t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal) } h := haveList(m, protocol.LocalNodeID) sort.Sort(fileList(h)) if fmt.Sprint(h) != fmt.Sprint(localTot) { t.Errorf("Have incorrect;\n A: %v !=\n E: %v", h, localTot) } h = haveList(m, remoteNode) sort.Sort(fileList(h)) if fmt.Sprint(h) != fmt.Sprint(remoteTot) { t.Errorf("Have incorrect;\n A: %v !=\n E: %v", h, remoteTot) } n := needList(m, protocol.LocalNodeID) sort.Sort(fileList(n)) if fmt.Sprint(n) != fmt.Sprint(expectedLocalNeed) { t.Errorf("Need incorrect;\n A: %v !=\n E: %v", n, expectedLocalNeed) } n = needList(m, remoteNode) sort.Sort(fileList(n)) if fmt.Sprint(n) != fmt.Sprint(expectedRemoteNeed) { t.Errorf("Need incorrect;\n A: %v !=\n E: %v", n, expectedRemoteNeed) } f := m.Get(protocol.LocalNodeID, "b") if fmt.Sprint(f) != fmt.Sprint(localTot[1]) { t.Errorf("Get incorrect;\n A: %v !=\n E: %v", f, localTot[1]) } f = m.Get(remoteNode, "b") if fmt.Sprint(f) != fmt.Sprint(remote1[0]) { t.Errorf("Get incorrect;\n A: %v !=\n E: %v", f, remote1[0]) } f = m.GetGlobal("b") if fmt.Sprint(f) != fmt.Sprint(remote1[0]) { t.Errorf("GetGlobal incorrect;\n A: %v !=\n E: %v", f, remote1[0]) } f = m.Get(protocol.LocalNodeID, "zz") if f.Name != "" { t.Errorf("Get incorrect;\n A: %v !=\n E: %v", f, protocol.FileInfo{}) } f = m.GetGlobal("zz") if f.Name != "" { t.Errorf("GetGlobal incorrect;\n A: %v !=\n E: %v", f, protocol.FileInfo{}) } av := []protocol.NodeID{protocol.LocalNodeID, remoteNode} a := m.Availability("a") if !(len(a) == 2 && (a[0] == av[0] && a[1] == av[1] || a[0] == av[1] && a[1] == av[0])) { t.Errorf("Availability incorrect;\n A: %v !=\n E: %v", a, av) } a = m.Availability("b") if len(a) != 1 || a[0] != remoteNode { t.Errorf("Availability incorrect;\n A: %v !=\n E: %v", a, remoteNode) } a = m.Availability("d") if len(a) != 1 || a[0] != protocol.LocalNodeID { t.Errorf("Availability incorrect;\n A: %v !=\n E: %v", a, protocol.LocalNodeID) } }
func TestGlobalSet(t *testing.T) { m := files.NewSet() local := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1000}, scanner.File{Name: "c", Version: 1000}, scanner.File{Name: "d", Version: 1000}, } remote0 := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "c", Version: 1002}, } remote1 := []scanner.File{ scanner.File{Name: "b", Version: 1001}, scanner.File{Name: "e", Version: 1000}, } remoteTot := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1001}, scanner.File{Name: "c", Version: 1002}, scanner.File{Name: "e", Version: 1000}, } expectedGlobal := []scanner.File{ scanner.File{Name: "a", Version: 1000}, scanner.File{Name: "b", Version: 1001}, scanner.File{Name: "c", Version: 1002}, scanner.File{Name: "d", Version: 1000}, scanner.File{Name: "e", Version: 1000}, } expectedLocalNeed := []scanner.File{ scanner.File{Name: "b", Version: 1001}, scanner.File{Name: "c", Version: 1002}, scanner.File{Name: "e", Version: 1000}, } expectedRemoteNeed := []scanner.File{ scanner.File{Name: "d", Version: 1000}, } m.ReplaceWithDelete(cid.LocalID, local) m.Replace(1, remote0) m.Update(1, remote1) g := m.Global() sort.Sort(fileList(g)) if !reflect.DeepEqual(g, expectedGlobal) { t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal) } h := m.Have(cid.LocalID) sort.Sort(fileList(h)) if !reflect.DeepEqual(h, local) { t.Errorf("Have incorrect;\n A: %v !=\n E: %v", h, local) } h = m.Have(1) sort.Sort(fileList(h)) if !reflect.DeepEqual(h, remoteTot) { t.Errorf("Have incorrect;\n A: %v !=\n E: %v", h, remoteTot) } n := m.Need(cid.LocalID) sort.Sort(fileList(n)) if !reflect.DeepEqual(n, expectedLocalNeed) { t.Errorf("Need incorrect;\n A: %v !=\n E: %v", n, expectedLocalNeed) } n = m.Need(1) sort.Sort(fileList(n)) if !reflect.DeepEqual(n, expectedRemoteNeed) { t.Errorf("Need incorrect;\n A: %v !=\n E: %v", n, expectedRemoteNeed) } f := m.Get(cid.LocalID, "b") if !reflect.DeepEqual(f, local[1]) { t.Errorf("Get incorrect;\n A: %v !=\n E: %v", f, local[1]) } f = m.Get(1, "b") if !reflect.DeepEqual(f, remote1[0]) { t.Errorf("Get incorrect;\n A: %v !=\n E: %v", f, remote1[0]) } f = m.GetGlobal("b") if !reflect.DeepEqual(f, remote1[0]) { t.Errorf("Get incorrect;\n A: %v !=\n E: %v", f, remote1[0]) } a := int(m.Availability("a")) if av := 1<<0 + 1<<1; a != av { t.Errorf("Availability incorrect;\n A: %v !=\n E: %v", a, av) } a = int(m.Availability("b")) if av := 1 << 1; a != av { t.Errorf("Availability incorrect;\n A: %v !=\n E: %v", a, av) } a = int(m.Availability("d")) if av := 1 << 0; a != av { t.Errorf("Availability incorrect;\n A: %v !=\n E: %v", a, av) } }
func TestLocalDeleted(t *testing.T) { db, err := leveldb.Open(storage.NewMemStorage(), nil) if err != nil { t.Fatal(err) } m := files.NewSet("test", db) lamport.Default = lamport.Clock{} local1 := []protocol.FileInfo{ protocol.FileInfo{Name: "a", Version: 1000}, protocol.FileInfo{Name: "b", Version: 1000}, protocol.FileInfo{Name: "c", Version: 1000}, protocol.FileInfo{Name: "d", Version: 1000}, protocol.FileInfo{Name: "z", Version: 1000, Flags: protocol.FlagDirectory}, } m.ReplaceWithDelete(protocol.LocalNodeID, local1) m.ReplaceWithDelete(protocol.LocalNodeID, []protocol.FileInfo{ local1[0], // [1] removed local1[2], local1[3], local1[4], }) m.ReplaceWithDelete(protocol.LocalNodeID, []protocol.FileInfo{ local1[0], local1[2], // [3] removed local1[4], }) m.ReplaceWithDelete(protocol.LocalNodeID, []protocol.FileInfo{ local1[0], local1[2], // [4] removed }) expectedGlobal1 := []protocol.FileInfo{ local1[0], protocol.FileInfo{Name: "b", Version: 1001, Flags: protocol.FlagDeleted}, local1[2], protocol.FileInfo{Name: "d", Version: 1002, Flags: protocol.FlagDeleted}, protocol.FileInfo{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory}, } g := globalList(m) sort.Sort(fileList(g)) sort.Sort(fileList(expectedGlobal1)) if fmt.Sprint(g) != fmt.Sprint(expectedGlobal1) { t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal1) } m.ReplaceWithDelete(protocol.LocalNodeID, []protocol.FileInfo{ local1[0], // [2] removed }) expectedGlobal2 := []protocol.FileInfo{ local1[0], protocol.FileInfo{Name: "b", Version: 1001, Flags: protocol.FlagDeleted}, protocol.FileInfo{Name: "c", Version: 1004, Flags: protocol.FlagDeleted}, protocol.FileInfo{Name: "d", Version: 1002, Flags: protocol.FlagDeleted}, protocol.FileInfo{Name: "z", Version: 1003, Flags: protocol.FlagDeleted | protocol.FlagDirectory}, } g = globalList(m) sort.Sort(fileList(g)) sort.Sort(fileList(expectedGlobal2)) if fmt.Sprint(g) != fmt.Sprint(expectedGlobal2) { t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal2) } }