Browse Source

cmd/syncthing: Basic smoke test of all API endpoints

... except /rest/system/upgrade that requires a correct response from
Github, which we shouldn't depend on.
Jakob Borg 9 years ago
parent
commit
95247f7740
1 changed files with 184 additions and 51 deletions
  1. 184 51
      cmd/syncthing/gui_test.go

+ 184 - 51
cmd/syncthing/gui_test.go

@@ -180,6 +180,14 @@ func TestDirNames(t *testing.T) {
 	}
 }
 
+type httpTestCase struct {
+	URL     string        // URL to check
+	Code    int           // Expected result code
+	Type    string        // Expected content type
+	Prefix  string        // Expected result prefix
+	Timeout time.Duration // Defaults to a second
+}
+
 func TestAPIServiceRequests(t *testing.T) {
 	model := new(mockedModel)
 	cfg := new(mockedConfig)
@@ -216,71 +224,196 @@ func TestAPIServiceRequests(t *testing.T) {
 	supervisor.Add(svc)
 	supervisor.ServeBackground()
 
-	// Try requests to common URLs, all of which should succeed and return
-	// some sort of JSON object.
-	urls := []string{
-		"/rest/system/status",
-		"/rest/system/config",
-		"/rest/system/config/insync",
-		// "/rest/system/connections", does not return an object in the empty case ("null"), should be fixed
-		"/rest/system/discovery",
-		"/rest/system/error?since=0",
-		"/rest/system/ping",
-		// "/rest/system/upgrade", depends on Github API, not good for testing
-		"/rest/system/version",
-		"/rest/system/debug",
-		"/rest/system/log?since=0",
+	cases := []httpTestCase{
+		// /rest/db
+		{
+			URL:    "/rest/db/completion?device=" + protocol.LocalDeviceID.String() + "&folder=default",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:  "/rest/db/file?folder=default&file=something",
+			Code: 404,
+		},
+		{
+			URL:    "/rest/db/ignores?folder=default",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/db/need?folder=default",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/db/status?folder=default",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/db/browse?folder=default",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "null",
+		},
+
+		// /rest/stats
+		{
+			URL:    "/rest/stats/device",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "null",
+		},
+		{
+			URL:    "/rest/stats/folder",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "null",
+		},
+
+		// /rest/svc
+		{
+			URL:    "/rest/svc/deviceid?id=" + protocol.LocalDeviceID.String(),
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/svc/lang",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "[",
+		},
+		{
+			URL:     "/rest/svc/report",
+			Code:    200,
+			Type:    "application/json",
+			Prefix:  "{",
+			Timeout: 5 * time.Second,
+		},
+
+		// /rest/system
+		{
+			URL:    "/rest/system/browse?current=~",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "[",
+		},
+		{
+			URL:    "/rest/system/config",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/config/insync",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/connections",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "null",
+		},
+		{
+			URL:    "/rest/system/discovery",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/error?since=0",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/ping",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/status",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/version",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/debug",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/log?since=0",
+			Code:   200,
+			Type:   "application/json",
+			Prefix: "{",
+		},
+		{
+			URL:    "/rest/system/log.txt?since=0",
+			Code:   200,
+			Type:   "text/plain",
+			Prefix: "",
+		},
 	}
-	for _, url := range urls {
-		t.Log("Testing", url, "...")
-		testHTTPJSONObject(t, baseURL+url)
+
+	for _, tc := range cases {
+		t.Log("Testing", tc.URL, "...")
+		testHTTPRequest(t, baseURL, tc)
 	}
 }
 
-// testHTTPJSONObject tries the given URL and verifies that the HTTP request
-// succeeds and that a JSON object (something beginning with "{") is
-// returned. Returns the object data, or nil on failure.
-func testHTTPJSONObject(t *testing.T, url string) []byte {
-	resp := testHTTPRequest(t, url)
-	if resp == nil {
-		return nil
+// testHTTPRequest tries the given test case, comparing the result code,
+// content type, and result prefix.
+func testHTTPRequest(t *testing.T, baseURL string, tc httpTestCase) {
+	timeout := time.Second
+	if tc.Timeout > 0 {
+		timeout = tc.Timeout
 	}
-
-	ct := resp.Header.Get("Content-Type")
-	if !strings.HasPrefix(ct, "application/json") {
-		t.Errorf("The content type on %s should be application/json, not %q", url, ct)
-		return nil
+	cli := &http.Client{
+		Timeout: timeout,
 	}
 
-	defer resp.Body.Close()
-	data, err := ioutil.ReadAll(resp.Body)
+	resp, err := cli.Get(baseURL + tc.URL)
 	if err != nil {
-		t.Errorf("Unexpected error reading %s: %v", url, err)
-		return nil
+		t.Errorf("Unexpected error requesting %s: %v", tc.URL, err)
+		return
 	}
+	defer resp.Body.Close()
 
-	if !bytes.HasPrefix(data, []byte("{")) {
-		t.Errorf("Returned data from %s does not look like a JSON object: %s", url, data)
-		return nil
+	if resp.StatusCode != tc.Code {
+		t.Errorf("Get on %s should have returned status code %d, not %s", tc.URL, tc.Code, resp.Status)
+		return
 	}
-	return data
-}
 
-// testHTTPRequest performs a HTTP GET request and verifies that the
-// response is successfull (code 200). Returns the *http.Response or nil on
-// failure.
-func testHTTPRequest(t *testing.T, url string) *http.Response {
-	cli := &http.Client{
-		Timeout: time.Second,
+	ct := resp.Header.Get("Content-Type")
+	if !strings.HasPrefix(ct, tc.Type) {
+		t.Errorf("The content type on %s should be %q, not %q", tc.URL, tc.Type, ct)
+		return
 	}
-	resp, err := cli.Get(url)
+
+	data, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
-		t.Errorf("Unexpected error requesting %s: %v", url, err)
-		return nil
+		t.Errorf("Unexpected error reading %s: %v", tc.URL, err)
+		return
 	}
-	if resp.StatusCode != 200 {
-		t.Errorf("Get on %s should have returned status code 200, not %s", url, resp.Status)
-		return nil
+
+	if !bytes.HasPrefix(data, []byte(tc.Prefix)) {
+		t.Errorf("Returned data from %s does not have prefix %q: %s", tc.URL, tc.Prefix, data)
+		return
 	}
-	return resp
 }