diff --git a/test/common_test.go b/test/common_test.go
index 75cc8aca9..0132fa276 100644
--- a/test/common_test.go
+++ b/test/common_test.go
@@ -8,14 +8,12 @@ package integration_test
import (
"crypto/md5"
- "crypto/rand"
"encoding/json"
"errors"
"fmt"
"io"
- "io/ioutil"
"log"
- mr "math/rand"
+ "math/rand"
"net/http"
"os"
"os/exec"
@@ -23,6 +21,10 @@ import (
"time"
)
+func init() {
+ rand.Seed(42)
+}
+
const (
id1 = "I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU"
id2 = "JMFJCXB-GZDE4BN-OCJE3VF-65GYZNU-AIVJRET-3J6HMRQ-AUQIGJO-FKNHMQU"
@@ -34,6 +36,7 @@ var env = []string{
"STTRACE=model",
"STGUIAPIKEY=" + apiKey,
"STNORESTART=1",
+ "STPERFSTATS=1",
}
type syncthingProcess struct {
@@ -42,6 +45,7 @@ type syncthingProcess struct {
port int
apiKey string
csrfToken string
+ lastEvent int
cmd *exec.Cmd
logfd *os.File
@@ -114,17 +118,46 @@ func (p *syncthingProcess) peerCompletion() (map[string]int, error) {
return comp, err
}
+type event struct {
+ ID int
+ Time time.Time
+ Type string
+ Data interface{}
+}
+
+func (p *syncthingProcess) events() ([]event, error) {
+ resp, err := p.get(fmt.Sprintf("/rest/events?since=%d", p.lastEvent))
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ var evs []event
+ err = json.NewDecoder(resp.Body).Decode(&evs)
+ if err != nil {
+ return nil, err
+ }
+ p.lastEvent = evs[len(evs)-1].ID
+ return evs, err
+}
+
+type versionResp struct {
+ Version string
+}
+
func (p *syncthingProcess) version() (string, error) {
resp, err := p.get("/rest/version")
if err != nil {
return "", err
}
- bs, err := ioutil.ReadAll(resp.Body)
- resp.Body.Close()
+ defer resp.Body.Close()
+
+ var v versionResp
+ err = json.NewDecoder(resp.Body).Decode(&v)
if err != nil {
return "", err
}
- return string(bs), nil
+ return v.Version, nil
}
type fileGenerator struct {
@@ -147,12 +180,12 @@ func generateFiles(dir string, files, maxexp int, srcname string) error {
log.Fatal(err)
}
- s := 1 << uint(mr.Intn(maxexp))
+ s := 1 << uint(rand.Intn(maxexp))
a := 128 * 1024
if a > s {
a = s
}
- s += mr.Intn(a)
+ s += rand.Intn(a)
src := io.LimitReader(&inifiteReader{fd}, int64(s))
@@ -172,12 +205,12 @@ func generateFiles(dir string, files, maxexp int, srcname string) error {
return err
}
- err = os.Chmod(p1, os.FileMode(mr.Intn(0777)|0400))
+ err = os.Chmod(p1, os.FileMode(rand.Intn(0777)|0400))
if err != nil {
return err
}
- t := time.Now().Add(-time.Duration(mr.Intn(30*86400)) * time.Second)
+ t := time.Now().Add(-time.Duration(rand.Intn(30*86400)) * time.Second)
err = os.Chtimes(p1, t, t)
if err != nil {
return err
@@ -187,9 +220,20 @@ func generateFiles(dir string, files, maxexp int, srcname string) error {
return nil
}
+func ReadRand(bs []byte) (int, error) {
+ var r uint32
+ for i := range bs {
+ if i%4 == 0 {
+ r = uint32(rand.Int63())
+ }
+ bs[i] = byte(r >> uint((i%4)*8))
+ }
+ return len(bs), nil
+}
+
func randomName() string {
var b [16]byte
- rand.Reader.Read(b[:])
+ ReadRand(b[:])
return fmt.Sprintf("%x", b[:])
}
diff --git a/test/genfiles.go b/test/genfiles.go
index b1b3fa47b..e30d48d9d 100644
--- a/test/genfiles.go
+++ b/test/genfiles.go
@@ -7,20 +7,34 @@
package main
import (
- "crypto/rand"
"flag"
"fmt"
"io"
"log"
- mr "math/rand"
+ "math/rand"
"os"
"path/filepath"
"time"
)
+func init() {
+ rand.Seed(42)
+}
+
+func ReadRand(bs []byte) (int, error) {
+ var r uint32
+ for i := range bs {
+ if i%4 == 0 {
+ r = uint32(rand.Int63())
+ }
+ bs[i] = byte(r >> uint((i%4)*8))
+ }
+ return len(bs), nil
+}
+
func name() string {
var b [16]byte
- rand.Reader.Read(b[:])
+ ReadRand(b[:])
return fmt.Sprintf("%x", b[:])
}
@@ -47,12 +61,12 @@ func main() {
log.Fatal(err)
}
- s := 1 << uint(mr.Intn(maxexp))
+ s := 1 << uint(rand.Intn(maxexp))
a := 128 * 1024
if a > s {
a = s
}
- s += mr.Intn(a)
+ s += rand.Intn(a)
src := io.LimitReader(&inifiteReader{fd}, int64(s))
@@ -72,12 +86,12 @@ func main() {
log.Fatal(err)
}
- err = os.Chmod(p1, os.FileMode(mr.Intn(0777)|0400))
+ err = os.Chmod(p1, os.FileMode(rand.Intn(0777)|0400))
if err != nil {
log.Fatal(err)
}
- t := time.Now().Add(-time.Duration(mr.Intn(30*86400)) * time.Second)
+ t := time.Now().Add(-time.Duration(rand.Intn(30*86400)) * time.Second)
err = os.Chtimes(p1, t, t)
if err != nil {
log.Fatal(err)
diff --git a/test/h1/config.xml b/test/h1/config.xml
index 96bce685f..bd06639cb 100644
--- a/test/h1/config.xml
+++ b/test/h1/config.xml
@@ -36,8 +36,8 @@
21025
[ff32::5222]:21026
16
- 0
- 0
+ 50000
+ 50000
5
false
true
diff --git a/test/transfer-bench_test.go b/test/transfer-bench_test.go
new file mode 100644
index 000000000..fbee825cd
--- /dev/null
+++ b/test/transfer-bench_test.go
@@ -0,0 +1,90 @@
+// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
+// All rights reserved. Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build integration
+
+package integration_test
+
+import (
+ "log"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestBenchmarkTransfer(t *testing.T) {
+ log.Println("Cleaning...")
+ err := removeAll("s1", "s2", "h1/index", "h2/index")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ log.Println("Generating files...")
+ err = generateFiles("s1", 10000, 22, "../bin/syncthing")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ log.Println("Starting up...")
+ sender := syncthingProcess{ // id1
+ log: "1.out",
+ argv: []string{"-home", "h1"},
+ port: 8081,
+ apiKey: apiKey,
+ }
+ ver, err := sender.start()
+ if err != nil {
+ t.Fatal(err)
+ }
+ log.Println(ver)
+
+ receiver := syncthingProcess{ // id2
+ log: "2.out",
+ argv: []string{"-home", "h2"},
+ port: 8082,
+ apiKey: apiKey,
+ }
+ ver, err = receiver.start()
+ if err != nil {
+ sender.stop()
+ t.Fatal(err)
+ }
+ log.Println(ver)
+
+ var t0 time.Time
+loop:
+ for {
+ evs, err := receiver.events()
+ if err != nil {
+ if strings.Contains(err.Error(), "use of closed network connection") {
+ log.Println("...")
+ continue
+ }
+ sender.stop()
+ receiver.stop()
+ t.Fatal(err)
+ }
+
+ for _, ev := range evs {
+ if ev.Type == "StateChanged" {
+ data := ev.Data.(map[string]interface{})
+ if data["repo"].(string) != "default" {
+ continue
+ }
+ log.Println(ev)
+ if data["to"].(string) == "syncing" {
+ t0 = ev.Time
+ continue
+ }
+ if t0 != (time.Time{}) && data["to"].(string) == "idle" {
+ log.Println("Sync took", ev.Time.Sub(t0))
+ break loop
+ }
+ }
+ }
+ }
+
+ sender.stop()
+ receiver.stop()
+}