github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/pkg/test/integration/camlistore_test.go (about) 1 /* 2 Copyright 2013 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 integration 18 19 import ( 20 "bufio" 21 "fmt" 22 "io/ioutil" 23 "net" 24 "net/http" 25 "net/url" 26 "os" 27 "path/filepath" 28 "strings" 29 "testing" 30 "time" 31 32 "camlistore.org/pkg/test" 33 "camlistore.org/third_party/github.com/gorilla/websocket" 34 ) 35 36 // Test that running: 37 // $ camput permanode 38 // ... creates and uploads a permanode, and that we can camget it back. 39 func TestCamputPermanode(t *testing.T) { 40 w := test.GetWorld(t) 41 br := w.NewPermanode(t) 42 43 out := test.MustRunCmd(t, w.Cmd("camget", br.String())) 44 mustHave := []string{ 45 `{"camliVersion": 1,`, 46 `"camliSigner": "`, 47 `"camliType": "permanode",`, 48 `random": "`, 49 `,"camliSig":"`, 50 } 51 for _, str := range mustHave { 52 if !strings.Contains(out, str) { 53 t.Errorf("Expected permanode response to contain %q; it didn't. Got: %s", str, out) 54 } 55 } 56 } 57 58 func TestWebsocketQuery(t *testing.T) { 59 w := test.GetWorld(t) 60 pn := w.NewPermanode(t) 61 test.MustRunCmd(t, w.Cmd("camput", "attr", pn.String(), "tag", "foo")) 62 63 check := func(err error) { 64 if err != nil { 65 t.Fatal(err) 66 } 67 } 68 69 const bufSize = 1 << 20 70 71 c, err := net.Dial("tcp", w.Addr()) 72 if err != nil { 73 t.Fatalf("Dial: %v", err) 74 } 75 76 wc, _, err := websocket.NewClient(c, &url.URL{Host: w.Addr(), Path: w.SearchHandlerPath() + "ws"}, nil, bufSize, bufSize) 77 check(err) 78 79 msg, err := wc.NextWriter(websocket.TextMessage) 80 check(err) 81 82 _, err = msg.Write([]byte(`{"tag": "foo", "query": { "expression": "tag:foo" }}`)) 83 check(err) 84 check(msg.Close()) 85 86 errc := make(chan error, 1) 87 go func() { 88 inType, inMsg, err := wc.ReadMessage() 89 if err != nil { 90 errc <- err 91 return 92 } 93 if strings.Contains(string(inMsg), pn.String()) { 94 errc <- nil 95 return 96 } 97 errc <- fmt.Errorf("unexpected message type=%d msg=%q", inType, inMsg) 98 }() 99 select { 100 case err := <-errc: 101 if err != nil { 102 t.Error(err) 103 } 104 case <-time.After(5 * time.Second): 105 t.Error("timeout") 106 } 107 } 108 109 func TestInternalHandler(t *testing.T) { 110 w := test.GetWorld(t) 111 tests := map[string]int{ 112 "/no-http-storage/": 401, 113 "/no-http-handler/": 401, 114 "/good-status/": 200, 115 "/bs-and-maybe-also-index/camli": 400, 116 "/bs/camli/sha1-b2201302e129a4396a323cb56283cddeef11bbe8": 404, 117 "/no-http-storage/camli/sha1-b2201302e129a4396a323cb56283cddeef11bbe8": 401, 118 } 119 for suffix, want := range tests { 120 res, err := http.Get(w.ServerBaseURL() + suffix) 121 if err != nil { 122 t.Fatalf("On %s: %v", suffix, err) 123 } 124 if res.StatusCode != want { 125 t.Errorf("For %s: Status = %d; want %d", suffix, res.StatusCode, want) 126 } 127 res.Body.Close() 128 } 129 } 130 131 func mustTempDir(t *testing.T) (name string, cleanup func()) { 132 dir, err := ioutil.TempDir("", "") 133 if err != nil { 134 t.Fatal(err) 135 } 136 return dir, func() { os.RemoveAll(dir) } 137 } 138 139 func mustWriteFile(t *testing.T, path, contents string) { 140 err := ioutil.WriteFile(path, []byte(contents), 0644) 141 if err != nil { 142 t.Fatal(err) 143 } 144 } 145 146 // Run camput in the environment it runs in under the Android app. 147 // This matches how camput is used in UploadThread.java. 148 func TestAndroidCamputFile(t *testing.T) { 149 w := test.GetWorld(t) 150 // UploadThread.java sets: 151 // CAMLI_AUTH (set by w.CmdWithEnv) 152 // CAMLI_TRUSTED_CERT (not needed) 153 // CAMLI_CACHE_DIR 154 // CAMPUT_ANDROID_OUTPUT=1 155 cacheDir, clean := mustTempDir(t) 156 defer clean() 157 env := []string{ 158 "CAMPUT_ANDROID_OUTPUT=1", 159 "CAMLI_CACHE_DIR=" + cacheDir, 160 } 161 cmd := w.CmdWithEnv("camput", 162 env, 163 "--server="+w.ServerBaseURL(), 164 "file", 165 "-stdinargs", 166 "-vivify") 167 cmd.Stderr = os.Stderr 168 in, err := cmd.StdinPipe() 169 if err != nil { 170 t.Fatal(err) 171 } 172 out, err := cmd.StdoutPipe() 173 if err != nil { 174 t.Fatal(err) 175 } 176 if err := w.Ping(); err != nil { 177 t.Fatal(err) 178 } 179 if err := cmd.Start(); err != nil { 180 t.Fatal(err) 181 } 182 defer cmd.Process.Kill() 183 184 srcDir, clean := mustTempDir(t) 185 defer clean() 186 187 file1 := filepath.Join(srcDir, "file1.txt") 188 mustWriteFile(t, file1, "contents 1") 189 file2 := filepath.Join(srcDir, "file2.txt") 190 mustWriteFile(t, file2, "contents 2 longer length") 191 192 go func() { 193 fmt.Fprintf(in, "%s\n", file1) 194 fmt.Fprintf(in, "%s\n", file2) 195 }() 196 197 waitc := make(chan error) 198 go func() { 199 sc := bufio.NewScanner(out) 200 fileUploaded := 0 201 for sc.Scan() { 202 t.Logf("Got: %q", sc.Text()) 203 f := strings.Fields(sc.Text()) 204 if len(f) == 0 { 205 t.Logf("empty text?") 206 continue 207 } 208 if f[0] == "FILE_UPLOADED" { 209 fileUploaded++ 210 if fileUploaded == 2 { 211 break 212 } 213 } 214 } 215 in.Close() 216 if err := sc.Err(); err != nil { 217 t.Error(err) 218 } 219 }() 220 221 defer cmd.Process.Kill() 222 go func() { 223 waitc <- cmd.Wait() 224 }() 225 select { 226 case <-time.After(5 * time.Second): 227 t.Fatal("timeout waiting for camput to end") 228 case err := <-waitc: 229 if err != nil { 230 t.Errorf("camput exited uncleanly: %v", err) 231 } 232 } 233 }