mirror of
https://github.com/octoleo/syncthing.git
synced 2025-02-08 14:58:26 +00:00
cmd/syncthing: Add test for starting API service and requesting some URLs
This commit is contained in:
parent
52c74ad866
commit
e5731229c7
@ -9,10 +9,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/d4l3k/messagediff"
|
"github.com/d4l3k/messagediff"
|
||||||
"github.com/syncthing/syncthing/lib/config"
|
"github.com/syncthing/syncthing/lib/config"
|
||||||
@ -176,7 +180,7 @@ func TestDirNames(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInstantiateAPIService(t *testing.T) {
|
func TestAPIServiceRequests(t *testing.T) {
|
||||||
model := new(mockedModel)
|
model := new(mockedModel)
|
||||||
cfg := new(mockedConfig)
|
cfg := new(mockedConfig)
|
||||||
httpsCertFile := "../../test/h1/https-cert.pem"
|
httpsCertFile := "../../test/h1/https-cert.pem"
|
||||||
@ -188,10 +192,95 @@ func TestInstantiateAPIService(t *testing.T) {
|
|||||||
errorLog := new(mockedLoggerRecorder)
|
errorLog := new(mockedLoggerRecorder)
|
||||||
systemLog := new(mockedLoggerRecorder)
|
systemLog := new(mockedLoggerRecorder)
|
||||||
|
|
||||||
|
// Instantiate the API service
|
||||||
svc, err := newAPIService(protocol.LocalDeviceID, cfg, httpsCertFile, httpsKeyFile, assetDir, model,
|
svc, err := newAPIService(protocol.LocalDeviceID, cfg, httpsCertFile, httpsKeyFile, assetDir, model,
|
||||||
eventSub, discoverer, relayService, errorLog, systemLog)
|
eventSub, discoverer, relayService, errorLog, systemLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
_ = svc
|
_ = svc
|
||||||
|
|
||||||
|
// Make sure the API service is listening, and get the URL to use.
|
||||||
|
addr := svc.listener.Addr()
|
||||||
|
if addr == nil {
|
||||||
|
t.Fatal("Nil listening address from API service")
|
||||||
|
}
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr("tcp", addr.String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Weird address from API service:", err)
|
||||||
|
}
|
||||||
|
baseURL := fmt.Sprintf("http://127.0.0.1:%d", tcpAddr.Port)
|
||||||
|
|
||||||
|
// Actually start the API service
|
||||||
|
supervisor := suture.NewSimple("API test")
|
||||||
|
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",
|
||||||
|
}
|
||||||
|
for _, url := range urls {
|
||||||
|
t.Log("Testing", url, "...")
|
||||||
|
testHTTPJSONObject(t, baseURL+url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error reading %s: %v", url, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.HasPrefix(data, []byte("{")) {
|
||||||
|
t.Errorf("Returned data from %s does not look like a JSON object: %s", url, data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
resp, err := cli.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error requesting %s: %v", url, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
t.Errorf("Get on %s should have returned status code 200, not %s", url, resp.Status)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return resp
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,12 @@ import (
|
|||||||
type mockedLoggerRecorder struct{}
|
type mockedLoggerRecorder struct{}
|
||||||
|
|
||||||
func (r *mockedLoggerRecorder) Since(t time.Time) []logger.Line {
|
func (r *mockedLoggerRecorder) Since(t time.Time) []logger.Line {
|
||||||
select {}
|
return []logger.Line{
|
||||||
|
{
|
||||||
|
When: time.Now(),
|
||||||
|
Message: "Test message",
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mockedLoggerRecorder) Clear() {}
|
func (r *mockedLoggerRecorder) Clear() {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user