예제 #1
0
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)
}
예제 #2
0
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)
}
예제 #3
0
파일: main.go 프로젝트: hernad/syncthing
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
}
예제 #4
0
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)
}
예제 #5
0
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)
}
예제 #6
0
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)
}
예제 #7
0
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)
}
예제 #8
0
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")
	}
}
예제 #9
0
파일: rc.go 프로젝트: hernad/syncthing
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()
			}
		}
	}
}
예제 #10
0
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")
	}
}