[ARVADOS] updated: 1a844d06238368c9d5c946a34c0c52485de1c435

git at public.curoverse.com git at public.curoverse.com
Fri May 9 02:51:35 EDT 2014


Summary of changes:
 services/keep/src/keep/handler_test.go |  346 ++++++++++++++++++++------------
 1 files changed, 221 insertions(+), 125 deletions(-)

       via  1a844d06238368c9d5c946a34c0c52485de1c435 (commit)
      from  04ec74cf7dedfbb0becea0e0cb5018ccf55a31eb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 1a844d06238368c9d5c946a34c0c52485de1c435
Author: Tim Pierce <twp at curoverse.com>
Date:   Fri May 9 02:49:51 2014 -0400

    2328: handler_test.go refactoring
    
    Refactoring to make tests easier to read and understand.

diff --git a/services/keep/src/keep/handler_test.go b/services/keep/src/keep/handler_test.go
index a45ab43..9455a8a 100644
--- a/services/keep/src/keep/handler_test.go
+++ b/services/keep/src/keep/handler_test.go
@@ -11,6 +11,7 @@ package main
 
 import (
 	"bytes"
+	"github.com/gorilla/mux"
 	"net/http"
 	"net/http/httptest"
 	"regexp"
@@ -18,6 +19,22 @@ import (
 	"time"
 )
 
+// A RequestTester represents the parameters for an HTTP request to
+// be issued on behalf of a unit test.
+type RequestTester struct {
+	uri          string
+	api_token    string
+	method       string
+	request_body []byte
+}
+
+// Test GetBlockHandler on the following situations:
+//   - permissions off, unauthenticated request, unsigned locator
+//   - permissions on, authenticated request, signed locator
+//   - permissions on, authenticated request, unsigned locator
+//   - permissions on, unauthenticated request, signed locator
+//   - permissions on, authenticated request, expired locator
+//
 func TestGetHandler(t *testing.T) {
 	defer teardown()
 
@@ -33,59 +50,77 @@ func TestGetHandler(t *testing.T) {
 	// Set up a REST router for testing the handlers.
 	rest := NewRESTRouter()
 
-	// Test an unsigned GET request.
-	test_url := "http://localhost:25107/" + TEST_HASH
-	req, _ := http.NewRequest("GET", test_url, nil)
-	resp := httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
+	// -----------------
+	// Permissions: off.
 
-	ExpectStatusCode(t, "unsigned GET", resp, http.StatusOK)
-	ExpectBody(t, "unsigned GET", resp, string(TEST_BLOCK))
+	// Unauthenticated request, unsigned locator
+	// => OK
+	unsigned_locator := "http://localhost:25107/" + TEST_HASH
+	response := IssueRequest(rest,
+		&RequestTester{
+			method: "GET",
+			uri:    unsigned_locator,
+		})
+	ExpectStatusCode(t, "unsigned GET (permissions off)", http.StatusOK, response)
+	ExpectBody(t, "unsigned GET (permissions off)", string(TEST_BLOCK), response)
 
-	// Enable permissions.
+	// ----------------
+	// Permissions: on.
+
+	// Create signed and expired locators for testing.
 	enforce_permissions = true
 	PermissionSecret = []byte(known_key)
-	permission_ttl = 300
-	expiry := time.Now().Add(time.Duration(permission_ttl) * time.Second)
-
-	// Test GET with a signed locator.
-	test_url = "http://localhost:25107/" + SignLocator(TEST_HASH, known_token, expiry)
-	resp = httptest.NewRecorder()
-	req, _ = http.NewRequest("GET", test_url, nil)
-	req.Header.Set("Authorization", "OAuth "+known_token)
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "signed GET", resp, http.StatusOK)
-	ExpectBody(t, "signed GET", resp, string(TEST_BLOCK))
-
-	// Test GET with an unsigned locator.
-	test_url = "http://localhost:25107/" + TEST_HASH
-	resp = httptest.NewRecorder()
-	req, _ = http.NewRequest("GET", test_url, nil)
-	req.Header.Set("Authorization", "OAuth "+known_token)
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "unsigned locator", resp, PermissionError.HTTPCode)
-
-	// Test GET with a signed locator and an unauthenticated request.
-	test_url = "http://localhost:25107/" + SignLocator(TEST_HASH, known_token, expiry)
-	resp = httptest.NewRecorder()
-	req, _ = http.NewRequest("GET", test_url, nil)
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "signed locator", resp, PermissionError.HTTPCode)
-
-	// Test GET with an expired, signed locator.
-	expired_ts := time.Now().Add(-time.Hour)
-	test_url = "http://localhost:25107/" + SignLocator(TEST_HASH, known_token, expired_ts)
-	resp = httptest.NewRecorder()
-	req, _ = http.NewRequest("GET", test_url, nil)
-	req.Header.Set("Authorization", "OAuth "+known_token)
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "expired signature", resp, ExpiredError.HTTPCode)
+	permission_ttl = time.Duration(300) * time.Second
+
+	var (
+		expiration        = time.Now().Add(permission_ttl)
+		expired_timestamp = time.Now().Add(-time.Hour)
+		signed_locator    = "http://localhost:25107/" + SignLocator(TEST_HASH, known_token, expiration)
+		expired_locator   = "http://localhost:25107/" + SignLocator(TEST_HASH, known_token, expired_timestamp)
+	)
+
+	// Authenticated request, signed locator
+	// => OK
+	response = IssueRequest(rest, &RequestTester{
+		method:    "GET",
+		uri:       signed_locator,
+		api_token: known_token,
+	})
+	ExpectStatusCode(t, "signed GET (permissions on)", http.StatusOK, response)
+	ExpectBody(t, "signed GET (permissions on)", string(TEST_BLOCK), response)
+
+	// Authenticated request, unsigned locator
+	// => PermissionError
+	response = IssueRequest(rest, &RequestTester{
+		method:    "GET",
+		uri:       unsigned_locator,
+		api_token: known_token,
+	})
+	ExpectStatusCode(t, "unsigned locator", PermissionError.HTTPCode, response)
+
+	// Unauthenticated request, signed locator
+	// => PermissionError
+	response = IssueRequest(rest, &RequestTester{
+		method: "GET",
+		uri:    signed_locator,
+	})
+	ExpectStatusCode(t, "signed locator", PermissionError.HTTPCode, response)
+
+	// Authenticated request, expired locator
+	// => ExpiredError
+	response = IssueRequest(rest, &RequestTester{
+		method:    "GET",
+		uri:       expired_locator,
+		api_token: known_token,
+	})
+	ExpectStatusCode(t, "expired signature", ExpiredError.HTTPCode, response)
 }
 
