// Copyright (C) 2016 The Syncthing Authors. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. package main import ( "bytes" "compress/gzip" "io/ioutil" "net/http" "net/http/httptest" "testing" "github.com/d4l3k/messagediff" "github.com/syncthing/syncthing/lib/config" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/sync" "github.com/thejerf/suture" ) func TestCSRFToken(t *testing.T) { t1 := newCsrfToken() t2 := newCsrfToken() t3 := newCsrfToken() if !validCsrfToken(t3) { t.Fatal("t3 should be valid") } for i := 0; i < 250; i++ { if i%5 == 0 { // t1 and t2 should remain valid by virtue of us checking them now // and then. if !validCsrfToken(t1) { t.Fatal("t1 should be valid at iteration", i) } if !validCsrfToken(t2) { t.Fatal("t2 should be valid at iteration", i) } } // The newly generated token is always valid t4 := newCsrfToken() if !validCsrfToken(t4) { t.Fatal("t4 should be valid at iteration", i) } } if validCsrfToken(t3) { t.Fatal("t3 should have expired by now") } } func TestStopAfterBrokenConfig(t *testing.T) { baseDirs["config"] = "../../test/h1" // to load HTTPS keys expandLocations() cfg := config.Configuration{ GUI: config.GUIConfiguration{ RawAddress: "127.0.0.1:0", RawUseTLS: false, }, } w := config.Wrap("/dev/null", cfg) srv, err := newAPIService(protocol.LocalDeviceID, w, "", nil, nil, nil, nil, nil, nil) if err != nil { t.Fatal(err) } srv.started = make(chan struct{}) sup := suture.NewSimple("test") sup.Add(srv) sup.ServeBackground() <-srv.started // Service is now running, listening on a random port on localhost. Now we // request a config change to a completely invalid listen address. The // commit will fail and the service will be in a broken state. newCfg := config.Configuration{ GUI: config.GUIConfiguration{ RawAddress: "totally not a valid address", RawUseTLS: false, }, } if srv.CommitConfiguration(cfg, newCfg) { t.Fatal("Config commit should have failed") } // Nonetheless, it should be fine to Stop() it without panic. sup.Stop() } func TestAssetsDir(t *testing.T) { // For any given request to $FILE, we should return the first found of // - assetsdir/$THEME/$FILE // - compiled in asset $THEME/$FILE // - assetsdir/default/$FILE // - compiled in asset default/$FILE // The asset map contains compressed assets, so create a couple of gzip compressed assets here. buf := new(bytes.Buffer) gw := gzip.NewWriter(buf) gw.Write([]byte("default")) gw.Close() def := buf.Bytes() buf = new(bytes.Buffer) gw = gzip.NewWriter(buf) gw.Write([]byte("foo")) gw.Close() foo := buf.Bytes() e := embeddedStatic{ theme: "foo", mut: sync.NewRWMutex(), assetDir: "testdata", assets: map[string][]byte{ "foo/a": foo, // overridden in foo/a "foo/b": foo, "default/a": def, // overridden in default/a (but foo/a takes precedence) "default/b": def, // overridden in default/b (but foo/b takes precedence) "default/c": def, }, } s := httptest.NewServer(e) defer s.Close() // assetsdir/foo/a exists, overrides compiled in expectURLToContain(t, s.URL+"/a", "overridden-foo") // foo/b is compiled in, default/b is overriden, return compiled in expectURLToContain(t, s.URL+"/b", "foo") // only exists as compiled in default/c so use that expectURLToContain(t, s.URL+"/c", "default") // only exists as overriden default/d so use that expectURLToContain(t, s.URL+"/d", "overridden-default") } func expectURLToContain(t *testing.T, url, exp string) { res, err := http.Get(url) if err != nil { t.Error(err) return } if res.StatusCode != 200 { t.Errorf("Got %s instead of 200 OK", res.Status) return } data, err := ioutil.ReadAll(res.Body) res.Body.Close() if err != nil { t.Error(err) return } if string(data) != exp { t.Errorf("Got %q instead of %q on %q", data, exp, url) return } } func TestDirNames(t *testing.T) { names := dirNames("testdata") expected := []string{"default", "foo", "testfolder"} if diff, equal := messagediff.PrettyDiff(expected, names); !equal { t.Errorf("Unexpected dirNames return: %#v\n%s", names, diff) } }