diff --git a/build.sh b/build.sh
index e4560715c..e9070bc3f 100755
--- a/build.sh
+++ b/build.sh
@@ -105,7 +105,7 @@ case "${1:-default}" in
;;
docker-init)
- docker build -q -t syncthing/build:$DOCKERIMGV docker >/dev/null
+ docker build -q -t syncthing/build:$DOCKERIMGV docker
;;
docker-all)
@@ -122,17 +122,15 @@ case "${1:-default}" in
docker-test)
docker run --rm -h syncthing-builder -u $(id -u) -t \
- -v $(pwd):/tmp/syncthing \
+ -v $(pwd):/go/src/github.com/syncthing/syncthing \
+ -w /go/src/github.com/syncthing/syncthing \
syncthing/build:$DOCKERIMGV \
- sh -euxc 'mkdir -p /go/src/github.com/syncthing \
- && cd /go/src/github.com/syncthing \
- && cp -r /tmp/syncthing syncthing \
- && cd syncthing \
- && ./build.sh clean \
+ sh -euxc './build.sh clean \
&& go run build.go -race \
&& export GOPATH=$(pwd)/Godeps/_workspace:$GOPATH \
&& cd test \
- && go test -tags integration -v -timeout 60m -short'
+ && go test -tags integration -v -timeout 60m -short \
+ && git clean -fxd .'
;;
*)
diff --git a/test/all.sh b/test/all.sh
deleted file mode 100755
index 67d356247..000000000
--- a/test/all.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-IFS=$'\n\t'
-
-go test -tags integration -v -short
-./test-merge.sh
-./test-delupd.sh
diff --git a/test/cli_test.go b/test/cli_test.go
index 78c0deb53..85e3fe9d3 100644
--- a/test/cli_test.go
+++ b/test/cli_test.go
@@ -15,7 +15,7 @@
// +build integration
-package integration_test
+package integration
import (
"os"
diff --git a/test/f1/cert.pem b/test/f1/cert.pem
deleted file mode 100644
index 3af840e15..000000000
--- a/test/f1/cert.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID3jCCAkigAwIBAgIBADALBgkqhkiG9w0BAQUwFDESMBAGA1UEAxMJc3luY3Ro
-aW5nMB4XDTE0MDMxNDA3MDA1M1oXDTQ5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJ
-c3luY3RoaW5nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArDOcd5ft
-R7SnalxF1ckU3lDQpgfMIPhFDU//4dvdSSFevrMuVDTbUYhyCfGtg/g+F5TmKhZg
-E2peYhllITupz5MP7OHGaO2GHf2XnUDD4QUO3E+KVAUw7dyFSwy09esqApVLzH3+
-ov+QXyyzmRWPsJe9u18BHU1Hob/RmBhS9m2CAJgzN6EJ8KGjApiW3iR8lD/hjVyi
-IVde8IRD6qYHEJYiPJuziTVcQpCblVYxTz3ScmmT190/O9UvViIpcOPQdwgOdewP
-NNMK35c9Edt0AH5flYp6jgrja9NkLQJ3+KOiro6yl9IUS5w87GMxI8qzI8SgCAZZ
-pYSoLbu1FJPvxV4p5eHwuprBCwmFYZWw6Y7rqH0sN52C+3TeObJCMNP9ilPadqRI
-+G0Q99TCaloeR022x33r/8D8SIn3FP35zrlFM+DvqlxoS6glbNb/Bj3p9vN0XONO
-RCuynOGe9F/4h/DaNnrbrRWqJOxBsZTsbbcJaKATfWU/Z9GcC+pUpPRhAgMBAAGj
-PzA9MA4GA1UdDwEB/wQEAwIAoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
-AwIwDAYDVR0TAQH/BAIwADALBgkqhkiG9w0BAQUDggGBAFF8dklGoC43fMrUZfb4
-6areRWG8quO6cSX6ATzRQVJ8WJ5VcC7OJk8/FeiYA+wcvUJ/1Zm/VHMYugtOz5M8
-CrWAF1r9D3Xfe5D8qfrEOYG2XjxD2nFHCnkbY4fP+SMSuXaDs7ixQnzw0UFh1wsV
-9Jy/QrgXFAIFZtu1Nz+rrvoAgw24gkDhY3557MbmYfmfPsJ8cw+WJ845sxGMPFF2
-c+5EN0jiSm0AwZK11BMJda36ke829UZctDkopbGEg1peydDR5LiyhiTAPtWn7uT/
-PkzHYLuaECAkVbWC3bZLocMGOP6F1pG+BMr00NJgVy05ASQzi4FPjcZQNNY8s69R
-ZgoCIBaJZq3ti1EsZQ1H0Ynm2c2NMVKdj4czoy8a9ZC+DCuhG7EV5Foh20VhCWgA
-RfPhlHVJthuimsWBx39X85gjSBR017uk0AxOJa6pzh/b/RPCRtUfX8EArInS3XCf
-RvRtdrnBZNI3tiREopZGt0SzgDZUs4uDVBUX8HnHzyFJrg==
------END CERTIFICATE-----
diff --git a/test/f1/config.xml b/test/f1/config.xml
deleted file mode 100644
index 6a9203c27..000000000
--- a/test/f1/config.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
- 127.0.0.1:22001
-
-
- 127.0.0.1:22002
-
-
- 127.0.0.1:8081
- abc123
-
-
- 127.0.0.1:22001
- announce.syncthing.net:22025
- false
- true
- 21025
- 16
- 500
- 10
- 5
- 10000
- false
- false
- -1
-
-
diff --git a/test/f1/https-cert.pem b/test/f1/https-cert.pem
deleted file mode 100644
index 0879c68af..000000000
--- a/test/f1/https-cert.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID5TCCAk+gAwIBAgIIHozuBlC9RPswCwYJKoZIhvcNAQELMBQxEjAQBgNVBAMT
-CXN5bmN0aGluZzAeFw0xNDA5MTUwNTE0MDBaFw00OTEyMzEyMzU5NTlaMBQxEjAQ
-BgNVBAMTCXN5bmN0aGluZzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
-ALxVRAh6EWr1Vum1EDafEGNTxWYcsMFssl4lc18cgQ5SRFtdkDi2IxELqiAPT0K9
-11DkD563o7MIdCvB/XCA2hEaapfKKMiba/yH6tSnE7Fud5Wq8AtsAZV5weCjhGrc
-s2YL8Nm57tiJC4W0K7txB8Ob5Q9gxvSpzLak2eh/fqhNoO6DxvUF/iE3VsdhKbKb
-epXsTEvR1T3Qx0MUam7Dkz1eT4kXpwPGwLKfXY+BOxybxHAKM12qKV4R5Ebs/JZB
-5GajZqd6XpwgldIg7KHWpWWSSjH4ojnP4XmEy5WZA33t0o+xkrg+EcQbzSEFhRMD
-KT7fKT9+Evf+xB0j8FJ1+kL2ajTVfOPx3Fyg+YAPK9OVI6fr9OMJD6pLxZMLaRi9
-R8IHEgOLo4vLRNLCmJWVIqfMtUlsVkXLM+alDo0maPUesPDTXeCuMG9TpDyHFQI5
-6H4OYD3/9DOEOYMXXCCpPqpjk0CpS4GAtI6qXFG3dUY3EdfOcrKvnKi/DoRrpdzp
-7wIDAQABoz8wPTAOBgNVHQ8BAf8EBAMCAKAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
-CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwCwYJKoZIhvcNAQELA4IBgQB4MajA42Wp
-L1xFMb4Ba7+aW3o3j0N7wqJjHuU5HtbpwdYgv3tgmn+Ju6rvy6BwAQt8OsVNbai9
-ptwsHbR6epoXPzAGyqY/9A74PJr6GraYJS148zuEgCir2Q0TfzbPtd4rDYN3LE81
-STwtBvcaQsuAukQbeTQJkayobLQH8ve34BVX43XHUchEPLeZqAec5/btVyR9xwWz
-rwJyEfCtx1/YxkPRBPs1cBQOK0Edn9nBKF114ogpWKlKt1Ou1HZzsMS2usWPdme1
-IATpCR9i5/ZRIC7vhSK3se7IRaMrmOXc0kpgmbi9pr+Tg2sgJSC1Bvyfh3ReC53F
-R6WJrmqut+SqCJlefQh+6On4MaW9hnrv62OTkyBKZZ3ogCQ+FMNFs+jRJHpdtxs4
-ZVkuv1NZu8nB7NsY8i6vHKkOE6XCejg6HZL4R70iXoDDgo9E6A8TwTN7TZz7SdWh
-+Bh3GGJAMubzuHysmEkKBSYHYlrW8GuUwCbLCl+HcQnfOtN7ffJwJb4=
------END CERTIFICATE-----
diff --git a/test/f1/https-key.pem b/test/f1/https-key.pem
deleted file mode 100644
index a33343f14..000000000
--- a/test/f1/https-key.pem
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----
diff --git a/test/f1/key.pem b/test/f1/key.pem
deleted file mode 100644
index 4c40deb8b..000000000
--- a/test/f1/key.pem
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----
diff --git a/test/f2/cert.pem b/test/f2/cert.pem
deleted file mode 100644
index 46e3c73f9..000000000
--- a/test/f2/cert.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID3jCCAkigAwIBAgIBADALBgkqhkiG9w0BAQUwFDESMBAGA1UEAxMJc3luY3Ro
-aW5nMB4XDTE0MDMxNDA3MDEwNFoXDTQ5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJ
-c3luY3RoaW5nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsIV0syyR
-O56BvIOro4bIqB6iFJsNc4zX8MiM4QPTWgqGlYwsKSVmNppTdlACZCJIqyzoscrF
-qJPto8/e2Fc3oaTdEREGIs7cmc7LSXfot/mAgPpy71SVWtb7xNmXro2JJPZjRBCS
-pl1ulPug+/8w7fSKQdLMjh4Hp2YlwVBfVu0bYEEW+7Vl9PZVTv+NbTqXYvYVc9R6
-QFIbN/njWAuo2wpjJlY7vqNnSYZyskAaaAC17fFJkVQKKblTeTk1C9PxTmVTB1j9
-yOoD3+V/6IrTYKXdTHGJ1MqdieTHj1jHXe5TOeSB+Hjgq4tr25mPfQ4ixXqDqIcx
-5390DAjInuSKNUJ5pqiFrVe9eIDmySZCg5/JIL3c8phy6g1bxiJN14+Dn0om/0+9
-UrHK8LVzWMmtFRVycWVUYmARWFY3EE10k0RXU2HtzmjfnBkRrl13b0ExizlA1qJ3
-3ngxF5rNEDSMpwf4og5uYOjRUPYuvCL9XtQKr254NFO/sg/qqPV4hFWTAgMBAAGj
-PzA9MA4GA1UdDwEB/wQEAwIAoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
-AwIwDAYDVR0TAQH/BAIwADALBgkqhkiG9w0BAQUDggGBAAZSU08zAzyuGqKqqU/c
-Pr+xML8oKiJqko5pb3ETDQC+uVw+qUHwiGYsvHI1cih4ix+tKvf+Yaiizp/35VkP
-qwls3a4ljq1Ww0Sf7J87QX0DumYpBGOfoCpmV4MacyjLhpLRKRGZHwIbOeFsmEu9
-oO38co+GvDy4CiAt3tuOdjBNs0gNOAdTTxqgm97raB9oXeg2i4Fb4MCT4UBUdXLM
-ZNLCifza+PWkBxmfBORvlKGeJBruLpXHBWnWEigZSLXIFjn3JJUy4fKd+/JMp063
-8Pjo6zUOckBCH8Lv90vzfrmdlQK555jWpcebN0l9neESEXw19l0OlqkJGVTr6JKq
-w5kjiL4eP7kpKKwCezhDSX3jf4P36wdF8MpOUBxVqfM+Oh5tHIcZctnurhYV7rXs
-jR70FMqWjHBmwemsXGrObNVt8c75yB+19U6DAulr2RhRw5GD74U1znP00eGZ8TJf
-RN1FYilUPCawMYeQoB8WIn9So7zIm0MfOl4KXNWDX02+Kw==
------END CERTIFICATE-----
diff --git a/test/f2/config.xml b/test/f2/config.xml
deleted file mode 100644
index 261854e6e..000000000
--- a/test/f2/config.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
- 127.0.0.1:22001
-
-
- 127.0.0.1:22002
-
-
- 127.0.0.1:8082
- abc123
-
-
- 127.0.0.1:22002
- announce.syncthing.net:22026
- false
- true
- 21025
- 16
- 0
- 15
- 5
- 10000
- false
- false
- -1
-
-
diff --git a/test/f2/https-cert.pem b/test/f2/https-cert.pem
deleted file mode 100644
index d3c54132c..000000000
--- a/test/f2/https-cert.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID5TCCAk+gAwIBAgIIORN2TOZWOjwwCwYJKoZIhvcNAQELMBQxEjAQBgNVBAMT
-CXN5bmN0aGluZzAeFw0xNDA5MTUwNTE0MDJaFw00OTEyMzEyMzU5NTlaMBQxEjAQ
-BgNVBAMTCXN5bmN0aGluZzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
-ANizpGVpWvlhkwRddVkVHo68JFSRG74ostSECMUGZTt3vpoUFuCYBUsh138KOPUH
-qN59mlgGoCbvH0RVN54UDTjw32n3r5c/Pzm+ky842O1gkrexizxrODtVL/SQnp35
-nPsiU86GUZ8IJIfiqYmcjd+exHmi3iU0f+m39pHQuxjeHpSNBJ9VsV30pCouFcSu
-i2PI1VEsPWG/w9gL19al7JcOPhxrLQBcUzG8rTnXTFq0cxGaZre4NsVacQPC2IcE
-Jdis6M6b/eTCbHquPSVs+gd9NT8ubJy6CzX5w3FGODTsQAtW1lpI7qgOQ3DRT6+n
-LY3SP792le1ZEs/C0wd/xIP0gkM+PD6ZW070xmdDTbgSj48JvJIn1Xo3+XVTSVJ0
-bzEbGMfGwxstZR+d/vIH1XX8gu8M9reJsT1InTLvGvJDuiZjp1aHUo8z4E6ZPKRb
-I/d7h/V4nZmBaCZYjht5hxR4e3jcpzaEBq4Foh4/0e/iLnZn8JxgejDys2NqqUTx
-8wIDAQABoz8wPTAOBgNVHQ8BAf8EBAMCAKAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
-CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwCwYJKoZIhvcNAQELA4IBgQANaMq2yf7A
-R5r2ac1+MCwzgLSBFTMrdfperjhEvkkyC7ln73qU6FhJzbccU3NCR1pI6052X5sM
-68wFBf/opIEFJLm/KRmfAlNQ1I02a0gCmmpm8stjtfynC6Iu7fKdWjytZRfXY6F7
-bXCNoUlbQmePHOawIS26JP3QMauhnetRPUJt72/Yt+HFgt2cEdazzuWpbs/JVp1T
-UFI/GvVTKkAgDWcb93mm1dKkHd8pOA0ATURnV+zyfOOky85Gky3++WOMre6Cb9rQ
-PlooY9tQGvvuBqc17yY/RPcOBMtpUna6SKw+gW9D67fIjp529lIhcmInh1nuBjHS
-EbSIxeQBGlYQKHcMfOW2HQrax0QSsMT39ppIHuiJ7ZHBO26HhtdnryhJNMiSpEs3
-BK2/kGZev8CQCJrNTXCRMEPLhDHMKhHGHTSMkYJnAVEsKtzY9yFqfL7LiFA6k2Lu
-CPNNZ5Ftb1RpEV2rkiNK2Le/oqg15c3la+UbTy+rfMzjLvkV33kFYcQ=
------END CERTIFICATE-----
diff --git a/test/f2/https-key.pem b/test/f2/https-key.pem
deleted file mode 100644
index bb151c2fe..000000000
--- a/test/f2/https-key.pem
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIG5QIBAAKCAYEA2LOkZWla+WGTBF11WRUejrwkVJEbviiy1IQIxQZlO3e+mhQW
-4JgFSyHXfwo49Qeo3n2aWAagJu8fRFU3nhQNOPDfafevlz8/Ob6TLzjY7WCSt7GL
-PGs4O1Uv9JCenfmc+yJTzoZRnwgkh+KpiZyN357EeaLeJTR/6bf2kdC7GN4elI0E
-n1WxXfSkKi4VxK6LY8jVUSw9Yb/D2AvX1qXslw4+HGstAFxTMbytOddMWrRzEZpm
-t7g2xVpxA8LYhwQl2Kzozpv95MJseq49JWz6B301Py5snLoLNfnDcUY4NOxAC1bW
-WkjuqA5DcNFPr6ctjdI/v3aV7VkSz8LTB3/Eg/SCQz48PplbTvTGZ0NNuBKPjwm8
-kifVejf5dVNJUnRvMRsYx8bDGy1lH53+8gfVdfyC7wz2t4mxPUidMu8a8kO6JmOn
-VodSjzPgTpk8pFsj93uH9XidmYFoJliOG3mHFHh7eNynNoQGrgWiHj/R7+Iudmfw
-nGB6MPKzY2qpRPHzAgMBAAECggGBAL698Rhqke8smdGfyejtlAYjSP8+8uKAxFgX
-F/kE1hpwHk9VG4X5ib9GPH7QKq5TXarpd++/dTyQAj+NmvUDxVe3fY+yutYwj6Bu
-RPOt4BOhi8Mw/dPitI5VP27P1S5MRocvAgGpbTLEYhNRydUc/iw1fc9rMoohGe5J
-RTm4Ntd+vAAZ2FW/ge2nptCR3AtRb9QXNNzMSgM+Xk5Orl97kTKtELLHC8djfL8s
-ynU9MzIr35VBCOTxuxQftZaP7TN6y46obQFTpwNhX2ouXT5CH4QzGOLebo3Af2gT
-3CWFtW+o6ISKJyEsGUOsxuxCKWJX3X3FNQ4TeQm38hzV9ocZOfOXq7vQMTdkB8SP
-Y9LNFzaQwGAzBsBiY8aeDSWZ3TCOI+HyDIhkSjWE7ybYkcFcUv8z2yuB/gspIEgW
-VhYwBoorrIZYRQXVwrWd9SKzlt/nmLOuEQWLBifEt31zmMzJhZZkUaYEssyfBvhh
-/zi3BMbngkDhr2g+G6bQznwsoAQv8QKBwQDvgIdlWJbUTrfB5HBzAsW6z44phyBj
-utDlhyaflAHs4BOPYPkpeeYrn/LvhhwTyhR2nIbbKCpzorjnm9LvxLu0t96SD22p
-qnYJ5M7dMj6tfN7CYLqRSUkrDFm8MLDrOEjqFPriyYoITQNjbVFHwPv0k4yem8y2
-RoCfM0iU9mS9q+9sKcVN7HBY5dR9KDf+k6fljYE+bETcTrTkDiacxhJhPO/PKmp2
-0YvgQzb9MJaKIhZ+ovy0/0YtA9F8ZGonmf8CgcEA56ELGwfPYALv/IczCgUsheWX
-S4OO4Lukv5LtgqHylvog+ZeSGxNh6wDgDhVK5XIuzVW3GiTC8sxaynsSvpyGMSeS
-V7Crs85VqMryw20Con3NVttELslsYQ46ljtNNP4yFOdKIPMFrP8x7EwegqNHZ976
-1/fGI9h7CMrYbUU5sndducUZoVDU79shRILJ/+Z+UZvsaMznqPCiHo1w22WPxW2W
-Eo9zNnZ9t7L+jybevro0NVlKPMrHg/ZQf1WTfeANAoHAGdc1RJMFWwzPOMVL+KzA
-5sIEJajlrrz2Uv19BlSyzHr0wVCGMZpsYiKU1JEUsHHqOU30Ius3gVh6OMsQPDxu
-wDXidsHhZB/3MmQUibslFhTV+AT1vD06/sELYYmjXQ2qmE8BLrzt/q1Ig07FKUfC
-J4ZP8sD+mmAK+qJO33uiLPDDGVl8Z0bubDkH7yUKvZXy1Iqq+jA2UcrQK5b3RYz9
-aK5pdWGvMPi07dJyuWinpWm+IZW2TFUKnkq+LHytE27DAoHBAN4ZvKVhmsZMasOw
-/A66oVOOr8EX19PD+Zg8kYO2N//uvdm2LcHKlxSY1T6LyjIyh5AahaUK5Oedbd1D
-n9ioC8BsWlW9MRcLXXWpjJg5GdKnYFLNkxZty39Q/np5SHHs4CbNFHZ9sM6OMNeM
-saDAYcLGu66Ehjhu5qKqplY4j7eB35w203msIVIQw1iHNJws7qjgIxLmj6edfUZg
-h3vIadB8YO9RH790ZN3VQ2QOeH1X3KHfCWE7a44sjElczD1hrQKBwQDnnERBvdNS
-47FYK+OZ88eLMedXxFuWF2PRntnSvhHohY5FcqBEh1QXbrEldS5bj+lJwk29Skqd
-u+qfOKtG0VwzZcn9Rq/PG8D8cO3WwOYP+/Y1CFpDSQavVgzGgpt6DMv6lMDWD/LT
-H4s6kiSfcjVm7T9FeMUKHTFbE8A0VAXMsFyasRfycdaCKfmnSpI3mMXppM26pb4C
-Z/gKcbosQm2MANDrvUwnIaFeghRUtDRP3KK9kEQJX1xP6TcMxiMH58k=
------END RSA PRIVATE KEY-----
diff --git a/test/f2/key.pem b/test/f2/key.pem
deleted file mode 100644
index 08bc24c2e..000000000
--- a/test/f2/key.pem
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----
diff --git a/test/filetype_test.go b/test/filetype_test.go
index 440921636..8cb4bd3ce 100644
--- a/test/filetype_test.go
+++ b/test/filetype_test.go
@@ -15,13 +15,11 @@
// +build integration
-// This currently fails; it should be fixed
-package integration_test
+package integration
import (
"log"
"os"
- "strings"
"testing"
"time"
@@ -128,7 +126,7 @@ func testFileTypeChange(t *testing.T) {
for {
comp, err := sender.peerCompletion()
if err != nil {
- if strings.Contains(err.Error(), "use of closed network connection") {
+ if isTimeout(err) {
time.Sleep(time.Second)
continue
}
@@ -200,7 +198,7 @@ func testFileTypeChange(t *testing.T) {
for {
comp, err := sender.peerCompletion()
if err != nil {
- if strings.Contains(err.Error(), "use of closed network connection") {
+ if isTimeout(err) {
time.Sleep(time.Second)
continue
}
diff --git a/test/genfiles.go b/test/genfiles.go
deleted file mode 100644
index 79f5b9729..000000000
--- a/test/genfiles.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (C) 2014 The Syncthing Authors.
-//
-// This program is free software: you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation, either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program. If not, see .
-
-// +build ignore
-
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "log"
- "math/rand"
- "os"
- "path/filepath"
- "time"
-)
-
-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
- ReadRand(b[:])
- return fmt.Sprintf("%x", b[:])
-}
-
-func main() {
- var files int
- var maxexp int
- var srcname string
- var random bool
-
- flag.IntVar(&files, "files", 1000, "Number of files")
- flag.IntVar(&maxexp, "maxexp", 20, "Maximum file size (max = 2^n + 128*1024 B)")
- flag.StringVar(&srcname, "src", "/usr/share/dict/words", "Source material")
- flag.BoolVar(&random, "random", true, "When false, always generate the same set of file")
- flag.Parse()
-
- if random {
- rand.Seed(time.Now().UnixNano())
- } else {
- rand.Seed(42)
- }
-
- fd, err := os.Open(srcname)
- if err != nil {
- log.Fatal(err)
- }
-
- for i := 0; i < files; i++ {
- n := name()
- p0 := filepath.Join(string(n[0]), n[0:2])
- err = os.MkdirAll(p0, 0755)
- if err != nil {
- log.Fatal(err)
- }
-
- s := 1 << uint(rand.Intn(maxexp))
- a := 128 * 1024
- if a > s {
- a = s
- }
- s += rand.Intn(a)
-
- src := io.LimitReader(&inifiteReader{fd}, int64(s))
-
- p1 := filepath.Join(p0, n)
- dst, err := os.Create(p1)
- if err != nil {
- log.Fatal(err)
- }
-
- _, err = io.Copy(dst, src)
- if err != nil {
- log.Fatal(err)
- }
-
- err = dst.Close()
- if err != nil {
- log.Fatal(err)
- }
-
- err = os.Chmod(p1, os.FileMode(rand.Intn(0777)|0400))
- if err != nil {
- log.Fatal(err)
- }
-
- t := time.Now().Add(-time.Duration(rand.Intn(30*86400)) * time.Second)
- err = os.Chtimes(p1, t, t)
- if err != nil {
- log.Fatal(err)
- }
- }
-}
-
-type inifiteReader struct {
- rd io.ReadSeeker
-}
-
-func (i *inifiteReader) Read(bs []byte) (int, error) {
- n, err := i.rd.Read(bs)
- if err == io.EOF {
- err = nil
- i.rd.Seek(0, 0)
- }
- return n, err
-}
diff --git a/test/h1/config.xml b/test/h1/config.xml
index 47e64ebca..c41341e18 100644
--- a/test/h1/config.xml
+++ b/test/h1/config.xml
@@ -43,8 +43,8 @@
true
21025
[ff32::5222]:21026
- 50000
- 50000
+ 0
+ 0
5
false
true
diff --git a/test/h2/config.xml b/test/h2/config.xml
index 374031061..1a456eec1 100644
--- a/test/h2/config.xml
+++ b/test/h2/config.xml
@@ -1,106 +1,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
false
1
16
@@ -124,306 +27,15 @@
16
1
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
127.0.0.1:22001
127.0.0.1:22002
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
127.0.0.1:22003
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
-
- dynamic
-
127.0.0.1:8082
abc123
@@ -439,7 +51,7 @@
0
5
false
- true
+ false
0
30
-1
diff --git a/test/h4/cert.pem b/test/h4/cert.pem
deleted file mode 100644
index eea071930..000000000
--- a/test/h4/cert.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID3jCCAkigAwIBAgIBADALBgkqhkiG9w0BAQswFDESMBAGA1UEAxMJc3luY3Ro
-aW5nMB4XDTE0MDUxMDAwNTM0N1oXDTQ5MTIzMTIzNTk1OVowFDESMBAGA1UEAxMJ
-c3luY3RoaW5nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA9MRyBtAr
-Sjt29azNoCWxx5xZF3RodBcQu+wv5sRR8lWozrr4brfUJLslcQHowqaAprOU1NP+
-BH12P5CSymsUrwAmCwSQ54CimXrNi5RiNMl7dtInJksk4Kp6nJgfyR7TqeQgqxtv
-+skVWdJY7ptxqpVuDfkf1JnNr68dbANw8hEJpPaGm3qOt81YvSg37R75HiOCzv+h
-FcSjKpPyFMvPARMCOHuZS0fYRJtI5nwmR0mWtKfnH/2204YNiQUne/8h2fgtkpxy
-OjxKOs2KJxbmpV6Uur/YyGyinb5+Aa0df3KCBuZmE+i/AsZcTsk0fgefe+bshWG/
-hzrNfV0wsX3TYjYOSBJ04+f/uQW00G1GGSxPwTsShGqVuwfJkTqkjAXX5wcH+PgJ
-ewG/dyMzKklMg19Y65WkhpWa/19o2KSZNw6TO8YM1arwT0STcMc+4fdrVB09lX6q
-NJA8UL8hUX+jbKBzatDY64h1d9E8PE0ODHYgYFO2Ko7e2GnWCQeijGmnAgMBAAGj
-PzA9MA4GA1UdDwEB/wQEAwIAoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
-AwIwDAYDVR0TAQH/BAIwADALBgkqhkiG9w0BAQsDggGBANFiHcATP5Lm11o65wbh
-sKk7yteTapRohMoLNdW44YNyM8ZkELnrdNY8pe3CWSGy3spBH01+4jbUT+gSltQr
-KTLVxSZ7f91696Og5ag4BQCeFY6ghKD/G9+PlBSj6yb3Y98NZsx8huLfylH+XuJw
-2gP5Nqov4uXaKgYylx2gdaeCb2M+wM/br1DO2HCPCmgbZE5g8RM5JxzojGn/41Le
-IbCd39zdI6NKj9c7T1Bxmt20uzca4nRgXVVzJymedEoF+//sBRk6PQzqgjgn/r3S
-h9vrqo5j8ly/+ojFjBaVY7gq2XHM6/q0LTjeKkv2MUQw+vEEZX65GpBOgBZ8U0Wb
-/NMUUhhDjGE/0G6TCJgq/HdkjmsNaWjO5sWjhnwXNImYXBdH4OenhXIrHcLhcnxN
-2n5sPkDc6n0LVVV7VAjBPXcTmu2uOSK02yqNZLLWJygp1Wl6lbiqLS3bJgYrUv2m
-YkRaR+IqVPw5EPs/QlH0qLBeCyIasaSWUVZeitVwRmqIUA==
------END CERTIFICATE-----
diff --git a/test/h4/config.xml b/test/h4/config.xml
deleted file mode 100644
index 8cf146edd..000000000
--- a/test/h4/config.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
-
-
- false
- 1
- 16
- 1
-
-
-
-
-
- false
- 1
- 16
- 1
-
-
- dynamic
-
-
- 127.0.0.1:22001
-
-
- 127.0.0.1:22002
-
-
- 127.0.0.1:22003
-
-
- 127.0.0.1:8084
- abc123
-
-
- :22004
- udp4://announce.syncthing.net:22026
- false
- false
- 21025
- [ff32::5222]:21026
- 0
- 0
- 10
- false
- false
- 0
- 30
- -1
-
- true
- 12
- 24
- true
- 5
- true
-
-
diff --git a/test/h4/https-cert.pem b/test/h4/https-cert.pem
deleted file mode 100644
index ae4685208..000000000
--- a/test/h4/https-cert.pem
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID5TCCAk+gAwIBAgIISAohRYcPi4cwCwYJKoZIhvcNAQELMBQxEjAQBgNVBAMT
-CXN5bmN0aGluZzAeFw0xNDA5MTQyMjI0MTBaFw00OTEyMzEyMzU5NTlaMBQxEjAQ
-BgNVBAMTCXN5bmN0aGluZzCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGB
-ANqeoSRjMEnjCOTO6yAaAl3XeV3nAYlC1MK2qPPIBo4NuY8ilEXM0Q7BL1ux8f+k
-V7VPRL2QBizRai7/DqdsXdVQGPY38p4MKpIyp/PXQcPxLyIgZXPE8OQqX9sBltKV
-Xjbe9aJbiGnFrLeQye10DBkq+2UXCMeNX06KjVPaxNf7O4fdowgfYu28QsyMb1lw
-g72ve501lKvtjEobBN2+NAxm1vBKLVU9onbU6ewGZBMHtap9qE+gDulkS419U62p
-79HG/xvBcazWIGSWw9AsHNO6GOtvsjb1U2m2KUHqFAIKmmNPuiy/RupXHoHpgiec
-r+sZHx3OFL66gdnZWNRTMcDUrpflD8f/Mp6gba2+1CM2RB3bIzNaEiYbgippH5FM
-/Hpa9q931+Rucll+NMwPb3ORTG8XSAB7DoNqudixid1S+Grc1bqF2dq9ZzJUwIqH
-uJBtshb1U/p8t7I1pEOTGnWs1b/tasDOIHiHx1AWCKa8mMLzqqx6d9IuzUI5vcql
-xwIDAQABoz8wPTAOBgNVHQ8BAf8EBAMCAKAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
-CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwCwYJKoZIhvcNAQELA4IBgQCYFBRPZqpc
-1+A7CpfcYezH4/9Cd9yUMeYBFebGnB9NEsp6Q/BaLAHBaeDfxjed45etOH3WaYBJ
-IUru+bAuk8xKitYmpXi4AByPmYp3pI1gsldqYSZWS6ivpdGD/t4Yd6nOxNZokOOq
-Ygxdg7WCu1d5fgvReZ3GbBlRn6+uym7ZZuTcpgOqbdeMY3EFKwoBR5LtW9iaDeZ5
-gQXvTRk276TgFZuh9GPYv4iD3F3iAlDHdA8sQz4mUnYHxYrWoSViy7TOPZbB/NP0
-eAN5d4s1BhESNzDX3ODR47VL7IyZtVqbNURPdw0BVMnC7m1iKTsSAsh+b4zShNqg
-RNjBtv3Kew5BKP79qUZL5v/WSBgIl1RIko/jp+RwlghoFJGl5ku2A0syZLgUBor1
-VaTfL9Uv/fSYUscBnAd/2Yt+Gxm3Ng48I24FkXdL4ZWVP76+63ugoEGvgAiRTHBC
-Lls7vBQS7a/3TVayhogADkUo6XgZE/FfNTqLeLKoljBLLyYs3CIHE8s=
------END CERTIFICATE-----
diff --git a/test/h4/https-key.pem b/test/h4/https-key.pem
deleted file mode 100644
index fbba5ab3f..000000000
--- a/test/h4/https-key.pem
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----
diff --git a/test/h4/key.pem b/test/h4/key.pem
deleted file mode 100644
index 73f2c05df..000000000
--- a/test/h4/key.pem
+++ /dev/null
@@ -1,39 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----
diff --git a/test/http_test.go b/test/http_test.go
index 5be425186..3eb3d8ddd 100644
--- a/test/http_test.go
+++ b/test/http_test.go
@@ -15,7 +15,7 @@
// +build integration
-package integration_test
+package integration
import (
"encoding/json"
diff --git a/test/httpstress_test.go b/test/httpstress_test.go
index 1370f8549..6f70cf9db 100644
--- a/test/httpstress_test.go
+++ b/test/httpstress_test.go
@@ -15,7 +15,7 @@
// +build integration
-package integration_test
+package integration
import (
"bytes"
diff --git a/test/json.go b/test/json.go
deleted file mode 100644
index 00e1291a1..000000000
--- a/test/json.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (C) 2014 The Syncthing Authors.
-//
-// This program is free software: you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation, either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program. If not, see .
-
-// +build ignore
-
-package main
-
-import (
- "encoding/json"
- "flag"
- "fmt"
- "log"
- "os"
- "strconv"
- "strings"
-)
-
-func main() {
- log.SetFlags(0)
- flag.Parse()
- path := strings.Split(flag.Arg(0), "/")
-
- var obj map[string]interface{}
- dec := json.NewDecoder(os.Stdin)
- dec.UseNumber()
- dec.Decode(&obj)
-
- var v interface{} = obj
- for _, p := range path {
- switch tv := v.(type) {
- case map[string]interface{}:
- v = tv[p]
- case []interface{}:
- i, err := strconv.Atoi(p)
- if err != nil {
- log.Fatal(err)
- }
- v = tv[i]
- default:
- return // Silence is golden
- }
- }
- fmt.Println(v)
-}
diff --git a/test/manypeers_test.go b/test/manypeers_test.go
index 9621d9bf2..641fb92ca 100644
--- a/test/manypeers_test.go
+++ b/test/manypeers_test.go
@@ -15,13 +15,12 @@
// +build integration
-package integration_test
+package integration
import (
"bytes"
"encoding/json"
"log"
- "strings"
"testing"
"time"
@@ -105,7 +104,7 @@ func TestManyPeers(t *testing.T) {
for {
comp, err := sender.peerCompletion()
if err != nil {
- if strings.Contains(err.Error(), "use of closed network connection") {
+ if isTimeout(err) {
time.Sleep(250 * time.Millisecond)
continue
}
diff --git a/test/md5r.go b/test/md5r.go
deleted file mode 100644
index 3d091b21e..000000000
--- a/test/md5r.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (C) 2014 The Syncthing Authors.
-//
-// This program is free software: you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation, either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program. If not, see .
-
-// +build ignore
-
-package main
-
-import (
- "crypto/md5"
- "flag"
- "fmt"
- "io"
- "os"
- "path/filepath"
-)
-
-var (
- long bool
- dirs bool
-)
-
-func main() {
- flag.BoolVar(&long, "l", false, "Long output")
- flag.BoolVar(&dirs, "d", false, "Check dirs")
- flag.Parse()
- args := flag.Args()
-
- if len(args) == 0 {
- args = []string{"."}
- }
-
- for _, path := range args {
- err := filepath.Walk(path, walker)
-
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- }
-}
-
-func walker(path string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
-
- if dirs && info.IsDir() {
- fmt.Printf("%s %s 0%03o %d\n", "-", path, info.Mode(), info.ModTime().Unix())
- } else if !info.IsDir() {
- sum, err := md5file(path)
- if err != nil {
- return err
- }
- if long {
- fmt.Printf("%s %s 0%03o %d\n", sum, path, info.Mode(), info.ModTime().Unix())
- } else {
- fmt.Printf("%s %s\n", sum, path)
- }
- }
-
- return nil
-}
-
-func md5file(fname string) (hash string, err error) {
- f, err := os.Open(fname)
- if err != nil {
- return
- }
- defer f.Close()
-
- h := md5.New()
- io.Copy(h, f)
- hb := h.Sum(nil)
- hash = fmt.Sprintf("%x", hb)
-
- return
-}
diff --git a/test/parallell_scan_test.go b/test/parallell_scan_test.go
index 7e2c62491..0849906bd 100644
--- a/test/parallell_scan_test.go
+++ b/test/parallell_scan_test.go
@@ -15,7 +15,7 @@
// +build integration
-package integration_test
+package integration
import (
"io/ioutil"
diff --git a/test/reconnect_test.go b/test/reconnect_test.go
index bf62855d2..579d61fb6 100644
--- a/test/reconnect_test.go
+++ b/test/reconnect_test.go
@@ -15,11 +15,10 @@
// +build integration
-package integration_test
+package integration
import (
"log"
- "strings"
"sync"
"testing"
"time"
@@ -81,8 +80,7 @@ func testRestartDuringTransfer(t *testing.T, restartSender, restartReceiver bool
for {
comp, err := sender.peerCompletion()
if err != nil {
- if strings.Contains(err.Error(), "use of closed network connection") ||
- strings.Contains(err.Error(), "request cancelled while waiting") {
+ if isTimeout(err) {
time.Sleep(250 * time.Millisecond)
continue
}
diff --git a/test/symlink_test.go b/test/symlink_test.go
index edece4fc0..5d28821dc 100644
--- a/test/symlink_test.go
+++ b/test/symlink_test.go
@@ -15,14 +15,13 @@
// +build integration
-package integration_test
+package integration
import (
"io/ioutil"
"log"
"os"
"path/filepath"
- "strings"
"testing"
"time"
@@ -62,7 +61,7 @@ func TestSymlinksSimpleVersioning(t *testing.T) {
t.Skip("symlinks unsupported")
}
- // Use no versioning
+ // Use simple versioning
id, _ := protocol.DeviceIDFromString(id2)
cfg, _ := config.Load("h2/config.xml", id)
fld := cfg.Folders()["default"]
@@ -81,7 +80,7 @@ func TestSymlinksStaggeredVersioning(t *testing.T) {
t.Skip("symlinks unsupported")
}
- // Use no versioning
+ // Use staggered versioning
id, _ := protocol.DeviceIDFromString(id2)
cfg, _ := config.Load("h2/config.xml", id)
fld := cfg.Folders()["default"]
@@ -203,7 +202,7 @@ func testSymlinks(t *testing.T) {
for {
comp, err := sender.peerCompletion()
if err != nil {
- if strings.Contains(err.Error(), "use of closed network connection") {
+ if isTimeout(err) {
time.Sleep(time.Second)
continue
}
@@ -328,7 +327,7 @@ func testSymlinks(t *testing.T) {
for {
comp, err := sender.peerCompletion()
if err != nil {
- if strings.Contains(err.Error(), "use of closed network connection") {
+ if isTimeout(err) {
time.Sleep(time.Second)
continue
}
diff --git a/test/sync_test.go b/test/sync_test.go
new file mode 100644
index 000000000..3c4bf4968
--- /dev/null
+++ b/test/sync_test.go
@@ -0,0 +1,284 @@
+// Copyright (C) 2014 The Syncthing Authors.
+//
+// This program is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation, either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see .
+
+// +build integration
+
+package integration
+
+import (
+ "fmt"
+ "log"
+ "testing"
+ "time"
+
+ "github.com/syncthing/syncthing/internal/config"
+ "github.com/syncthing/syncthing/internal/protocol"
+)
+
+func TestSyncCluster(t *testing.T) {
+ // Use no versioning
+ id, _ := protocol.DeviceIDFromString(id2)
+ cfg, _ := config.Load("h2/config.xml", id)
+ fld := cfg.Folders()["default"]
+ fld.Versioning = config.VersioningConfiguration{}
+ cfg.SetFolder(fld)
+ cfg.Save()
+
+ testSyncCluster(t)
+}
+
+func TestSyncClusterSimpleVersioning(t *testing.T) {
+ // Use simple versioning
+ id, _ := protocol.DeviceIDFromString(id2)
+ cfg, _ := config.Load("h2/config.xml", id)
+ fld := cfg.Folders()["default"]
+ fld.Versioning = config.VersioningConfiguration{
+ Type: "simple",
+ Params: map[string]string{"keep": "5"},
+ }
+ cfg.SetFolder(fld)
+ cfg.Save()
+
+ testSyncCluster(t)
+}
+
+func TestSyncClusterStaggeredVersioning(t *testing.T) {
+ // Use staggered versioning
+ id, _ := protocol.DeviceIDFromString(id2)
+ cfg, _ := config.Load("h2/config.xml", id)
+ fld := cfg.Folders()["default"]
+ fld.Versioning = config.VersioningConfiguration{
+ Type: "staggered",
+ }
+ cfg.SetFolder(fld)
+ cfg.Save()
+
+ testSyncCluster(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.
+
+ */
+ log.Println("Cleaning...")
+ err := removeAll("s1", "s12-1",
+ "s2", "s12-2", "s23-2",
+ "s3", "s23-3",
+ "h1/index", "h2/index", "h3/index")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Create initial folder contents. All three devices have stuff in
+ // "default", which should be merged. The other two folders are initially
+ // empty on one side.
+
+ log.Println("Generating files...")
+
+ err = generateFiles("s1", 1000, 21, "../LICENSE")
+ if err != nil {
+ t.Fatal(err)
+ }
+ err = generateFiles("s12-1", 1000, 21, "../LICENSE")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = generateFiles("s2", 1000, 21, "../LICENSE")
+ if err != nil {
+ t.Fatal(err)
+ }
+ err = generateFiles("s23-2", 1000, 21, "../LICENSE")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = generateFiles("s3", 1000, 21, "../LICENSE")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ p, err := scStartProcesses()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Prepare the expected state of folders after the sync
+ e1 := mergeDirectoryContents(directoryContents("s1"),
+ directoryContents("s2"),
+ directoryContents("s3"))
+ e2 := directoryContents("s12-1")
+ e3 := directoryContents("s23-2")
+ expected := [][]fileInfo{e1, e2, e3}
+
+ for count := 0; count < 5; 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)
+ }
+ if i > 1 {
+ p[i].post("/rest/scan?folder=s23", nil)
+ }
+ }
+
+ // Sync stuff and verify it looks right
+ err = scSyncAndCompare(p, expected)
+ if err != nil {
+ t.Error(err)
+ break
+ }
+
+ log.Println("Altering...")
+
+ // Alter the source files for another round
+ err = alterFiles("s1")
+ if err != nil {
+ t.Error(err)
+ break
+ }
+ err = alterFiles("s12-1")
+ if err != nil {
+ t.Error(err)
+ break
+ }
+ err = alterFiles("s23-2")
+ if err != nil {
+ t.Error(err)
+ break
+ }
+
+ // Prepare the expected state of folders after the sync
+ e1 = directoryContents("s1")
+ e2 = directoryContents("s12-1")
+ e3 = directoryContents("s23-2")
+ expected = [][]fileInfo{e1, e2, e3}
+ }
+
+ for i := range p {
+ p[i].stop()
+ }
+}
+
+func scStartProcesses() ([]syncthingProcess, error) {
+ p := make([]syncthingProcess, 3)
+
+ p[0] = syncthingProcess{ // id1
+ log: "1.out",
+ argv: []string{"-home", "h1"},
+ port: 8081,
+ apiKey: apiKey,
+ }
+ err := p[0].start()
+ if err != nil {
+ return nil, err
+ }
+
+ p[1] = syncthingProcess{ // id2
+ log: "2.out",
+ argv: []string{"-home", "h2"},
+ port: 8082,
+ apiKey: apiKey,
+ }
+ err = p[1].start()
+ if err != nil {
+ _ = p[0].stop()
+ return nil, err
+ }
+
+ p[2] = syncthingProcess{ // id3
+ log: "3.out",
+ argv: []string{"-home", "h3"},
+ port: 8083,
+ apiKey: apiKey,
+ }
+ err = p[2].start()
+ if err != nil {
+ _ = p[0].stop()
+ _ = p[1].stop()
+ return nil, err
+ }
+
+ return p, nil
+}
+
+func scSyncAndCompare(p []syncthingProcess, expected [][]fileInfo) error {
+ ids := []string{id1, id2, id3}
+
+ log.Println("Syncing...")
+
+mainLoop:
+ for {
+ time.Sleep(2500 * time.Millisecond)
+
+ 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
+ }
+ }
+ }
+
+ break
+ }
+
+ log.Println("Checking...")
+
+ for _, dir := range []string{"s1", "s2", "s3"} {
+ actual := directoryContents(dir)
+ if err := compareDirectoryContents(actual, expected[0]); err != nil {
+ return fmt.Errorf("%s: %v", dir, err)
+ }
+ }
+
+ for _, dir := range []string{"s12-1", "s12-2"} {
+ actual := directoryContents(dir)
+ if err := compareDirectoryContents(actual, expected[1]); err != nil {
+ return fmt.Errorf("%s: %v", dir, err)
+ }
+ }
+
+ for _, dir := range []string{"s23-2", "s23-3"} {
+ actual := directoryContents(dir)
+ if err := compareDirectoryContents(actual, expected[2]); err != nil {
+ return fmt.Errorf("%s: %v", dir, err)
+ }
+ }
+
+ return nil
+}
diff --git a/test/syncthingprocess.go b/test/syncthingprocess.go
new file mode 100644
index 000000000..1aa868d1b
--- /dev/null
+++ b/test/syncthingprocess.go
@@ -0,0 +1,216 @@
+// Copyright (C) 2014 The Syncthing Authors.
+//
+// This program is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation, either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see .
+
+// +build integration
+
+package integration
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "os/exec"
+ "time"
+)
+
+var env = []string{
+ "HOME=.",
+ "STGUIAPIKEY=" + apiKey,
+ "STNORESTART=1",
+}
+
+type syncthingProcess struct {
+ log string
+ argv []string
+ port int
+ apiKey string
+ csrfToken string
+ lastEvent int
+
+ cmd *exec.Cmd
+ logfd *os.File
+}
+
+func (p *syncthingProcess) start() error {
+ if p.logfd == nil {
+ logfd, err := os.Create(p.log)
+ if err != nil {
+ return err
+ }
+ p.logfd = logfd
+ }
+
+ cmd := exec.Command("../bin/syncthing", p.argv...)
+ cmd.Stdout = p.logfd
+ cmd.Stderr = p.logfd
+ cmd.Env = append(os.Environ(), env...)
+
+ err := cmd.Start()
+ if err != nil {
+ return err
+ }
+ p.cmd = cmd
+
+ for {
+ resp, err := p.get("/")
+ if err == nil {
+ resp.Body.Close()
+ return nil
+ }
+ time.Sleep(250 * time.Millisecond)
+ }
+}
+
+func (p *syncthingProcess) stop() error {
+ p.cmd.Process.Signal(os.Kill)
+ p.cmd.Wait()
+
+ fd, err := os.Open(p.log)
+ if err != nil {
+ return err
+ }
+ defer fd.Close()
+
+ raceConditionStart := []byte("WARNING: DATA RACE")
+ raceConditionSep := []byte("==================")
+ sc := bufio.NewScanner(fd)
+ race := false
+ for sc.Scan() {
+ line := sc.Bytes()
+ if race {
+ fmt.Printf("%s\n", line)
+ if bytes.Contains(line, raceConditionSep) {
+ race = false
+ }
+ } else if bytes.Contains(line, raceConditionStart) {
+ fmt.Printf("%s\n", raceConditionSep)
+ fmt.Printf("%s\n", raceConditionStart)
+ race = true
+ if err == nil {
+ err = errors.New("Race condition detected")
+ }
+ }
+ }
+ return err
+}
+
+func (p *syncthingProcess) get(path string) (*http.Response, error) {
+ client := &http.Client{
+ Timeout: 30 * time.Second,
+ Transport: &http.Transport{
+ DisableKeepAlives: true,
+ },
+ }
+ req, err := http.NewRequest("GET", fmt.Sprintf("http://127.0.0.1:%d%s", p.port, path), nil)
+ if err != nil {
+ return nil, err
+ }
+ if p.apiKey != "" {
+ req.Header.Add("X-API-Key", p.apiKey)
+ }
+ if p.csrfToken != "" {
+ req.Header.Add("X-CSRF-Token", p.csrfToken)
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+func (p *syncthingProcess) post(path string, data io.Reader) (*http.Response, error) {
+ client := &http.Client{
+ Timeout: 600 * time.Second,
+ Transport: &http.Transport{
+ DisableKeepAlives: true,
+ },
+ }
+ req, err := http.NewRequest("POST", fmt.Sprintf("http://127.0.0.1:%d%s", p.port, path), data)
+ if err != nil {
+ return nil, err
+ }
+ if p.apiKey != "" {
+ req.Header.Add("X-API-Key", p.apiKey)
+ }
+ if p.csrfToken != "" {
+ req.Header.Add("X-CSRF-Token", p.csrfToken)
+ }
+ req.Header.Add("Content-Type", "application/json")
+
+ resp, err := client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ 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)
+ 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
+ }
+ defer resp.Body.Close()
+
+ var v versionResp
+ err = json.NewDecoder(resp.Body).Decode(&v)
+ if err != nil {
+ return "", err
+ }
+ return v.Version, nil
+}
diff --git a/test/test-delupd.sh b/test/test-delupd.sh
deleted file mode 100755
index 33e47ca6e..000000000
--- a/test/test-delupd.sh
+++ /dev/null
@@ -1,177 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-IFS=$'\n\t'
-
-# Copyright (C) 2014 The Syncthing Authors.
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see .
-
-iterations=${1:-5}
-
-id1=I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU
-id2=JMFJCXB-GZDE4BN-OCJE3VF-65GYZNU-AIVJRET-3J6HMRQ-AUQIGJO-FKNHMQU
-id3=373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU
-
-go build genfiles.go
-go build md5r.go
-go build json.go
-
-start() {
- echo "Starting..."
- for i in 1 2 3 ; do
- STTRACE=model,scanner STPROFILER=":909$i" ../bin/syncthing -home "h$i" > "$i.out" 2>&1 &
- done
-}
-
-stop() {
- for i in 1 2 3 ; do
- curl -s -o /dev/null -HX-API-Key:abc123 -X POST "http://127.0.0.1:808$i/rest/shutdown"
- done
- exit $1
-}
-
-testConvergence() {
- while true ; do
- sleep 5
- s1comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8082/rest/debug/peerCompletion" | ./json "$id1")
- s2comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8083/rest/debug/peerCompletion" | ./json "$id2")
- s3comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8081/rest/debug/peerCompletion" | ./json "$id3")
- s1comp=${s1comp:-0}
- s2comp=${s2comp:-0}
- s3comp=${s3comp:-0}
- tot=$(($s1comp + $s2comp + $s3comp))
- echo $tot / 300
- if [[ $tot == 300 ]] ; then
- break
- fi
- done
-
- echo "Verifying..."
- cp md5-1 md5-tot
- cp md5-12-2 md5-12-tot
- cp md5-23-3 md5-23-tot
-
- for i in 1 2 3 12-1 12-2 23-2 23-3; do
- pushd "s$i" >/dev/null
- ../md5r -l | sort | grep -v .stversions | grep -v .stfolder > ../md5-$i
- popd >/dev/null
- done
-
- ok=0
- for i in 1 2 3 ; do
- if ! cmp "md5-$i" md5-tot >/dev/null ; then
- echo "Fail: instance $i unconverged for default"
- else
- ok=$(($ok + 1))
- echo "OK: instance $i converged for default"
- fi
- done
- for i in 12-1 12-2 ; do
- if ! cmp "md5-$i" md5-12-tot >/dev/null ; then
- echo "Fail: instance $i unconverged for s12"
- else
- ok=$(($ok + 1))
- echo "OK: instance $i converged for s12"
- fi
- done
- for i in 23-2 23-3 ; do
- if ! cmp "md5-$i" md5-23-tot >/dev/null ; then
- echo "Fail: instance $i unconverged for s23"
- else
- ok=$(($ok + 1))
- echo "OK: instance $i converged for s23"
- fi
- done
- if [[ $ok != 7 ]] ; then
- stop 1
- fi
-}
-
-alterFiles() {
- pkill -STOP syncthing
-
- for i in 1 12-2 23-3 ; do
- # Delete some files
- pushd "s$i" >/dev/null
- chmod 755 ro-test
- nfiles=$(find . -type f | wc -l)
- if [[ $nfiles -ge 300 ]] ; then
- todelete=$(( $nfiles - 300 ))
- echo " $i: deleting $todelete files..."
- set +o pipefail
- find . -type f \
- | grep -v timechanged \
- | grep -v .stfolder \
- | sort -k 1.16 \
- | head -n "$todelete" \
- | xargs rm -f
- set -o pipefail
- fi
-
- # Create some new files and alter existing ones
- echo " $i: random nonoverlapping"
- ../genfiles -maxexp 22 -files 200 -src ../genfiles
- echo " $i: new files in ro directory"
- uuidgen > ro-test/$(uuidgen)
- chmod 500 ro-test
- touch "timechanged-$i"
-
- ../md5r -l | sort | grep -v .stversions | grep -v .stfolder > ../md5-$i
- popd >/dev/null
- done
-
- pkill -CONT syncthing
-
- echo "Restarting instance 2"
- curl -s -o /dev/null -HX-API-Key:abc123 -X POST "http://127.0.0.1:8082/rest/restart"
-}
-
-rm -rf h?/*.idx.gz h?/index
-chmod -R u+w s? s??-? || true
-rm -rf s? s??-?
-mkdir s1 s2 s3 s12-1 s12-2 s23-2 s23-3
-
-echo "Setting up files..."
-for i in 1 12-2 23-3; do
- pushd "s$i" >/dev/null
- echo " $i: random nonoverlapping"
- ../genfiles -maxexp 22 -files 400 -src ../genfiles
- echo " $i: ro directory"
- mkdir ro-test
- uuidgen > ro-test/$(uuidgen)
- chmod 500 ro-test
- dd if=/dev/urandom of="timechanged-$i" bs=1024k count=1
- popd >/dev/null
-done
-
-echo "MD5-summing..."
-for i in 1 12-2 23-3 ; do
- pushd "s$i" >/dev/null
- ../md5r -l | grep -v .stfolder | sort > ../md5-$i
- popd >/dev/null
-done
-
-start
-testConvergence
-
-for ((t = 1; t <= $iterations; t++)) ; do
- echo "Add and remove random files ($t / $iterations)..."
- alterFiles
-
- echo "Waiting..."
- sleep 30
- testConvergence
-done
-
-stop 0
diff --git a/test/test-folders.sh b/test/test-folders.sh
deleted file mode 100755
index 959736646..000000000
--- a/test/test-folders.sh
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-IFS=$'\n\t'
-
-# Copyright (C) 2014 The Syncthing Authors.
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see .
-
-iterations=${1:-5}
-
-id1=I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU
-id2=JMFJCXB-GZDE4BN-OCJE3VF-65GYZNU-AIVJRET-3J6HMRQ-AUQIGJO-FKNHMQU
-
-go build json.go
-
-start() {
- echo "Starting..."
- STTRACE=model,scanner STPROFILER=":9091" ../bin/syncthing -home "f1" > 1.out 2>&1 &
- STTRACE=model,scanner STPROFILER=":9092" ../bin/syncthing -home "f2" > 2.out 2>&1 &
- sleep 1
-}
-
-stop() {
- echo "Stopping..."
- for i in 1 2 ; do
- curl -s -o /dev/null -HX-API-Key:abc123 -X POST "http://127.0.0.1:808$i/rest/shutdown"
- done
-}
-
-setup() {
- echo "Setting up dirs..."
- mkdir -p s1
- pushd s1 >/dev/null
- rm -r */*[02468] 2>/dev/null || true
- rm -rf *2
- for ((i = 0; i < 500; i++)) ; do
- mkdir -p "$RANDOM/$RANDOM"
- done
- for ((i = 0; i < 500; i++)) ; do
- d="$RANDOM/$RANDOM"
- mkdir -p "$d"
- touch "$d/foo"
- done
- ../md5r -d | grep -v ' . ' > ../dirs-1
- popd >/dev/null
-}
-
-testConvergence() {
- while true ; do
- sleep 5
- s1comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8082/rest/debug/peerCompletion" | ./json "$id1")
- s2comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8081/rest/debug/peerCompletion" | ./json "$id2")
- s1comp=${s1comp:-0}
- s2comp=${s2comp:-0}
- tot=$(($s1comp + $s2comp))
- echo $tot / 200
- if [[ $tot == 200 ]] ; then
- # when fixing up directories, a device will announce completion
- # slightly before it's actually complete. this is arguably a bug,
- # but we let it slide for the moment as long as it gets there
- # eventually.
- sleep 5
- break
- fi
- done
-
- echo "Verifying..."
-
- pushd s2 >/dev/null
- ../md5r -d | grep -v ' . ' | grep -v .stversions > ../dirs-2
- popd >/dev/null
-
- if ! cmp dirs-1 dirs-2 ; then
- echo Folders differ
- stop
- exit 1
- fi
-}
-
-chmod -R +w s? s??-? || true
-rm -rf s? s??-?
-rm -rf f?/*.idx.gz f?/index
-
-setup
-start
-
-for ((j = 0; j < iterations; j++)) ; do
- echo "#$j..."
- testConvergence
- setup
- echo "Waiting..."
- sleep 30
-done
-
-stop
diff --git a/test/test-merge.sh b/test/test-merge.sh
deleted file mode 100755
index 732aec271..000000000
--- a/test/test-merge.sh
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-IFS=$'\n\t'
-
-# Copyright (C) 2014 The Syncthing Authors.
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see .
-
-iterations=${1:-5}
-
-id1=I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU
-id2=JMFJCXB-GZDE4BN-OCJE3VF-65GYZNU-AIVJRET-3J6HMRQ-AUQIGJO-FKNHMQU
-id3=373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU
-
-go build genfiles.go
-go build md5r.go
-go build json.go
-
-start() {
- echo "Starting..."
- for i in 1 2 3 4 ; do
- STTRACE=files,model,puller,versioner STPROFILER=":909$i" ../bin/syncthing -home "h$i" > "$i.out" 2>&1 &
- done
-}
-
-stop() {
- for i in 1 2 3 4 ; do
- curl -s -o /dev/null -HX-API-Key:abc123 -X POST "http://127.0.0.1:808$i/rest/shutdown"
- done
- exit $1
-}
-
-clean() {
- if [[ $(uname -s) == "Linux" ]] ; then
- grep -v .stversions | grep -v .stfolder | grep -v utf8-nfd
- else
- grep -v .stversions | grep -v .stfolder
- fi
-}
-
-
-testConvergence() {
- while true ; do
- sleep 5
- s1comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8082/rest/debug/peerCompletion" | ./json "$id1")
- s2comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8083/rest/debug/peerCompletion" | ./json "$id2")
- s3comp=$(curl -HX-API-Key:abc123 -s "http://127.0.0.1:8081/rest/debug/peerCompletion" | ./json "$id3")
- s1comp=${s1comp:-0}
- s2comp=${s2comp:-0}
- s3comp=${s3comp:-0}
- tot=$(($s1comp + $s2comp + $s3comp))
- echo $tot / 300
- if [[ $tot == 300 ]] ; then
- break
- fi
- done
-
- echo "Verifying..."
- cat md5-? | sort | clean | uniq > md5-tot
- cat md5-12-? | sort | clean | uniq > md5-12-tot
- cat md5-23-? | sort | clean | uniq > md5-23-tot
-
- for i in 1 2 3 12-1 12-2 23-2 23-3; do
- pushd "s$i" >/dev/null
- ../md5r -l | sort | clean > ../md5-$i
- popd >/dev/null
- done
-
- ok=0
- for i in 1 2 3 ; do
- if ! cmp "md5-$i" md5-tot >/dev/null ; then
- echo "Fail: instance $i unconverged for default"
- else
- ok=$(($ok + 1))
- echo "OK: instance $i converged for default"
- fi
- done
- for i in 12-1 12-2 ; do
- if ! cmp "md5-$i" md5-12-tot >/dev/null ; then
- echo "Fail: instance $i unconverged for s12"
- else
- ok=$(($ok + 1))
- echo "OK: instance $i converged for s12"
- fi
- done
- for i in 23-2 23-3 ; do
- if ! cmp "md5-$i" md5-23-tot >/dev/null ; then
- echo "Fail: instance $i unconverged for s23"
- else
- ok=$(($ok + 1))
- echo "OK: instance $i converged for s23"
- fi
- done
- if [[ $ok != 7 ]] ; then
- stop 1
- fi
-}
-
-alterFiles() {
- pkill -STOP syncthing
-
- # Create some new files and alter existing ones
- for i in 1 2 3 12-1 12-2 23-2 23-3 ; do
- pushd "s$i" >/dev/null
-
- echo " $i: random nonoverlapping"
- ../genfiles -maxexp 22 -files 200 -src ../genfiles
- echo " $i: append to large file"
- dd if=large-$i bs=1024k count=4 >> large-$i 2>/dev/null
- ../md5r -l > ../md5-tmp
- (grep -v large ../md5-tmp ; grep "large-$i" ../md5-tmp) | grep -v '/.syncthing.' > ../md5-$i
- popd >/dev/null
- done
-
- pkill -CONT syncthing
-}
-
-rm -rf h?/*.idx.gz h?/index
-chmod -R +w s? s??-? s4d || true
-rm -rf s? s??-? s4d
-
-echo "Setting up files..."
-for i in 1 2 3 12-1 12-2 23-2 23-3; do
- mkdir "s$i"
- pushd "s$i" >/dev/null
- echo " $i: random nonoverlapping"
- ../genfiles -maxexp 22 -files 200 -src ../genfiles
- echo " $i: empty file"
- touch "empty-$i"
- echo " $i: large file"
- dd if=/dev/urandom of=large-$i bs=1024k count=15 2>/dev/null
- echo " $i: weird encodings"
- echo somedata > "$(echo -e utf8-nfc-\\xc3\\xad)-$i"
- echo somedata > "$(echo -e utf8-nfd-i\\xcc\\x81)-$i"
- echo somedata > "$(echo -e cp850-\\xa1)-$i"
- touch "empty-$i"
- popd >/dev/null
-done
-
-mkdir s4d
-echo somerandomdata > s4d/extrafile
-
-echo "MD5-summing..."
-for i in 1 2 3 12-1 12-2 23-2 23-3 ; do
- pushd "s$i" >/dev/null
- ../md5r -l > ../md5-$i
- popd >/dev/null
-done
-
-start
-testConvergence
-
-for ((t = 1; t <= $iterations; t++)) ; do
- echo "Add and alter random files ($t / $iterations)..."
- alterFiles
-
- echo "Waiting..."
- sleep 30
- testConvergence
-done
-
-stop 0
diff --git a/test/transfer-bench_test.go b/test/transfer-bench_test.go
index 272969744..e338e3ac1 100644
--- a/test/transfer-bench_test.go
+++ b/test/transfer-bench_test.go
@@ -13,23 +13,17 @@
// You should have received a copy of the GNU General Public License along
// with this program. If not, see .
-// +build integration
+// +build integration,benchmark
-package integration_test
+package integration
import (
"log"
- "strings"
"testing"
"time"
)
func TestBenchmarkTransfer(t *testing.T) {
- nfiles := 10000
- if testing.Short() {
- nfiles = 1000
- }
-
log.Println("Cleaning...")
err := removeAll("s1", "s2", "h1/index", "h2/index")
if err != nil {
@@ -37,12 +31,13 @@ func TestBenchmarkTransfer(t *testing.T) {
}
log.Println("Generating files...")
- err = generateFiles("s1", nfiles, 22, "../LICENSE")
+ err = generateFiles("s1", 10000, 22, "../LICENSE")
if err != nil {
t.Fatal(err)
}
+ expected := directoryContents("s1")
- log.Println("Starting up...")
+ log.Println("Starting sender...")
sender := syncthingProcess{ // id1
log: "1.out",
argv: []string{"-home", "h1"},
@@ -54,6 +49,10 @@ func TestBenchmarkTransfer(t *testing.T) {
t.Fatal(err)
}
+ // Make sure the sender has the full index before they connect
+ sender.post("/rest/scan?folder=default", nil)
+
+ log.Println("Starting receiver...")
receiver := syncthingProcess{ // id2
log: "2.out",
argv: []string{"-home", "h2"},
@@ -66,13 +65,12 @@ func TestBenchmarkTransfer(t *testing.T) {
t.Fatal(err)
}
- var t0 time.Time
+ var t0, t1 time.Time
loop:
for {
evs, err := receiver.events()
if err != nil {
- if strings.Contains(err.Error(), "use of closed network connection") {
- log.Println("...")
+ if isTimeout(err) {
continue
}
sender.stop()
@@ -91,8 +89,8 @@ loop:
t0 = ev.Time
continue
}
- if t0 != (time.Time{}) && data["to"].(string) == "idle" {
- log.Println("Sync took", ev.Time.Sub(t0))
+ if !t0.IsZero() && data["to"].(string) == "idle" {
+ t1 = ev.Time
break loop
}
}
@@ -103,4 +101,14 @@ loop:
sender.stop()
receiver.stop()
+
+ log.Println("Verifying...")
+
+ actual := directoryContents("s2")
+ err = compareDirectoryContents(actual, expected)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ log.Println("Sync took", t1.Sub(t0))
}
diff --git a/test/common_test.go b/test/util.go
similarity index 59%
rename from test/common_test.go
rename to test/util.go
index 2b480a01c..c82d34eef 100644
--- a/test/common_test.go
+++ b/test/util.go
@@ -15,22 +15,20 @@
// +build integration
-package integration_test
+package integration
import (
- "bufio"
- "bytes"
"crypto/md5"
- "encoding/json"
+ cr "crypto/rand"
"errors"
"fmt"
"io"
"log"
"math/rand"
- "net/http"
"os"
- "os/exec"
"path/filepath"
+ "sort"
+ "strings"
"time"
"github.com/syncthing/syncthing/internal/symlinks"
@@ -43,194 +41,10 @@ func init() {
const (
id1 = "I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU"
id2 = "JMFJCXB-GZDE4BN-OCJE3VF-65GYZNU-AIVJRET-3J6HMRQ-AUQIGJO-FKNHMQU"
+ id3 = "373HSRP-QLPNLIE-JYKZVQF-P4PKZ63-R2ZE6K3-YD442U2-JHBGBQG-WWXAHAU"
apiKey = "abc123"
)
-var env = []string{
- "HOME=.",
- "STGUIAPIKEY=" + apiKey,
- "STNORESTART=1",
-}
-
-type syncthingProcess struct {
- log string
- argv []string
- port int
- apiKey string
- csrfToken string
- lastEvent int
-
- cmd *exec.Cmd
- logfd *os.File
-}
-
-func (p *syncthingProcess) start() error {
- if p.logfd == nil {
- logfd, err := os.Create(p.log)
- if err != nil {
- return err
- }
- p.logfd = logfd
- }
-
- cmd := exec.Command("../bin/syncthing", p.argv...)
- cmd.Stdout = p.logfd
- cmd.Stderr = p.logfd
- cmd.Env = append(os.Environ(), env...)
-
- err := cmd.Start()
- if err != nil {
- return err
- }
- p.cmd = cmd
-
- for {
- resp, err := p.get("/")
- if err == nil {
- resp.Body.Close()
- return nil
- }
- time.Sleep(250 * time.Millisecond)
- }
-}
-
-func (p *syncthingProcess) stop() error {
- p.cmd.Process.Signal(os.Kill)
- p.cmd.Wait()
-
- fd, err := os.Open(p.log)
- if err != nil {
- return err
- }
- defer fd.Close()
-
- raceConditionStart := []byte("WARNING: DATA RACE")
- raceConditionSep := []byte("==================")
- sc := bufio.NewScanner(fd)
- race := false
- for sc.Scan() {
- line := sc.Bytes()
- if race {
- fmt.Printf("%s\n", line)
- if bytes.Contains(line, raceConditionSep) {
- race = false
- }
- } else if bytes.Contains(line, raceConditionStart) {
- fmt.Printf("%s\n", raceConditionSep)
- fmt.Printf("%s\n", raceConditionStart)
- race = true
- if err == nil {
- err = errors.New("Race condition detected")
- }
- }
- }
- return err
-}
-
-func (p *syncthingProcess) get(path string) (*http.Response, error) {
- client := &http.Client{
- Timeout: 2 * time.Second,
- Transport: &http.Transport{
- DisableKeepAlives: true,
- },
- }
- req, err := http.NewRequest("GET", fmt.Sprintf("http://127.0.0.1:%d%s", p.port, path), nil)
- if err != nil {
- return nil, err
- }
- if p.apiKey != "" {
- req.Header.Add("X-API-Key", p.apiKey)
- }
- if p.csrfToken != "" {
- req.Header.Add("X-CSRF-Token", p.csrfToken)
- }
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- return resp, nil
-}
-
-func (p *syncthingProcess) post(path string, data io.Reader) (*http.Response, error) {
- client := &http.Client{
- Timeout: 600 * time.Second,
- Transport: &http.Transport{
- DisableKeepAlives: true,
- },
- }
- req, err := http.NewRequest("POST", fmt.Sprintf("http://127.0.0.1:%d%s", p.port, path), data)
- if err != nil {
- return nil, err
- }
- if p.apiKey != "" {
- req.Header.Add("X-API-Key", p.apiKey)
- }
- if p.csrfToken != "" {
- req.Header.Add("X-CSRF-Token", p.csrfToken)
- }
- req.Header.Add("Content-Type", "application/json")
-
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- 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)
- 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
- }
- defer resp.Body.Close()
-
- var v versionResp
- err = json.NewDecoder(resp.Body).Decode(&v)
- if err != nil {
- return "", err
- }
- return v.Version, nil
-}
-
func generateFiles(dir string, files, maxexp int, srcname string) error {
fd, err := os.Open(srcname)
if err != nil {
@@ -239,6 +53,12 @@ func generateFiles(dir string, files, maxexp int, srcname string) error {
for i := 0; i < files; i++ {
n := randomName()
+
+ if rand.Float64() < 0.05 {
+ // Some files and directories are dotfiles
+ n = "." + n
+ }
+
p0 := filepath.Join(dir, string(n[0]), n[0:2])
err = os.MkdirAll(p0, 0755)
if err != nil {
@@ -285,6 +105,73 @@ func generateFiles(dir string, files, maxexp int, srcname string) error {
return nil
}
+func alterFiles(dir string) error {
+ err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+ if os.IsNotExist(err) {
+ // Something we deleted. Never mind.
+ return nil
+ }
+
+ if err != nil {
+ return err
+ }
+
+ switch filepath.Base(path) {
+ case ".stfolder":
+ return nil
+ case ".stversions":
+ return nil
+ }
+
+ r := rand.Float64()
+ comps := len(strings.Split(path, string(os.PathSeparator)))
+ switch {
+ case r < 0.1 && comps > 2:
+ // Delete every tenth file or directory, except top levels
+ err := removeAll(path)
+ if err != nil {
+ return err
+ }
+
+ case r < 0.2 && info.Mode().IsRegular():
+ if info.Mode()&0200 != 0200 {
+ // Not owner writable. Fix.
+ err = os.Chmod(path, 0644)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Overwrite a random kilobyte of every tenth file
+ fd, err := os.OpenFile(path, os.O_RDWR, 0644)
+ if err != nil {
+ return err
+ }
+ if info.Size() > 1024 {
+ _, err = fd.Seek(rand.Int63n(info.Size()), os.SEEK_SET)
+ if err != nil {
+ return err
+ }
+ }
+ _, err = io.Copy(fd, io.LimitReader(cr.Reader, 1024))
+ if err != nil {
+ return err
+ }
+ err = fd.Close()
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ // Create 100 new files
+ return generateFiles(dir, 100, 20, "../LICENSE")
+}
+
func ReadRand(bs []byte) (int, error) {
var r uint32
for i := range bs {
@@ -370,6 +257,53 @@ func compareDirectories(dirs ...string) error {
}
}
+func directoryContents(dir string) []fileInfo {
+ res := make(chan fileInfo)
+ startWalker(dir, res, nil)
+
+ var files []fileInfo
+ for f := range res {
+ files = append(files, f)
+ }
+
+ return files
+}
+
+func mergeDirectoryContents(c ...[]fileInfo) []fileInfo {
+ m := make(map[string]fileInfo)
+
+ for _, l := range c {
+ for _, f := range l {
+ if cur, ok := m[f.name]; !ok || cur.mod < f.mod {
+ m[f.name] = f
+ }
+ }
+ }
+
+ res := make([]fileInfo, len(m))
+ i := 0
+ for _, f := range m {
+ res[i] = f
+ i++
+ }
+
+ sort.Sort(fileInfoList(res))
+ return res
+}
+
+func compareDirectoryContents(actual, expected []fileInfo) error {
+ if len(actual) != len(expected) {
+ return fmt.Errorf("len(actual) = %d; len(expected) = %d", len(actual), len(expected))
+ }
+
+ for i := range actual {
+ if actual[i] != expected[i] {
+ return fmt.Errorf("Mismatch; actual %#v != expected %#v", actual[i], expected[i])
+ }
+ }
+ return nil
+}
+
type fileInfo struct {
name string
mode os.FileMode
@@ -377,6 +311,20 @@ type fileInfo struct {
hash [16]byte
}
+type fileInfoList []fileInfo
+
+func (l fileInfoList) Len() int {
+ return len(l)
+}
+
+func (l fileInfoList) Less(a, b int) bool {
+ return l[a].name < l[b].name
+}
+
+func (l fileInfoList) Swap(a, b int) {
+ l[a], l[b] = l[b], l[a]
+}
+
func startWalker(dir string, res chan<- fileInfo, abort <-chan struct{}) {
walker := func(path string, info os.FileInfo, err error) error {
if err != nil {
@@ -453,3 +401,11 @@ func md5file(fname string) (hash [16]byte, err error) {
return
}
+
+func isTimeout(err error) bool {
+ if err == nil {
+ return false
+ }
+ return strings.Contains(err.Error(), "use of closed network connection") ||
+ strings.Contains(err.Error(), "request cancelled while waiting")
+}