+// Test PutBlockHandler on the following situations:
+//   - no server key
+//   - with server key, authenticated request, unsigned locator
+//   - with server key, unauthenticated request, unsigned locator
+//
 func TestPutHandler(t *testing.T) {
 	defer teardown()
 
@@ -96,48 +131,71 @@ func TestPutHandler(t *testing.T) {
 	// Set up a REST router for testing the handlers.
 	rest := NewRESTRouter()
 
-	// Execute a PUT request.
-	test_url := "http://localhost:25107/" + TEST_HASH
-	test_body := bytes.NewReader(TEST_BLOCK)
-	req, _ := http.NewRequest("PUT", test_url, test_body)
-	resp := httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
+	// --------------
+	// No server key.
 
-	ExpectStatusCode(t, "permissions off", resp, http.StatusOK)
-	ExpectBody(t, "permissions off", resp, TEST_HASH)
+	// Unauthenticated request, no server key
+	// => OK (unsigned response)
+	unsigned_locator := "http://localhost:25107/" + TEST_HASH
+	response := IssueRequest(rest,
+		&RequestTester{
+			method:       "PUT",
+			uri:          unsigned_locator,
+			request_body: TEST_BLOCK,
+		})
+
+	ExpectStatusCode(t,
+		"unauthenticated PUT (no server key)", http.StatusOK, response)
+	ExpectBody(t, "unauthenticated PUT (no server key)", TEST_HASH, response)
+
+	// ------------------
+	// With a server key.
 
-	// Add a permission key.
-	// When a permission key is available, the locator returned
-	// from a PUT request will be signed.
 	PermissionSecret = []byte(known_key)
 	permission_ttl = time.Duration(300) * time.Second
 
-	// An authenticated PUT request returns a signed locator.
-	test_url = "http://localhost:25107/" + TEST_HASH
-	test_body = bytes.NewReader(TEST_BLOCK)
-	req, _ = http.NewRequest("PUT", test_url, test_body)
-	req.Header.Set("Authorization", "OAuth "+known_token)
-	resp = httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "authenticated PUT", resp, http.StatusOK)
-	if !VerifySignature(resp.Body.String(), known_token) {
-		t.Errorf("authenticated PUT: response '%s' failed signature check",
-			resp.Body.String())
+	// When a permission key is available, the locator returned
+	// from an authenticated PUT request will be signed.
+
+	// Authenticated PUT, signed locator
+	// => OK (signed response)
+	response = IssueRequest(rest,
+		&RequestTester{
+			method:       "PUT",
+			uri:          unsigned_locator,
+			request_body: TEST_BLOCK,
+			api_token:    known_token,
+		})
+
+	ExpectStatusCode(t,
+		"authenticated PUT (with server key)", http.StatusOK, response)
+	if !VerifySignature(response.Body.String(), known_token) {
+		t.Errorf("authenticated PUT (with server key): response '%s' does not contain a valid signature",
+			response.Body.String())
 	}
 
-	// An unauthenticated PUT request returns an unsigned locator
-	// even when a permission key is available.
-	test_url = "http://localhost:25107/" + TEST_HASH
-	test_body = bytes.NewReader(TEST_BLOCK)
-	req, _ = http.NewRequest("PUT", test_url, test_body)
-	resp = httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "anon PUT with server key", resp, http.StatusOK)
-	ExpectBody(t, "anon PUT with server key", resp, TEST_HASH)
+	// Unauthenticated PUT, unsigned locator
+	// => OK
+	response = IssueRequest(rest,
+		&RequestTester{
+			method:       "PUT",
+			uri:          unsigned_locator,
+			request_body: TEST_BLOCK,
+		})
+
+	ExpectStatusCode(t,
+		"unauthenticated PUT (with server key)", http.StatusOK, response)
+	ExpectBody(t,
+		"unauthenticated PUT (with server key)", TEST_HASH, response)
 }
 
