Пример #1
0
func TestSortByAge(t *testing.T) {
	q := newJobQueue()
	q.Push("f1", 0, 20)
	q.Push("f2", 0, 40)
	q.Push("f3", 0, 30)
	q.Push("f4", 0, 10)

	q.SortOldestFirst()

	_, actual := q.Jobs()
	if l := len(actual); l != 4 {
		t.Fatalf("Weird length %d returned from Jobs()", l)
	}
	expected := []string{"f4", "f1", "f3", "f2"}

	if diff, equal := messagediff.PrettyDiff(expected, actual); !equal {
		t.Errorf("SortOldestFirst() diff:\n%s", diff)
	}

	q.SortNewestFirst()

	_, actual = q.Jobs()
	if l := len(actual); l != 4 {
		t.Fatalf("Weird length %d returned from Jobs()", l)
	}
	expected = []string{"f2", "f3", "f1", "f4"}

	if diff, equal := messagediff.PrettyDiff(expected, actual); !equal {
		t.Errorf("SortNewestFirst() diff:\n%s", diff)
	}
}
Пример #2
0
func TestSortBySize(t *testing.T) {
	q := newJobQueue()
	q.Push("f1", 20, time.Time{})
	q.Push("f2", 40, time.Time{})
	q.Push("f3", 30, time.Time{})
	q.Push("f4", 10, time.Time{})

	q.SortSmallestFirst()

	_, actual := q.Jobs()
	if l := len(actual); l != 4 {
		t.Fatalf("Weird length %d returned from Jobs()", l)
	}
	expected := []string{"f4", "f1", "f3", "f2"}

	if diff, equal := messagediff.PrettyDiff(expected, actual); !equal {
		t.Errorf("SortSmallestFirst() diff:\n%s", diff)
	}

	q.SortLargestFirst()

	_, actual = q.Jobs()
	if l := len(actual); l != 4 {
		t.Fatalf("Weird length %d returned from Jobs()", l)
	}
	expected = []string{"f2", "f3", "f1", "f4"}

	if diff, equal := messagediff.PrettyDiff(expected, actual); !equal {
		t.Errorf("SortLargestFirst() diff:\n%s", diff)
	}
}
Пример #3
0
func TestListDropFolder(t *testing.T) {
	ldb := db.OpenMemory()

	s0 := db.NewFileSet("test0", ldb)
	local1 := []protocol.FileInfo{
		{Name: "a", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
		{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
		{Name: "c", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1000}}}},
	}
	s0.Replace(protocol.LocalDeviceID, local1)

	s1 := db.NewFileSet("test1", ldb)
	local2 := []protocol.FileInfo{
		{Name: "d", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}},
		{Name: "e", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1002}}}},
		{Name: "f", Version: protocol.Vector{Counters: []protocol.Counter{{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"}
	actualFolderList := ldb.ListFolders()
	if diff, equal := messagediff.PrettyDiff(expectedFolderList, actualFolderList); !equal {
		t.Fatalf("FolderList mismatch. Diff:\n%s", diff)
	}
	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"}
	actualFolderList = ldb.ListFolders()
	if diff, equal := messagediff.PrettyDiff(expectedFolderList, actualFolderList); !equal {
		t.Fatalf("FolderList mismatch. Diff:\n%s", diff)
	}
	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)
	}
}
Пример #4
0
func TestKeyspaceComplement(t *testing.T) {
	t.Parallel()

	testData := []struct {
		a, want *Keyspace
	}{
		{
			&Keyspace{1, 10},
			&Keyspace{10, 1},
		},
		{
			nil,
			&Keyspace{1, 0},
		},
		{
			&Keyspace{1, 0},
			nil,
		},
	}
	for i, td := range testData {
		out := td.a.Complement()
		if diff, equal := messagediff.PrettyDiff(td.want, out); !equal {
			t.Errorf("%d. %+v.Complement() = %+v not %+v\n%s", i, td.a, out, td.want, diff)
		}
	}
}
Пример #5
0
func ExampleAtom() {
	got := data2()
	want := data1()
	diff, equal := messagediff.PrettyDiff(want, got)
	fmt.Printf("%v %s", equal, diff)
	// Output: false modified: [0].FirstChild.NextSibling.Attr = " baz"
}
Пример #6
0
func TestDeviceAddressesStatic(t *testing.T) {
	name, _ := os.Hostname()
	expected := map[protocol.DeviceID]DeviceConfiguration{
		device1: {
			DeviceID:  device1,
			Addresses: []string{"tcp://192.0.2.1", "tcp://192.0.2.2"},
		},
		device2: {
			DeviceID:  device2,
			Addresses: []string{"tcp://192.0.2.3:6070", "tcp://[2001:db8::42]:4242"},
		},
		device3: {
			DeviceID:  device3,
			Addresses: []string{"tcp://[2001:db8::44]:4444", "tcp://192.0.2.4:6090"},
		},
		device4: {
			DeviceID:    device4,
			Name:        name, // Set when auto created
			Addresses:   []string{"dynamic"},
			Compression: protocol.CompressMetadata,
		},
	}

	cfg, err := Load("testdata/deviceaddressesstatic.xml", device4)
	if err != nil {
		t.Error(err)
	}

	actual := cfg.Devices()
	if diff, equal := messagediff.PrettyDiff(expected, actual); !equal {
		t.Errorf("Devices differ. Diff:\n%s", diff)
	}
}
Пример #7
0
func TestParse(t *testing.T) {
	testData := []struct {
		in   string
		want []*protocol.Triple
	}{{
		`[{"subj":"foo", "pred":"bar", "obj":"moo"}, {}]`,
		[]*protocol.Triple{
			{
				Subj: "foo",
				Pred: "bar",
				Obj:  "moo",
			},
			{},
		},
	}}
	for i, td := range testData {
		out, err := Parse(td.in)
		if err != nil {
			t.Error(err)
		}
		if diff, eq := messagediff.PrettyDiff(td.want, out); !eq {
			t.Errorf("%d. Parse(%#v) = %#v\ndiff %s", i, td.in, out, diff)
		}
	}
}
Пример #8
0
func TestDirNames(t *testing.T) {
	names := dirNames("testdata")
	expected := []string{"default", "foo", "testfolder"}
	if diff, equal := messagediff.PrettyDiff(expected, names); !equal {
		t.Errorf("Unexpected dirNames return: %#v\n%s", names, diff)
	}
}
Пример #9
0
func TestWalk(t *testing.T) {
	ignores := ignore.New(false)
	err := ignores.Load("testdata/.stignore")
	if err != nil {
		t.Fatal(err)
	}
	t.Log(ignores)

	fchan, err := Walk(Config{
		Dir:       "testdata",
		BlockSize: 128 * 1024,
		Matcher:   ignores,
		Hashers:   2,
	})

	if err != nil {
		t.Fatal(err)
	}

	var tmp []protocol.FileInfo
	for f := range fchan {
		tmp = append(tmp, f)
	}
	sort.Sort(fileList(tmp))
	files := fileList(tmp).testfiles()

	if diff, equal := messagediff.PrettyDiff(testdata, files); !equal {
		t.Errorf("Walk returned unexpected data. Diff:\n%s", diff)
	}
}
Пример #10
0
func TestShardQueryByHash(t *testing.T) {
	t.Parallel()

	testData := []struct {
		step *protocol.ArrayOp
		want map[uint64]*protocol.ArrayOp
	}{
		{
			nil,
			nil,
		},
		{
			&protocol.ArrayOp{
				Triples: []*protocol.Triple{
					{Subj: "foo"},
					{Subj: "bar"},
				},
			},
			map[uint64]*protocol.ArrayOp{
				0xe271865701f54561: {
					Triples: []*protocol.Triple{
						{Subj: "foo"},
						{Subj: "bar"},
					},
				},
				0x923658dbfd3ae604: {
					Triples: []*protocol.Triple{
						{Subj: "foo"},
						{Subj: "bar"},
					},
				},
			},
		},
		{
			&protocol.ArrayOp{
				Triples: []*protocol.Triple{
					{Pred: "bar"},
				},
			},
			map[uint64]*protocol.ArrayOp{
				0: {
					Triples: []*protocol.Triple{
						{Pred: "bar"},
					},
				},
			},
		},
	}
	for i, td := range testData {
		out := ShardQueryByHash(td.step)
		if diff, eq := messagediff.PrettyDiff(td.want, out); !eq {
			t.Errorf("%d. Parse(%#v) = %#v\ndiff %s", i, td.step, out, diff)
		}
	}
}
Пример #11
0
func TestStaggeredVersioningVersionCount(t *testing.T) {
	/* Default settings:

	{30, 3600},       // first hour -> 30 sec between versions
	{3600, 86400},    // next day -> 1 h between versions
	{86400, 592000},  // next 30 days -> 1 day between versions
	{604800, maxAge}, // next year -> 1 week between versions
	*/

	loc, _ := time.LoadLocation("Local")
	now, _ := time.ParseInLocation(TimeFormat, "20160415-140000", loc)
	files := []string{
		// 14:00:00 is "now"
		"test~20160415-140000", // 0 seconds ago
		"test~20160415-135959", // 1 second ago
		"test~20160415-135958", // 2 seconds ago
		"test~20160415-135900", // 1 minute ago
		"test~20160415-135859", // 1 minute 1 second ago
		"test~20160415-135830", // 1 minute 30 seconds ago
		"test~20160415-135829", // 1 minute 31 seconds ago
		"test~20160415-135700", // 3 minutes ago
		"test~20160415-135630", // 3 minutes 30 seconds ago
		"test~20160415-133000", // 30 minutes ago
		"test~20160415-132900", // 31 minutes ago
		"test~20160415-132500", // 35 minutes ago
		"test~20160415-132000", // 40 minutes ago
		"test~20160415-130000", // 60 minutes ago
		"test~20160415-124000", // 80 minutes ago
		"test~20160415-122000", // 100 minutes ago
		"test~20160415-110000", // 120 minutes ago
	}
	sort.Strings(files)

	delete := []string{
		"test~20160415-140000", // 0 seconds ago
		"test~20160415-135959", // 1 second ago
		"test~20160415-135900", // 1 minute ago
		"test~20160415-135830", // 1 minute 30 second ago
		"test~20160415-130000", // 60 minutes ago
		"test~20160415-124000", // 80 minutes ago
	}
	sort.Strings(delete)

	os.MkdirAll("testdata/.stversions", 0755)
	defer os.RemoveAll("testdata")

	testCleanDone = make(chan struct{})
	v := NewStaggered("", "testdata", map[string]string{"maxAge": strconv.Itoa(365 * 86400)}).(Staggered)
	<-testCleanDone

	rem := v.toRemove(files, now)
	if diff, equal := messagediff.PrettyDiff(delete, rem); !equal {
		t.Errorf("Incorrect deleted files; got %v, expected %v\n%v", rem, delete, diff)
	}
}
Пример #12
0
func TestNoListenAddresses(t *testing.T) {
	cfg, err := Load("testdata/nolistenaddress.xml", device1)
	if err != nil {
		t.Error(err)
	}

	expected := []string{""}
	actual := cfg.Options().ListenAddresses
	if diff, equal := messagediff.PrettyDiff(expected, actual); !equal {
		t.Errorf("Unexpected ListenAddresses. Diff:\n%s", diff)
	}
}
Пример #13
0
func TestQuery(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}

	nodes := launchSwarm(5, t)
	defer killSwarm(nodes)

	primary := nodes[0]
	triples := protocol.CloneTriples(testTriples)
	if err := primary.signAndInsertTriples(triples, primary.crypto); err != nil {
		t.Fatal(err)
	}

	testData := []struct {
		query *protocol.QueryRequest
		want  []*protocol.Triple
	}{
		{
			&protocol.QueryRequest{
				Type: protocol.BASIC,
				Steps: []*protocol.ArrayOp{{
					Triples: []*protocol.Triple{{
						Subj: "/m/02mjmr",
					}},
				}},
			},
			[]*protocol.Triple{
				{
					Subj: "/m/02mjmr",
					Pred: "/type/object/name",
					Obj:  "Barack Obama",
				},
				{
					Subj: "/m/02mjmr",
					Pred: "/type/object/type",
					Obj:  "/people/person",
				},
			},
		},
	}
	for i, td := range testData {
		trips, err := primary.ExecuteQuery(td.query)
		if err != nil {
			t.Error(err)
		}
		trips = stripCreated(stripSigning(trips))

		if diff, equal := messagediff.PrettyDiff(td.want, trips); !equal {
			t.Errorf("%d. s.ExecuteQuery(%+v) = %+v\n%s", i, td.query, trips, diff)
		}
	}
}
Пример #14
0
func TestBringToFront(t *testing.T) {
	q := newJobQueue()
	q.Push("f1", 0, 0)
	q.Push("f2", 0, 0)
	q.Push("f3", 0, 0)
	q.Push("f4", 0, 0)

	_, queued := q.Jobs()
	if diff, equal := messagediff.PrettyDiff([]string{"f1", "f2", "f3", "f4"}, queued); !equal {
		t.Errorf("Order does not match. Diff:\n%s", diff)
	}

	q.BringToFront("f1") // corner case: does nothing

	_, queued = q.Jobs()
	if diff, equal := messagediff.PrettyDiff([]string{"f1", "f2", "f3", "f4"}, queued); !equal {
		t.Errorf("Order does not match. Diff:\n%s", diff)
	}

	q.BringToFront("f3")

	_, queued = q.Jobs()
	if diff, equal := messagediff.PrettyDiff([]string{"f3", "f1", "f2", "f4"}, queued); !equal {
		t.Errorf("Order does not match. Diff:\n%s", diff)
	}

	q.BringToFront("f2")

	_, queued = q.Jobs()
	if diff, equal := messagediff.PrettyDiff([]string{"f2", "f3", "f1", "f4"}, queued); !equal {
		t.Errorf("Order does not match. Diff:\n%s", diff)
	}

	q.BringToFront("f4") // corner case: last element

	_, queued = q.Jobs()
	if diff, equal := messagediff.PrettyDiff([]string{"f4", "f2", "f3", "f1"}, queued); !equal {
		t.Errorf("Order does not match. Diff:\n%s", diff)
	}
}
Пример #15
0
func TestSortTriples(t *testing.T) {
	t.Parallel()

	testData := []struct {
		a, want []*Triple
	}{
		{
			[]*Triple{
				{
					Subj: "b",
				},
				{
					Subj: "c",
				},
				{
					Subj: "a",
					Pred: "b",
				},
				{
					Subj: "a",
					Pred: "a",
				},
			},
			[]*Triple{
				{
					Subj: "a",
					Pred: "a",
				},
				{
					Subj: "a",
					Pred: "b",
				},
				{
					Subj: "b",
				},
				{
					Subj: "c",
				},
			},
		},
	}
	for i, td := range testData {
		out := CloneTriples(td.a)
		SortTriples(out)
		if diff, equal := messagediff.PrettyDiff(td.want, out); !equal {
			t.Errorf("%d. SortTriples(%+v) = %+v not %+v\n%s", i, td.a, out, td.want, diff)
		}
	}
}
Пример #16
0
func TestInsertAndRetreiveTriples(t *testing.T) {
	t.Parallel()

	s := testServer(t)
	go s.network.Listen()

	time.Sleep(10 * time.Millisecond)
	base := fmt.Sprintf("http://localhost:%d", s.network.Port)

	testTriples := testTriplesKeyspace(s.network.LocalKeyspace())

	triples, err := json.Marshal(testTriples)
	if err != nil {
		t.Error(err)
	}

	buf := bytes.NewBuffer(triples)

	resp, err := http.Post(base+"/api/v1/insert", "application/json", buf)
	if err != nil {
		t.Error(err)
	}
	out, _ := ioutil.ReadAll(resp.Body)
	if !bytes.Contains(out, []byte(strconv.Itoa(len(testTriples)))) {
		t.Errorf("http.Post(/api/v1/insert) = %+v; missing %+v", string(out), len(testTriples))
	}

	// Takes a bit of time to write
	time.Sleep(100 * time.Millisecond)

	var signedTriples []*protocol.Triple

	resp, err = http.Get(base + "/api/v1/triples")
	if err != nil {
		t.Error(err)
	}
	err = json.NewDecoder(resp.Body).Decode(&signedTriples)
	if err != nil {
		t.Error(err)
	}
	strippedTriples := stripCreated(stripSigning(signedTriples))
	protocol.SortTriples(strippedTriples)

	if diff, equal := messagediff.PrettyDiff(testTriples, strippedTriples); !equal {
		t.Errorf("http.Get(/api/v1/insert) = %+v\n;not %+v\n%s", strippedTriples, testTriples, diff)
	}
}
Пример #17
0
func TestOverriddenValues(t *testing.T) {
	expected := OptionsConfiguration{
		ListenAddresses:         []string{"tcp://:23000"},
		GlobalAnnServers:        []string{"udp4://syncthing.nym.se:22026"},
		GlobalAnnEnabled:        false,
		LocalAnnEnabled:         false,
		LocalAnnPort:            42123,
		LocalAnnMCAddr:          "quux:3232",
		MaxSendKbps:             1234,
		MaxRecvKbps:             2341,
		ReconnectIntervalS:      6000,
		RelaysEnabled:           false,
		RelayReconnectIntervalM: 20,
		StartBrowser:            false,
		NATEnabled:              false,
		NATLeaseM:               90,
		NATRenewalM:             15,
		NATTimeoutS:             15,
		RestartOnWakeup:         false,
		AutoUpgradeIntervalH:    24,
		KeepTemporariesH:        48,
		CacheIgnoredFiles:       true,
		ProgressUpdateIntervalS: 10,
		SymlinksEnabled:         false,
		LimitBandwidthInLan:     true,
		MinHomeDiskFreePct:      5.2,
		URURL:                   "https://localhost/newdata",
		URInitialDelayS:         800,
		URPostInsecurely:        true,
		ReleasesURL:             "https://localhost/releases",
		AlwaysLocalNets:         []string{},
		OverwriteRemoteDevNames: true,
		TempIndexMinBlocks:      100,
		UnackedNotificationIDs:  []string{},
	}

	cfg, err := Load("testdata/overridenvalues.xml", device1)
	if err != nil {
		t.Error(err)
	}

	if diff, equal := messagediff.PrettyDiff(expected, cfg.Options()); !equal {
		t.Errorf("Overridden config differs. Diff:\n%s", diff)
	}
}
Пример #18
0
func TestDefaultValues(t *testing.T) {
	expected := OptionsConfiguration{
		ListenAddresses:         []string{"default"},
		GlobalAnnServers:        []string{"default"},
		GlobalAnnEnabled:        true,
		LocalAnnEnabled:         true,
		LocalAnnPort:            21027,
		LocalAnnMCAddr:          "[ff12::8384]:21027",
		MaxSendKbps:             0,
		MaxRecvKbps:             0,
		ReconnectIntervalS:      60,
		RelaysEnabled:           true,
		RelayReconnectIntervalM: 10,
		StartBrowser:            true,
		NATEnabled:              true,
		NATLeaseM:               60,
		NATRenewalM:             30,
		NATTimeoutS:             10,
		RestartOnWakeup:         true,
		AutoUpgradeIntervalH:    12,
		KeepTemporariesH:        24,
		CacheIgnoredFiles:       false,
		ProgressUpdateIntervalS: 5,
		SymlinksEnabled:         true,
		LimitBandwidthInLan:     false,
		MinHomeDiskFreePct:      1,
		URURL:                   "https://data.syncthing.net/newdata",
		URInitialDelayS:         1800,
		URPostInsecurely:        false,
		ReleasesURL:             "https://upgrades.syncthing.net/meta.json",
		AlwaysLocalNets:         []string{},
		OverwriteRemoteDevNames: false,
		TempIndexMinBlocks:      10,
		UnackedNotificationIDs:  []string{},
	}

	cfg := New(device1)

	if diff, equal := messagediff.PrettyDiff(expected, cfg.Options); !equal {
		t.Errorf("Default config differs. Diff:\n%s", diff)
	}
}
Пример #19
0
// Ensures that PartitionedBloomFilter can be serialized and deserialized without errors.
func TestPartitionedBloomGob(t *testing.T) {
	f := NewPartitionedBloomFilter(100, 0.1)
	for i := 0; i < 1000; i++ {
		f.Add([]byte(strconv.Itoa(i)))
	}

	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(f); err != nil {
		t.Error(err)
	}

	f2 := NewPartitionedBloomFilter(100, 0.1)
	if err := gob.NewDecoder(&buf).Decode(f2); err != nil {
		t.Error(err)
	}

	if diff, equal := messagediff.PrettyDiff(f, f2); !equal {
		t.Errorf("PartitionedBoomFilter Gob Encode and Decode = %+v; not %+v\n%s", f2, f, diff)
	}
}
Пример #20
0
// Ensures that Buckets can be serialized and deserialized without errors.
func TestBucketsGob(t *testing.T) {
	b := NewBuckets(5, 2)
	for i := 0; i < 5; i++ {
		b.Increment(uint(i), 1)
	}

	var buf bytes.Buffer
	if err := gob.NewEncoder(&buf).Encode(b); err != nil {
		t.Error(err)
	}

	b2 := NewBuckets(5, 2)
	if err := gob.NewDecoder(&buf).Decode(b2); err != nil {
		t.Error(err)
	}

	if diff, equal := messagediff.PrettyDiff(b, b2); !equal {
		t.Errorf("Buckets Gob Encode and Decode = %+v; not %+v\n%s", b2, b, diff)
	}
}
Пример #21
0
func TestDefaultValues(t *testing.T) {
	expected := OptionsConfiguration{
		ListenAddress:           []string{"tcp://0.0.0.0:22000"},
		GlobalAnnServers:        []string{"default"},
		GlobalAnnEnabled:        true,
		LocalAnnEnabled:         true,
		LocalAnnPort:            21027,
		LocalAnnMCAddr:          "[ff12::8384]:21027",
		RelayServers:            []string{"dynamic+https://relays.syncthing.net/endpoint"},
		MaxSendKbps:             0,
		MaxRecvKbps:             0,
		ReconnectIntervalS:      60,
		RelaysEnabled:           true,
		RelayReconnectIntervalM: 10,
		StartBrowser:            true,
		UPnPEnabled:             true,
		UPnPLeaseM:              60,
		UPnPRenewalM:            30,
		UPnPTimeoutS:            10,
		RestartOnWakeup:         true,
		AutoUpgradeIntervalH:    12,
		KeepTemporariesH:        24,
		CacheIgnoredFiles:       false,
		ProgressUpdateIntervalS: 5,
		SymlinksEnabled:         true,
		LimitBandwidthInLan:     false,
		MinHomeDiskFreePct:      1,
		URURL:                   "https://data.syncthing.net/newdata",
		URInitialDelayS:         1800,
		URPostInsecurely:        false,
		ReleasesURL:             "https://api.github.com/repos/syncthing/syncthing/releases?per_page=30",
		AlwaysLocalNets:         []string{},
	}

	cfg := New(device1)

	if diff, equal := messagediff.PrettyDiff(expected, cfg.Options); !equal {
		t.Errorf("Default config differs. Diff:\n%s", diff)
	}
}
Пример #22
0
func TestVersioningConfig(t *testing.T) {
	cfg, err := Load("testdata/versioningconfig.xml", device4)
	if err != nil {
		t.Error(err)
	}

	vc := cfg.Folders()["test"].Versioning
	if vc.Type != "simple" {
		t.Errorf(`vc.Type %q != "simple"`, vc.Type)
	}
	if l := len(vc.Params); l != 2 {
		t.Errorf("len(vc.Params) %d != 2", l)
	}

	expected := map[string]string{
		"foo": "bar",
		"baz": "quux",
	}
	if diff, equal := messagediff.PrettyDiff(expected, vc.Params); !equal {
		t.Errorf("vc.Params differ. Diff:\n%s", diff)
	}
}
Пример #23
0
func TestNewSaveLoad(t *testing.T) {
	path := "testdata/temp.xml"
	os.Remove(path)

	exists := func(path string) bool {
		_, err := os.Stat(path)
		return err == nil
	}

	intCfg := New(device1)
	cfg := Wrap(path, intCfg)

	// To make the equality pass later
	cfg.cfg.XMLName.Local = "configuration"

	if exists(path) {
		t.Error(path, "exists")
	}

	err := cfg.Save()
	if err != nil {
		t.Error(err)
	}
	if !exists(path) {
		t.Error(path, "does not exist")
	}

	cfg2, err := Load(path, device1)
	if err != nil {
		t.Error(err)
	}

	if diff, equal := messagediff.PrettyDiff(cfg.RawCopy(), cfg2.RawCopy()); !equal {
		t.Errorf("Configs are not equal. Diff:\n%s", diff)
	}

	os.Remove(path)
}
Пример #24
0
func TestLocalPeer(t *testing.T) {
	t.Parallel()

	testData := []struct {
		ip      string
		port    int
		serving bool
		want    *protocol.Peer
	}{
		{
			"127.0.0.1", 7946, false,
			&protocol.Peer{
				Id:       "127.0.0.1:7946",
				Serving:  false,
				Keyspace: &protocol.Keyspace{Start: 0x5677ecc49097f350, End: 0xd677ecc49097f34e},
			},
		},
		{
			"127.0.0.2", 7947, true,
			&protocol.Peer{
				Id:       "127.0.0.2:7947",
				Serving:  true,
				Keyspace: &protocol.Keyspace{Start: 0xfa367fcf18de76bd, End: 0x7a367fcf18de76bb},
			},
		},
	}
	for i, td := range testData {
		s := Server{
			IP:      td.ip,
			Port:    td.port,
			Serving: td.serving,
		}
		out := s.LocalPeer()
		if diff, ok := messagediff.PrettyDiff(td.want, out); !ok {
			t.Errorf("%d. %#v.LocalPeer() = %#v; diff %s", i, s, out, diff)
		}
	}
}
Пример #25
0
func TestDeviceCompression(t *testing.T) {
	name, _ := os.Hostname()
	expected := map[protocol.DeviceID]DeviceConfiguration{
		device1: {
			DeviceID:    device1,
			Addresses:   []string{"dynamic"},
			Compression: protocol.CompressMetadata,
		},
		device2: {
			DeviceID:    device2,
			Addresses:   []string{"dynamic"},
			Compression: protocol.CompressMetadata,
		},
		device3: {
			DeviceID:    device3,
			Addresses:   []string{"dynamic"},
			Compression: protocol.CompressNever,
		},
		device4: {
			DeviceID:    device4,
			Name:        name, // Set when auto created
			Addresses:   []string{"dynamic"},
			Compression: protocol.CompressMetadata,
		},
	}

	cfg, err := Load("testdata/devicecompression.xml", device4)
	if err != nil {
		t.Error(err)
	}

	actual := cfg.Devices()
	if diff, equal := messagediff.PrettyDiff(expected, actual); !equal {
		t.Errorf("Devices differ. Diff:\n%s", diff)
	}
}
Пример #26
0
func TestShuffle(t *testing.T) {
	q := newJobQueue()
	q.Push("f1", 0, 0)
	q.Push("f2", 0, 0)
	q.Push("f3", 0, 0)
	q.Push("f4", 0, 0)

	// This test will fail once in eight million times (1 / (4!)^5) :)
	for i := 0; i < 5; i++ {
		q.Shuffle()
		_, queued := q.Jobs()
		if l := len(queued); l != 4 {
			t.Fatalf("Weird length %d returned from Jobs()", l)
		}

		t.Logf("%v", queued)
		if _, equal := messagediff.PrettyDiff([]string{"f1", "f2", "f3", "f4"}, queued); !equal {
			// The queue was shuffled
			return
		}
	}

	t.Error("Queue was not shuffled after five attempts.")
}
Пример #27
0
func TestTripleStore(t *testing.T) {
	file, err := ioutil.TempFile(os.TempDir(), "triplestore.db")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(file.Name())
	db, err := NewTripleStore(file.Name())
	if err != nil {
		t.Fatal(err)
	}

	triples := []*protocol.Triple{
		{
			Subj: "/m/02mjmr",
			Pred: "/type/object/name",
			Obj:  "Barack Obama",
		},
		{
			Subj: "/m/02mjmr",
			Pred: "/type/object/type",
			Obj:  "/people/person",
		},
		{
			Subj: "/m/0hume",
			Pred: "/type/object/name",
			Obj:  "Hume",
		},
		{
			Subj: "/m/0hume",
			Pred: "/type/object/type",
			Obj:  "/organization/team",
		},
	}

	db.Insert(triples)
	// Insert twice to ensure no duplicates.
	db.Insert(triples)

	testData := []struct {
		query *protocol.Triple
		want  []*protocol.Triple
	}{
		{
			&protocol.Triple{
				Subj: "/m/02mjmr",
			},
			[]*protocol.Triple{
				{
					Subj: "/m/02mjmr",
					Pred: "/type/object/name",
					Obj:  "Barack Obama",
				},
				{
					Subj: "/m/02mjmr",
					Pred: "/type/object/type",
					Obj:  "/people/person",
				},
			},
		},
		{
			&protocol.Triple{
				Pred: "/type/object/type",
			},
			[]*protocol.Triple{
				{
					Subj: "/m/02mjmr",
					Pred: "/type/object/type",
					Obj:  "/people/person",
				},
				{
					Subj: "/m/0hume",
					Pred: "/type/object/type",
					Obj:  "/organization/team",
				},
			},
		},
		{
			&protocol.Triple{
				Pred: "/type/object/name",
				Obj:  "Barack Obama",
			},
			[]*protocol.Triple{
				{
					Subj: "/m/02mjmr",
					Pred: "/type/object/name",
					Obj:  "Barack Obama",
				},
			},
		},
	}

	for i, td := range testData {
		triples, err := db.Query(td.query, -1)
		if err != nil {
			t.Error(err)
		}
		if diff, ok := messagediff.PrettyDiff(td.want, triples); !ok {
			t.Errorf("%d. Query(%#v, -1) = %#v; diff %s", i, td.query, triples, diff)
		}
	}

	info, err := db.Size()
	if err != nil {
		t.Fatal(err)
	}
	if info.Triples != uint64(len(triples)) {
		t.Errorf("Size() = %#v; not %d", info, len(triples))
	}
}
Пример #28
0
func TestUnifySubs(t *testing.T) {
	cases := []struct {
		in     []string // input to unifySubs
		exists []string // paths that exist in the database
		out    []string // expected output
	}{
		{
			// 0. trailing slashes are cleaned, known paths are just passed on
			[]string{"foo/", "bar//"},
			[]string{"foo", "bar"},
			[]string{"bar", "foo"}, // the output is sorted
		},
		{
			// 1. "foo/bar" gets trimmed as it's covered by foo
			[]string{"foo", "bar/", "foo/bar/"},
			[]string{"foo", "bar"},
			[]string{"bar", "foo"},
		},
		{
			// 2. "" gets simplified to the empty list; ie scan all
			[]string{"foo", ""},
			[]string{"foo"},
			nil,
		},
		{
			// 3. "foo/bar" is unknown, but it's kept
			// because its parent is known
			[]string{"foo/bar"},
			[]string{"foo"},
			[]string{"foo/bar"},
		},
		{
			// 4. two independent known paths, both are kept
			// "usr/lib" is not a prefix of "usr/libexec"
			[]string{"usr/lib", "usr/libexec"},
			[]string{"usr", "usr/lib", "usr/libexec"},
			[]string{"usr/lib", "usr/libexec"},
		},
		{
			// 5. "usr/lib" is a prefix of "usr/lib/exec"
			[]string{"usr/lib", "usr/lib/exec"},
			[]string{"usr", "usr/lib", "usr/libexec"},
			[]string{"usr/lib"},
		},
		{
			// 6. .stignore and .stfolder are special and are passed on
			// verbatim even though they are unknown
			[]string{".stfolder", ".stignore"},
			[]string{},
			[]string{".stfolder", ".stignore"},
		},
		{
			// 7. but the presense of something else unknown forces an actual
			// scan
			[]string{".stfolder", ".stignore", "foo/bar"},
			[]string{},
			[]string{".stfolder", ".stignore", "foo"},
		},
		{
			// 8. explicit request to scan all
			nil,
			[]string{"foo"},
			nil,
		},
		{
			// 9. empty list of subs
			[]string{},
			[]string{"foo"},
			nil,
		},
	}

	if runtime.GOOS == "windows" {
		// Fixup path separators
		for i := range cases {
			for j, p := range cases[i].in {
				cases[i].in[j] = filepath.FromSlash(p)
			}
			for j, p := range cases[i].exists {
				cases[i].exists[j] = filepath.FromSlash(p)
			}
			for j, p := range cases[i].out {
				cases[i].out[j] = filepath.FromSlash(p)
			}
		}
	}

	for i, tc := range cases {
		exists := func(f string) bool {
			for _, e := range tc.exists {
				if f == e {
					return true
				}
			}
			return false
		}

		out := unifySubs(tc.in, exists)
		if diff, equal := messagediff.PrettyDiff(tc.out, out); !equal {
			t.Errorf("Case %d failed; got %v, expected %v, diff:\n%s", i, out, tc.out, diff)
		}
	}
}
Пример #29
0
func TestDeviceConfig(t *testing.T) {
	for i := OldestHandledVersion; i <= CurrentVersion; i++ {
		os.Remove("testdata/.stfolder")
		wr, err := Load(fmt.Sprintf("testdata/v%d.xml", i), device1)
		if err != nil {
			t.Fatal(err)
		}

		_, err = os.Stat("testdata/.stfolder")
		if i < 6 && err != nil {
			t.Fatal(err)
		} else if i >= 6 && err == nil {
			t.Fatal("Unexpected file")
		}

		cfg := wr.cfg

		expectedFolders := []FolderConfiguration{
			{
				ID:              "test",
				RawPath:         "testdata",
				Devices:         []FolderDeviceConfiguration{{DeviceID: device1}, {DeviceID: device4}},
				Type:            FolderTypeReadOnly,
				RescanIntervalS: 600,
				Copiers:         0,
				Pullers:         0,
				Hashers:         0,
				AutoNormalize:   true,
				MinDiskFreePct:  1,
				MaxConflicts:    -1,
				Fsync:           true,
				Versioning: VersioningConfiguration{
					Params: map[string]string{},
				},
			},
		}

		// The cachedPath will have been resolved to an absolute path,
		// depending on where the tests are running. Zero it out so we don't
		// fail based on that.
		for i := range cfg.Folders {
			cfg.Folders[i].cachedPath = ""
		}

		if runtime.GOOS != "windows" {
			expectedFolders[0].RawPath += string(filepath.Separator)
		}

		expectedDevices := []DeviceConfiguration{
			{
				DeviceID:    device1,
				Name:        "node one",
				Addresses:   []string{"tcp://a"},
				Compression: protocol.CompressMetadata,
			},
			{
				DeviceID:    device4,
				Name:        "node two",
				Addresses:   []string{"tcp://b"},
				Compression: protocol.CompressMetadata,
			},
		}
		expectedDeviceIDs := []protocol.DeviceID{device1, device4}

		if cfg.Version != CurrentVersion {
			t.Errorf("%d: Incorrect version %d != %d", i, cfg.Version, CurrentVersion)
		}
		if diff, equal := messagediff.PrettyDiff(expectedFolders, cfg.Folders); !equal {
			t.Errorf("%d: Incorrect Folders. Diff:\n%s", i, diff)
		}
		if diff, equal := messagediff.PrettyDiff(expectedDevices, cfg.Devices); !equal {
			t.Errorf("%d: Incorrect Devices. Diff:\n%s", i, diff)
		}
		if diff, equal := messagediff.PrettyDiff(expectedDeviceIDs, cfg.Folders[0].DeviceIDs()); !equal {
			t.Errorf("%d: Incorrect DeviceIDs. Diff:\n%s", i, diff)
		}
	}
}
Пример #30
0
func TestBloom(t *testing.T) {
	t.Parallel()

	file, err := ioutil.TempFile(os.TempDir(), "triplestore.db")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(file.Name())
	db, err := NewTripleStore(file.Name(), log.New(os.Stdout, "", log.Flags()))
	if err != nil {
		t.Fatal(err)
	}

	tripleCount := 5000

	additionalTriples := make([]*protocol.Triple, 0, tripleCount+len(testTriples))
	for i := 0; i < tripleCount; i++ {
		additionalTriples = append(additionalTriples, &protocol.Triple{
			Subj: "/m/0test",
			Pred: "/type/object/name",
			Obj:  "Bloom " + strconv.Itoa(i),
		})
	}
	additionalTriples = append(additionalTriples, testTriples...)
	protocol.SortTriples(additionalTriples)

	db.Insert(additionalTriples)

	filter, err := db.Bloom(nil)
	if err != nil {
		t.Fatal(err)
	}
	for _, triple := range additionalTriples {
		data, err := triple.Marshal()
		if err != nil {
			t.Error(err)
			continue
		}
		if !filter.Test(data) {
			t.Errorf("Bloom filter missing triple %+v", triple)
		}
	}

	filter2, err := db.Bloom(&protocol.Keyspace{})
	if err != nil {
		t.Fatal(err)
	}

	for _, triple := range additionalTriples {
		data, err := triple.Marshal()
		if err != nil {
			t.Error(err)
			continue
		}
		if filter2.Test(data) {
			t.Errorf("Bloom filter incorrectly has %+v", triple)
		}
	}

	var resultTriples []*protocol.Triple
	results, errs := db.TriplesMatchingBloom(filter)
	for triples := range results {
		resultTriples = append(resultTriples, triples...)
	}
	for err := range errs {
		t.Error(err)
	}
	protocol.SortTriples(resultTriples)
	if diff, ok := messagediff.PrettyDiff(additionalTriples, resultTriples); !ok {
		t.Errorf("TriplesMatchingBloom(filter) = %#v; diff %s", resultTriples, diff)
	}

	resultTriples = nil
	results, errs = db.TriplesMatchingBloom(filter2)
	for triples := range results {
		resultTriples = append(resultTriples, triples...)
	}
	for err := range errs {
		t.Error(err)
	}
	for _, triple := range resultTriples {
		t.Errorf("TriplesMatchingBLoom(nil) incorrectly has %+v", triple)
	}
}