func TestFileTypeChange(t *testing.T) { // Use no versioning id, _ := protocol.DeviceIDFromString(id2) cfg, _ := config.Load("h2/config.xml", id) fld := cfg.Folders()["default"] fld.Versioning = config.VersioningConfiguration{} cfg.SetFolder(fld) cfg.Save() testFileTypeChange(t) }
func TestSyncClusterStaggeredVersioning(t *testing.T) { // Use staggered versioning id, _ := protocol.DeviceIDFromString(id2) cfg, _ := config.Load("h2/config.xml", id) fld := cfg.Folders()["default"] fld.Versioning = config.VersioningConfiguration{ Type: "staggered", } cfg.SetFolder(fld) cfg.Save() testSyncCluster(t) }
func loadConfig() (*config.Wrapper, error) { cfgFile := locations[locConfigFile] cfg, err := config.Load(cfgFile, myID) if err != nil { l.Infoln("Error loading config file; using defaults for now") myName, _ := os.Hostname() newCfg := defaultConfig(myName) cfg = config.Wrap(cfgFile, newCfg) } return cfg, err }
func TestFileTypeChangeSimpleVersioning(t *testing.T) { // Use simple versioning id, _ := protocol.DeviceIDFromString(id2) cfg, _ := config.Load("h2/config.xml", id) fld := cfg.Folders()["default"] fld.Versioning = config.VersioningConfiguration{ Type: "simple", Params: map[string]string{"keep": "5"}, } cfg.SetFolder(fld) cfg.Save() testFileTypeChange(t) }
func TestSyncClusterTrashcanVersioning(t *testing.T) { // Use simple versioning id, _ := protocol.DeviceIDFromString(id2) cfg, _ := config.Load("h2/config.xml", id) fld := cfg.Folders()["default"] fld.Versioning = config.VersioningConfiguration{ Type: "trashcan", Params: map[string]string{"cleanoutDays": "1"}, } cfg.SetFolder(fld) cfg.Save() testSyncCluster(t) }
func TestSymlinks(t *testing.T) { if !symlinksSupported() { t.Skip("symlinks unsupported") } // Use no versioning id, _ := protocol.DeviceIDFromString(id2) cfg, _ := config.Load("h2/config.xml", id) fld := cfg.Folders()["default"] fld.Versioning = config.VersioningConfiguration{} cfg.SetFolder(fld) cfg.Save() testSymlinks(t) }
func TestSymlinksSimpleVersioning(t *testing.T) { if !symlinksSupported() { t.Skip("symlinks unsupported") } // Use simple versioning id, _ := protocol.DeviceIDFromString(id2) cfg, _ := config.Load("h2/config.xml", id) fld := cfg.Folders()["default"] fld.Versioning = config.VersioningConfiguration{ Type: "simple", Params: map[string]string{"keep": "5"}, } cfg.SetFolder(fld) cfg.Save() testSymlinks(t) }
func TestOverride(t *testing.T) { // Enable "Master" on s1/default id, _ := protocol.DeviceIDFromString(id1) cfg, _ := config.Load("h1/config.xml", id) fld := cfg.Folders()["default"] fld.ReadOnly = true cfg.SetFolder(fld) os.Rename("h1/config.xml", "h1/config.xml.orig") defer osutil.Rename("h1/config.xml.orig", "h1/config.xml") cfg.Save() log.Println("Cleaning...") err := removeAll("s1", "s2", "h1/index*", "h2/index*") if err != nil { t.Fatal(err) } log.Println("Generating files...") err = generateFiles("s1", 100, 20, "../LICENSE") if err != nil { t.Fatal(err) } fd, err := os.Create("s1/testfile.txt") if err != nil { t.Fatal(err) } _, err = fd.WriteString("hello\n") if err != nil { t.Fatal(err) } err = fd.Close() if err != nil { t.Fatal(err) } expected, err := directoryContents("s1") if err != nil { t.Fatal(err) } master := startInstance(t, 1) defer checkedStop(t, master) slave := startInstance(t, 2) defer checkedStop(t, slave) log.Println("Syncing...") rc.AwaitSync("default", master, slave) log.Println("Verifying...") actual, err := directoryContents("s2") if err != nil { t.Fatal(err) } err = compareDirectoryContents(actual, expected) if err != nil { t.Fatal(err) } log.Println("Changing file on slave side...") fd, err = os.OpenFile("s2/testfile.txt", os.O_WRONLY|os.O_APPEND, 0644) if err != nil { t.Fatal(err) } _, err = fd.WriteString("text added to s2\n") if err != nil { t.Fatal(err) } err = fd.Close() if err != nil { t.Fatal(err) } if err := slave.Rescan("default"); err != nil { t.Fatal(err) } log.Println("Waiting for index to send...") time.Sleep(10 * time.Second) log.Println("Hitting Override on master...") if _, err := master.Post("/rest/db/override?folder=default", nil); err != nil { t.Fatal(err) } log.Println("Syncing...") rc.AwaitSync("default", master, slave) // Verify that the override worked fd, err = os.Open("s1/testfile.txt") if err != nil { t.Fatal(err) } bs, err := ioutil.ReadAll(fd) if err != nil { t.Fatal(err) } fd.Close() if strings.Contains(string(bs), "added to s2") { t.Error("Change should not have been synced to master") } fd, err = os.Open("s2/testfile.txt") if err != nil { t.Fatal(err) } bs, err = ioutil.ReadAll(fd) if err != nil { t.Fatal(err) } fd.Close() if strings.Contains(string(bs), "added to s2") { t.Error("Change should have been overridden on slave") } }
func (p *Process) eventLoop() { since := 0 notScanned := make(map[string]struct{}) start := time.Now() for { p.eventMut.Lock() if p.stop { p.eventMut.Unlock() return } p.eventMut.Unlock() time.Sleep(250 * time.Millisecond) events, err := p.Events(since) if err != nil { if time.Since(start) < 5*time.Second { // The API has probably not started yet, lets give it some time. continue } // If we're stopping, no need to print the error. p.eventMut.Lock() if p.stop { p.eventMut.Unlock() return } p.eventMut.Unlock() log.Println("eventLoop: events:", err) continue } since = events[len(events)-1].ID for _, ev := range events { switch ev.Type { case "Starting": // The Starting event tells us where the configuration is. Load // it and populate our list of folders. data := ev.Data.(map[string]interface{}) id, err := protocol.DeviceIDFromString(data["myID"].(string)) if err != nil { log.Println("eventLoop: DeviceIdFromString:", err) continue } p.id = id home := data["home"].(string) w, err := config.Load(filepath.Join(home, "config.xml"), protocol.LocalDeviceID) if err != nil { log.Println("eventLoop: Starting:", err) continue } for id := range w.Folders() { p.eventMut.Lock() p.folders = append(p.folders, id) p.eventMut.Unlock() notScanned[id] = struct{}{} } case "StateChanged": // When a folder changes to idle, we tick it off by removing // it from p.notScanned. if !p.startComplete { data := ev.Data.(map[string]interface{}) to := data["to"].(string) if to == "idle" { folder := data["folder"].(string) delete(notScanned, folder) if len(notScanned) == 0 { p.eventMut.Lock() p.startComplete = true p.startCompleteCond.Broadcast() p.eventMut.Unlock() } } } case "LocalIndexUpdated": data := ev.Data.(map[string]interface{}) folder := data["folder"].(string) version, _ := data["version"].(json.Number).Int64() p.eventMut.Lock() m := p.localVersion[folder] if m == nil { m = make(map[string]int64) } m[p.id.String()] = version p.localVersion[folder] = m p.done[folder] = false l.Debugf("LocalIndexUpdated %v %v done=false\n\t%+v", p.id, folder, m) p.eventMut.Unlock() case "RemoteIndexUpdated": data := ev.Data.(map[string]interface{}) device := data["device"].(string) folder := data["folder"].(string) version, _ := data["version"].(json.Number).Int64() p.eventMut.Lock() m := p.localVersion[folder] if m == nil { m = make(map[string]int64) } m[device] = version p.localVersion[folder] = m p.done[folder] = false l.Debugf("RemoteIndexUpdated %v %v done=false\n\t%+v", p.id, folder, m) p.eventMut.Unlock() case "FolderSummary": data := ev.Data.(map[string]interface{}) folder := data["folder"].(string) summary := data["summary"].(map[string]interface{}) need, _ := summary["needBytes"].(json.Number).Int64() done := need == 0 p.eventMut.Lock() p.done[folder] = done l.Debugf("Foldersummary %v %v\n\t%+v", p.id, folder, p.done) p.eventMut.Unlock() } } } }
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 := db.OpenMemory() m := NewModel(cfg, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil) fc := FakeConnection{ id: device1, requestData: []byte("some data to return"), } m.AddConnection(Connection{ &net.TCPConn{}, fc, ConnectionTypeDirectAccept, }) 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.DeviceName = "tester" m.ClusterConfig(device1, ccm) if cfg.Devices()[device1].Name != "tester" { t.Errorf("Device did not get a name") } ccm.DeviceName = "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") } }