+// Test /index requests:
+//   - unauthenticated /index/{prefix} request
+//   - unauthenticated /index request
+//   - authenticated /index request, non-superuser
+//   - authenticated /index request by superuser, enforce_permissions = false
+//   - authenticated /index request by superuser, enforce_permissions = true
+//
 func TestIndexHandler(t *testing.T) {
 	defer teardown()
 
@@ -154,64 +212,102 @@ func TestIndexHandler(t *testing.T) {
 	// Set up a REST router for testing the handlers.
 	rest := NewRESTRouter()
 
-	// Requests for /index with a prefix are okay even if unauthenticated.
-	test_url := "http://localhost:25107/index/" + TEST_HASH[0:5]
-	req, _ := http.NewRequest("GET", test_url, nil)
-	resp := httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
+	// Unauthenticated /index/{prefix}
+	// => OK
+	response := IssueRequest(rest,
+		&RequestTester{
+			method: "GET",
+			uri:    "http://localhost:25107/index/" + TEST_HASH[0:5],
+		})
 
 	expected := `^` + TEST_HASH + `\+\d+ \d+\n$`
-	match, _ := regexp.MatchString(expected, resp.Body.String())
+	match, _ := regexp.MatchString(expected, response.Body.String())
 	if !match {
 		t.Errorf("IndexHandler expected: %s, returned:\n%s",
-			expected, resp.Body.String())
+			expected, response.Body.String())
 	}
 
-	// Unauthenticated /index requests: fail.
-	test_url = "http://localhost:25107/index"
-	req, _ = http.NewRequest("GET", test_url, nil)
-	resp = httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "unauthenticated /index", resp, PermissionError.HTTPCode)
-
-	// Authenticated /index requests by a non-superuser: also fail.
-	test_url = "http://localhost:25107/index"
-	req, _ = http.NewRequest("GET", test_url, nil)
-	req.Header.Set("Authorization", "OAuth "+known_token)
-	resp = httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
-
-	ExpectStatusCode(t, "authenticated /index", resp, PermissionError.HTTPCode)
-
-	// Even superuser /index requests fail if enforce_permissions is off!
+	// Unauthenticated /index
+	// => PermissionError
+	response = IssueRequest(rest,
+		&RequestTester{
+			method: "GET",
+			uri:    "http://localhost:25107/index",
+		})
+
+	ExpectStatusCode(t,
+		"unauthenticated /index", PermissionError.HTTPCode, response)
+
+	// Authenticated /index request by non-superuser
+	// => PermissionError
+	response = IssueRequest(rest,
+		&RequestTester{
+			method:    "GET",
+			uri:       "http://localhost:25107/index",
+			api_token: known_token,
+		})
+
+	ExpectStatusCode(t,
+		"authenticated /index by non-superuser",
+		PermissionError.HTTPCode,
+		response)
+
+	// Authenticated /index request by superuser, enforce_permissions = false
+	// => PermissionError
 	enforce_permissions = false
 	data_manager_token = "DATA MANAGER TOKEN"
