Refactor and improve integration tests

This commit is contained in:
Jakob Borg 2015-04-01 10:43:19 +02:00
parent 6459d11d32
commit a3cf37cb2e
6 changed files with 134 additions and 74 deletions

View File

@ -78,6 +78,7 @@ func TestGetIndexAuth(t *testing.T) {
argv: []string{"-home", "h1"},
port: 8081,
instance: "1",
apiKey: "abc123",
}
err := st.start()
if err != nil {

View File

@ -42,16 +42,11 @@ func TestIgnores(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.
for i := 0; i < 20; i++ {
resp, err := p.post("/rest/scan?folder=default", nil)
err := p.rescan("default")
if err != nil {
time.Sleep(time.Second)
continue
}
if resp.StatusCode != 200 {
resp.Body.Close()
time.Sleep(time.Second)
continue
}
break
}
@ -93,16 +88,11 @@ func TestIgnores(t *testing.T) {
// Wait for one scan to succeed, or up to 20 seconds...
// This is to let startup, UPnP etc complete.
for i := 0; i < 20; i++ {
resp, err := p.post("/rest/scan?folder=default", nil)
err := p.rescan("default")
if err != nil {
time.Sleep(time.Second)
continue
}
if resp.StatusCode != 200 {
resp.Body.Close()
time.Sleep(time.Second)
continue
}
break
}
@ -132,7 +122,7 @@ func TestIgnores(t *testing.T) {
// Rescan and verify that we see them
p.post("/rest/scan?folder=default", nil)
p.rescan("default")
m, err = p.model("default")
if err != nil {
t.Fatal(err)
@ -159,7 +149,7 @@ func TestIgnores(t *testing.T) {
// Rescan and verify that we see them
p.post("/rest/scan?folder=default", nil)
p.rescan("default")
m, err = p.model("default")
if err != nil {
t.Fatal(err)

View File

@ -50,16 +50,11 @@ func TestParallellScan(t *testing.T) {
// Wait for one scan to succeed, or up to 20 seconds...
// This is to let startup, UPnP etc complete.
for i := 0; i < 20; i++ {
resp, err := st.post("/rest/scan?folder=default", nil)
err := st.rescan("default")
if err != nil {
time.Sleep(time.Second)
continue
}
if resp.StatusCode != 200 {
resp.Body.Close()
time.Sleep(time.Second)
continue
}
break
}
@ -73,16 +68,12 @@ func TestParallellScan(t *testing.T) {
wg.Add(1)
go func() {
defer wg.Done()
resp, err := st.post("/rest/scan?folder=default", nil)
err := st.rescan("default")
log.Println(j)
if err != nil {
log.Println(err)
t.Fatal(err)
}
if resp.StatusCode != 200 {
t.Fatalf("%d != 200", resp.StatusCode)
}
resp.Body.Close()
}()
}

View File

@ -38,7 +38,7 @@ func testRestartDuringTransfer(t *testing.T, restartSender, restartReceiver bool
}
log.Println("Generating files...")
err = generateFiles("s1", 1000, 22, "../LICENSE")
err = generateFiles("s1", 250, 20, "../LICENSE")
if err != nil {
t.Fatal(err)
}
@ -138,7 +138,7 @@ func testRestartDuringTransfer(t *testing.T, restartSender, restartReceiver bool
prevComp = curComp
}
time.Sleep(250 * time.Millisecond)
time.Sleep(time.Second)
}
err = sender.stop()

View File

@ -61,16 +61,20 @@ func TestSyncClusterStaggeredVersioning(t *testing.T) {
}
func testSyncCluster(t *testing.T) {
/*
// This tests syncing files back and forth between three cluster members.
// Their configs are in h1, h2 and h3. The folder "default" is shared
// between all and stored in s1, s2 and s3 respectively.
//
// Another folder is shared between 1 and 2 only, in s12-1 and s12-2. A
// third folders is shared between 2 and 3, in s23-2 and s23-3.
This tests syncing files back and forth between three cluster members.
Their configs are in h1, h2 and h3. The folder "default" is shared
between all and stored in s1, s2 and s3 respectively.
const (
numFiles = 100
fileSizeExp = 20
iterations = 3
)
log.Printf("Testing with numFiles=%d, fileSizeExp=%d, iterations=%d", numFiles, fileSizeExp, iterations)
Another folder is shared between 1 and 2 only, in s12-1 and s12-2. A
third folders is shared between 2 and 3, in s23-2 and s23-3.
*/
log.Println("Cleaning...")
err := removeAll("s1", "s12-1",
"s2", "s12-2", "s23-2",
@ -86,11 +90,11 @@ func testSyncCluster(t *testing.T) {
log.Println("Generating files...")
err = generateFiles("s1", 1000, 21, "../LICENSE")
err = generateFiles("s1", numFiles, fileSizeExp, "../LICENSE")
if err != nil {
t.Fatal(err)
}
err = generateFiles("s12-1", 1000, 21, "../LICENSE")
err = generateFiles("s12-1", numFiles, fileSizeExp, "../LICENSE")
if err != nil {
t.Fatal(err)
}
@ -109,16 +113,16 @@ func testSyncCluster(t *testing.T) {
t.Fatal(err)
}
err = generateFiles("s2", 1000, 21, "../LICENSE")
err = generateFiles("s2", numFiles, fileSizeExp, "../LICENSE")
if err != nil {
t.Fatal(err)
}
err = generateFiles("s23-2", 1000, 21, "../LICENSE")
err = generateFiles("s23-2", numFiles, fileSizeExp, "../LICENSE")
if err != nil {
t.Fatal(err)
}
err = generateFiles("s3", 1000, 21, "../LICENSE")
err = generateFiles("s3", numFiles, fileSizeExp, "../LICENSE")
if err != nil {
t.Fatal(err)
}
@ -158,17 +162,37 @@ func testSyncCluster(t *testing.T) {
}
}()
for count := 0; count < 5; count++ {
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 count := 0; count < iterations; count++ {
log.Println("Forcing rescan...")
// Force rescan of folders
for i := range p {
p[i].post("/rest/scan?folder=default", nil)
if i < 3 {
p[i].post("/rest/scan?folder=s12", nil)
for i, device := range p {
if err := device.rescan("default"); err != nil {
t.Fatal(err)
}
if i < 2 {
if err := device.rescan("s12"); err != nil {
t.Fatal(err)
}
}
if i > 1 {
p[i].post("/rest/scan?folder=s23", nil)
if err := device.rescan("s23"); err != nil {
t.Fatal(err)
}
}
}
@ -284,38 +308,23 @@ func scStartProcesses() ([]syncthingProcess, error) {
}
func scSyncAndCompare(p []syncthingProcess, expected [][]fileInfo) error {
ids := []string{id1, id2, id3}
log.Println("Syncing...")
mainLoop:
for {
time.Sleep(2500 * time.Millisecond)
time.Sleep(2 * time.Second)
for i := range p {
comp, err := p[i].peerCompletion()
if err != nil {
if isTimeout(err) {
continue mainLoop
}
return err
}
for id, pct := range comp {
if id == ids[i] {
// Don't check for self, which will be 0%
continue
}
if pct != 100 {
log.Printf("%s not done yet: %d%%", id, pct)
continue mainLoop
}
}
if err := allDevicesInSync(p); err != nil {
log.Println(err)
continue
}
break
}
// This is necessary, or all files won't be in place even when everything
// is already reported in sync. Why?!
time.Sleep(5 * time.Second)
log.Println("Checking...")
for _, dir := range []string{"s1", "s2", "s3"} {

View File

@ -15,10 +15,14 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"time"
"github.com/syncthing/protocol"
)
var env = []string{
@ -34,6 +38,7 @@ type syncthingProcess struct {
apiKey string
csrfToken string
lastEvent int
id protocol.DeviceID
cmd *exec.Cmd
logfd *os.File
@ -72,12 +77,32 @@ func (p *syncthingProcess) start() error {
p.cmd = cmd
for {
resp, err := p.get("/")
if err == nil {
resp.Body.Close()
return nil
}
time.Sleep(250 * time.Millisecond)
resp, err := p.get("/rest/system")
if err != nil {
continue
}
var sysData map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&sysData)
resp.Body.Close()
if err != nil {
// This one is unexpected. Print it.
log.Println("/rest/system (JSON):", err)
continue
}
id, err := protocol.DeviceIDFromString(sysData["myID"].(string))
if err != nil {
// This one is unexpected. Print it.
log.Println("/rest/system (myID):", err)
continue
}
p.id = id
return nil
}
}
@ -173,9 +198,31 @@ func (p *syncthingProcess) peerCompletion() (map[string]int, error) {
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
@ -249,3 +296,25 @@ func (p *syncthingProcess) version() (string, error) {
}
return v.Version, nil
}
func (p *syncthingProcess) rescan(folder string) error {
resp, err := p.post("/rest/scan?folder="+folder, nil)
if err != nil {
return err
}
data, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("Rescan %q: status code %d: %s", folder, resp.StatusCode, data)
}
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)
}
}
return nil
}