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  }