-	test_url = "http://localhost:25107/index"
-	req, _ = http.NewRequest("GET", test_url, nil)
-	req.Header.Set("Authorization", "OAuth "+data_manager_token)
-	resp = httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
 
-	ExpectStatusCode(t, "superuser /index (permissions off)", resp, PermissionError.HTTPCode)
+	response = IssueRequest(rest,
+		&RequestTester{
+			method:    "GET",
+			uri:       "http://localhost:25107/index",
+			api_token: data_manager_token,
+		})
 
-	// Superuser /index requests with enforce_permissions set: succeed!
+	ExpectStatusCode(t,
+		"authenticated /index request by superuser (permissions off)",
+		PermissionError.HTTPCode,
+		response)
+
+	// Authenticated /index request by superuser, enforce_permissions = true
+	// => OK
 	enforce_permissions = true
-	data_manager_token = "DATA MANAGER TOKEN"
-	test_url = "http://localhost:25107/index"
-	req, _ = http.NewRequest("GET", test_url, nil)
-	req.Header.Set("Authorization", "OAuth "+data_manager_token)
-	resp = httptest.NewRecorder()
-	rest.ServeHTTP(resp, req)
+	response = IssueRequest(rest,
+		&RequestTester{
+			method:    "GET",
+			uri:       "http://localhost:25107/index",
+			api_token: data_manager_token,
+		})
+
+	ExpectStatusCode(t,
+		"authenticated /index request by superuser (permissions on)",
+		http.StatusOK,
+		response)
 
-	ExpectStatusCode(t, "superuser /index (permissions on)", resp, http.StatusOK)
 	expected = `^` + TEST_HASH + `\+\d+ \d+\n` +
 		TEST_HASH_2 + `\+\d+ \d+\n$`
-	match, _ = regexp.MatchString(expected, resp.Body.String())
+	match, _ = regexp.MatchString(expected, response.Body.String())
 	if !match {
 		t.Errorf("superuser /index: expected %s, got:\n%s",
-			expected, resp.Body.String())
+			expected, response.Body.String())
+	}
+}
+
+// ====================
+// Helper functions
+// ====================
+
+// IssueTestRequest executes an HTTP request described by rt, to a
+// specified REST router.  It returns the HTTP response to the request.
+func IssueRequest(router *mux.Router, rt *RequestTester) *httptest.ResponseRecorder {
+	response := httptest.NewRecorder()
+	body := bytes.NewReader(rt.request_body)
+	req, _ := http.NewRequest(rt.method, rt.uri, body)
+	if rt.api_token != "" {
+		req.Header.Set("Authorization", "OAuth "+rt.api_token)
 	}
+	router.ServeHTTP(response, req)
+	return response
 }
 
 // ExpectStatusCode checks whether a response has the specified status code,
@@ -219,8 +315,8 @@ func TestIndexHandler(t *testing.T) {
 func ExpectStatusCode(
 	t *testing.T,
 	testname string,
-	response *httptest.ResponseRecorder,
-	expected_status int) {
+	expected_status int,
+	response *httptest.ResponseRecorder) {
 	if response.Code != expected_status {
 		t.Errorf("%s: expected status %s, got %+v",
 			testname, expected_status, response)
@@ -230,8 +326,8 @@ func ExpectStatusCode(
 func ExpectBody(
 	t *testing.T,
 	testname string,
-	response *httptest.ResponseRecorder,
-	expected_body string) {
+	expected_body string,
+	response *httptest.ResponseRecorder) {
 	if response.Body.String() != expected_body {
 		t.Errorf("%s: expected response body '%s', got %+v",
 			testname, expected_body, response)

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list