github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/pkg/serverconfig/serverconfig_test.go (about) 1 /* 2 Copyright 2012 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package serverconfig_test 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "errors" 23 "flag" 24 "fmt" 25 "io" 26 "io/ioutil" 27 "os" 28 "path/filepath" 29 "sort" 30 "strings" 31 "testing" 32 33 "camlistore.org/pkg/jsonconfig" 34 "camlistore.org/pkg/serverconfig" 35 "camlistore.org/pkg/test" 36 ) 37 38 var updateGolden = flag.Bool("update_golden", false, "Update golden *.want files") 39 40 const ( 41 // relativeRing points to a real secret ring, but serverconfig 42 // rewrites it to be an absolute path. We then canonicalize 43 // it to secringPlaceholder in the golden files. 44 relativeRing = "../jsonsign/testdata/test-secring.gpg" 45 secringPlaceholder = "/path/to/secring" 46 ) 47 48 func init() { 49 // Avoid Linux vs. OS X differences in tests. 50 serverconfig.SetTempDirFunc(func() string { return "/tmp" }) 51 serverconfig.SetNoMkdir(true) 52 } 53 54 func sortedKeys(m map[string]interface{}) (keys []string) { 55 for k := range m { 56 keys = append(keys, k) 57 } 58 sort.Strings(keys) 59 return 60 } 61 62 func prettyPrint(t *testing.T, w io.Writer, i interface{}, indent int) { 63 out, err := json.MarshalIndent(i, "", " ") 64 if err != nil { 65 t.Fatal(err) 66 } 67 w.Write(out) 68 } 69 70 func TestConfigs(t *testing.T) { 71 dir, err := os.Open("testdata") 72 if err != nil { 73 t.Fatal(err) 74 } 75 names, err := dir.Readdirnames(-1) 76 if err != nil { 77 t.Fatal(err) 78 } 79 for _, name := range names { 80 if strings.HasSuffix(name, ".json") { 81 if strings.HasSuffix(name, "-want.json") { 82 continue 83 } 84 testConfig(filepath.Join("testdata", name), t) 85 } 86 } 87 } 88 89 type namedReadSeeker struct { 90 name string 91 io.ReadSeeker 92 } 93 94 func (n namedReadSeeker) Name() string { return n.name } 95 func (n namedReadSeeker) Close() error { return nil } 96 97 func configParser() *jsonconfig.ConfigParser { 98 // Make a custom jsonconfig ConfigParser whose reader rewrites "/path/to/secring" to the absolute 99 // path of the jsonconfig test-secring.gpg file. 100 secRing, err := filepath.Abs("../jsonsign/testdata/test-secring.gpg") 101 if err != nil { 102 panic(err) 103 } 104 return &jsonconfig.ConfigParser{ 105 Open: func(path string) (jsonconfig.File, error) { 106 slurpBytes, err := ioutil.ReadFile(path) 107 if err != nil { 108 return nil, err 109 } 110 slurp := strings.Replace(string(slurpBytes), secringPlaceholder, secRing, 1) 111 return namedReadSeeker{path, strings.NewReader(slurp)}, nil 112 }, 113 } 114 } 115 116 func testConfig(name string, t *testing.T) { 117 obj, err := configParser().ReadFile(name) 118 if err != nil { 119 t.Fatal(err) 120 } 121 wantedError := func() error { 122 slurp, err := ioutil.ReadFile(strings.Replace(name, ".json", ".err", 1)) 123 if os.IsNotExist(err) { 124 return nil 125 } 126 if err != nil { 127 t.Fatalf("Error reading .err file: %v", err) 128 } 129 return errors.New(string(slurp)) 130 } 131 lowLevelConf, err := serverconfig.GenLowLevelConfig(&serverconfig.Config{Obj: obj}) 132 if g, w := strings.TrimSpace(fmt.Sprint(err)), strings.TrimSpace(fmt.Sprint(wantedError())); g != w { 133 t.Fatalf("test %s: got GenLowLevelConfig error %q; want %q", name, g, w) 134 } 135 if err != nil { 136 return 137 } 138 139 wantFile := strings.Replace(name, ".json", "-want.json", 1) 140 wantConf, err := configParser().ReadFile(wantFile) 141 if err != nil { 142 t.Fatalf("test %s: ReadFile: %v", name, err) 143 } 144 var got, want bytes.Buffer 145 prettyPrint(t, &got, lowLevelConf.Obj, 0) 146 prettyPrint(t, &want, wantConf, 0) 147 if got.String() != want.String() { 148 if *updateGolden { 149 contents, err := json.MarshalIndent(lowLevelConf.Obj, "", "\t") 150 if err != nil { 151 t.Fatal(err) 152 } 153 contents = canonicalizeGolden(t, contents) 154 if err := ioutil.WriteFile(wantFile, contents, 0644); err != nil { 155 t.Fatal(err) 156 } 157 } 158 t.Errorf("test %s configurations differ.\nGot:\n%s\nWant:\n%s\nDiff (got -> want), %s:\n%s", 159 name, &got, &want, name, test.Diff(got.Bytes(), want.Bytes())) 160 } 161 } 162 163 func canonicalizeGolden(t *testing.T, v []byte) []byte { 164 localPath, err := filepath.Abs("../jsonsign/testdata/test-secring.gpg") 165 if err != nil { 166 t.Fatal(err) 167 } 168 v = bytes.Replace(v, []byte(localPath), []byte(secringPlaceholder), 1) 169 if !bytes.HasSuffix(v, []byte("\n")) { 170 v = append(v, '\n') 171 } 172 return v 173 }