瀏覽代碼

lib/model: Add simple file syncing test

GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3772
Jakob Borg 9 年之前
父節點
當前提交
913a85c571
共有 2 個文件被更改,包括 132 次插入15 次删除
  1. 54 15
      lib/model/model_test.go
  2. 78 0
      lib/model/requests_test.go

+ 54 - 15
lib/model/model_test.go

@@ -28,6 +28,7 @@ import (
 	"github.com/syncthing/syncthing/lib/osutil"
 	"github.com/syncthing/syncthing/lib/protocol"
 	srand "github.com/syncthing/syncthing/lib/rand"
+	"github.com/syncthing/syncthing/lib/scanner"
 )
 
 var device1, device2 protocol.DeviceID
@@ -219,9 +220,13 @@ type downloadProgressMessage struct {
 
 type fakeConnection struct {
 	id                       protocol.DeviceID
-	requestData              []byte
 	downloadProgressMessages []downloadProgressMessage
 	closed                   bool
+	files                    []protocol.FileInfo
+	fileData                 map[string][]byte
+	folder                   string
+	model                    *Model
+	indexFn                  func(string, []protocol.FileInfo)
 	mut                      sync.Mutex
 }
 
@@ -247,16 +252,22 @@ func (f *fakeConnection) Option(string) string {
 	return ""
 }
 
-func (f *fakeConnection) Index(string, []protocol.FileInfo) error {
+func (f *fakeConnection) Index(folder string, fs []protocol.FileInfo) error {
+	if f.indexFn != nil {
+		f.indexFn(folder, fs)
+	}
 	return nil
 }
 
-func (f *fakeConnection) IndexUpdate(string, []protocol.FileInfo) error {
+func (f *fakeConnection) IndexUpdate(folder string, fs []protocol.FileInfo) error {
+	if f.indexFn != nil {
+		f.indexFn(folder, fs)
+	}
 	return nil
 }
 
 func (f *fakeConnection) Request(folder, name string, offset int64, size int, hash []byte, fromTemporary bool) ([]byte, error) {
-	return f.requestData, nil
+	return f.fileData[name], nil
 }
 
 func (f *fakeConnection) ClusterConfig(protocol.ClusterConfig) {}
@@ -292,6 +303,35 @@ func (f *fakeConnection) DownloadProgress(folder string, updates []protocol.File
 	})
 }
 
+func (f *fakeConnection) addFile(name string, flags uint32, data []byte) {
+	f.mut.Lock()
+	defer f.mut.Unlock()
+
+	blocks, _ := scanner.Blocks(bytes.NewReader(data), protocol.BlockSize, int64(len(data)), nil)
+	var version protocol.Vector
+	version.Update(f.id.Short())
+
+	f.files = append(f.files, protocol.FileInfo{
+		Name:        name,
+		Type:        protocol.FileInfoTypeFile,
+		Size:        int64(len(data)),
+		ModifiedS:   time.Now().Unix(),
+		Permissions: flags,
+		Version:     version,
+		Sequence:    time.Now().UnixNano(),
+		Blocks:      blocks,
+	})
+
+	if f.fileData == nil {
+		f.fileData = make(map[string][]byte)
+	}
+	f.fileData[name] = data
+}
+
+func (f *fakeConnection) sendIndexUpdate() {
+	f.model.IndexUpdate(f.id, f.folder, f.files)
+}
+
 func BenchmarkRequest(b *testing.B) {
 	db := db.OpenMemory()
 	m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", db, nil)
@@ -303,9 +343,9 @@ func BenchmarkRequest(b *testing.B) {
 	const n = 1000
 	files := genFiles(n)
 
-	fc := &fakeConnection{
-		id:          device1,
-		requestData: []byte("some data to return"),
+	fc := &fakeConnection{id: device1}
+	for _, f := range files {
+		fc.addFile(f.Name, 0644, []byte("some data to return"))
 	}
 	m.AddConnection(fc, protocol.HelloResult{})
 	m.Index(device1, "default", files)
@@ -344,10 +384,7 @@ func TestDeviceRename(t *testing.T) {
 		t.Errorf("Device already has a name")
 	}
 
-	conn := &fakeConnection{
-		id:          device1,
-		requestData: []byte("some data to return"),
-	}
+	conn := &fakeConnection{id: device1}
 
 	m.AddConnection(conn, hello)
 
@@ -2082,11 +2119,11 @@ func TestIssue3496(t *testing.T) {
 	}
 }
 
-func addFakeConn(m *Model, dev protocol.DeviceID) {
-	conn1 := &fakeConnection{id: dev}
-	m.AddConnection(conn1, protocol.HelloResult{})
+func addFakeConn(m *Model, dev protocol.DeviceID) *fakeConnection {
+	fc := &fakeConnection{id: dev, model: m}
+	m.AddConnection(fc, protocol.HelloResult{})
 
-	m.ClusterConfig(device1, protocol.ClusterConfig{
+	m.ClusterConfig(dev, protocol.ClusterConfig{
 		Folders: []protocol.Folder{
 			{
 				ID: "default",
@@ -2097,6 +2134,8 @@ func addFakeConn(m *Model, dev protocol.DeviceID) {
 			},
 		},
 	})
+
+	return fc
 }
 
 type fakeAddr struct{}

+ 78 - 0
lib/model/requests_test.go

@@ -0,0 +1,78 @@
+// Copyright (C) 2016 The Syncthing Authors.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package model
+
+import (
+	"bytes"
+	"io/ioutil"
+	"os"
+	"testing"
+
+	"github.com/syncthing/syncthing/lib/config"
+	"github.com/syncthing/syncthing/lib/db"
+	"github.com/syncthing/syncthing/lib/protocol"
+)
+
+func TestRequestSimple(t *testing.T) {
+	// Verify that the model performs a request and creates a file based on
+	// an incoming index update.
+
+	defer os.RemoveAll("_tmpfolder")
+
+	m, fc := setupModelWithConnection()
+	defer m.Stop()
+
+	// We listen for incoming index updates and trigger when we see one for
+	// the expected test file.
+	done := make(chan struct{})
+	fc.indexFn = func(folder string, fs []protocol.FileInfo) {
+		for _, f := range fs {
+			if f.Name == "testfile" {
+				close(done)
+				return
+			}
+		}
+	}
+
+	// Send an update for the test file, wait for it to sync and be reported back.
+	contents := []byte("test file contents\n")
+	fc.addFile("testfile", 0644, contents)
+	fc.sendIndexUpdate()
+	<-done
+
+	// Verify the contents
+	bs, err := ioutil.ReadFile("_tmpfolder/testfile")
+	if err != nil {
+		t.Error("File did not sync correctly:", err)
+		return
+	}
+	if !bytes.Equal(bs, contents) {
+		t.Error("File did not sync correctly: incorrect data")
+	}
+}
+
+func setupModelWithConnection() (*Model, *fakeConnection) {
+	cfg := defaultConfig.RawCopy()
+	cfg.Folders[0] = config.NewFolderConfiguration("default", "_tmpfolder")
+	cfg.Folders[0].PullerSleepS = 1
+	cfg.Folders[0].Devices = []config.FolderDeviceConfiguration{
+		{DeviceID: device1},
+		{DeviceID: device2},
+	}
+	w := config.Wrap("/tmp/cfg", cfg)
+
+	db := db.OpenMemory()
+	m := NewModel(w, device1, "device", "syncthing", "dev", db, nil)
+	m.AddFolder(cfg.Folders[0])
+	m.ServeBackground()
+	m.StartFolder("default")
+
+	fc := addFakeConn(m, device2)
+	fc.folder = "default"
+
+	return m, fc
+}