github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/emswift/emswiftpkg/pkg_test.go (about)

     1  // Copyright (c) 2015-2021, NVIDIA CORPORATION.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package emswiftpkg
     5  
     6  import (
     7  	"bytes"
     8  	"io"
     9  	"io/ioutil"
    10  	"net"
    11  	"net/http"
    12  	"strings"
    13  	"sync"
    14  	"testing"
    15  
    16  	"github.com/swiftstack/ProxyFS/conf"
    17  	"github.com/swiftstack/ProxyFS/utils"
    18  )
    19  
    20  func TestAuthEmulation(t *testing.T) {
    21  	var (
    22  		confMap     conf.ConfMap
    23  		confStrings = []string{
    24  			"EMSWIFT.AuthIPAddr=127.0.0.1",
    25  			"EMSWIFT.AuthTCPPort=9997",
    26  			"EMSWIFT.JRPCIPAddr=127.0.0.1",
    27  			"EMSWIFT.JRPCTCPPort=9998",
    28  			"EMSWIFT.NoAuthIPAddr=127.0.0.1",
    29  			"EMSWIFT.NoAuthTCPPort=9999",
    30  			"EMSWIFT.MaxAccountNameLength=256",
    31  			"EMSWIFT.MaxContainerNameLength=256",
    32  			"EMSWIFT.MaxObjectNameLength=1024",
    33  			"EMSWIFT.AccountListingLimit=10000",
    34  			"EMSWIFT.ContainerListingLimit=10000",
    35  		}
    36  		err                              error
    37  		expectedInfo                     string
    38  		expectedStorageURL               string
    39  		httpClient                       *http.Client
    40  		httpRequest                      *http.Request
    41  		httpResponse                     *http.Response
    42  		readBuf                          []byte
    43  		testJRPCServerHandlerTCPListener *net.TCPListener
    44  		testJRPCServerHandlerWG          *sync.WaitGroup
    45  		urlForAuth                       string
    46  		urlForInfo                       string
    47  		urlPrefix                        string
    48  	)
    49  
    50  	confMap, err = conf.MakeConfMapFromStrings(confStrings)
    51  	if nil != err {
    52  		t.Fatalf("conf.MakeConfMapFromStrings(confStrings) returned unexpected error: %v", err)
    53  	}
    54  
    55  	err = Start(confMap)
    56  	if nil != err {
    57  		t.Fatalf("Start(confMap) returned unexpected error: %v", err)
    58  	}
    59  
    60  	testJRPCServerHandlerTCPListener, err = net.ListenTCP("tcp", globals.authEmulator.resolvedJRPCTCPAddr)
    61  	if nil != err {
    62  		t.Fatalf("net.ListenTCP() returned unexpected error: %v", err)
    63  	}
    64  
    65  	testJRPCServerHandlerWG = new(sync.WaitGroup)
    66  	testJRPCServerHandlerWG.Add(1)
    67  	go testJRPCServerHandler(testJRPCServerHandlerTCPListener, testJRPCServerHandlerWG)
    68  
    69  	// Format URLs
    70  
    71  	urlForInfo = "http://" + globals.authEmulator.httpServer.Addr + "/info"
    72  	urlForAuth = "http://" + globals.authEmulator.httpServer.Addr + "/auth/v1.0"
    73  	urlPrefix = "http://" + globals.authEmulator.httpServer.Addr + "/proxyfs/"
    74  
    75  	expectedStorageURL = "http://" + globals.authEmulator.httpServer.Addr + "/v1/" + "AUTH_test"
    76  
    77  	// Setup http.Client that we will use for all HTTP requests
    78  
    79  	httpClient = &http.Client{}
    80  
    81  	// Send a GET for "/info" expecting [EMSWIFT] data in compact JSON form
    82  
    83  	httpRequest, err = http.NewRequest("GET", urlForInfo, nil)
    84  	if nil != err {
    85  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
    86  	}
    87  	httpResponse, err = httpClient.Do(httpRequest)
    88  	if nil != err {
    89  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
    90  	}
    91  	if http.StatusOK != httpResponse.StatusCode {
    92  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
    93  	}
    94  	expectedInfo = "{\"swift\": {\"max_account_name_length\": 256,\"max_container_name_length\": 256,\"max_object_name_length\": 1024,\"account_listing_limit\": 10000,\"container_listing_limit\": 10000}}"
    95  	if int64(len(expectedInfo)) != httpResponse.ContentLength {
    96  		t.Fatalf("GET of /info httpResponse.ContentLength unexpected")
    97  	}
    98  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
    99  	if nil != err {
   100  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
   101  	}
   102  	if expectedInfo != utils.ByteSliceToString(readBuf) {
   103  		t.Fatalf("GET of /info httpResponse.Body contents unexpected")
   104  	}
   105  	err = httpResponse.Body.Close()
   106  	if nil != err {
   107  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   108  	}
   109  
   110  	// Send a GET for "/auth/v1.0" expecting X-Auth-Token & X-Storage-Url
   111  
   112  	httpRequest, err = http.NewRequest("GET", urlForAuth, nil)
   113  	if nil != err {
   114  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   115  	}
   116  	httpRequest.Header.Add("X-Auth-User", "test:tester")
   117  	httpRequest.Header.Add("X-Auth-Key", "testing")
   118  	httpResponse, err = httpClient.Do(httpRequest)
   119  	if nil != err {
   120  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   121  	}
   122  	if http.StatusOK != httpResponse.StatusCode {
   123  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   124  	}
   125  	err = httpResponse.Body.Close()
   126  	if nil != err {
   127  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   128  	}
   129  	if httpResponse.Header.Get("X-Auth-Token") != fixedAuthToken {
   130  		t.Fatalf("Auth response should have header X-Auth-Token: %s", fixedAuthToken)
   131  	}
   132  	if httpResponse.Header.Get("X-Storage-Url") != expectedStorageURL {
   133  		t.Fatalf("Auth response should have header X-Storage-Url: %s", expectedStorageURL)
   134  	}
   135  
   136  	// Send a PUT for account "TestAccount"
   137  
   138  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount", nil)
   139  	if nil != err {
   140  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   141  	}
   142  	httpRequest.Header.Add("X-Auth-Token", fixedAuthToken)
   143  	httpResponse, err = httpClient.Do(httpRequest)
   144  	if nil != err {
   145  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   146  	}
   147  	if http.StatusCreated != httpResponse.StatusCode {
   148  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   149  	}
   150  	err = httpResponse.Body.Close()
   151  	if nil != err {
   152  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   153  	}
   154  
   155  	// Send a GET for account "TestAccount" expecting Content-Length: 0
   156  
   157  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount", nil)
   158  	if nil != err {
   159  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   160  	}
   161  	httpRequest.Header.Add("X-Auth-Token", fixedAuthToken)
   162  	httpResponse, err = httpClient.Do(httpRequest)
   163  	if nil != err {
   164  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   165  	}
   166  	if http.StatusNoContent != httpResponse.StatusCode {
   167  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   168  	}
   169  	if 0 != httpResponse.ContentLength {
   170  		t.Fatalf("TestAccount should contain no elements at this point")
   171  	}
   172  	err = httpResponse.Body.Close()
   173  	if nil != err {
   174  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   175  	}
   176  
   177  	// Send a PROXYFS JSON-RPC "request" that simply gets echo'd
   178  
   179  	httpRequest, err = http.NewRequest("PROXYFS", urlPrefix+"TestAccount", bytes.NewReader([]byte{'{', 'p', 'i', 'n', 'g', '}'}))
   180  	if nil != err {
   181  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   182  	}
   183  	httpRequest.Header.Add("X-Auth-Token", fixedAuthToken)
   184  	httpRequest.Header.Add("Content-Type", "application/json")
   185  	httpResponse, err = httpClient.Do(httpRequest)
   186  	if nil != err {
   187  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   188  	}
   189  	if http.StatusOK != httpResponse.StatusCode {
   190  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   191  	}
   192  	if httpResponse.Header.Get("Content-Type") != "application/json" {
   193  		t.Fatalf("TestAccount should have header Content-Type: application/json")
   194  	}
   195  	if int64(len("{ping}")) != httpResponse.ContentLength {
   196  		t.Fatalf("TestContainer should contain only \"{ping}\"")
   197  	}
   198  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
   199  	if nil != err {
   200  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
   201  	}
   202  	if "{ping}" != utils.ByteSliceToString(readBuf) {
   203  		t.Fatalf("TestContainer should contain only \"{ping}\"")
   204  	}
   205  	err = httpResponse.Body.Close()
   206  	if nil != err {
   207  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   208  	}
   209  
   210  	err = testJRPCServerHandlerTCPListener.Close()
   211  	if nil != err {
   212  		t.Fatalf("testJRPCServerHandlerTCPListener.Close() returned unexpected error: %v", err)
   213  	}
   214  
   215  	testJRPCServerHandlerWG.Wait()
   216  
   217  	err = Stop()
   218  	if nil != err {
   219  		t.Fatalf("Stop() returned unexpected error: %v", err)
   220  	}
   221  }
   222  
   223  func testJRPCServerHandler(testJRPCServerHandlerTCPListener *net.TCPListener, testJRPCServerHandlerWG *sync.WaitGroup) {
   224  	var (
   225  		bytesWritten                int
   226  		bytesWrittenInTotal         int
   227  		err                         error
   228  		jrpcRequest                 []byte
   229  		jrpcRequestNestedLeftBraces uint32
   230  		jrpcRequestSingleByte       []byte
   231  		jrpcResponse                []byte
   232  		jrpcTCPConn                 *net.TCPConn
   233  	)
   234  
   235  DoAcceptTCP:
   236  	jrpcTCPConn, err = testJRPCServerHandlerTCPListener.AcceptTCP()
   237  	if nil != err {
   238  		testJRPCServerHandlerWG.Done()
   239  		return
   240  	}
   241  
   242  	jrpcRequest = make([]byte, 0)
   243  	jrpcRequestSingleByte = make([]byte, 1)
   244  
   245  	_, err = jrpcTCPConn.Read(jrpcRequestSingleByte)
   246  	if nil != err {
   247  		_ = jrpcTCPConn.Close()
   248  		goto DoAcceptTCP
   249  	}
   250  	jrpcRequest = append(jrpcRequest, jrpcRequestSingleByte[0])
   251  
   252  	if '{' != jrpcRequestSingleByte[0] {
   253  		_ = jrpcTCPConn.Close()
   254  		goto DoAcceptTCP
   255  	}
   256  
   257  	jrpcRequestNestedLeftBraces = 1
   258  
   259  	for 0 < jrpcRequestNestedLeftBraces {
   260  		_, err = jrpcTCPConn.Read(jrpcRequestSingleByte)
   261  		if nil != err {
   262  			_ = jrpcTCPConn.Close()
   263  			goto DoAcceptTCP
   264  		}
   265  		jrpcRequest = append(jrpcRequest, jrpcRequestSingleByte[0])
   266  
   267  		switch jrpcRequestSingleByte[0] {
   268  		case '{':
   269  			jrpcRequestNestedLeftBraces++
   270  		case '}':
   271  			jrpcRequestNestedLeftBraces--
   272  		default:
   273  			// Nothing special to do here
   274  		}
   275  	}
   276  
   277  	jrpcResponse = jrpcRequest
   278  
   279  	bytesWrittenInTotal = 0
   280  
   281  	for bytesWrittenInTotal < len(jrpcResponse) {
   282  		bytesWritten, err = jrpcTCPConn.Write(jrpcResponse[bytesWrittenInTotal:])
   283  		if nil != err {
   284  			_ = jrpcTCPConn.Close()
   285  			goto DoAcceptTCP
   286  		}
   287  		bytesWrittenInTotal += bytesWritten
   288  	}
   289  
   290  	_ = jrpcTCPConn.Close()
   291  	goto DoAcceptTCP
   292  }
   293  
   294  func TestNoAuthEmulation(t *testing.T) {
   295  	var (
   296  		confMap     conf.ConfMap
   297  		confStrings = []string{
   298  			"EMSWIFT.NoAuthIPAddr=127.0.0.1",
   299  			"EMSWIFT.NoAuthTCPPort=9999",
   300  			"EMSWIFT.MaxAccountNameLength=256",
   301  			"EMSWIFT.MaxContainerNameLength=256",
   302  			"EMSWIFT.MaxObjectNameLength=1024",
   303  			"EMSWIFT.AccountListingLimit=10000",
   304  			"EMSWIFT.ContainerListingLimit=10000",
   305  		}
   306  		contentType                  string
   307  		contentTypeMultiPartBoundary string
   308  		err                          error
   309  		errChan                      chan error
   310  		expectedBuf                  []byte
   311  		expectedInfo                 string
   312  		httpClient                   *http.Client
   313  		httpRequest                  *http.Request
   314  		httpResponse                 *http.Response
   315  		mouseHeaderPresent           bool
   316  		pipeReader                   *io.PipeReader
   317  		pipeWriter                   *io.PipeWriter
   318  		readBuf                      []byte
   319  		urlForInfo                   string
   320  		urlPrefix                    string
   321  	)
   322  
   323  	confMap, err = conf.MakeConfMapFromStrings(confStrings)
   324  	if nil != err {
   325  		t.Fatalf("conf.MakeConfMapFromStrings(confStrings) returned unexpected error: %v", err)
   326  	}
   327  
   328  	err = Start(confMap)
   329  	if nil != err {
   330  		t.Fatalf("Start(confMap) returned unexpected error: %v", err)
   331  	}
   332  
   333  	// Format URLs
   334  
   335  	urlForInfo = "http://" + globals.noAuthEmulator.httpServer.Addr + "/info"
   336  	urlPrefix = "http://" + globals.noAuthEmulator.httpServer.Addr + "/v1/"
   337  
   338  	// Setup http.Client that we will use for all HTTP requests
   339  
   340  	httpClient = &http.Client{}
   341  
   342  	// Send a GET for "/info" expecting [EMSWIFT] data in compact JSON form
   343  
   344  	httpRequest, err = http.NewRequest("GET", urlForInfo, nil)
   345  	if nil != err {
   346  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   347  	}
   348  	httpResponse, err = httpClient.Do(httpRequest)
   349  	if nil != err {
   350  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   351  	}
   352  	if http.StatusOK != httpResponse.StatusCode {
   353  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   354  	}
   355  	expectedInfo = "{\"swift\": {\"max_account_name_length\": 256,\"max_container_name_length\": 256,\"max_object_name_length\": 1024,\"account_listing_limit\": 10000,\"container_listing_limit\": 10000}}"
   356  	if int64(len(expectedInfo)) != httpResponse.ContentLength {
   357  		t.Fatalf("GET of /info httpResponse.ContentLength unexpected")
   358  	}
   359  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
   360  	if nil != err {
   361  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
   362  	}
   363  	if expectedInfo != utils.ByteSliceToString(readBuf) {
   364  		t.Fatalf("GET of /info httpResponse.Body contents unexpected")
   365  	}
   366  	err = httpResponse.Body.Close()
   367  	if nil != err {
   368  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   369  	}
   370  
   371  	// Send a PUT for account "TestAccount" and header Cat: Dog
   372  
   373  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount", nil)
   374  	if nil != err {
   375  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   376  	}
   377  	httpRequest.Header.Add("Cat", "Dog")
   378  	httpResponse, err = httpClient.Do(httpRequest)
   379  	if nil != err {
   380  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   381  	}
   382  	if http.StatusCreated != httpResponse.StatusCode {
   383  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   384  	}
   385  	err = httpResponse.Body.Close()
   386  	if nil != err {
   387  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   388  	}
   389  
   390  	// Send a HEAD for account "TestAccount" expecting header Cat: Dog
   391  
   392  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount", nil)
   393  	if nil != err {
   394  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   395  	}
   396  	httpResponse, err = httpClient.Do(httpRequest)
   397  	if nil != err {
   398  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   399  	}
   400  	if http.StatusNoContent != httpResponse.StatusCode {
   401  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   402  	}
   403  	if httpResponse.Header.Get("Cat") != "Dog" {
   404  		t.Fatalf("TestAccount should have header Cat: Dog")
   405  	}
   406  	err = httpResponse.Body.Close()
   407  	if nil != err {
   408  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   409  	}
   410  
   411  	// Send a GET for account "TestAccount" expecting Content-Length: 0 and header Cat: Dog
   412  
   413  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount", nil)
   414  	if nil != err {
   415  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   416  	}
   417  	httpResponse, err = httpClient.Do(httpRequest)
   418  	if nil != err {
   419  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   420  	}
   421  	if http.StatusNoContent != httpResponse.StatusCode {
   422  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   423  	}
   424  	if httpResponse.Header.Get("Cat") != "Dog" {
   425  		t.Fatalf("TestAccount should have header Cat: Dog")
   426  	}
   427  	if 0 != httpResponse.ContentLength {
   428  		t.Fatalf("TestAccount should contain no elements at this point")
   429  	}
   430  	err = httpResponse.Body.Close()
   431  	if nil != err {
   432  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   433  	}
   434  
   435  	// Send a POST for account "TestAccount" and header Mouse: Bird
   436  
   437  	httpRequest, err = http.NewRequest("POST", urlPrefix+"TestAccount", nil)
   438  	if nil != err {
   439  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   440  	}
   441  	httpRequest.Header.Add("Mouse", "Bird")
   442  	httpResponse, err = httpClient.Do(httpRequest)
   443  	if nil != err {
   444  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   445  	}
   446  	if http.StatusNoContent != httpResponse.StatusCode {
   447  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   448  	}
   449  	err = httpResponse.Body.Close()
   450  	if nil != err {
   451  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   452  	}
   453  
   454  	// Send a HEAD for account "TestAccount" expecting header Cat: Dog & Mouse: Bird
   455  
   456  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount", nil)
   457  	if nil != err {
   458  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   459  	}
   460  	httpResponse, err = httpClient.Do(httpRequest)
   461  	if nil != err {
   462  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   463  	}
   464  	if http.StatusNoContent != httpResponse.StatusCode {
   465  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   466  	}
   467  	if httpResponse.Header.Get("Cat") != "Dog" {
   468  		t.Fatalf("TestAccount should have header Cat: Dog")
   469  	}
   470  	if httpResponse.Header.Get("Mouse") != "Bird" {
   471  		t.Fatalf("TestAccount should have header Mouse: Bird")
   472  	}
   473  	err = httpResponse.Body.Close()
   474  	if nil != err {
   475  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   476  	}
   477  
   478  	// Send a POST for account "TestAccount" deleting header Mouse
   479  
   480  	httpRequest, err = http.NewRequest("POST", urlPrefix+"TestAccount", nil)
   481  	if nil != err {
   482  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   483  	}
   484  	httpRequest.Header.Add("Mouse", "")
   485  	httpResponse, err = httpClient.Do(httpRequest)
   486  	if nil != err {
   487  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   488  	}
   489  	if http.StatusNoContent != httpResponse.StatusCode {
   490  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   491  	}
   492  	err = httpResponse.Body.Close()
   493  	if nil != err {
   494  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   495  	}
   496  
   497  	// Send a HEAD for account "TestAccount" expecting header Cat: Dog & no Mouse header
   498  
   499  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount", nil)
   500  	if nil != err {
   501  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   502  	}
   503  	httpResponse, err = httpClient.Do(httpRequest)
   504  	if nil != err {
   505  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   506  	}
   507  	if http.StatusNoContent != httpResponse.StatusCode {
   508  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   509  	}
   510  	if httpResponse.Header.Get("Cat") != "Dog" {
   511  		t.Fatalf("TestAccount should have header Cat: Dog")
   512  	}
   513  	_, mouseHeaderPresent = httpResponse.Header["Mouse"]
   514  	if mouseHeaderPresent {
   515  		t.Fatalf("TestAccount should not have header Mouse")
   516  	}
   517  	err = httpResponse.Body.Close()
   518  	if nil != err {
   519  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   520  	}
   521  
   522  	// Send a PUT for account "TestAccount" and header Mouse: Bird
   523  
   524  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount", nil)
   525  	if nil != err {
   526  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   527  	}
   528  	httpRequest.Header.Add("Mouse", "Bird")
   529  	httpResponse, err = httpClient.Do(httpRequest)
   530  	if nil != err {
   531  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   532  	}
   533  	if http.StatusAccepted != httpResponse.StatusCode {
   534  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   535  	}
   536  	err = httpResponse.Body.Close()
   537  	if nil != err {
   538  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   539  	}
   540  
   541  	// Send a HEAD for account "TestAccount" expecting header Cat: Dog & Mouse: Bird
   542  
   543  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount", nil)
   544  	if nil != err {
   545  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   546  	}
   547  	httpResponse, err = httpClient.Do(httpRequest)
   548  	if nil != err {
   549  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   550  	}
   551  	if http.StatusNoContent != httpResponse.StatusCode {
   552  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   553  	}
   554  	if httpResponse.Header.Get("Cat") != "Dog" {
   555  		t.Fatalf("TestAccount should have header Cat: Dog")
   556  	}
   557  	if httpResponse.Header.Get("Mouse") != "Bird" {
   558  		t.Fatalf("TestAccount should have header Mouse: Bird")
   559  	}
   560  	err = httpResponse.Body.Close()
   561  	if nil != err {
   562  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   563  	}
   564  
   565  	// Send a PUT for account "TestAccount" deleting header Mouse
   566  
   567  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount", nil)
   568  	if nil != err {
   569  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   570  	}
   571  	httpRequest.Header.Add("Mouse", "")
   572  	httpResponse, err = httpClient.Do(httpRequest)
   573  	if nil != err {
   574  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   575  	}
   576  	if http.StatusAccepted != httpResponse.StatusCode {
   577  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   578  	}
   579  	err = httpResponse.Body.Close()
   580  	if nil != err {
   581  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   582  	}
   583  
   584  	// Send a HEAD for account "TestAccount" expecting header Cat: Dog & no Mouse header
   585  
   586  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount", nil)
   587  	if nil != err {
   588  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   589  	}
   590  	httpResponse, err = httpClient.Do(httpRequest)
   591  	if nil != err {
   592  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   593  	}
   594  	if http.StatusNoContent != httpResponse.StatusCode {
   595  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   596  	}
   597  	if httpResponse.Header.Get("Cat") != "Dog" {
   598  		t.Fatalf("TestAccount should have header Cat: Dog")
   599  	}
   600  	_, mouseHeaderPresent = httpResponse.Header["Mouse"]
   601  	if mouseHeaderPresent {
   602  		t.Fatalf("TestAccount should not have header Mouse")
   603  	}
   604  	err = httpResponse.Body.Close()
   605  	if nil != err {
   606  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   607  	}
   608  
   609  	// Send a PUT for container "TestContainer" and header Cat: Dog
   610  
   611  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount/TestContainer", nil)
   612  	if nil != err {
   613  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   614  	}
   615  	httpRequest.Header.Add("Cat", "Dog")
   616  	httpResponse, err = httpClient.Do(httpRequest)
   617  	if nil != err {
   618  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   619  	}
   620  	if http.StatusCreated != httpResponse.StatusCode {
   621  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   622  	}
   623  	err = httpResponse.Body.Close()
   624  	if nil != err {
   625  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   626  	}
   627  
   628  	// Send a GET for account "TestAccount" expecting "TestContainer\n" and header Cat: Dog
   629  
   630  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount", nil)
   631  	if nil != err {
   632  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   633  	}
   634  	httpResponse, err = httpClient.Do(httpRequest)
   635  	if nil != err {
   636  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   637  	}
   638  	if http.StatusOK != httpResponse.StatusCode {
   639  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   640  	}
   641  	if httpResponse.Header.Get("Cat") != "Dog" {
   642  		t.Fatalf("TestAccount should have header Cat: Dog")
   643  	}
   644  	if int64(len("TestContainer\n")) != httpResponse.ContentLength {
   645  		t.Fatalf("TestAccount should contain only \"TestContainer\\n\" at this point")
   646  	}
   647  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
   648  	if nil != err {
   649  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
   650  	}
   651  	if "TestContainer\n" != utils.ByteSliceToString(readBuf) {
   652  		t.Fatalf("TestAccount should contain only \"TestContainer\\n\" at this point")
   653  	}
   654  	err = httpResponse.Body.Close()
   655  	if nil != err {
   656  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   657  	}
   658  
   659  	// Send a GET for account "TestAccount" with marker "AAA" expecting "TestContainer\n" and header Cat: Dog
   660  
   661  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount?marker=AAA", nil)
   662  	if nil != err {
   663  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   664  	}
   665  	httpResponse, err = httpClient.Do(httpRequest)
   666  	if nil != err {
   667  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   668  	}
   669  	if http.StatusOK != httpResponse.StatusCode {
   670  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   671  	}
   672  	if httpResponse.Header.Get("Cat") != "Dog" {
   673  		t.Fatalf("TestAccount should have header Cat: Dog")
   674  	}
   675  	if int64(len("TestContainer\n")) != httpResponse.ContentLength {
   676  		t.Fatalf("TestAccount should contain only \"TestContainer\\n\" at this point")
   677  	}
   678  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
   679  	if nil != err {
   680  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
   681  	}
   682  	if "TestContainer\n" != utils.ByteSliceToString(readBuf) {
   683  		t.Fatalf("TestAccount should contain only \"TestContainer\\n\" at this point")
   684  	}
   685  	err = httpResponse.Body.Close()
   686  	if nil != err {
   687  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   688  	}
   689  
   690  	// Send a GET for account "TestAccount" with marker "ZZZ" expecting Content-Length: 0 and header Cat: Dog
   691  
   692  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount?marker=ZZZ", nil)
   693  	if nil != err {
   694  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   695  	}
   696  	httpResponse, err = httpClient.Do(httpRequest)
   697  	if nil != err {
   698  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   699  	}
   700  	if http.StatusNoContent != httpResponse.StatusCode {
   701  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   702  	}
   703  	if httpResponse.Header.Get("Cat") != "Dog" {
   704  		t.Fatalf("TestAccount should have header Cat: Dog")
   705  	}
   706  	if 0 != httpResponse.ContentLength {
   707  		t.Fatalf("TestAccount should contain no elements at this point")
   708  	}
   709  	err = httpResponse.Body.Close()
   710  	if nil != err {
   711  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   712  	}
   713  
   714  	// Send a HEAD for container "TestContainer" expecting header Cat: Dog
   715  
   716  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer", nil)
   717  	if nil != err {
   718  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   719  	}
   720  	httpResponse, err = httpClient.Do(httpRequest)
   721  	if nil != err {
   722  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   723  	}
   724  	if http.StatusNoContent != httpResponse.StatusCode {
   725  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   726  	}
   727  	if httpResponse.Header.Get("Cat") != "Dog" {
   728  		t.Fatalf("TestContainer should have header Cat: Dog")
   729  	}
   730  	err = httpResponse.Body.Close()
   731  	if nil != err {
   732  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   733  	}
   734  
   735  	// Send a GET for container "TestContainer" expecting Content-Length: 0 and header Cat: Dog
   736  
   737  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer", nil)
   738  	if nil != err {
   739  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   740  	}
   741  	httpResponse, err = httpClient.Do(httpRequest)
   742  	if nil != err {
   743  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   744  	}
   745  	if http.StatusNoContent != httpResponse.StatusCode {
   746  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   747  	}
   748  	if httpResponse.Header.Get("Cat") != "Dog" {
   749  		t.Fatalf("TestContainer should have header Cat: Dog")
   750  	}
   751  	if 0 != httpResponse.ContentLength {
   752  		t.Fatalf("TestContainer should contain no elements at this point")
   753  	}
   754  	err = httpResponse.Body.Close()
   755  	if nil != err {
   756  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   757  	}
   758  
   759  	// Send a POST for container "TestContainer" and header Mouse: Bird
   760  
   761  	httpRequest, err = http.NewRequest("POST", urlPrefix+"TestAccount/TestContainer", nil)
   762  	if nil != err {
   763  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   764  	}
   765  	httpRequest.Header.Add("Mouse", "Bird")
   766  	httpResponse, err = httpClient.Do(httpRequest)
   767  	if nil != err {
   768  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   769  	}
   770  	if http.StatusNoContent != httpResponse.StatusCode {
   771  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   772  	}
   773  	err = httpResponse.Body.Close()
   774  	if nil != err {
   775  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   776  	}
   777  
   778  	// Send a HEAD for container "TestContainer" expecting header Cat: Dog & Mouse: Bird
   779  
   780  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer", nil)
   781  	if nil != err {
   782  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   783  	}
   784  	httpResponse, err = httpClient.Do(httpRequest)
   785  	if nil != err {
   786  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   787  	}
   788  	if http.StatusNoContent != httpResponse.StatusCode {
   789  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   790  	}
   791  	if httpResponse.Header.Get("Cat") != "Dog" {
   792  		t.Fatalf("TestContainer should have header Cat: Dog")
   793  	}
   794  	if httpResponse.Header.Get("Mouse") != "Bird" {
   795  		t.Fatalf("TestContainer should have header Mouse: Bird")
   796  	}
   797  	err = httpResponse.Body.Close()
   798  	if nil != err {
   799  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   800  	}
   801  
   802  	// Send a POST for container "TestContainer" deleting header Mouse
   803  
   804  	httpRequest, err = http.NewRequest("POST", urlPrefix+"TestAccount/TestContainer", nil)
   805  	if nil != err {
   806  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   807  	}
   808  	httpRequest.Header.Add("Mouse", "")
   809  	httpResponse, err = httpClient.Do(httpRequest)
   810  	if nil != err {
   811  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   812  	}
   813  	if http.StatusNoContent != httpResponse.StatusCode {
   814  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   815  	}
   816  	err = httpResponse.Body.Close()
   817  	if nil != err {
   818  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   819  	}
   820  
   821  	// Send a HEAD for container "TestContainer" expecting header Cat: Dog & no Mouse header
   822  
   823  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer", nil)
   824  	if nil != err {
   825  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   826  	}
   827  	httpResponse, err = httpClient.Do(httpRequest)
   828  	if nil != err {
   829  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   830  	}
   831  	if http.StatusNoContent != httpResponse.StatusCode {
   832  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   833  	}
   834  	if httpResponse.Header.Get("Cat") != "Dog" {
   835  		t.Fatalf("TestContainer should have header Cat: Dog")
   836  	}
   837  	_, mouseHeaderPresent = httpResponse.Header["Mouse"]
   838  	if mouseHeaderPresent {
   839  		t.Fatalf("TestContainer should not have header Mouse")
   840  	}
   841  	err = httpResponse.Body.Close()
   842  	if nil != err {
   843  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   844  	}
   845  
   846  	// Send a PUT for container "TestContainer" and header Mouse: Bird
   847  
   848  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount/TestContainer", nil)
   849  	if nil != err {
   850  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   851  	}
   852  	httpRequest.Header.Add("Mouse", "Bird")
   853  	httpResponse, err = httpClient.Do(httpRequest)
   854  	if nil != err {
   855  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   856  	}
   857  	if http.StatusAccepted != httpResponse.StatusCode {
   858  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   859  	}
   860  	err = httpResponse.Body.Close()
   861  	if nil != err {
   862  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   863  	}
   864  
   865  	// Send a HEAD for container "TestContainer" expecting header Cat: Dog & Mouse: Bird
   866  
   867  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer", nil)
   868  	if nil != err {
   869  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   870  	}
   871  	httpResponse, err = httpClient.Do(httpRequest)
   872  	if nil != err {
   873  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   874  	}
   875  	if http.StatusNoContent != httpResponse.StatusCode {
   876  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   877  	}
   878  	if httpResponse.Header.Get("Cat") != "Dog" {
   879  		t.Fatalf("TestContainer should have header Cat: Dog")
   880  	}
   881  	if httpResponse.Header.Get("Mouse") != "Bird" {
   882  		t.Fatalf("TestContainer should have header Mouse: Bird")
   883  	}
   884  	err = httpResponse.Body.Close()
   885  	if nil != err {
   886  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   887  	}
   888  
   889  	// Send a PUT for container "TestContainer" deleting header Mouse
   890  
   891  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount/TestContainer", nil)
   892  	if nil != err {
   893  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   894  	}
   895  	httpRequest.Header.Add("Mouse", "")
   896  	httpResponse, err = httpClient.Do(httpRequest)
   897  	if nil != err {
   898  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   899  	}
   900  	if http.StatusAccepted != httpResponse.StatusCode {
   901  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   902  	}
   903  	err = httpResponse.Body.Close()
   904  	if nil != err {
   905  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   906  	}
   907  
   908  	// Send a HEAD for container "TestContainer" expecting header Cat: Dog & no Mouse header
   909  
   910  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer", nil)
   911  	if nil != err {
   912  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   913  	}
   914  	httpResponse, err = httpClient.Do(httpRequest)
   915  	if nil != err {
   916  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   917  	}
   918  	if http.StatusNoContent != httpResponse.StatusCode {
   919  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   920  	}
   921  	if httpResponse.Header.Get("Cat") != "Dog" {
   922  		t.Fatalf("TestContainer should have header Cat: Dog")
   923  	}
   924  	_, mouseHeaderPresent = httpResponse.Header["Mouse"]
   925  	if mouseHeaderPresent {
   926  		t.Fatalf("TestContainer should not have header Mouse")
   927  	}
   928  	err = httpResponse.Body.Close()
   929  	if nil != err {
   930  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   931  	}
   932  
   933  	// Send a non-chunked PUT for object "Foo" to contain []byte{0x00, 0x01, 0x02}
   934  
   935  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount/TestContainer/Foo", bytes.NewReader([]byte{0x00, 0x01, 0x02}))
   936  	if nil != err {
   937  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   938  	}
   939  	httpResponse, err = httpClient.Do(httpRequest)
   940  	if nil != err {
   941  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   942  	}
   943  	if http.StatusCreated != httpResponse.StatusCode {
   944  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   945  	}
   946  	err = httpResponse.Body.Close()
   947  	if nil != err {
   948  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   949  	}
   950  
   951  	// Send a chunked PUT for object "Bar"" with 1st chunk being []byte{0xAA, 0xBB} & 2nd chunk being []byte{0xCC, 0xDD, 0xEE}
   952  
   953  	pipeReader, pipeWriter = io.Pipe()
   954  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount/TestContainer/Bar", pipeReader)
   955  	if nil != err {
   956  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
   957  	}
   958  	httpRequest.ContentLength = -1
   959  	httpRequest.Header.Del("Content-Length")
   960  	errChan = make(chan error, 1)
   961  	go func() {
   962  		var (
   963  			nonShadowingErr          error
   964  			nonShadowingHTTPResponse *http.Response
   965  		)
   966  		nonShadowingHTTPResponse, nonShadowingErr = httpClient.Do(httpRequest)
   967  		if nil == nonShadowingErr {
   968  			httpResponse = nonShadowingHTTPResponse
   969  		}
   970  		errChan <- nonShadowingErr
   971  	}()
   972  	_, err = pipeWriter.Write([]byte{0xAA, 0xBB})
   973  	if nil != err {
   974  		t.Fatalf("pipeWriter.Write() returned unexpected error: %v", err)
   975  	}
   976  	_, err = pipeWriter.Write([]byte{0xCC, 0xDD, 0xEE})
   977  	if nil != err {
   978  		t.Fatalf("pipeWriter.Write() returned unexpected error: %v", err)
   979  	}
   980  	err = pipeWriter.Close()
   981  	if nil != err {
   982  		t.Fatalf("pipeWriter.Close() returned unexpected error: %v", err)
   983  	}
   984  	err = <-errChan
   985  	if nil != err {
   986  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
   987  	}
   988  	if http.StatusCreated != httpResponse.StatusCode {
   989  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
   990  	}
   991  	err = httpResponse.Body.Close()
   992  	if nil != err {
   993  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
   994  	}
   995  
   996  	// Send a GET for container "TestContainer" expecting "Bar\nFoo\n" and header Cat: Dog
   997  
   998  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer", nil)
   999  	if nil != err {
  1000  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1001  	}
  1002  	httpResponse, err = httpClient.Do(httpRequest)
  1003  	if nil != err {
  1004  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1005  	}
  1006  	if http.StatusOK != httpResponse.StatusCode {
  1007  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1008  	}
  1009  	if httpResponse.Header.Get("Cat") != "Dog" {
  1010  		t.Fatalf("TestAccount should have header Cat: Dog")
  1011  	}
  1012  	if int64(len("Bar\nFoo\n")) != httpResponse.ContentLength {
  1013  		t.Fatalf("TestContainer should contain only \"Bar\\nFoo\\n\" at this point")
  1014  	}
  1015  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
  1016  	if nil != err {
  1017  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
  1018  	}
  1019  	if "Bar\nFoo\n" != utils.ByteSliceToString(readBuf) {
  1020  		t.Fatalf("TestContainer should contain only \"Bar\\nFoo\\n\" at this point")
  1021  	}
  1022  	err = httpResponse.Body.Close()
  1023  	if nil != err {
  1024  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1025  	}
  1026  
  1027  	// Send a GET for container "TestContainer" with marker "AAA" expecting "Bar\nFoo\n" and header Cat: Dog
  1028  
  1029  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer?marker=AAA", nil)
  1030  	if nil != err {
  1031  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1032  	}
  1033  	httpResponse, err = httpClient.Do(httpRequest)
  1034  	if nil != err {
  1035  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1036  	}
  1037  	if http.StatusOK != httpResponse.StatusCode {
  1038  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1039  	}
  1040  	if httpResponse.Header.Get("Cat") != "Dog" {
  1041  		t.Fatalf("TestAccount should have header Cat: Dog")
  1042  	}
  1043  	if int64(len("Bar\nFoo\n")) != httpResponse.ContentLength {
  1044  		t.Fatalf("TestContainer should contain only \"Bar\\nFoo\\n\" at this point")
  1045  	}
  1046  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
  1047  	if nil != err {
  1048  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
  1049  	}
  1050  	if "Bar\nFoo\n" != utils.ByteSliceToString(readBuf) {
  1051  		t.Fatalf("TestContainer should contain only \"Bar\\nFoo\\n\" at this point")
  1052  	}
  1053  	err = httpResponse.Body.Close()
  1054  	if nil != err {
  1055  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1056  	}
  1057  
  1058  	// Send a GET for container "TestContainer" with marker "ZZZ" expecting Content-Length: 0 and header Cat: Dog
  1059  
  1060  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer?marker=ZZZ", nil)
  1061  	if nil != err {
  1062  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1063  	}
  1064  	httpResponse, err = httpClient.Do(httpRequest)
  1065  	if nil != err {
  1066  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1067  	}
  1068  	if http.StatusNoContent != httpResponse.StatusCode {
  1069  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1070  	}
  1071  	if httpResponse.Header.Get("Cat") != "Dog" {
  1072  		t.Fatalf("TestContainer should have header Cat: Dog")
  1073  	}
  1074  	if 0 != httpResponse.ContentLength {
  1075  		t.Fatalf("TestContainer should contain no elements at this point")
  1076  	}
  1077  	err = httpResponse.Body.Close()
  1078  	if nil != err {
  1079  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1080  	}
  1081  
  1082  	// Send a HEAD for object "Foo" expecting Content-Length: 3
  1083  
  1084  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer/Foo", nil)
  1085  	if nil != err {
  1086  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1087  	}
  1088  	httpResponse, err = httpClient.Do(httpRequest)
  1089  	if nil != err {
  1090  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1091  	}
  1092  	if http.StatusOK != httpResponse.StatusCode {
  1093  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1094  	}
  1095  	if 3 != httpResponse.ContentLength {
  1096  		t.Fatalf("httpResponse.ContentLength contained unexpected value: %v", httpResponse.ContentLength)
  1097  	}
  1098  	err = httpResponse.Body.Close()
  1099  	if nil != err {
  1100  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1101  	}
  1102  
  1103  	// Send a full object GET for object "Foo" expecting []byte{0x00, 0x01, 0x02}
  1104  
  1105  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer/Foo", nil)
  1106  	if nil != err {
  1107  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1108  	}
  1109  	httpResponse, err = httpClient.Do(httpRequest)
  1110  	if nil != err {
  1111  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1112  	}
  1113  	if http.StatusOK != httpResponse.StatusCode {
  1114  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1115  	}
  1116  	if int64(len([]byte{0x00, 0x01, 0x02})) != httpResponse.ContentLength {
  1117  		t.Fatalf("Foo should contain precisely []byte{0x00, 0x01, 0x02}")
  1118  	}
  1119  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
  1120  	if nil != err {
  1121  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
  1122  	}
  1123  	if 0 != bytes.Compare([]byte{0x00, 0x01, 0x02}, readBuf) {
  1124  		t.Fatalf("Foo should contain precisely []byte{0x00, 0x01, 0x02}")
  1125  	}
  1126  	err = httpResponse.Body.Close()
  1127  	if nil != err {
  1128  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1129  	}
  1130  
  1131  	// Send a range GET of bytes at offset 1 for length 3 for object "Bar" expecting []byte{0xBB, 0xCC, 0xDD}
  1132  
  1133  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer/Bar", nil)
  1134  	if nil != err {
  1135  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1136  	}
  1137  	httpRequest.Header.Add("Range", "bytes=1-3")
  1138  	httpResponse, err = httpClient.Do(httpRequest)
  1139  	if nil != err {
  1140  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1141  	}
  1142  	if http.StatusPartialContent != httpResponse.StatusCode {
  1143  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1144  	}
  1145  	if int64(len([]byte{0xBB, 0xCC, 0xDD})) != httpResponse.ContentLength {
  1146  		t.Fatalf("Bar's bytes 1-3 should contain precisely []byte{0xBB, 0xCC, 0xDD}")
  1147  	}
  1148  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
  1149  	if nil != err {
  1150  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
  1151  	}
  1152  	if 0 != bytes.Compare([]byte{0xBB, 0xCC, 0xDD}, readBuf) {
  1153  		t.Fatalf("Bar's bytes 1-3 should contain precisely []byte{0xBB, 0xCC, 0xDD}")
  1154  	}
  1155  	err = httpResponse.Body.Close()
  1156  	if nil != err {
  1157  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1158  	}
  1159  
  1160  	// Send a range GET of bytes at offset 0 for length 2
  1161  	//                          and offset 3 for length of 1 for object "Bar"
  1162  	// expecting two MIME parts: []byte{0xAA, 0xBB} and  []byte{0xDD}
  1163  
  1164  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer/Bar", nil)
  1165  	if nil != err {
  1166  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1167  	}
  1168  	httpRequest.Header.Add("Range", "bytes=0-1,3-3")
  1169  	httpResponse, err = httpClient.Do(httpRequest)
  1170  	if nil != err {
  1171  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1172  	}
  1173  	if http.StatusPartialContent != httpResponse.StatusCode {
  1174  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1175  	}
  1176  	contentType = httpResponse.Header.Get("Content-Type")
  1177  	contentTypeMultiPartBoundary = strings.TrimPrefix(contentType, "multipart/byteranges; boundary=")
  1178  	if (len(contentType) == len(contentTypeMultiPartBoundary)) || (0 == len(contentTypeMultiPartBoundary)) {
  1179  		t.Fatalf("httpReponse.Header[\"Content-Type\"] contained unexpected value: \"%v\"", contentType)
  1180  	}
  1181  	expectedBuf = make([]byte, 0, httpResponse.ContentLength)
  1182  	expectedBuf = append(expectedBuf, []byte("--"+contentTypeMultiPartBoundary+"\r\n")...)
  1183  	expectedBuf = append(expectedBuf, []byte("Content-Type: application/octet-stream\r\n")...)
  1184  	expectedBuf = append(expectedBuf, []byte("Content-Range: bytes 0-1/5\r\n")...)
  1185  	expectedBuf = append(expectedBuf, []byte("\r\n")...)
  1186  	expectedBuf = append(expectedBuf, []byte{0xAA, 0xBB}...)
  1187  	expectedBuf = append(expectedBuf, []byte("\r\n")...)
  1188  	expectedBuf = append(expectedBuf, []byte("--"+contentTypeMultiPartBoundary+"\r\n")...)
  1189  	expectedBuf = append(expectedBuf, []byte("Content-Type: application/octet-stream\r\n")...)
  1190  	expectedBuf = append(expectedBuf, []byte("Content-Range: bytes 3-3/5\r\n")...)
  1191  	expectedBuf = append(expectedBuf, []byte("\r\n")...)
  1192  	expectedBuf = append(expectedBuf, []byte{0xDD}...)
  1193  	expectedBuf = append(expectedBuf, []byte("\r\n")...)
  1194  	expectedBuf = append(expectedBuf, []byte("--"+contentTypeMultiPartBoundary+"--")...)
  1195  	if int64(len(expectedBuf)) != httpResponse.ContentLength {
  1196  		t.Fatalf("Unexpected multi-part GET response Content-Length")
  1197  	}
  1198  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
  1199  	if nil != err {
  1200  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
  1201  	}
  1202  	if 0 != bytes.Compare(expectedBuf, readBuf) {
  1203  		t.Fatalf("Unexpected payload of multi-part GET response")
  1204  	}
  1205  	err = httpResponse.Body.Close()
  1206  	if nil != err {
  1207  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1208  	}
  1209  
  1210  	// Send a tail GET of the last 2 bytes for object "Bar" expecting []byte{0xDD, 0xEE}
  1211  
  1212  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer/Bar", nil)
  1213  	if nil != err {
  1214  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1215  	}
  1216  	httpRequest.Header.Add("Range", "bytes=-2")
  1217  	httpResponse, err = httpClient.Do(httpRequest)
  1218  	if nil != err {
  1219  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1220  	}
  1221  	if http.StatusPartialContent != httpResponse.StatusCode {
  1222  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1223  	}
  1224  	if int64(len([]byte{0xDD, 0xEE})) != httpResponse.ContentLength {
  1225  		t.Fatalf("Bar's last 2 bytes should contain precisely []byte{0xDD, 0xEE}")
  1226  	}
  1227  	readBuf, err = ioutil.ReadAll(httpResponse.Body)
  1228  	if nil != err {
  1229  		t.Fatalf("ioutil.ReadAll() returned unexpected error: %v", err)
  1230  	}
  1231  	if 0 != bytes.Compare([]byte{0xDD, 0xEE}, readBuf) {
  1232  		t.Fatalf("Bar's last 2 bytes should contain precisely []byte{0xDD, 0xEE}")
  1233  	}
  1234  	err = httpResponse.Body.Close()
  1235  	if nil != err {
  1236  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1237  	}
  1238  
  1239  	// Send a PUT for object "ZigZag" and header Cat: Dog
  1240  
  1241  	httpRequest, err = http.NewRequest("PUT", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1242  	if nil != err {
  1243  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1244  	}
  1245  	httpRequest.Header.Add("Cat", "Dog")
  1246  	httpResponse, err = httpClient.Do(httpRequest)
  1247  	if nil != err {
  1248  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1249  	}
  1250  	if http.StatusCreated != httpResponse.StatusCode {
  1251  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1252  	}
  1253  	err = httpResponse.Body.Close()
  1254  	if nil != err {
  1255  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1256  	}
  1257  
  1258  	// Send a HEAD for object "ZigZag" expecting header Cat: Dog
  1259  
  1260  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1261  	if nil != err {
  1262  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1263  	}
  1264  	httpResponse, err = httpClient.Do(httpRequest)
  1265  	if nil != err {
  1266  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1267  	}
  1268  	if http.StatusOK != httpResponse.StatusCode {
  1269  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1270  	}
  1271  	if httpResponse.Header.Get("Cat") != "Dog" {
  1272  		t.Fatalf("TestAccount should have header Cat: Dog")
  1273  	}
  1274  	err = httpResponse.Body.Close()
  1275  	if nil != err {
  1276  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1277  	}
  1278  
  1279  	// Send a HEAD for object "ZigZag" expecting header Cat: Dog
  1280  
  1281  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1282  	if nil != err {
  1283  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1284  	}
  1285  	httpResponse, err = httpClient.Do(httpRequest)
  1286  	if nil != err {
  1287  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1288  	}
  1289  	if http.StatusOK != httpResponse.StatusCode {
  1290  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1291  	}
  1292  	if httpResponse.Header.Get("Cat") != "Dog" {
  1293  		t.Fatalf("TestAccount should have header Cat: Dog")
  1294  	}
  1295  	err = httpResponse.Body.Close()
  1296  	if nil != err {
  1297  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1298  	}
  1299  
  1300  	// Send a POST for object "ZigZag" and header Mouse: Bird
  1301  
  1302  	httpRequest, err = http.NewRequest("POST", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1303  	if nil != err {
  1304  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1305  	}
  1306  	httpRequest.Header.Add("Mouse", "Bird")
  1307  	httpResponse, err = httpClient.Do(httpRequest)
  1308  	if nil != err {
  1309  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1310  	}
  1311  	if http.StatusNoContent != httpResponse.StatusCode {
  1312  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1313  	}
  1314  	err = httpResponse.Body.Close()
  1315  	if nil != err {
  1316  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1317  	}
  1318  
  1319  	// Send a HEAD for object "ZigZag" expecting header Cat: Dog & Mouse: Bird
  1320  
  1321  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1322  	if nil != err {
  1323  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1324  	}
  1325  	httpResponse, err = httpClient.Do(httpRequest)
  1326  	if nil != err {
  1327  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1328  	}
  1329  	if http.StatusOK != httpResponse.StatusCode {
  1330  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1331  	}
  1332  	if httpResponse.Header.Get("Cat") != "Dog" {
  1333  		t.Fatalf("TestAccount should have header Cat: Dog")
  1334  	}
  1335  	if httpResponse.Header.Get("Mouse") != "Bird" {
  1336  		t.Fatalf("TestAccount should have header Mouse: Bird")
  1337  	}
  1338  	err = httpResponse.Body.Close()
  1339  	if nil != err {
  1340  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1341  	}
  1342  
  1343  	// Send a POST for object "ZigZag" deleting header Mouse
  1344  
  1345  	httpRequest, err = http.NewRequest("POST", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1346  	if nil != err {
  1347  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1348  	}
  1349  	httpRequest.Header.Add("Mouse", "")
  1350  	httpResponse, err = httpClient.Do(httpRequest)
  1351  	if nil != err {
  1352  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1353  	}
  1354  	if http.StatusNoContent != httpResponse.StatusCode {
  1355  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1356  	}
  1357  	err = httpResponse.Body.Close()
  1358  	if nil != err {
  1359  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1360  	}
  1361  
  1362  	// Send a HEAD for object "ZigZag" expecting header Cat: Dog & no Mouse header
  1363  
  1364  	httpRequest, err = http.NewRequest("HEAD", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1365  	if nil != err {
  1366  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1367  	}
  1368  	httpResponse, err = httpClient.Do(httpRequest)
  1369  	if nil != err {
  1370  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1371  	}
  1372  	if http.StatusOK != httpResponse.StatusCode {
  1373  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1374  	}
  1375  	if httpResponse.Header.Get("Cat") != "Dog" {
  1376  		t.Fatalf("TestAccount should have header Cat: Dog")
  1377  	}
  1378  	_, mouseHeaderPresent = httpResponse.Header["Mouse"]
  1379  	if mouseHeaderPresent {
  1380  		t.Fatalf("TestAccount should not have header Mouse")
  1381  	}
  1382  	err = httpResponse.Body.Close()
  1383  	if nil != err {
  1384  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1385  	}
  1386  
  1387  	// Send a DELETE for object "Foo"
  1388  
  1389  	httpRequest, err = http.NewRequest("DELETE", urlPrefix+"TestAccount/TestContainer/Foo", nil)
  1390  	if nil != err {
  1391  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1392  	}
  1393  	httpResponse, err = httpClient.Do(httpRequest)
  1394  	if nil != err {
  1395  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1396  	}
  1397  	if http.StatusNoContent != httpResponse.StatusCode {
  1398  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1399  	}
  1400  	err = httpResponse.Body.Close()
  1401  	if nil != err {
  1402  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1403  	}
  1404  
  1405  	// Send a DELETE for object "Bar"
  1406  
  1407  	httpRequest, err = http.NewRequest("DELETE", urlPrefix+"TestAccount/TestContainer/Bar", nil)
  1408  	if nil != err {
  1409  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1410  	}
  1411  	httpResponse, err = httpClient.Do(httpRequest)
  1412  	if nil != err {
  1413  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1414  	}
  1415  	if http.StatusNoContent != httpResponse.StatusCode {
  1416  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1417  	}
  1418  	err = httpResponse.Body.Close()
  1419  	if nil != err {
  1420  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1421  	}
  1422  
  1423  	// Send a DELETE for object "ZigZag"
  1424  
  1425  	httpRequest, err = http.NewRequest("DELETE", urlPrefix+"TestAccount/TestContainer/ZigZag", nil)
  1426  	if nil != err {
  1427  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1428  	}
  1429  	httpResponse, err = httpClient.Do(httpRequest)
  1430  	if nil != err {
  1431  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1432  	}
  1433  	if http.StatusNoContent != httpResponse.StatusCode {
  1434  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1435  	}
  1436  	err = httpResponse.Body.Close()
  1437  	if nil != err {
  1438  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1439  	}
  1440  
  1441  	// Send a GET for container "TestContainer" expecting Content-Length: 0 and header Cat: Dog
  1442  
  1443  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount/TestContainer", nil)
  1444  	if nil != err {
  1445  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1446  	}
  1447  	httpResponse, err = httpClient.Do(httpRequest)
  1448  	if nil != err {
  1449  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1450  	}
  1451  	if http.StatusNoContent != httpResponse.StatusCode {
  1452  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1453  	}
  1454  	if httpResponse.Header.Get("Cat") != "Dog" {
  1455  		t.Fatalf("TestContainer should have header Cat: Dog")
  1456  	}
  1457  	if 0 != httpResponse.ContentLength {
  1458  		t.Fatalf("TestContainer should contain no elements at this point")
  1459  	}
  1460  	err = httpResponse.Body.Close()
  1461  	if nil != err {
  1462  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1463  	}
  1464  
  1465  	// Send a DELETE for container "TestContainer"
  1466  
  1467  	httpRequest, err = http.NewRequest("DELETE", urlPrefix+"TestAccount/TestContainer", nil)
  1468  	if nil != err {
  1469  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1470  	}
  1471  	httpResponse, err = httpClient.Do(httpRequest)
  1472  	if nil != err {
  1473  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1474  	}
  1475  	if http.StatusNoContent != httpResponse.StatusCode {
  1476  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1477  	}
  1478  	err = httpResponse.Body.Close()
  1479  	if nil != err {
  1480  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1481  	}
  1482  
  1483  	// Send a GET for account "TestAccount" expecting Content-Length: 0 and header Cat: Dog
  1484  
  1485  	httpRequest, err = http.NewRequest("GET", urlPrefix+"TestAccount", nil)
  1486  	if nil != err {
  1487  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1488  	}
  1489  	httpResponse, err = httpClient.Do(httpRequest)
  1490  	if nil != err {
  1491  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1492  	}
  1493  	if http.StatusNoContent != httpResponse.StatusCode {
  1494  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1495  	}
  1496  	if httpResponse.Header.Get("Cat") != "Dog" {
  1497  		t.Fatalf("TestAccount should have header Cat: Dog")
  1498  	}
  1499  	if 0 != httpResponse.ContentLength {
  1500  		t.Fatalf("TestAccount should contain no elements at this point")
  1501  	}
  1502  	err = httpResponse.Body.Close()
  1503  	if nil != err {
  1504  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1505  	}
  1506  
  1507  	// Send a DELETE for account "TestAccount"
  1508  
  1509  	httpRequest, err = http.NewRequest("DELETE", urlPrefix+"TestAccount", nil)
  1510  	if nil != err {
  1511  		t.Fatalf("http.NewRequest() returned unexpected error: %v", err)
  1512  	}
  1513  	httpResponse, err = httpClient.Do(httpRequest)
  1514  	if nil != err {
  1515  		t.Fatalf("httpClient.Do() returned unexpected error: %v", err)
  1516  	}
  1517  	if http.StatusNoContent != httpResponse.StatusCode {
  1518  		t.Fatalf("httpResponse.StatusCode contained unexpected value: %v", httpResponse.StatusCode)
  1519  	}
  1520  	err = httpResponse.Body.Close()
  1521  	if nil != err {
  1522  		t.Fatalf("http.Response.Body.Close() returned unexpected error: %v", err)
  1523  	}
  1524  
  1525  	err = Stop()
  1526  	if nil != err {
  1527  		t.Fatalf("Stop() returned unexpected error: %v", err)
  1528  	}
  1529  }