2012-03-15 12:31:06 +00:00
|
|
|
/*
|
|
|
|
Copyright 2012 Google Inc.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2014-01-23 16:18:22 +00:00
|
|
|
package serverinit_test
|
2012-03-15 12:31:06 +00:00
|
|
|
|
|
|
|
import (
|
2012-04-13 22:46:01 +00:00
|
|
|
"bytes"
|
2013-11-24 23:04:20 +00:00
|
|
|
"encoding/json"
|
2013-01-10 23:29:08 +00:00
|
|
|
"errors"
|
2013-11-24 23:04:20 +00:00
|
|
|
"flag"
|
2012-03-15 12:31:06 +00:00
|
|
|
"fmt"
|
2012-04-13 22:46:01 +00:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
2014-09-22 22:25:41 +00:00
|
|
|
"net/http"
|
2016-04-27 21:29:06 +00:00
|
|
|
"net/http/httptest"
|
2012-03-15 12:31:06 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2014-09-22 22:25:41 +00:00
|
|
|
"reflect"
|
2014-07-31 18:50:54 +00:00
|
|
|
"regexp"
|
|
|
|
"runtime"
|
2012-03-15 12:31:06 +00:00
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
2015-12-01 16:19:49 +00:00
|
|
|
"go4.org/jsonconfig"
|
2018-01-03 05:03:30 +00:00
|
|
|
"perkeep.org/internal/httputil"
|
|
|
|
"perkeep.org/internal/osutil"
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
"perkeep.org/pkg/auth"
|
|
|
|
"perkeep.org/pkg/importer"
|
|
|
|
"perkeep.org/pkg/jsonsign/signhandler"
|
|
|
|
"perkeep.org/pkg/search"
|
|
|
|
"perkeep.org/pkg/server"
|
|
|
|
"perkeep.org/pkg/serverinit"
|
|
|
|
"perkeep.org/pkg/test"
|
|
|
|
"perkeep.org/pkg/types/clientconfig"
|
|
|
|
"perkeep.org/pkg/types/serverconfig"
|
2014-09-22 22:25:41 +00:00
|
|
|
|
|
|
|
// For registering all the handler constructors needed in TestInstallHandlers
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
_ "perkeep.org/pkg/blobserver/cond"
|
|
|
|
_ "perkeep.org/pkg/blobserver/replica"
|
|
|
|
_ "perkeep.org/pkg/importer/allimporters"
|
|
|
|
_ "perkeep.org/pkg/search"
|
|
|
|
_ "perkeep.org/pkg/server"
|
2012-03-15 12:31:06 +00:00
|
|
|
)
|
|
|
|
|
2014-03-17 15:42:19 +00:00
|
|
|
var (
|
|
|
|
updateGolden = flag.Bool("update_golden", false, "Update golden *.want files")
|
|
|
|
flagOnly = flag.String("only", "", "If non-empty, substring of foo.json input file to match.")
|
|
|
|
)
|
2013-11-24 23:04:20 +00:00
|
|
|
|
2013-11-25 16:27:11 +00:00
|
|
|
const (
|
2014-01-23 22:40:12 +00:00
|
|
|
// relativeRing points to a real secret ring, but serverinit
|
2013-11-25 16:27:11 +00:00
|
|
|
// rewrites it to be an absolute path. We then canonicalize
|
|
|
|
// it to secringPlaceholder in the golden files.
|
|
|
|
relativeRing = "../jsonsign/testdata/test-secring.gpg"
|
|
|
|
secringPlaceholder = "/path/to/secring"
|
|
|
|
)
|
2013-11-25 04:38:00 +00:00
|
|
|
|
2013-01-11 18:52:22 +00:00
|
|
|
func init() {
|
|
|
|
// Avoid Linux vs. OS X differences in tests.
|
2014-01-23 16:18:22 +00:00
|
|
|
serverinit.SetTempDirFunc(func() string { return "/tmp" })
|
|
|
|
serverinit.SetNoMkdir(true)
|
2013-01-11 18:52:22 +00:00
|
|
|
}
|
|
|
|
|
2014-08-08 01:47:42 +00:00
|
|
|
func prettyPrint(t *testing.T, w io.Writer, v interface{}) {
|
|
|
|
out, err := json.MarshalIndent(v, "", " ")
|
2013-11-24 23:04:20 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
2012-03-15 12:31:06 +00:00
|
|
|
}
|
2013-11-24 23:04:20 +00:00
|
|
|
w.Write(out)
|
2012-03-15 12:31:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestConfigs(t *testing.T) {
|
|
|
|
dir, err := os.Open("testdata")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
names, err := dir.Readdirnames(-1)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
for _, name := range names {
|
2015-01-19 02:08:18 +00:00
|
|
|
if strings.HasPrefix(name, ".#") {
|
|
|
|
// Emacs noise.
|
|
|
|
continue
|
|
|
|
}
|
2014-03-17 15:42:19 +00:00
|
|
|
if *flagOnly != "" && !strings.Contains(name, *flagOnly) {
|
|
|
|
continue
|
|
|
|
}
|
2012-03-15 12:31:06 +00:00
|
|
|
if strings.HasSuffix(name, ".json") {
|
|
|
|
if strings.HasSuffix(name, "-want.json") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
testConfig(filepath.Join("testdata", name), t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-13 22:46:01 +00:00
|
|
|
type namedReadSeeker struct {
|
|
|
|
name string
|
|
|
|
io.ReadSeeker
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n namedReadSeeker) Name() string { return n.name }
|
|
|
|
func (n namedReadSeeker) Close() error { return nil }
|
|
|
|
|
2014-07-31 18:50:54 +00:00
|
|
|
// configParser returns a custom jsonconfig ConfigParser whose reader rewrites
|
|
|
|
// "/path/to/secring" to the absolute path of the jsonconfig test-secring.gpg file.
|
|
|
|
// On windows, it also fixes the slash separated paths.
|
2012-04-13 22:46:01 +00:00
|
|
|
func configParser() *jsonconfig.ConfigParser {
|
|
|
|
return &jsonconfig.ConfigParser{
|
|
|
|
Open: func(path string) (jsonconfig.File, error) {
|
2014-01-23 22:40:12 +00:00
|
|
|
slurp, err := replaceRingPath(path)
|
2012-04-13 22:46:01 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2014-07-31 18:50:54 +00:00
|
|
|
slurp = backslashEscape(slurp)
|
2014-01-23 22:40:12 +00:00
|
|
|
return namedReadSeeker{path, bytes.NewReader(slurp)}, nil
|
2012-04-13 22:46:01 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-23 22:40:12 +00:00
|
|
|
// replaceRingPath returns the contents of the file at path with secringPlaceholder replaced with the absolute path of relativeRing.
|
|
|
|
func replaceRingPath(path string) ([]byte, error) {
|
|
|
|
secRing, err := filepath.Abs(relativeRing)
|
2012-03-15 12:31:06 +00:00
|
|
|
if err != nil {
|
2014-01-23 22:40:12 +00:00
|
|
|
return nil, fmt.Errorf("Could not get absolute path of %v: %v", relativeRing, err)
|
2012-03-15 12:31:06 +00:00
|
|
|
}
|
2014-07-31 18:50:54 +00:00
|
|
|
secRing = strings.Replace(secRing, `\`, `\\`, -1)
|
2014-01-23 22:40:12 +00:00
|
|
|
slurpBytes, err := ioutil.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2014-07-31 18:50:54 +00:00
|
|
|
|
2014-01-23 22:40:12 +00:00
|
|
|
return bytes.Replace(slurpBytes, []byte(secringPlaceholder), []byte(secRing), 1), nil
|
|
|
|
}
|
|
|
|
|
2014-07-31 18:50:54 +00:00
|
|
|
// We just need to make sure that we don't match the prefix handlers too.
|
|
|
|
var unixPathPattern = regexp.MustCompile(`"/.*/.+"`)
|
|
|
|
|
|
|
|
// backslashEscape, on windows, changes all the slash separated paths (which
|
|
|
|
// match unixPathPattern, to omit the prefix handler paths) with escaped
|
|
|
|
// backslashes.
|
|
|
|
func backslashEscape(b []byte) []byte {
|
|
|
|
if runtime.GOOS != "windows" {
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
unixPaths := unixPathPattern.FindAll(b, -1)
|
|
|
|
if unixPaths == nil {
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
var oldNew []string
|
|
|
|
for _, v := range unixPaths {
|
|
|
|
bStr := string(v)
|
|
|
|
oldNew = append(oldNew, bStr, strings.Replace(bStr, `/`, `\\`, -1))
|
|
|
|
}
|
|
|
|
r := strings.NewReplacer(oldNew...)
|
|
|
|
return []byte(r.Replace(string(b)))
|
|
|
|
}
|
|
|
|
|
2014-01-23 22:40:12 +00:00
|
|
|
func testConfig(name string, t *testing.T) {
|
2013-01-10 23:29:08 +00:00
|
|
|
wantedError := func() error {
|
|
|
|
slurp, err := ioutil.ReadFile(strings.Replace(name, ".json", ".err", 1))
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error reading .err file: %v", err)
|
|
|
|
}
|
|
|
|
return errors.New(string(slurp))
|
|
|
|
}
|
2014-01-23 22:40:12 +00:00
|
|
|
b, err := replaceRingPath(name)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not read %s: %v", name, err)
|
|
|
|
}
|
2014-07-31 18:50:54 +00:00
|
|
|
b = backslashEscape(b)
|
2014-01-23 22:40:12 +00:00
|
|
|
var hiLevelConf serverconfig.Config
|
|
|
|
if err := json.Unmarshal(b, &hiLevelConf); err != nil {
|
|
|
|
t.Fatalf("Could not unmarshal %s into a serverconfig.Config: %v", name, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
lowLevelConf, err := serverinit.GenLowLevelConfig(&hiLevelConf)
|
2013-01-10 23:29:08 +00:00
|
|
|
if g, w := strings.TrimSpace(fmt.Sprint(err)), strings.TrimSpace(fmt.Sprint(wantedError())); g != w {
|
|
|
|
t.Fatalf("test %s: got GenLowLevelConfig error %q; want %q", name, g, w)
|
|
|
|
}
|
2012-03-15 12:31:06 +00:00
|
|
|
if err != nil {
|
2013-01-10 23:29:08 +00:00
|
|
|
return
|
2012-03-15 12:31:06 +00:00
|
|
|
}
|
2014-04-02 15:00:57 +00:00
|
|
|
if err := (&jsonconfig.ConfigParser{}).CheckTypes(lowLevelConf.Obj); err != nil {
|
|
|
|
t.Fatalf("Error while parsing low-level conf generated from %v: %v", name, err)
|
|
|
|
}
|
2013-01-10 23:29:08 +00:00
|
|
|
|
2015-02-21 12:22:11 +00:00
|
|
|
// TODO(mpl): should we stop execution (and not update golden files)
|
|
|
|
// if the comparison fails? Currently this is not the case.
|
2012-04-22 14:35:30 +00:00
|
|
|
wantFile := strings.Replace(name, ".json", "-want.json", 1)
|
|
|
|
wantConf, err := configParser().ReadFile(wantFile)
|
2012-03-15 12:31:06 +00:00
|
|
|
if err != nil {
|
2012-10-20 19:33:39 +00:00
|
|
|
t.Fatalf("test %s: ReadFile: %v", name, err)
|
2012-03-15 12:31:06 +00:00
|
|
|
}
|
2014-04-17 17:20:05 +00:00
|
|
|
if *updateGolden {
|
|
|
|
contents, err := json.MarshalIndent(lowLevelConf.Obj, "", "\t")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
contents = canonicalizeGolden(t, contents)
|
|
|
|
if err := ioutil.WriteFile(wantFile, contents, 0644); err != nil {
|
|
|
|
t.Fatal(err)
|
2012-04-13 22:46:01 +00:00
|
|
|
}
|
2014-04-17 17:20:05 +00:00
|
|
|
}
|
2015-02-21 12:22:11 +00:00
|
|
|
compareConfigurations(t, name, lowLevelConf.Obj, wantConf)
|
|
|
|
}
|
|
|
|
|
|
|
|
func compareConfigurations(t *testing.T, name, g interface{}, w interface{}) {
|
|
|
|
var got, want bytes.Buffer
|
|
|
|
prettyPrint(t, &got, g)
|
|
|
|
prettyPrint(t, &want, w)
|
|
|
|
|
2014-04-17 17:20:05 +00:00
|
|
|
if got.String() != want.String() {
|
2014-03-17 15:42:19 +00:00
|
|
|
t.Errorf("test %s configurations differ.\nGot:\n%s\nWant:\n%s\nDiff (want -> got), %s:\n%s",
|
|
|
|
name, &got, &want, name, test.Diff(want.Bytes(), got.Bytes()))
|
2012-03-15 12:31:06 +00:00
|
|
|
}
|
|
|
|
}
|
2013-11-25 16:27:11 +00:00
|
|
|
|
|
|
|
func canonicalizeGolden(t *testing.T, v []byte) []byte {
|
2014-01-23 22:40:12 +00:00
|
|
|
localPath, err := filepath.Abs(relativeRing)
|
2013-11-25 16:27:11 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
v = bytes.Replace(v, []byte(localPath), []byte(secringPlaceholder), 1)
|
|
|
|
if !bytes.HasSuffix(v, []byte("\n")) {
|
|
|
|
v = append(v, '\n')
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|
2014-08-06 17:49:27 +00:00
|
|
|
|
|
|
|
func TestExpansionsInHighlevelConfig(t *testing.T) {
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
camroot, err := osutil.GoPackagePath("perkeep.org")
|
2014-08-06 17:49:27 +00:00
|
|
|
if err != nil {
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
t.Fatalf("failed to find perkeep.org GOPATH root: %v", err)
|
2014-08-06 17:49:27 +00:00
|
|
|
}
|
|
|
|
const keyID = "26F5ABDA"
|
|
|
|
os.Setenv("TMP_EXPANSION_TEST", keyID)
|
|
|
|
os.Setenv("TMP_EXPANSION_SECRING", filepath.Join(camroot, filepath.FromSlash("pkg/jsonsign/testdata/test-secring.gpg")))
|
2015-11-27 22:46:00 +00:00
|
|
|
// Setting CAMLI_CONFIG_DIR to avoid triggering failInTests in osutil.CamliConfigDir
|
|
|
|
defer os.Setenv("CAMLI_CONFIG_DIR", os.Getenv("CAMLI_CONFIG_DIR")) // restore after test
|
|
|
|
os.Setenv("CAMLI_CONFIG_DIR", "whatever")
|
2014-08-06 17:49:27 +00:00
|
|
|
conf, err := serverinit.Load([]byte(`
|
|
|
|
{
|
|
|
|
"auth": "localhost",
|
|
|
|
"listen": ":4430",
|
|
|
|
"https": false,
|
|
|
|
"identity": ["_env", "${TMP_EXPANSION_TEST}"],
|
|
|
|
"identitySecretRing": ["_env", "${TMP_EXPANSION_SECRING}"],
|
|
|
|
"googlecloudstorage": ":camlistore-dev-blobs",
|
|
|
|
"kvIndexFile": "/tmp/camli-index.kvdb"
|
|
|
|
}
|
|
|
|
`))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
got := fmt.Sprintf("%#v", conf)
|
|
|
|
if !strings.Contains(got, keyID) {
|
2014-11-12 22:21:42 +00:00
|
|
|
t.Errorf("Expected key %s in resulting low-level config. Got: %s", keyID, got)
|
2014-08-06 17:49:27 +00:00
|
|
|
}
|
|
|
|
}
|
2014-09-22 22:25:41 +00:00
|
|
|
|
|
|
|
func TestInstallHandlers(t *testing.T) {
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
camroot, err := osutil.GoPackagePath("perkeep.org")
|
2014-09-22 22:25:41 +00:00
|
|
|
if err != nil {
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
t.Fatalf("failed to find perkeep.org GOPATH root: %v", err)
|
2014-09-22 22:25:41 +00:00
|
|
|
}
|
|
|
|
conf := serverinit.DefaultBaseConfig
|
|
|
|
conf.Identity = "26F5ABDA"
|
|
|
|
conf.IdentitySecretRing = filepath.Join(camroot, filepath.FromSlash("pkg/jsonsign/testdata/test-secring.gpg"))
|
|
|
|
conf.MemoryStorage = true
|
|
|
|
conf.MemoryIndex = true
|
|
|
|
|
|
|
|
confData, err := json.MarshalIndent(conf, "", " ")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not json encode config: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-11-27 22:46:00 +00:00
|
|
|
// Setting CAMLI_CONFIG_DIR to avoid triggering failInTests in osutil.CamliConfigDir
|
|
|
|
defer os.Setenv("CAMLI_CONFIG_DIR", os.Getenv("CAMLI_CONFIG_DIR")) // restore after test
|
|
|
|
os.Setenv("CAMLI_CONFIG_DIR", "whatever")
|
2014-09-22 22:25:41 +00:00
|
|
|
lowConf, err := serverinit.Load(confData)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
// because these two are normally consumed in camlistored.go
|
|
|
|
// TODO(mpl): serverinit.Load should consume these 2 as well. Once
|
|
|
|
// consumed, we should keep all the answers as private fields, and then we
|
|
|
|
// put accessors on serverinit.Config. Maybe we even stop embedding
|
|
|
|
// jsonconfig.Obj in serverinit.Config too, so none of those methods are
|
|
|
|
// accessible.
|
|
|
|
lowConf.OptionalBool("https", true)
|
|
|
|
lowConf.OptionalString("listen", "")
|
|
|
|
|
|
|
|
reindex := false
|
|
|
|
var context *http.Request // only used by App Engine. See handlerLoader in serverinit.go
|
|
|
|
hi := http.NewServeMux()
|
|
|
|
address := "http://" + conf.Listen
|
|
|
|
_, err = lowConf.InstallHandlers(hi, address, reindex, context)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
prefix string
|
|
|
|
authWrapped bool
|
|
|
|
prefixWrapped bool
|
|
|
|
handlerType reflect.Type
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
prefix: "/",
|
|
|
|
handlerType: reflect.TypeOf(&server.RootHandler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/sync/",
|
|
|
|
handlerType: reflect.TypeOf(&server.SyncHandler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
authWrapped: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/my-search/",
|
|
|
|
handlerType: reflect.TypeOf(&search.Handler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
authWrapped: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/ui/",
|
|
|
|
handlerType: reflect.TypeOf(&server.UIHandler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
authWrapped: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/importer/",
|
|
|
|
handlerType: reflect.TypeOf(&importer.Host{}),
|
|
|
|
prefixWrapped: true,
|
2015-07-20 15:11:47 +00:00
|
|
|
authWrapped: true,
|
2014-09-22 22:25:41 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/sighelper/",
|
|
|
|
handlerType: reflect.TypeOf(&signhandler.Handler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
authWrapped: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/status/",
|
|
|
|
handlerType: reflect.TypeOf(&server.StatusHandler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
authWrapped: true,
|
|
|
|
},
|
|
|
|
|
2015-02-21 12:22:11 +00:00
|
|
|
{
|
|
|
|
prefix: "/help/",
|
|
|
|
handlerType: reflect.TypeOf(&server.HelpHandler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
authWrapped: true,
|
|
|
|
},
|
|
|
|
|
2014-09-22 22:25:41 +00:00
|
|
|
{
|
|
|
|
prefix: "/setup/",
|
|
|
|
handlerType: reflect.TypeOf(&server.SetupHandler{}),
|
|
|
|
prefixWrapped: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/bs/camli/",
|
|
|
|
handlerType: reflect.TypeOf(http.HandlerFunc(nil)),
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/index/camli/",
|
|
|
|
handlerType: reflect.TypeOf(http.HandlerFunc(nil)),
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/bs-and-index/camli/",
|
|
|
|
handlerType: reflect.TypeOf(http.HandlerFunc(nil)),
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/bs-and-maybe-also-index/camli/",
|
|
|
|
handlerType: reflect.TypeOf(http.HandlerFunc(nil)),
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
prefix: "/cache/camli/",
|
|
|
|
handlerType: reflect.TypeOf(http.HandlerFunc(nil)),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, v := range tests {
|
|
|
|
req, err := http.NewRequest("GET", address+v.prefix, nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
h, _ := hi.Handler(req)
|
|
|
|
if v.authWrapped {
|
|
|
|
ah, ok := h.(auth.Handler)
|
|
|
|
if !ok {
|
|
|
|
t.Errorf("handler for %v should be auth wrapped", v.prefix)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
h = ah.Handler
|
|
|
|
}
|
|
|
|
if v.prefixWrapped {
|
|
|
|
ph, ok := h.(*httputil.PrefixHandler)
|
|
|
|
if !ok {
|
|
|
|
t.Errorf("handler for %v should be prefix wrapped", v.prefix)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
h = ph.Handler
|
|
|
|
}
|
|
|
|
if reflect.TypeOf(h) != v.handlerType {
|
|
|
|
t.Errorf("for %v: want %v, got %v", v.prefix, v.handlerType, reflect.TypeOf(h))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-02-21 12:22:11 +00:00
|
|
|
|
|
|
|
// TestGenerateClientConfig validates the client config generated for display
|
|
|
|
// by the HelpHandler.
|
|
|
|
func TestGenerateClientConfig(t *testing.T) {
|
|
|
|
inName := filepath.Join("testdata", "gen_client_config.in")
|
|
|
|
wantName := strings.Replace(inName, ".in", ".out", 1)
|
|
|
|
|
|
|
|
b, err := replaceRingPath(inName)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to read high-level server config file: %v", err)
|
|
|
|
}
|
|
|
|
b = backslashEscape(b)
|
|
|
|
var hiLevelConf serverconfig.Config
|
|
|
|
if err := json.Unmarshal(b, &hiLevelConf); err != nil {
|
|
|
|
t.Fatalf("Failed to unmarshal server config: %v", err)
|
|
|
|
}
|
|
|
|
lowLevelConf, err := serverinit.GenLowLevelConfig(&hiLevelConf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to generate low-level config: %v", err)
|
|
|
|
}
|
|
|
|
generatedConf, err := clientconfig.GenerateClientConfig(lowLevelConf.Obj)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to generate client config: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
wb, err := replaceRingPath(wantName)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to read want config file: %v", err)
|
|
|
|
}
|
|
|
|
wb = backslashEscape(wb)
|
|
|
|
var wantConf clientconfig.Config
|
|
|
|
if err := json.Unmarshal(wb, &wantConf); err != nil {
|
|
|
|
t.Fatalf("Failed to unmarshall want config: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
compareConfigurations(t, inName, generatedConf, wantConf)
|
|
|
|
}
|
2016-04-27 21:29:06 +00:00
|
|
|
|
2016-04-29 05:08:50 +00:00
|
|
|
// TestConfigHandlerRedaction validates that configHandler redacts sensitive
|
|
|
|
// values, still resulting in a valid JSON document.
|
2016-04-27 21:29:06 +00:00
|
|
|
func TestConfigHandlerRedaction(t *testing.T) {
|
|
|
|
config := &serverinit.Config{
|
|
|
|
Obj: jsonconfig.Obj{
|
|
|
|
"auth": "secret",
|
|
|
|
"aws_secret_access_key": "secret",
|
|
|
|
"password": "secret",
|
|
|
|
"client_secret": "secret",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
serverinit.ConfigHandler(config).ServeHTTP(rr, nil)
|
|
|
|
got := make(map[string]string)
|
|
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &got); err != nil {
|
|
|
|
t.Fatalf("Failed to unmarshal configHandler response: %v", err)
|
|
|
|
}
|
|
|
|
want := map[string]string{
|
|
|
|
"auth": "REDACTED",
|
|
|
|
"aws_secret_access_key": "REDACTED",
|
|
|
|
"password": "REDACTED",
|
|
|
|
"client_secret": "REDACTED",
|
|
|
|
}
|
|
|
|
|
|
|
|
compareConfigurations(t, "configHandlerRedaction", got, want)
|
|
|
|
}
|
2016-04-29 05:08:50 +00:00
|
|
|
|
|
|
|
// TestConfigHandlerRemoveKnownKeys validates that configHandler removes
|
|
|
|
// "knowkeys" keys properly, still resulting in a valid JSON document.
|
|
|
|
func TestConfigHandlerRemoveKnownKeys(t *testing.T) {
|
|
|
|
config := &serverinit.Config{
|
|
|
|
Obj: jsonconfig.Obj{
|
|
|
|
"/ui/": "",
|
|
|
|
"_knownkeys": map[string]string{
|
|
|
|
"key": "value",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
serverinit.ConfigHandler(config).ServeHTTP(rr, nil)
|
|
|
|
got := make(map[string]string)
|
|
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &got); err != nil {
|
|
|
|
t.Fatalf("Failed to unmarshal configHandler response: %v", err)
|
|
|
|
}
|
|
|
|
want := map[string]string{
|
|
|
|
"/ui/": "",
|
|
|
|
}
|
|
|
|
|
|
|
|
compareConfigurations(t, "configHandlerRemoveKnownKeys", got, want)
|
|
|
|
}
|