Exemple #1
0
func TestPutWithBackend(t *testing.T) {
	uuid, _ := util.NewUUID()

	storage, _, put := fileServer(uuid)
	defer storage.Close()

	*util.StorageBaseURL = storage.URL
	defer func() {
		*util.StorageBaseURL = baseURL
	}()

	server := httptest.NewServer(app())
	defer server.Close()

	transport := &http.Transport{}
	client := &http.Client{Transport: transport}

	registrar := broker.NewRedisRegistrar()
	registrar.Register(uuid)

	// uuid = curl -XPUT <url>/streams/1/2/3
	request, _ := http.NewRequest("POST", server.URL+"/streams/"+uuid, bytes.NewReader([]byte("hello world")))
	request.TransferEncoding = []string{"chunked"}
	resp, err := client.Do(request)
	defer resp.Body.Close()
	assert.Nil(t, err)
	assert.Equal(t, resp.StatusCode, 200)
	assert.Equal(t, <-put, []byte("hello world"))
}
Exemple #2
0
func TestPubWithoutTransferEncoding(t *testing.T) {
	request, _ := http.NewRequest("POST", "/streams/1234", nil)
	response := httptest.NewRecorder()

	pub(response, request)

	assert.Equal(t, response.Code, http.StatusBadRequest)
	assert.Equal(t, response.Body.String(), "A chunked Transfer-Encoding header is required.\n")
}
Exemple #3
0
func Test410(t *testing.T) {
	streamId, _ := util.NewUUID()
	request, _ := http.NewRequest("GET", "/streams/"+streamId, nil)
	response := httptest.NewRecorder()

	sub(response, request)

	assert.Equal(t, response.Code, http.StatusNotFound)
	assert.Equal(t, response.Body.String(), "Channel is not registered.\n")
}
Exemple #4
0
func TestAuthentication(t *testing.T) {
	*util.Creds = "u:pass1|u:pass2"
	defer func() {
		*util.Creds = ""
	}()

	server := httptest.NewServer(app())
	defer server.Close()

	transport := &http.Transport{}
	client := &http.Client{Transport: transport}

	testdata := map[string]string{
		"POST": "/streams",
		"PUT":  "/streams/1/2/3",
	}

	status := map[string]int{
		"POST": http.StatusOK,
		"PUT":  http.StatusCreated,
	}

	// Validate that we return 401 for empty and invalid tokens
	for _, token := range []string{"", "invalid"} {
		for method, path := range testdata {
			request, _ := http.NewRequest(method, server.URL+path, nil)
			if token != "" {
				request.SetBasicAuth("", token)
			}
			resp, err := client.Do(request)
			defer resp.Body.Close()
			assert.Nil(t, err)
			assert.Equal(t, resp.Status, "401 Unauthorized")
		}
	}

	// Validate that all the colon separated token values are
	// accepted
	for _, token := range []string{"pass1", "pass2"} {
		for method, path := range testdata {
			request, _ := http.NewRequest(method, server.URL+path, nil)
			request.SetBasicAuth("u", token)
			resp, err := client.Do(request)
			defer resp.Body.Close()
			assert.Nil(t, err)
			assert.Equal(t, resp.StatusCode, status[method])
		}
	}
}
Exemple #5
0
func TestRedisReadFromClosed(t *testing.T) {
	r, w := newReaderWriter()
	p := make([]byte, 10)

	r.Read(p)
	w.Write([]byte("hello"))
	w.Close()

	// this read should short circuit with EOF
	_, err := r.Read(p)
	assert.Equal(t, err, io.EOF)

	// We'll get true here because r.closed is already set
	assert.True(t, ReaderDone(r))

	// We should still get true here because doneId is set
	r, _ = NewReader(string(r.(*reader).channel))
	assert.True(t, ReaderDone(r))

	// Reader done on a regular io.Reader should return false
	// and not panic
	assert.False(t, ReaderDone(strings.NewReader("hello")))

	// NoContent should respond accordingly based on offset
	assert.False(t, NoContent(r, 0))
	assert.True(t, NoContent(r, 5))
}
Exemple #6
0
func TestOverflowingBuffer(t *testing.T) {
	uuid := setup()

	w, _ := NewWriter(uuid)
	w.Write(bytes.Repeat([]byte("0"), 4096))
	w.Write(bytes.Repeat([]byte("1"), 4096))
	w.Write(bytes.Repeat([]byte("2"), 4096))
	w.Write(bytes.Repeat([]byte("3"), 4096))
	w.Write(bytes.Repeat([]byte("4"), 4096))
	w.Write(bytes.Repeat([]byte("5"), 4096))
	w.Write(bytes.Repeat([]byte("6"), 4096))
	w.Write(bytes.Repeat([]byte("7"), 4096))
	w.Write(bytes.Repeat([]byte("A"), 1))

	r, _ := NewReader(uuid)
	defer r.(io.Closer).Close()

	done := make(chan int64)
	go func() {
		n, _ := io.Copy(ioutil.Discard, r)
		done <- n
	}()
	w.Close()
	assert.Equal(t, int64(32769), <-done)
}
Exemple #7
0
func TestGet(t *testing.T) {
	_, requestURI := setup()
	if requestURI == "" {
		t.Skip("No GET URL supplied")
	}

	data := []string{
		"hello",
		"ello",
		"llo",
		"lo",
		"o",
	}

	for offset, expected := range data {
		r, _ := Get(requestURI, int64(offset))
		if r != nil {
			defer r.(io.Closer).Close()
		}

		bytes, err := ioutil.ReadAll(r)
		assert.Nil(t, err)
		assert.Equal(t, expected, string(bytes))
	}
}
Exemple #8
0
func TestNoNewline(t *testing.T) {
	for _, data := range testdata {
		r := strings.NewReader(data.input)
		enc := NewEncoder(r)
		enc.(io.Seeker).Seek(data.offset, 0)
		assert.Equal(t, data.output, readstring(enc))
	}
}
Exemple #9
0
func TestMkstream(t *testing.T) {
	request, _ := http.NewRequest("POST", "/streams", nil)
	response := httptest.NewRecorder()

	mkstream(response, request)

	assert.Equal(t, response.Code, 200)
	assert.Len(t, response.Body.String(), 32)
}
Exemple #10
0
func TestPutWithoutBaseURL(t *testing.T) {
	*util.StorageBaseURL = ""
	defer func() {
		*util.StorageBaseURL = baseURL
	}()

	err := Put("1/2/3", nil)
	assert.Equal(t, err, ErrNoStorage)
}
Exemple #11
0
func TestGetWithoutBaseURL(t *testing.T) {
	*util.StorageBaseURL = ""
	defer func() {
		*util.StorageBaseURL = baseURL
	}()

	_, err := Get("1/2/3", 0)
	assert.Equal(t, err, ErrNoStorage)
}
Exemple #12
0
func TestPubNotRegistered(t *testing.T) {
	streamId, _ := util.NewUUID()
	request, _ := http.NewRequest("POST", "/streams/"+streamId, nil)
	request.TransferEncoding = []string{"chunked"}
	response := httptest.NewRecorder()

	pub(response, request)

	assert.Equal(t, response.Code, http.StatusNotFound)
}
Exemple #13
0
func TestSeekBeyond(t *testing.T) {
	uuid := setup()

	w, _ := NewWriter(uuid)
	w.Write([]byte("busl"))
	w.Write([]byte(" hello"))
	w.Write([]byte(" world"))
	w.Close()

	r, _ := NewReader(uuid)
	r.(io.Seeker).Seek(16, 0)
	defer r.Close()

	buf, _ := ioutil.ReadAll(r)
	assert.Equal(t, []byte{}, buf)
}
Exemple #14
0
func TestSeekCorrect(t *testing.T) {
	uuid := setup()

	w, _ := NewWriter(uuid)
	w.Write([]byte("busl"))
	w.Write([]byte(" hello"))
	w.Write([]byte(" world"))
	w.Close()

	r, _ := NewReader(uuid)
	r.(io.Seeker).Seek(10, 0)
	defer r.(io.Closer).Close()

	buf, _ := ioutil.ReadAll(r)
	assert.Equal(t, " world", string(buf))
}
Exemple #15
0
func TestNonSeekableReader(t *testing.T) {
	// Seek the underlying reader before
	// passing to LimitReader: comparably similar
	// to scenario when reading from an http.Response
	r := strings.NewReader("hello world")
	r.Seek(10, 0)

	// Use LimitReader to hide the Seeker interface
	lr := io.LimitReader(r, 11)

	enc := NewEncoder(lr)
	enc.(io.Seeker).Seek(10, 0)

	// `id` should be 11 even though the underlying
	// reader wasn't seeked at all.
	assert.Equal(t, "id: 11\ndata: d\n\n", readstring(enc))
}
Exemple #16
0
func TestPut(t *testing.T) {
	server := httptest.NewServer(app())
	defer server.Close()

	transport := &http.Transport{}
	client := &http.Client{Transport: transport}

	// uuid = curl -XPUT <url>/streams/1/2/3
	request, _ := http.NewRequest("PUT", server.URL+"/streams/1/2/3", nil)
	resp, err := client.Do(request)
	defer resp.Body.Close()
	assert.Nil(t, err)
	assert.Equal(t, resp.StatusCode, http.StatusCreated)

	registrar := broker.NewRedisRegistrar()
	assert.True(t, registrar.IsRegistered("1/2/3"))
}
Exemple #17
0
func TestSubGoneWithBackend(t *testing.T) {
	uuid, _ := util.NewUUID()

	storage, get, _ := fileServer(uuid)
	defer storage.Close()

	*util.StorageBaseURL = storage.URL
	defer func() {
		*util.StorageBaseURL = baseURL
	}()

	server := httptest.NewServer(app())
	defer server.Close()

	get <- []byte("hello world")

	resp, err := http.Get(server.URL + "/streams/" + uuid)
	defer resp.Body.Close()
	assert.Nil(t, err)

	body, _ := ioutil.ReadAll(resp.Body)
	assert.Equal(t, body, []byte("hello world"))
}
Exemple #18
0
func TestPubSub(t *testing.T) {
	server := httptest.NewServer(app())
	defer server.Close()

	data := [][]byte{
		[]byte{'h', 'e', 'l', 'l', 'o'},
		[]byte{0x1f, 0x8b, 0x08, 0x00, 0x3f, 0x6b, 0xe1, 0x53, 0x00, 0x03, 0xed, 0xce, 0xb1, 0x0a, 0xc2, 0x30},
		bytes.Repeat([]byte{'0'}, 32769),
	}

	for _, expected := range data {
		// uuid = curl -XPOST <url>/streams
		resp, err := http.Post(server.URL+"/streams", "", nil)
		defer resp.Body.Close()
		assert.Nil(t, err)

		body, err := ioutil.ReadAll(resp.Body)
		assert.Nil(t, err)

		// uuid extracted
		uuid := string(body)
		assert.Len(t, uuid, 32)

		done := make(chan bool)

		go func() {
			// curl <url>/streams/<uuid>
			// -- waiting for publish to arrive
			resp, err = http.Get(server.URL + "/streams/" + uuid)
			defer resp.Body.Close()
			assert.Nil(t, err)

			body, _ = ioutil.ReadAll(resp.Body)
			assert.Equal(t, body, expected)

			done <- true
		}()

		transport := &http.Transport{}
		client := &http.Client{Transport: transport}

		// curl -XPOST -H "Transfer-Encoding: chunked" -d "hello" <url>/streams/<uuid>
		req, _ := http.NewRequest("POST", server.URL+"/streams/"+uuid, bytes.NewReader(expected))
		req.TransferEncoding = []string{"chunked"}
		r, err := client.Do(req)
		r.Body.Close()
		assert.Nil(t, err)

		<-done

		// Read the whole response after the publisher has
		// completed. The mechanics of this is different in that
		// most of the content will be replayed instead of received
		// in chunks as they arrive.
		resp, err = http.Get(server.URL + "/streams/" + uuid)
		defer resp.Body.Close()
		assert.Nil(t, err)

		body, _ = ioutil.ReadAll(resp.Body)
		assert.Equal(t, body, expected)
	}
}
Exemple #19
0
func TestPubSubSSE(t *testing.T) {
	server := httptest.NewServer(app())
	defer server.Close()

	data := []struct {
		offset int
		input  string
		output string
	}{
		{0, "hello", "id: 5\ndata: hello\n\n"},
		{0, "hello\n", "id: 6\ndata: hello\ndata: \n\n"},
		{0, "hello\nworld", "id: 11\ndata: hello\ndata: world\n\n"},
		{0, "hello\nworld\n", "id: 12\ndata: hello\ndata: world\ndata: \n\n"},
		{1, "hello\nworld\n", "id: 12\ndata: ello\ndata: world\ndata: \n\n"},
		{6, "hello\nworld\n", "id: 12\ndata: world\ndata: \n\n"},
		{11, "hello\nworld\n", "id: 12\ndata: \ndata: \n\n"},
		{12, "hello\nworld\n", ""},
	}

	client := &http.Client{Transport: &http.Transport{}}

	for _, testdata := range data {
		uuid, _ := util.NewUUID()
		url := server.URL + "/streams/" + uuid

		// curl -XPUT <url>/streams/<uuid>
		request, _ := http.NewRequest("PUT", url, nil)
		resp, err := client.Do(request)
		defer resp.Body.Close()
		assert.Nil(t, err)

		done := make(chan bool)

		// curl -XPOST -H "Transfer-Encoding: chunked" -d "hello" <url>/streams/<uuid>
		req, _ := http.NewRequest("POST", url, bytes.NewReader([]byte(testdata.input)))
		req.TransferEncoding = []string{"chunked"}

		r, err := client.Do(req)
		assert.Nil(t, err)
		r.Body.Close()

		go func() {
			request, _ := http.NewRequest("GET", url, nil)
			request.Header.Add("Accept", "text/event-stream")
			request.Header.Add("Last-Event-Id", strconv.Itoa(testdata.offset))

			// curl <url>/streams/<uuid>
			// -- waiting for publish to arrive
			resp, err = client.Do(request)
			defer resp.Body.Close()
			assert.Nil(t, err)

			body, _ := ioutil.ReadAll(resp.Body)
			assert.Equal(t, body, []byte(testdata.output))

			if len(body) == 0 {
				assert.Equal(t, resp.StatusCode, http.StatusNoContent)
			}

			done <- true
		}()

		<-done
	}
}