all: Implement suture v4-api (#6947)
This commit is contained in:
+40
-40
@@ -9,6 +9,7 @@ package api
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -34,7 +35,8 @@ import (
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||
"github.com/syncthing/syncthing/lib/ur"
|
||||
"github.com/thejerf/suture"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
"github.com/thejerf/suture/v4"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -113,15 +115,14 @@ func TestStopAfterBrokenConfig(t *testing.T) {
|
||||
}
|
||||
w := config.Wrap("/dev/null", cfg, events.NoopLogger)
|
||||
|
||||
srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, false).(*service)
|
||||
srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, false).(*service)
|
||||
defer os.Remove(token)
|
||||
srv.started = make(chan string)
|
||||
|
||||
sup := suture.New("test", suture.Spec{
|
||||
PassThroughPanics: true,
|
||||
})
|
||||
sup := suture.New("test", util.Spec())
|
||||
sup.Add(srv)
|
||||
sup.ServeBackground()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
sup.ServeBackground(ctx)
|
||||
|
||||
<-srv.started
|
||||
|
||||
@@ -139,9 +140,7 @@ func TestStopAfterBrokenConfig(t *testing.T) {
|
||||
t.Fatal("Verify config should have failed")
|
||||
}
|
||||
|
||||
// Nonetheless, it should be fine to Stop() it without panic.
|
||||
|
||||
sup.Stop()
|
||||
cancel()
|
||||
}
|
||||
|
||||
func TestAssetsDir(t *testing.T) {
|
||||
@@ -250,11 +249,11 @@ func TestAPIServiceRequests(t *testing.T) {
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
cases := []httpTestCase{
|
||||
// /rest/db
|
||||
@@ -519,11 +518,11 @@ func TestHTTPLogin(t *testing.T) {
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.User = "üser"
|
||||
cfg.gui.Password = "$2a$10$IdIZTxTg/dCNuNEGlmLynOjqg4B1FvDKuIV5e0BB3pnWVHNb8.GSq" // bcrypt of "räksmörgås" in UTF-8
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
// Verify rejection when not using authorization
|
||||
|
||||
@@ -581,7 +580,7 @@ func TestHTTPLogin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func startHTTP(cfg config.Wrapper) (string, *suture.Supervisor, error) {
|
||||
func startHTTP(cfg config.Wrapper) (string, context.CancelFunc, error) {
|
||||
m := new(mockedModel)
|
||||
assetDir := "../../gui"
|
||||
eventSub := new(mockedEventSub)
|
||||
@@ -594,7 +593,7 @@ func startHTTP(cfg config.Wrapper) (string, *suture.Supervisor, error) {
|
||||
|
||||
// Instantiate the API service
|
||||
urService := ur.New(cfg, m, connections, false)
|
||||
svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, &mockedFolderSummaryService{}, errorLog, systemLog, nil, false).(*service)
|
||||
svc := New(protocol.LocalDeviceID, cfg, assetDir, "syncthing", m, eventSub, diskEventSub, events.NoopLogger, discoverer, connections, urService, &mockedFolderSummaryService{}, errorLog, systemLog, false).(*service)
|
||||
defer os.Remove(token)
|
||||
svc.started = addrChan
|
||||
|
||||
@@ -603,14 +602,15 @@ func startHTTP(cfg config.Wrapper) (string, *suture.Supervisor, error) {
|
||||
PassThroughPanics: true,
|
||||
})
|
||||
supervisor.Add(svc)
|
||||
supervisor.ServeBackground()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
supervisor.ServeBackground(ctx)
|
||||
|
||||
// Make sure the API service is listening, and get the URL to use.
|
||||
addr := <-addrChan
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||
if err != nil {
|
||||
supervisor.Stop()
|
||||
return "", nil, fmt.Errorf("weird address from API service: %w", err)
|
||||
cancel()
|
||||
return "", cancel, fmt.Errorf("weird address from API service: %w", err)
|
||||
}
|
||||
|
||||
host, _, _ := net.SplitHostPort(cfg.GUI().RawAddress)
|
||||
@@ -619,7 +619,7 @@ func startHTTP(cfg config.Wrapper) (string, *suture.Supervisor, error) {
|
||||
}
|
||||
baseURL := fmt.Sprintf("http://%s", net.JoinHostPort(host, strconv.Itoa(tcpAddr.Port)))
|
||||
|
||||
return baseURL, supervisor, nil
|
||||
return baseURL, cancel, nil
|
||||
}
|
||||
|
||||
func TestCSRFRequired(t *testing.T) {
|
||||
@@ -628,11 +628,11 @@ func TestCSRFRequired(t *testing.T) {
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal("Unexpected error from getting base URL:", err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
cli := &http.Client{
|
||||
Timeout: time.Minute,
|
||||
@@ -704,11 +704,11 @@ func TestRandomString(t *testing.T) {
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
cli := &http.Client{
|
||||
Timeout: time.Second,
|
||||
}
|
||||
@@ -797,11 +797,11 @@ func testConfigPost(data io.Reader) (*http.Response, error) {
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
cli := &http.Client{
|
||||
Timeout: time.Second,
|
||||
}
|
||||
@@ -818,11 +818,11 @@ func TestHostCheck(t *testing.T) {
|
||||
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.RawAddress = "127.0.0.1:0"
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
// A normal HTTP get to the localhost-bound service should succeed
|
||||
|
||||
@@ -879,11 +879,11 @@ func TestHostCheck(t *testing.T) {
|
||||
cfg = new(mockedConfig)
|
||||
cfg.gui.RawAddress = "127.0.0.1:0"
|
||||
cfg.gui.InsecureSkipHostCheck = true
|
||||
baseURL, sup, err = startHTTP(cfg)
|
||||
baseURL, cancel, err = startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
// A request with a suspicious Host header should be allowed
|
||||
|
||||
@@ -903,11 +903,11 @@ func TestHostCheck(t *testing.T) {
|
||||
cfg = new(mockedConfig)
|
||||
cfg.gui.RawAddress = "0.0.0.0:0"
|
||||
cfg.gui.InsecureSkipHostCheck = true
|
||||
baseURL, sup, err = startHTTP(cfg)
|
||||
baseURL, cancel, err = startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
// A request with a suspicious Host header should be allowed
|
||||
|
||||
@@ -931,11 +931,11 @@ func TestHostCheck(t *testing.T) {
|
||||
|
||||
cfg = new(mockedConfig)
|
||||
cfg.gui.RawAddress = "[::1]:0"
|
||||
baseURL, sup, err = startHTTP(cfg)
|
||||
baseURL, cancel, err = startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
// A normal HTTP get to the localhost-bound service should succeed
|
||||
|
||||
@@ -1026,11 +1026,11 @@ func TestAccessControlAllowOriginHeader(t *testing.T) {
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
cli := &http.Client{
|
||||
Timeout: time.Second,
|
||||
}
|
||||
@@ -1057,11 +1057,11 @@ func TestOptionsRequest(t *testing.T) {
|
||||
const testAPIKey = "foobarbaz"
|
||||
cfg := new(mockedConfig)
|
||||
cfg.gui.APIKey = testAPIKey
|
||||
baseURL, sup, err := startHTTP(cfg)
|
||||
baseURL, cancel, err := startHTTP(cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
cli := &http.Client{
|
||||
Timeout: time.Second,
|
||||
}
|
||||
@@ -1093,7 +1093,7 @@ func TestEventMasks(t *testing.T) {
|
||||
cfg := new(mockedConfig)
|
||||
defSub := new(mockedEventSub)
|
||||
diskSub := new(mockedEventSub)
|
||||
svc := New(protocol.LocalDeviceID, cfg, "", "syncthing", nil, defSub, diskSub, events.NoopLogger, nil, nil, nil, nil, nil, nil, nil, false).(*service)
|
||||
svc := New(protocol.LocalDeviceID, cfg, "", "syncthing", nil, defSub, diskSub, events.NoopLogger, nil, nil, nil, nil, nil, nil, false).(*service)
|
||||
defer os.Remove(token)
|
||||
|
||||
if mask := svc.getEventMask(""); mask != DefaultEventMask {
|
||||
@@ -1253,11 +1253,11 @@ func TestConfigChanges(t *testing.T) {
|
||||
defer os.Remove(tmpFile.Name())
|
||||
w := config.Wrap(tmpFile.Name(), cfg, events.NoopLogger)
|
||||
tmpFile.Close()
|
||||
baseURL, sup, err := startHTTP(w)
|
||||
baseURL, cancel, err := startHTTP(w)
|
||||
if err != nil {
|
||||
t.Fatal("Unexpected error from getting base URL:", err)
|
||||
}
|
||||
defer sup.Stop()
|
||||
defer cancel()
|
||||
|
||||
cli := &http.Client{
|
||||
Timeout: time.Second,
|
||||
|
||||
Reference in New Issue
Block a user