// Test that `camget -o' can restore a fifo correctly. func TestCamgetFIFO(t *testing.T) { if runtime.GOOS == "windows" { t.SkipNow() } fifo, cleanup := mkTmpFIFO(t) defer cleanup() // Upload the fifo w := test.GetWorld(t) out := test.MustRunCmd(t, w.Cmd("camput", "file", fifo)) br := strings.Split(out, "\n")[0] // Try and get it back tdir, err := ioutil.TempDir("", "fifo-test-") if err != nil { t.Fatalf("ioutil.TempDir(): %v", err) } defer os.RemoveAll(tdir) test.MustRunCmd(t, w.Cmd("camget", "-o", tdir, br)) // Ensure it is actually a fifo name := filepath.Join(tdir, filepath.Base(fifo)) fi, err := os.Lstat(name) if err != nil { t.Fatalf("os.Lstat(): %v", err) } if mask := fi.Mode() & os.ModeNamedPipe; mask == 0 { t.Fatalf("Retrieved file %s: Not a FIFO", name) } }
// Test that we can camput and camget a file whose name is not utf8, // that we don't panic in the process and that the results are // correct. func TestNonUTF8FileName(t *testing.T) { srcDir, cleanup := tempDir(t) defer cleanup() base, err := hex.DecodeString(nonUTF8) if err != nil { t.Fatalf("hex.DecodeString(): %v", err) } fd, err := os.Create(filepath.Join(srcDir, string(base))) if err != nil { t.Fatalf("os.Create(): %v", err) } fd.Close() w := test.GetWorld(t) out := test.MustRunCmd(t, w.Cmd("camput", "file", fd.Name())) br := strings.Split(out, "\n")[0] // camput was a success. Can we get the file back in another directory? dstDir, cleanup := tempDir(t) defer cleanup() _ = test.MustRunCmd(t, w.Cmd("camget", "-o", dstDir, br)) _, err = os.Lstat(filepath.Join(dstDir, string(base))) if err != nil { t.Fatalf("Failed to stat file %s in directory %s", fd.Name(), dstDir) } }
// Test that: // 1) `camget -contents' can restore a regular file correctly. // 2) if the file already exists, and has the same size as the one held by the server, // stop early and do not even fetch it from the server. func TestCamgetFile(t *testing.T) { dirName, err := ioutil.TempDir("", "camli-TestCamgetFile") if err != nil { t.Fatal(err) } defer os.RemoveAll(dirName) f, err := os.Create(filepath.Join(dirName, "test.txt")) if err != nil { t.Fatal(err) } filename := f.Name() contents := "not empty anymore" if _, err := f.Write([]byte(contents)); err != nil { t.Fatal(err) } if err := f.Close(); err != nil { t.Fatal(err) } outDir := filepath.Join(dirName, "fetched") if err := os.Mkdir(outDir, 0700); err != nil { t.Fatal(err) } w := test.GetWorld(t) out := test.MustRunCmd(t, w.Cmd("camput", "file", filename)) br := strings.Split(out, "\n")[0] _ = test.MustRunCmd(t, w.Cmd("camget", "-o", outDir, "-contents", br)) fetchedName := filepath.Join(outDir, "test.txt") b, err := ioutil.ReadFile(fetchedName) if err != nil { t.Fatal(err) } if string(b) != contents { t.Fatalf("fetched file different from original file, got contents %q, wanted %q", b, contents) } var stderr bytes.Buffer c := w.Cmd("camget", "-o", outDir, "-contents", "-verbose", br) c.Stderr = &stderr if err := c.Run(); err != nil { t.Fatalf("running second camget: %v", err) } if !strings.Contains(stderr.String(), fmt.Sprintf("Skipping %s; already exists.", fetchedName)) { t.Fatal(errors.New("Was expecting info message about local file already existing")) } }
// Test that `camput' can upload sockets correctly. func TestCamputSocket(t *testing.T) { if runtime.GOOS == "windows" { t.SkipNow() } socket, cleanup := mkTmpSocket(t) defer cleanup() // Can we successfully upload a socket? w := test.GetWorld(t) out := test.MustRunCmd(t, w.Cmd("camput", "file", socket)) br := strings.Split(out, "\n")[0] out = test.MustRunCmd(t, w.Cmd("camget", br)) t.Logf("Retrieved stored socket schema: %s", out) }
// Test that camput twice on the same file only uploads once. func TestCamputUploadOnce(t *testing.T) { w := test.GetWorld(t) camputCmd := func() *exec.Cmd { // Use --contents_only because if test is run from devcam, // server-config.json is going to be the one from within the fake gopath, // hence with a different cTime and with a different blobRef everytime. // Also, CAMLI_DEBUG is needed for --contents_only flag. return w.CmdWithEnv("camput", append(os.Environ(), "CAMLI_DEBUG=1"), "file", "--contents_only=true", filepath.FromSlash("../testdata/server-config.json")) } wantBlobRef := "sha1-46d4023ef523d6a19e45183ae9dab575a496f51f" cmd := camputCmd() out := test.MustRunCmd(t, cmd) out = strings.TrimSpace(out) if out != wantBlobRef { t.Fatalf("wrong camput output; wanted %v, got %v", wantBlobRef, out) } cmd = camputCmd() var stderr bytes.Buffer cmd.Stderr = &stderr output, err := cmd.Output() if err != nil { t.Fatalf("second camput failed: %v, stdout: %v, stderr: %v", err, output, stderr.String()) } out = strings.TrimSpace(string(output)) if out != wantBlobRef { t.Fatalf("wrong 2nd camput output; wanted %v, got %v", wantBlobRef, out) } wantStats := `[uploadRequests=[blobs=0 bytes=0] uploads=[blobs=0 bytes=0]]` if !strings.Contains(stderr.String(), wantStats) { t.Fatalf("Wrong stats for 2nd camput upload; wanted %v, got %v", wantStats, out) } }
func TestWebsocketQuery(t *testing.T) { w := test.GetWorld(t) pn := w.NewPermanode(t) test.MustRunCmd(t, w.Cmd("camput", "attr", pn.String(), "tag", "foo")) check := func(err error) { if err != nil { t.Fatal(err) } } const bufSize = 1 << 20 c, err := net.Dial("tcp", w.Addr()) if err != nil { t.Fatalf("Dial: %v", err) } defer c.Close() wc, _, err := websocket.NewClient(c, &url.URL{Host: w.Addr(), Path: w.SearchHandlerPath() + "ws"}, nil, bufSize, bufSize) check(err) msg, err := wc.NextWriter(websocket.TextMessage) check(err) _, err = msg.Write([]byte(`{"tag": "foo", "query": { "expression": "tag:foo" }}`)) check(err) check(msg.Close()) errc := make(chan error, 1) go func() { inType, inMsg, err := wc.ReadMessage() if err != nil { errc <- err return } if !strings.HasPrefix(string(inMsg), `{"tag":"_status"`) { errc <- fmt.Errorf("unexpected message type=%d msg=%q, wanted status update", inType, inMsg) return } inType, inMsg, err = wc.ReadMessage() if err != nil { errc <- err return } if strings.Contains(string(inMsg), pn.String()) { errc <- nil return } errc <- fmt.Errorf("unexpected message type=%d msg=%q", inType, inMsg) }() select { case err := <-errc: if err != nil { t.Error(err) } case <-time.After(5 * time.Second): t.Error("timeout") } }
func share(t *testing.T, file string) { w := test.GetWorld(t) out := test.MustRunCmd(t, w.Cmd("camput", "file", file)) fileRef := strings.Split(out, "\n")[0] out = test.MustRunCmd(t, w.Cmd("camput", "share", "-transitive", fileRef)) shareRef := strings.Split(out, "\n")[0] testDir, err := ioutil.TempDir("", "camli-share-test-") if err != nil { t.Fatalf("ioutil.TempDir(): %v", err) } defer os.RemoveAll(testDir) // test that we can get it through the share test.MustRunCmd(t, w.Cmd("camget", "-o", testDir, "-shared", fmt.Sprintf("%v/share/%v", w.ServerBaseURL(), shareRef))) filePath := filepath.Join(testDir, filepath.Base(file)) fi, err := os.Stat(filePath) if err != nil { t.Fatalf("camget -shared failed to get %v: %v", file, err) } if fi.IsDir() { // test that we also get the dir contents d, err := os.Open(filePath) if err != nil { t.Fatal(err) } defer d.Close() names, err := d.Readdirnames(-1) if err != nil { t.Fatal(err) } if len(names) == 0 { t.Fatalf("camget did not fetch contents of directory %v", file) } } // test that we're not allowed to get it directly fileURL := fmt.Sprintf("%v/share/%v", w.ServerBaseURL(), fileRef) _, err = test.RunCmd(w.Cmd("camget", "-shared", fileURL)) if err == nil { t.Fatal("Was expecting error for 'camget -shared " + fileURL + "'") } if !strings.Contains(err.Error(), "client: got status code 401") { t.Fatalf("'camget -shared %v': got error %v, was expecting 401", fileURL, err) } }
// Test that running: // $ camput permanode // ... creates and uploads a permanode, and that we can camget it back. func TestCamputPermanode(t *testing.T) { w := test.GetWorld(t) out := test.MustRunCmd(t, w.Cmd("camput", "permanode")) br, ok := blob.Parse(strings.TrimSpace(out)) if !ok { t.Fatalf("Expected permanode in stdout; got %q", out) } out = test.MustRunCmd(t, w.Cmd("camget", br.String())) mustHave := []string{ `{"camliVersion": 1,`, `"camliSigner": "`, `"camliType": "permanode",`, `random": "`, `,"camliSig":"`, } for _, str := range mustHave { if !strings.Contains(out, str) { t.Errorf("Expected permanode response to contain %q; it didn't. Got: %s", str, out) } } }
// Test that we can camput and camget a symbolic link whose target is // not utf8, that we do no panic in the process and that the results // are correct. func TestNonUTF8SymlinkTarget(t *testing.T) { srcDir, cleanup := tempDir(t) defer cleanup() base, err := hex.DecodeString(nonUTF8) if err != nil { t.Fatalf("hex.DecodeString(): %v", err) } fd, err := os.Create(filepath.Join(srcDir, string(base))) if err != nil { t.Fatalf("os.Create(): %v", err) } defer fd.Close() err = os.Symlink(string(base), filepath.Join(srcDir, "link")) if err != nil { t.Fatalf("os.Symlink(): %v", err) } w := test.GetWorld(t) out := test.MustRunCmd(t, w.Cmd("camput", "file", filepath.Join(srcDir, "link"))) br := strings.Split(out, "\n")[0] // See if we can camget it back correctly dstDir, cleanup := tempDir(t) defer cleanup() _ = test.MustRunCmd(t, w.Cmd("camget", "-o", dstDir, br)) target, err := os.Readlink(filepath.Join(dstDir, "link")) if err != nil { t.Fatalf("os.Readlink(): %v", err) } if !bytes.Equal([]byte(target), base) { t.Fatalf("Retrieved symlink contains points to unexpected target") } }
// Test that running: // $ camput permanode // ... creates and uploads a permanode, and that we can camget it back. func TestCamputPermanode(t *testing.T) { w := test.GetWorld(t) br := w.NewPermanode(t) out := test.MustRunCmd(t, w.Cmd("camget", br.String())) mustHave := []string{ `{"camliVersion": 1,`, `"camliSigner": "`, `"camliType": "permanode",`, `random": "`, `,"camliSig":"`, } for _, str := range mustHave { if !strings.Contains(out, str) { t.Errorf("Expected permanode response to contain %q; it didn't. Got: %s", str, out) } } }
func benchmarkWrite(b *testing.B, cfg string) { w, err := test.WorldFromConfig(cfg) if err != nil { b.Fatalf("could not create server for config: %v\nError: %v", cfg, err) } testFile := filepath.Join(w.CamliSourceRoot(), testFileRel) createTestFile(b, testFile, testFileSize) defer os.Remove(testFile) b.ResetTimer() b.StopTimer() for i := 0; i < b.N; i++ { err = w.Start() if err != nil { b.Fatalf("could not start server for config: %v\nError: %v", cfg, err) } b.StartTimer() test.MustRunCmd(b, w.Cmd("camput", "file", testFile)) b.StopTimer() w.Stop() } b.SetBytes(int64(testFileSize)) }
// Test that `camget -o' can restore a symlink correctly. func TestCamgetSymlink(t *testing.T) { w := test.GetWorld(t) srcDir, err := ioutil.TempDir("", "camget-test-") if err != nil { t.Fatalf("ioutil.TempDir(): %v", err) } defer os.RemoveAll(srcDir) targetBase := "a" target := filepath.Join(srcDir, targetBase) targetFD, err := os.Create(target) if err != nil { t.Fatalf("os.Create(): %v", err) } targetFD.Close() subdirBase := "child" subdirName := filepath.Join(srcDir, subdirBase) linkBase := "b" linkName := filepath.Join(subdirName, linkBase) err = os.Mkdir(subdirName, 0777) if err != nil { t.Fatalf("os.Mkdir(): %v", err) } err = os.Symlink("../"+targetBase, linkName) if err != nil { t.Fatalf("os.Symlink(): %v", err) } out := test.MustRunCmd(t, w.Cmd("camput", "file", srcDir)) asserts.ExpectBool(t, true, out != "", "camput") br := strings.Split(out, "\n")[0] dstDir, err := ioutil.TempDir("", "camget-test-") if err != nil { t.Fatalf("ioutil.TempDir(): %v", err) } defer os.RemoveAll(dstDir) // Now restore the symlink _ = test.MustRunCmd(t, w.Cmd("camget", "-o", dstDir, br)) symlink := filepath.Join(dstDir, filepath.Base(srcDir), subdirBase, linkBase) link, err := os.Readlink(symlink) if err != nil { t.Fatalf("os.Readlink(): %v", err) } expected := "../a" if expected != link { t.Fatalf("os.Readlink(): Expected: %s, got %s", expected, link) } // Ensure that the link is not broken _, err = os.Stat(symlink) if err != nil { t.Fatalf("os.Stat(): %v", err) } }