| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- package files
- import (
- "fmt"
- "reflect"
- "sort"
- "testing"
- "github.com/calmh/syncthing/cid"
- "github.com/calmh/syncthing/lamport"
- "github.com/calmh/syncthing/protocol"
- "github.com/calmh/syncthing/scanner"
- )
- type fileList []scanner.File
- func (l fileList) Len() int {
- return len(l)
- }
- func (l fileList) Less(a, b int) bool {
- return l[a].Name < l[b].Name
- }
- func (l fileList) Swap(a, b int) {
- l[a], l[b] = l[b], l[a]
- }
- func TestGlobalSet(t *testing.T) {
- m := 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},
- }
- 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},
- }
- m.ReplaceWithDelete(cid.LocalID, local)
- m.Replace(1, remote)
- g := m.Global()
- sort.Sort(fileList(g))
- sort.Sort(fileList(expectedGlobal))
- if !reflect.DeepEqual(g, expectedGlobal) {
- t.Errorf("Global incorrect;\n A: %v !=\n E: %v", g, expectedGlobal)
- }
- if lb := len(m.files); lb != 7 {
- t.Errorf("Num files incorrect %d != 7\n%v", lb, m.files)
- }
- }
- func TestLocalDeleted(t *testing.T) {
- m := 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 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 := NewSet()
- m.ReplaceWithDelete(cid.LocalID, local)
- }
- }
- 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 := 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 Benchmark10kUpdateSme(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 := 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++ {
- m.Update(cid.LocalID, local)
- }
- }
- func Benchmark10kNeed2k(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 := NewSet()
- m.Replace(cid.LocalID+1, remote)
- var local []scanner.File
- for i := 0; i < 8000; i++ {
- local = append(local, scanner.File{Name: fmt.Sprintf("file%d", i), Version: 1000})
- }
- for i := 8000; 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.Need(cid.LocalID)
- if l := len(fs); l != 2000 {
- b.Errorf("wrong length %d != 2k", l)
- }
- }
- }
- func Benchmark10kHave(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 := 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.Have(cid.LocalID)
- if l := len(fs); l != 10000 {
- b.Errorf("wrong length %d != 10k", l)
- }
- }
- }
- 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 := 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 TestGlobalReset(t *testing.T) {
- m := 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},
- }
- expectedGlobalKey := map[string]key{
- "a": keyFor(local[0]),
- "b": keyFor(local[1]),
- "c": keyFor(local[2]),
- "d": keyFor(local[3]),
- }
- m.ReplaceWithDelete(cid.LocalID, local)
- m.Replace(1, remote)
- m.Replace(1, nil)
- if !reflect.DeepEqual(m.globalKey, expectedGlobalKey) {
- t.Errorf("Global incorrect;\n%v !=\n%v", m.globalKey, expectedGlobalKey)
- }
- if lb := len(m.files); lb != 4 {
- t.Errorf("Num files incorrect %d != 4\n%v", lb, m.files)
- }
- }
- func TestNeed(t *testing.T) {
- m := 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 TestChanges(t *testing.T) {
- m := 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")
- }
- }
|