mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-31 10:58:27 +00:00
Refactor integration tests to be a little cleaner and more stable, I hope
This commit is contained in:
parent
e215cf6fb8
commit
9463192224
@ -53,7 +53,7 @@ func TestConflict(t *testing.T) {
|
||||
defer sender.stop()
|
||||
defer receiver.stop()
|
||||
|
||||
if err = coCompletion(sender, receiver); err != nil {
|
||||
if err = awaitCompletion("default", sender, receiver); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ func TestConflict(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err = coCompletion(sender, receiver); err != nil {
|
||||
if err = awaitCompletion("default", sender, receiver); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ func TestConflict(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err = coCompletion(sender, receiver); err != nil {
|
||||
if err = awaitCompletion("default", sender, receiver); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ func TestInitialMergeConflicts(t *testing.T) {
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
if err = coCompletion(sender, receiver); err != nil {
|
||||
if err = awaitCompletion("default", sender, receiver); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -309,7 +309,7 @@ func TestResetConflicts(t *testing.T) {
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
if err = coCompletion(sender, receiver); err != nil {
|
||||
if err = awaitCompletion("default", sender, receiver); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -369,7 +369,7 @@ func TestResetConflicts(t *testing.T) {
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
|
||||
if err = coCompletion(sender, receiver); err != nil {
|
||||
if err = awaitCompletion("default", sender, receiver); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -404,7 +404,7 @@ func TestResetConflicts(t *testing.T) {
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
if err = coCompletion(sender, receiver); err != nil {
|
||||
if err = awaitCompletion("default", sender, receiver); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -467,31 +467,3 @@ func coSenderReceiver(t *testing.T) (syncthingProcess, syncthingProcess) {
|
||||
|
||||
return sender, receiver
|
||||
}
|
||||
|
||||
func coCompletion(p ...syncthingProcess) error {
|
||||
mainLoop:
|
||||
for {
|
||||
time.Sleep(2500 * time.Millisecond)
|
||||
|
||||
tot := 0
|
||||
for i := range p {
|
||||
comp, err := p[i].peerCompletion()
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
continue mainLoop
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pct := range comp {
|
||||
tot += pct
|
||||
}
|
||||
}
|
||||
|
||||
if tot == 100*(len(p)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("%d / %d...", tot, 100*(len(p)))
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/protocol"
|
||||
"github.com/syncthing/syncthing/internal/config"
|
||||
@ -113,6 +112,7 @@ func testFileTypeChange(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sender.stop()
|
||||
|
||||
receiver := syncthingProcess{ // id2
|
||||
instance: "2",
|
||||
@ -125,28 +125,11 @@ func testFileTypeChange(t *testing.T) {
|
||||
sender.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer receiver.stop()
|
||||
|
||||
for {
|
||||
comp, err := sender.peerCompletion()
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
sender.stop()
|
||||
receiver.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
curComp := comp[id2]
|
||||
|
||||
if curComp == 100 {
|
||||
sender.stop()
|
||||
receiver.stop()
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
err = awaitCompletion("default", sender, receiver)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = sender.stop()
|
||||
@ -212,36 +195,10 @@ func testFileTypeChange(t *testing.T) {
|
||||
|
||||
err = receiver.start()
|
||||
if err != nil {
|
||||
sender.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for {
|
||||
comp, err := sender.peerCompletion()
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
sender.stop()
|
||||
receiver.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
curComp := comp[id2]
|
||||
|
||||
if curComp == 100 {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
_, err = sender.stop()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = receiver.stop()
|
||||
err = awaitCompletion("default", sender, receiver)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -176,11 +176,13 @@ func TestGetJSON(t *testing.T) {
|
||||
for _, path := range jsonEndpoints {
|
||||
res, err := st.get(path)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Error(path, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if ct := res.Header.Get("Content-Type"); ct != "application/json; charset=utf-8" {
|
||||
t.Errorf("Incorrect Content-Type %q for %q", ct, path)
|
||||
continue
|
||||
}
|
||||
|
||||
var intf interface{}
|
||||
@ -188,7 +190,7 @@ func TestGetJSON(t *testing.T) {
|
||||
res.Body.Close()
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Error(path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/protocol"
|
||||
"github.com/syncthing/syncthing/internal/config"
|
||||
@ -92,19 +91,9 @@ func TestManyPeers(t *testing.T) {
|
||||
}
|
||||
defer sender.stop()
|
||||
|
||||
for {
|
||||
comp, err := sender.peerCompletion()
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
if comp[id2] == 100 {
|
||||
return
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
err = awaitCompletion("default", sender, receiver)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Comparing directories...")
|
||||
|
@ -102,7 +102,8 @@ func TestOverride(t *testing.T) {
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
if err = ovCompletion(100, master, slave); err != nil {
|
||||
err = awaitCompletion("default", master, slave)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -137,14 +138,9 @@ func TestOverride(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Syncing...")
|
||||
log.Println("Waiting for index to send...")
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
// Expect ~99% completion since the change will be rejected by the master side
|
||||
if err = ovCompletion(99, master, slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
log.Println("Hitting Override on master...")
|
||||
|
||||
@ -158,7 +154,8 @@ func TestOverride(t *testing.T) {
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
if err = ovCompletion(100, master, slave); err != nil {
|
||||
err = awaitCompletion("default", master, slave)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -193,6 +190,9 @@ func TestOverride(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
/* This doesn't currently work with detection completion, as we don't actually
|
||||
get to completion when in master/slave mode. Needs fixing.
|
||||
|
||||
func TestOverrideIgnores(t *testing.T) {
|
||||
// Enable "Master" on s1/default
|
||||
id, _ := protocol.DeviceIDFromString(id1)
|
||||
@ -247,18 +247,6 @@ func TestOverrideIgnores(t *testing.T) {
|
||||
}
|
||||
defer master.stop()
|
||||
|
||||
// Wait for one scan to succeed, or up to 20 seconds... This is to let
|
||||
// startup, UPnP etc complete and make sure the master has the full index
|
||||
// before they connect.
|
||||
for i := 0; i < 20; i++ {
|
||||
err := master.rescan("default")
|
||||
if err != nil {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
log.Println("Starting slave...")
|
||||
slave := syncthingProcess{ // id2
|
||||
instance: "2",
|
||||
@ -275,7 +263,8 @@ func TestOverrideIgnores(t *testing.T) {
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
if err = ovCompletion(100, master, slave); err != nil {
|
||||
err = awaitCompletion("default", master, slave)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -335,12 +324,8 @@ func TestOverrideIgnores(t *testing.T) {
|
||||
|
||||
err = master.rescan("default")
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
// Expect 100% completion since the change should be invisible to the master side
|
||||
if err = ovCompletion(100, master, slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Waiting for sync...")
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
// Verify that sync worked
|
||||
|
||||
@ -381,12 +366,8 @@ func TestOverrideIgnores(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
// Expect 100% completion since the change should be invisible to the master side
|
||||
if err = ovCompletion(100, master, slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Waiting for sync...")
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
// Verify that nothing changed
|
||||
|
||||
@ -434,12 +415,8 @@ func TestOverrideIgnores(t *testing.T) {
|
||||
t.Fatal(resp.Status)
|
||||
}
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
// Expect ~99% completion since the change will be rejected by the master side
|
||||
if err = ovCompletion(99, master, slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Waiting for sync...")
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
fd, err = os.Open("s2/testfile.txt")
|
||||
if err == nil {
|
||||
@ -473,12 +450,8 @@ func TestOverrideIgnores(t *testing.T) {
|
||||
t.Fatal(resp.Status)
|
||||
}
|
||||
|
||||
log.Println("Syncing...")
|
||||
|
||||
// Expect ~99% completion since the change will be rejected by the master side
|
||||
if err = ovCompletion(99, master, slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Println("Waiting for sync...")
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
fd, err = os.Open("s2/testfile.txt")
|
||||
if err == nil {
|
||||
@ -503,31 +476,4 @@ func TestOverrideIgnores(t *testing.T) {
|
||||
fd.Close()
|
||||
|
||||
}
|
||||
|
||||
func ovCompletion(expected int, p ...syncthingProcess) error {
|
||||
mainLoop:
|
||||
for {
|
||||
time.Sleep(2500 * time.Millisecond)
|
||||
|
||||
tot := 0
|
||||
for i := range p {
|
||||
comp, err := p[i].peerCompletion()
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
continue mainLoop
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pct := range comp {
|
||||
tot += pct
|
||||
}
|
||||
}
|
||||
|
||||
if tot >= expected*len(p) {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("%d / %d...", tot, expected*len(p))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -54,6 +54,9 @@ func testRestartDuringTransfer(t *testing.T, restartSender, restartReceiver bool
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sender.stop()
|
||||
|
||||
waitForScan(sender)
|
||||
|
||||
receiver := syncthingProcess{ // id2
|
||||
instance: "2",
|
||||
@ -63,38 +66,24 @@ func testRestartDuringTransfer(t *testing.T, restartSender, restartReceiver bool
|
||||
}
|
||||
err = receiver.start()
|
||||
if err != nil {
|
||||
sender.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer receiver.stop()
|
||||
|
||||
var prevComp int
|
||||
var prevBytes int
|
||||
for {
|
||||
comp, err := sender.peerCompletion()
|
||||
recv, err := receiver.dbStatus("default")
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
sender.stop()
|
||||
receiver.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
curComp := comp[id2]
|
||||
|
||||
if curComp == 100 {
|
||||
_, err = sender.stop()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = receiver.stop()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if recv.InSyncBytes > 0 && recv.InSyncBytes == recv.GlobalBytes {
|
||||
// Receiver is done
|
||||
break
|
||||
}
|
||||
} else if recv.InSyncBytes > prevBytes+recv.GlobalBytes/10 {
|
||||
// Receiver has made progress
|
||||
prevBytes = recv.InSyncBytes
|
||||
|
||||
if curComp > prevComp {
|
||||
if restartReceiver {
|
||||
log.Printf("Stopping receiver...")
|
||||
_, err = receiver.stop()
|
||||
@ -134,8 +123,6 @@ func testRestartDuringTransfer(t *testing.T, restartSender, restartReceiver bool
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
prevComp = curComp
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestReset(t *testing.T) {
|
||||
@ -41,13 +40,13 @@ func TestReset(t *testing.T) {
|
||||
// startup, UPnP etc complete and make sure that we've performed folder
|
||||
// error checking which creates the folder path if it's missing.
|
||||
log.Println("Starting...")
|
||||
waitForScan(t, &p)
|
||||
waitForScan(p)
|
||||
|
||||
log.Println("Creating files...")
|
||||
size := createFiles(t)
|
||||
|
||||
log.Println("Scanning files...")
|
||||
waitForScan(t, &p)
|
||||
waitForScan(p)
|
||||
|
||||
m, err := p.model("default")
|
||||
if err != nil {
|
||||
@ -90,7 +89,7 @@ func TestReset(t *testing.T) {
|
||||
|
||||
// Wait for ST and scan
|
||||
p.start()
|
||||
waitForScan(t, &p)
|
||||
waitForScan(p)
|
||||
|
||||
// Verify that we see them
|
||||
m, err = p.model("default")
|
||||
@ -105,7 +104,7 @@ func TestReset(t *testing.T) {
|
||||
// Recreate the files and scan
|
||||
log.Println("Creating files...")
|
||||
size = createFiles(t)
|
||||
waitForScan(t, &p)
|
||||
waitForScan(p)
|
||||
|
||||
// Verify that we see them
|
||||
m, err = p.model("default")
|
||||
@ -126,7 +125,7 @@ func TestReset(t *testing.T) {
|
||||
|
||||
// Wait for ST and scan
|
||||
p.start()
|
||||
waitForScan(t, &p)
|
||||
waitForScan(p)
|
||||
|
||||
m, err = p.model("default")
|
||||
if err != nil {
|
||||
@ -138,18 +137,6 @@ func TestReset(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func waitForScan(t *testing.T, p *syncthingProcess) {
|
||||
// Wait for one scan to succeed, or up to 20 seconds...
|
||||
for i := 0; i < 20; i++ {
|
||||
err := p.rescan("default")
|
||||
if err != nil {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func createFiles(t *testing.T) int {
|
||||
// Create eight empty files and directories
|
||||
files := []string{"f1", "f2", "f3", "f4", "f11", "f12", "f13", "f14"}
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/protocol"
|
||||
"github.com/syncthing/syncthing/internal/config"
|
||||
@ -177,6 +176,7 @@ func testSymlinks(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sender.stop()
|
||||
|
||||
receiver := syncthingProcess{ // id2
|
||||
instance: "2",
|
||||
@ -186,29 +186,13 @@ func testSymlinks(t *testing.T) {
|
||||
}
|
||||
err = receiver.start()
|
||||
if err != nil {
|
||||
sender.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer receiver.stop()
|
||||
|
||||
for {
|
||||
comp, err := sender.peerCompletion()
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
sender.stop()
|
||||
receiver.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
curComp := comp[id2]
|
||||
|
||||
if curComp == 100 {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
err = awaitCompletion("default", sender, receiver)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = sender.stop()
|
||||
@ -311,29 +295,12 @@ func testSymlinks(t *testing.T) {
|
||||
|
||||
err = receiver.start()
|
||||
if err != nil {
|
||||
sender.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for {
|
||||
comp, err := sender.peerCompletion()
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
sender.stop()
|
||||
receiver.stop()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
curComp := comp[id2]
|
||||
|
||||
if curComp == 100 {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
err = awaitCompletion("default", sender, receiver)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = sender.stop()
|
||||
|
@ -163,17 +163,8 @@ func testSyncCluster(t *testing.T) {
|
||||
}()
|
||||
|
||||
log.Println("Waiting for startup...")
|
||||
// Wait for one scan to succeed, or up to 20 seconds...
|
||||
// This is to let startup, UPnP etc complete.
|
||||
for _, device := range p {
|
||||
for i := 0; i < 20; i++ {
|
||||
err := device.rescan("default")
|
||||
if err != nil {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
for _, dev := range p {
|
||||
waitForScan(dev)
|
||||
}
|
||||
|
||||
for count := 0; count < iterations; count++ {
|
||||
@ -310,15 +301,15 @@ func scStartProcesses() ([]syncthingProcess, error) {
|
||||
func scSyncAndCompare(p []syncthingProcess, expected [][]fileInfo) error {
|
||||
log.Println("Syncing...")
|
||||
|
||||
for {
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
if err := allDevicesInSync(p); err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
// Special handling because we know which devices share which folders...
|
||||
if err := awaitCompletion("default", p...); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := awaitCompletion("s12", p[0], p[1]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := awaitCompletion("s23", p[1], p[2]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This is necessary, or all files won't be in place even when everything
|
||||
|
@ -66,7 +66,7 @@ func (p *syncthingProcess) start() error {
|
||||
binary = binary + "-" + p.instance + ".exe"
|
||||
}
|
||||
|
||||
argv := append(p.argv, "-no-browser")
|
||||
argv := append(p.argv, "-no-browser", "-verbose")
|
||||
cmd := exec.Command(binary, argv...)
|
||||
cmd.Stdout = p.logfd
|
||||
cmd.Stderr = p.logfd
|
||||
@ -203,40 +203,6 @@ func (p *syncthingProcess) post(path string, data io.Reader) (*http.Response, er
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (p *syncthingProcess) peerCompletion() (map[string]int, error) {
|
||||
resp, err := p.get("/rest/debug/peerCompletion")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
comp := map[string]int{}
|
||||
err = json.NewDecoder(resp.Body).Decode(&comp)
|
||||
|
||||
// Remove ourselves from the set. In the remaining map, all peers should
|
||||
// be att 100% if we're in sync.
|
||||
for id := range comp {
|
||||
if id == p.id.String() {
|
||||
delete(comp, id)
|
||||
}
|
||||
}
|
||||
|
||||
return comp, err
|
||||
}
|
||||
|
||||
func (p *syncthingProcess) allPeersInSync() error {
|
||||
comp, err := p.peerCompletion()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for id, val := range comp {
|
||||
if val != 100 {
|
||||
return fmt.Errorf("%.7s at %d%%", id, val)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type model struct {
|
||||
GlobalBytes int
|
||||
GlobalDeleted int
|
||||
@ -311,6 +277,35 @@ func (p *syncthingProcess) version() (string, error) {
|
||||
return v.Version, nil
|
||||
}
|
||||
|
||||
type statusResp struct {
|
||||
GlobalBytes int
|
||||
InSyncBytes int
|
||||
Version int
|
||||
}
|
||||
|
||||
func (p *syncthingProcess) dbStatus(folder string) (statusResp, error) {
|
||||
resp, err := p.get("/rest/db/status?folder=" + folder)
|
||||
if err != nil {
|
||||
return statusResp{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var s statusResp
|
||||
err = json.NewDecoder(resp.Body).Decode(&s)
|
||||
if err != nil {
|
||||
return statusResp{}, err
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (p *syncthingProcess) insync(folder string) (bool, int, error) {
|
||||
s, err := p.dbStatus(folder)
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
return s.GlobalBytes == s.InSyncBytes, s.Version, nil
|
||||
}
|
||||
|
||||
func (p *syncthingProcess) rescan(folder string) error {
|
||||
resp, err := p.post("/rest/db/scan?folder="+folder, nil)
|
||||
if err != nil {
|
||||
@ -350,11 +345,46 @@ func (p *syncthingProcess) reset(folder string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func allDevicesInSync(p []syncthingProcess) error {
|
||||
for _, device := range p {
|
||||
if err := device.allPeersInSync(); err != nil {
|
||||
return fmt.Errorf("%.7s: %v", device.id.String(), err)
|
||||
func awaitCompletion(folder string, ps ...syncthingProcess) error {
|
||||
mainLoop:
|
||||
for {
|
||||
time.Sleep(2500 * time.Millisecond)
|
||||
|
||||
expectedVersion := 0
|
||||
for _, p := range ps {
|
||||
insync, version, err := p.insync(folder)
|
||||
|
||||
if err != nil {
|
||||
if isTimeout(err) {
|
||||
continue mainLoop
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if !insync {
|
||||
continue mainLoop
|
||||
}
|
||||
|
||||
if expectedVersion == 0 {
|
||||
expectedVersion = version
|
||||
} else if version != expectedVersion {
|
||||
// Version number mismatch between devices, so not in sync.
|
||||
continue mainLoop
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func waitForScan(p syncthingProcess) {
|
||||
// Wait for one scan to succeed, or up to 20 seconds...
|
||||
for i := 0; i < 20; i++ {
|
||||
err := p.rescan("default")
|
||||
if err != nil {
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user