Skip to content

Commit

Permalink
Rework of TestGetDirListHost to work with macOS
Browse files Browse the repository at this point in the history
macOS tests were failing for this test because of too many http test
servers running in parallel. Reworked the test to only have 1 http test
server that has different responses based on the request url path base.
Thought this was the best way to do this with 1 test server since we
cannot modify the request directly (and do it with headers)
  • Loading branch information
joereuss12 committed May 15, 2024
1 parent 1e38e4b commit 4ec1f4c
Showing 1 changed file with 57 additions and 83 deletions.
140 changes: 57 additions & 83 deletions client/handle_http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -853,24 +853,63 @@ func TestSearchJobAd(t *testing.T) {
})
}

// testCase is an enum to represent the different test cases for getDirListHost
type testCase int

const (
case307 testCase = iota
case307NoLocation
case405
case404
case503
)

// Create a map to associate the string values with the enum values
var testCases = map[string]testCase{
"307": case307,
"307NoLocation": case307NoLocation,
"405": case405,
"404": case404,
"503": case503,
}

// This function tests the getDirListHost helper function. Testing cases of reponses we could get from the director
func TestGetDirListHost(t *testing.T) {
// Test we get dirlisthost with valid PROPFIND on test server
t.Run("testValidPropfind", func(t *testing.T) {
expectedLocation := "http://some/origin/path/to/object"
handler := func(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()

// Handler for test server
handler := func(w http.ResponseWriter, r *http.Request) {
// We switch off of the base of the URL path, this way we don't need several http test servers running in parallel
// (lots of parallel http servers cause MacOS tests to fail)
switch testCases[filepath.Base(r.URL.Path)] {
case case307:
expectedLocation := "http://some/origin/path/to/object"
w.Header().Set("Location", expectedLocation)
w.WriteHeader(http.StatusTemporaryRedirect)
case case307NoLocation:
w.WriteHeader(http.StatusTemporaryRedirect)
case case405:
w.WriteHeader(http.StatusMethodNotAllowed)
case case404:
w.WriteHeader(http.StatusNotFound)
case case503:
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
err := json.NewEncoder(w).Encode(map[string]string{"error": "some server error"})
require.NoError(t, err)
default:
w.WriteHeader(http.StatusOK)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
require.NoError(t, err)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
err := server_utils.WaitUntilWorking(ctx, "PROPFIND", server.URL, "testServer", http.StatusTemporaryRedirect, true)
require.NoError(t, err)

// Wait until our server is working
err = server_utils.WaitUntilWorking(ctx, "PROPFIND", server.URL, "testServer", http.StatusTemporaryRedirect, true)
// Test we get dirlisthost with valid PROPFIND on test server
t.Run("testValidPropfind", func(t *testing.T) {
testObjectUrl, err := url.Parse("pelican://federation/some/object/307")
require.NoError(t, err)

dirListHost, err := getDirListHost(ctx, testObjectUrl, namespaces.Namespace{}, server.URL)
require.NoError(t, err)
assert.Equal(t, "http://some", dirListHost.String())
Expand All @@ -879,19 +918,8 @@ func TestGetDirListHost(t *testing.T) {
// Test we get dirlist host when PROPFIND returns 405 but dirlisthost set in namespace
t.Run("testInvalidPropfindValidDirListInNamespace", func(t *testing.T) {
expectedLocation := "http://origin"
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
require.NoError(t, err)

// Wait until our server is working
err = server_utils.WaitUntilWorking(ctx, "PROPFIND", server.URL, "testServer", http.StatusMethodNotAllowed, true)
testObjectUrl, err := url.Parse("pelican://federation/some/object/405")
require.NoError(t, err)

dirListHost, err := getDirListHost(ctx, testObjectUrl, namespaces.Namespace{DirListHost: expectedLocation}, server.URL)
require.NoError(t, err)
assert.Equal(t, expectedLocation, dirListHost.String())
Expand All @@ -900,19 +928,8 @@ func TestGetDirListHost(t *testing.T) {
// Test we get dirlist host when PROPFIND returns 404 but dirlisthost set in namespace
t.Run("test404PropfindValidDirListInNamespace", func(t *testing.T) {
expectedLocation := "http://origin"
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
testObjectUrl, err := url.Parse("pelican://federation/some/object/404")
require.NoError(t, err)

// Wait until our server is working
err = server_utils.WaitUntilWorking(ctx, "PROPFIND", server.URL, "testServer", http.StatusNotFound, true)
require.NoError(t, err)

dirListHost, err := getDirListHost(ctx, testObjectUrl, namespaces.Namespace{DirListHost: expectedLocation}, server.URL)
require.NoError(t, err)
assert.Equal(t, expectedLocation, dirListHost.String())
Expand All @@ -921,7 +938,6 @@ func TestGetDirListHost(t *testing.T) {
// Test we get dirlisthost when we are not using a director and namespace has dirlisthost set
t.Run("testNoDirectorValidDirListInNamespace", func(t *testing.T) {
expectedLocation := "http://origin"
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
require.NoError(t, err)
dirListHost, err := getDirListHost(ctx, testObjectUrl, namespaces.Namespace{DirListHost: expectedLocation}, "")
Expand All @@ -931,33 +947,16 @@ func TestGetDirListHost(t *testing.T) {

// Test if PROPFIND and ns.dirlisthost fail, we get dirListingNotSupported error
t.Run("testInvalidPropfindNoDirListInNamespace", func(t *testing.T) {
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
testObjectUrl, err := url.Parse("pelican://federation/some/object/405")
require.NoError(t, err)

// Wait until our server is working
err = server_utils.WaitUntilWorking(ctx, "PROPFIND", server.URL, "testServer", http.StatusMethodNotAllowed, true)
require.NoError(t, err)

_, err = getDirListHost(ctx, testObjectUrl, namespaces.Namespace{}, server.URL)
require.Error(t, err)
assert.ErrorIs(t, err, &dirListingNotSupportedError{})
})

// Test if PROPFIND if 404 and ns.dirlisthost fail, we get dirListingNotSupported error
t.Run("test404PropfindNoDirListInNamespace", func(t *testing.T) {
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
testObjectUrl, err := url.Parse("pelican://federation/some/object/404")
require.NoError(t, err)
_, err = getDirListHost(ctx, testObjectUrl, namespaces.Namespace{}, server.URL)
require.Error(t, err)
Expand All @@ -976,42 +975,17 @@ func TestGetDirListHost(t *testing.T) {

// Test when director does not return 'location' header (just blank response), we fail
t.Run("testNoLocationHeaderReturned", func(t *testing.T) {
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusTemporaryRedirect)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
testObjectUrl, err := url.Parse("pelican://federation/some/object/307NoLocation")
require.NoError(t, err)

// Wait until our server is working
err = server_utils.WaitUntilWorking(ctx, "PROPFIND", server.URL, "testServer", http.StatusTemporaryRedirect, true)
require.NoError(t, err)

_, err = getDirListHost(ctx, testObjectUrl, namespaces.Namespace{}, server.URL)
require.Error(t, err)
assert.Contains(t, err.Error(), "collections URL not found in director response")
})

// Test if failure to connect to director we handle that properly
t.Run("testDirectorFailedToConnect", func(t *testing.T) {
handler := func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusServiceUnavailable)
err := json.NewEncoder(w).Encode(map[string]string{"error": "some server error"})
require.NoError(t, err)
}
server := httptest.NewServer(http.HandlerFunc(handler))
defer server.Close()
ctx := context.Background()
testObjectUrl, err := url.Parse("pelican://federation/some/object")
require.NoError(t, err)

// Wait until our server is working
err = server_utils.WaitUntilWorking(ctx, "PROPFIND", server.URL, "testServer", http.StatusServiceUnavailable, true)
testObjectUrl, err := url.Parse("pelican://federation/some/object/503")
require.NoError(t, err)

_, err = getDirListHost(ctx, testObjectUrl, namespaces.Namespace{}, server.URL)
require.Error(t, err)
assert.Contains(t, err.Error(), "some server error")
Expand Down

0 comments on commit 4ec1f4c

Please sign in to comment.