lib/api: Refactor to run tests in parallel (#5998)
This is an experiment in testing, based on the advise to always call t.Parallel() at the start of every test. Doing so makes tests run in parallel, which is usually faster, but also exposes package level state and potential race conditions better. To support this I had to redesign the CSRF manager to not be package global, which was indeed an improvement. And tests run five times faster now.
This commit is contained in:
@@ -53,7 +53,7 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
|
||||
func TestCSRFToken(t *testing.T) {
|
||||
defer os.Remove(token)
|
||||
t.Parallel()
|
||||
|
||||
max := 250
|
||||
int := 5
|
||||
@@ -62,11 +62,13 @@ func TestCSRFToken(t *testing.T) {
|
||||
int = 2
|
||||
}
|
||||
|
||||
t1 := newCsrfToken()
|
||||
t2 := newCsrfToken()
|
||||
m := newCsrfManager("unique", "prefix", config.GUIConfiguration{}, nil, "")
|
||||
|
||||
t3 := newCsrfToken()
|
||||
if !validCsrfToken(t3) {
|
||||
t1 := m.newToken()
|
||||
t2 := m.newToken()
|
||||
|
||||
t3 := m.newToken()
|
||||
if !m.validToken(t3) {
|
||||
t.Fatal("t3 should be valid")
|
||||
}
|
||||
|
||||
@@ -74,27 +76,29 @@ func TestCSRFToken(t *testing.T) {
|
||||
if i%int == 0 {
|
||||
// t1 and t2 should remain valid by virtue of us checking them now
|
||||
// and then.
|
||||
if !validCsrfToken(t1) {
|
||||
if !m.validToken(t1) {
|
||||
t.Fatal("t1 should be valid at iteration", i)
|
||||
}
|
||||
if !validCsrfToken(t2) {
|
||||
if !m.validToken(t2) {
|
||||
t.Fatal("t2 should be valid at iteration", i)
|
||||
}
|
||||
}
|
||||
|
||||
// The newly generated token is always valid
|
||||
t4 := newCsrfToken()
|
||||
if !validCsrfToken(t4) {
|
||||
t4 := m.newToken()
|
||||
if !m.validToken(t4) {
|
||||
t.Fatal("t4 should be valid at iteration", i)
|
||||
}
|
||||
}
|
||||
|
||||
if validCsrfToken(t3) {
|
||||
if m.validToken(t3) {
|
||||
t.Fatal("t3 should have expired by now")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStopAfterBrokenConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := config.Configuration{
|
||||
GUI: config.GUIConfiguration{
|
||||
RawAddress: "127.0.0.1:0",
|
||||
@@ -135,6 +139,8 @@ func TestStopAfterBrokenConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAssetsDir(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// For any given request to $FILE, we should return the first found of
|
||||
// - assetsdir/$THEME/$FILE
|
||||
// - compiled in asset $THEME/$FILE
|
||||
@@ -209,6 +215,8 @@ func expectURLToContain(t *testing.T, url, exp string) {
|
||||
}
|
||||
|
||||
func TestDirNames(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
names := dirNames("testdata")
|
||||
expected := []string{"config", "default", "foo", "testfolder"}
|
||||
if diff, equal := messagediff.PrettyDiff(expected, names); !equal {
|
||||
@@ -225,6 +233,8 @@ type httpTestCase struct {
|
||||
}
|
||||
|
||||
func TestAPIServiceRequests(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
@@ -435,6 +445,8 @@ func testHTTPRequest(t *testing.T, baseURL string, tc httpTestCase, apikey strin
|
||||
}
|
||||
|
||||
func TestHTTPLogin(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.User = "üser"
|
||||
cfg.gui.Password = "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq" // bcrypt of "räksmörgås" in UTF-8
|
||||
@@ -542,6 +554,8 @@ func startHTTP(cfg *mockedConfig) (string, error) {
|
||||
}
|
||||
|
||||
func TestCSRFRequired(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
@@ -615,6 +629,8 @@ func TestCSRFRequired(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRandomString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
@@ -664,6 +680,8 @@ func TestRandomString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConfigPostOK(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := bytes.NewBuffer([]byte(`{
|
||||
"version": 15,
|
||||
"folders": [
|
||||
@@ -685,6 +703,8 @@ func TestConfigPostOK(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConfigPostDupFolder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := bytes.NewBuffer([]byte(`{
|
||||
"version": 15,
|
||||
"folders": [
|
||||
@@ -720,6 +740,8 @@ func testConfigPost(data io.Reader) (*http.Response, error) {
|
||||
}
|
||||
|
||||
func TestHostCheck(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// An API service bound to localhost should reject non-localhost host Headers
|
||||
|
||||
cfg := new(mockedConfig)
|
||||
@@ -878,6 +900,8 @@ func TestHostCheck(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAddressIsLocalhost(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testcases := []struct {
|
||||
address string
|
||||
result bool
|
||||
@@ -921,6 +945,8 @@ func TestAddressIsLocalhost(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAccessControlAllowOriginHeader(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
@@ -949,6 +975,8 @@ func TestAccessControlAllowOriginHeader(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOptionsRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
@@ -982,6 +1010,8 @@ func TestOptionsRequest(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEventMasks(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cfg := new(mockedConfig)
|
||||
defSub := new(mockedEventSub)
|
||||
diskSub := new(mockedEventSub)
|
||||
@@ -1014,6 +1044,8 @@ func TestEventMasks(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBrowse(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
pathSep := string(os.PathSeparator)
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "syncthing")
|
||||
@@ -1066,6 +1098,8 @@ func TestBrowse(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrefixMatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
s string
|
||||
prefix string
|
||||
|
||||
Reference in New Issue
Block a user