github.com/Ingenico-ePayments/connect-sdk-go@v0.0.0-20240318153750-1f8cd329b9c9/Client_Logging_test.go (about)

     1  package connectsdk
     2  
     3  import (
     4  	"math/rand"
     5  	"net"
     6  	"net/http"
     7  	"net/url"
     8  	"strconv"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/Ingenico-ePayments/connect-sdk-go/domain/definitions"
    14  	"github.com/Ingenico-ePayments/connect-sdk-go/domain/payment"
    15  	sdkErrors "github.com/Ingenico-ePayments/connect-sdk-go/errors"
    16  	"github.com/Ingenico-ePayments/connect-sdk-go/logging"
    17  	"github.com/Ingenico-ePayments/connect-sdk-go/merchant/services"
    18  	"github.com/Ingenico-ePayments/connect-sdk-go/merchant/tokens"
    19  )
    20  
    21  var testConnectionJSON = `{
    22  	"result": "OK"
    23  }`
    24  
    25  var convertAmountJSON = `{
    26  	"convertedAmount": 4547504
    27  }`
    28  
    29  var createPaymentUnicodeJSON = `{
    30      "creationOutput": {
    31          "additionalReference": "00000012341000059598",
    32          "externalReference": "000000123410000595980000100001"
    33      },
    34      "payment": {
    35          "id": "000000123410000595980000100001",
    36          "paymentOutput": {
    37              "amountOfMoney": {
    38                  "amount": 2345,
    39                  "currencyCode": "CAD"
    40              },
    41              "references": {
    42                  "paymentReference": "0"
    43              },
    44              "paymentMethod": "redirect",
    45              "redirectPaymentMethodSpecificOutput":{
    46                 "paymentProductId":840,
    47                 "paymentProduct840SpecificOutput":{
    48                    "customerAccount":{
    49                       "firstName":"Theresa",
    50                       "surname":"Schröder"
    51                    },
    52                    "customerAddress":{
    53                       "city":"sittensen",
    54                       "countryCode":"DE",
    55                       "street":"Westerberg 25",
    56                       "zip":"27419"
    57                    }
    58                 }
    59              }
    60          },
    61          "status": "PENDING_APPROVAL",
    62          "statusOutput": {
    63              "isCancellable": true,
    64              "statusCategory": "PENDING_MERCHANT",
    65              "statusCode": 600,
    66              "statusCodeChangeDateTime": "20160310094054",
    67              "isAuthorized": true
    68          }
    69      }
    70  }
    71  `
    72  
    73  var createPaymentJSON = `{
    74  	"creationOutput": {
    75  		"additionalReference": "00000012341000059598",
    76  		"externalReference": "000000123410000595980000100001"
    77  	},
    78  	"payment": {
    79  		"id": "000000123410000595980000100001",
    80  		"paymentOutput": {
    81  			"amountOfMoney": {
    82  				"amount": 2345,
    83  				"currencyCode": "CAD"
    84  			},
    85  			"references": {
    86  				"paymentReference": "0"
    87  			},
    88  			"paymentMethod": "card",
    89  			"cardPaymentMethodSpecificOutput": {
    90  				"paymentProductId": 1,
    91  				"authorisationCode": "OK1131",
    92  				"card": {
    93  					"cardNumber": "************3456",
    94  					"expiryDate": "1220"
    95  				},
    96  				"fraudResults": {
    97  					"fraudServiceResult": "error",
    98  					"avsResult": "X",
    99  					"cvvResult": "M"
   100  				}
   101  			}
   102  		},
   103  		"status": "PENDING_APPROVAL",
   104  		"statusOutput": {
   105  			"isCancellable": true,
   106  			"statusCategory": "PENDING_MERCHANT",
   107  			"statusCode": 600,
   108  			"statusCodeChangeDateTime": "20160310094054",
   109  			"isAuthorized": true
   110  		}
   111  	}
   112  }`
   113  
   114  var createPaymentFailedInvalidCardNumberJSON = `{
   115  	"errorId": "0953f236-9e54-4f23-9556-d66bc757dda8",
   116  	"errors": [{
   117  		"code": "21000020",
   118  		"requestId": "24146",
   119  		"message": "VALUE **************** OF FIELD CREDITCARDNUMBER DID NOT PASS THE LUHNCHECK",
   120  		"httpStatusCode": 400
   121  	}]
   122  }`
   123  
   124  var createPaymentFailedRejectedJSON = `{
   125  	"errorId": "833dfd83-52ae-419c-b871-9df1278da93e",
   126  	"errors": [{
   127  		"code": "430330",
   128  		"message": "Not authorised",
   129  		"httpStatusCode": 402
   130  	}],
   131  	"paymentResult": {
   132  		"creationOutput": {
   133  			"additionalReference": "00000200001000059614",
   134  			"externalReference": "000002000010000596140000100001"
   135  		},
   136  		"payment": {
   137  			"id": "000002000010000596140000100001",
   138  			"paymentOutput": {
   139  				"amountOfMoney": {
   140  					"amount": 2345,
   141  					"currencyCode": "CAD"
   142  				},
   143  				"references": {
   144  					"paymentReference": "0"
   145  				},
   146  				"paymentMethod": "card",
   147  				"cardPaymentMethodSpecificOutput": {
   148  					"paymentProductId": 1
   149  				}
   150  			},
   151  			"status": "REJECTED",
   152  			"statusOutput": {
   153  				"errors": [{
   154  					"code": "430330",
   155  					"requestId": "24162",
   156  					"message": "Not authorised",
   157  					"httpStatusCode": 402
   158  				}],
   159  				"isCancellable": false,
   160  				"statusCategory": "UNSUCCESSFUL",
   161  				"statusCode": 100,
   162  				"statusCodeChangeDateTime": "20160310121151",
   163  				"isAuthorized": false
   164  			}
   165  		}
   166  	}
   167  }`
   168  
   169  var unknownServerErrorJSON = `{
   170  	"errorId": "fbff1179-7ba4-4894-9021-d8a0011d23a7",
   171  	"errors": [{
   172  		"code": "9999",
   173  		"message": "UNKNOWN_SERVER_ERROR",
   174  		"httpStatusCode": 500
   175  	}]
   176  }`
   177  
   178  var notFoundErrorHTML = `Not Found`
   179  
   180  func TestLoggingTestConnection(t *testing.T) {
   181  	logPrefix := "TestLoggingTestConnection"
   182  
   183  	responseHeaders := map[string]string{
   184  		"Content-Type": "application/json",
   185  		"Dummy":        "dummy",
   186  	}
   187  	requestHeaders := map[string][]string{}
   188  
   189  	listener, sl, client, err := createTestEnvironment(
   190  		"/v1/1234/services/testconnection",
   191  		createRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders))
   192  	if err != nil {
   193  		t.Fatalf("%v: %v", logPrefix, err)
   194  	}
   195  	defer listener.Close()
   196  	defer sl.Close()
   197  	defer client.Close()
   198  
   199  	logger := &testLogger{}
   200  	client.EnableLogging(logger)
   201  
   202  	response, err := client.Merchant("1234").Services().Testconnection(nil)
   203  	if err != nil {
   204  		t.Fatalf("%v: %v", logPrefix, err)
   205  	}
   206  
   207  	if response.Result != nil && *response.Result != "OK" {
   208  		t.Fatalf("%v: responseResult %v", logPrefix, response.Result)
   209  	}
   210  
   211  	if len(logger.entries) != 2 {
   212  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
   213  	}
   214  
   215  	firstEntry := logger.entries[0]
   216  	if firstEntry.request == nil {
   217  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
   218  	}
   219  	if firstEntry.request.Method() != "GET" {
   220  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
   221  	}
   222  	if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" {
   223  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
   224  	}
   225  	if firstEntry.request.Headers() == nil {
   226  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
   227  	}
   228  	foundDate, foundMetainfo := false, false
   229  	for k, v := range firstEntry.request.Headers() {
   230  		switch k {
   231  		case "Authorization":
   232  			{
   233  				if v[0] != "********" {
   234  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
   235  				}
   236  
   237  				break
   238  			}
   239  		case "Date":
   240  			{
   241  				foundDate = true
   242  
   243  				break
   244  			}
   245  		case "X-GCS-ServerMetaInfo":
   246  			{
   247  				foundMetainfo = true
   248  
   249  				break
   250  			}
   251  		}
   252  	}
   253  	if !foundDate {
   254  		t.Fatalf("%v: date header not found", logPrefix)
   255  	}
   256  	if !foundMetainfo {
   257  		t.Fatalf("%v: meta info header not found", logPrefix)
   258  	}
   259  	if firstEntry.err != nil {
   260  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
   261  	}
   262  
   263  	secondEntry := logger.entries[1]
   264  	if secondEntry.response == nil {
   265  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
   266  	}
   267  	if secondEntry.response.StatusCode() != http.StatusOK {
   268  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
   269  	}
   270  	if secondEntry.response.ContentType() != "application/json" {
   271  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
   272  	}
   273  	if secondEntry.response.Headers() == nil {
   274  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
   275  	}
   276  	if secondEntry.response.Body() == "" {
   277  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body())
   278  	}
   279  	foundDate, foundDummy := false, false
   280  	for k := range secondEntry.response.Headers() {
   281  		switch k {
   282  		case "Date":
   283  			{
   284  				foundDate = true
   285  
   286  				break
   287  			}
   288  		case "Dummy":
   289  			{
   290  				foundDummy = true
   291  
   292  				break
   293  			}
   294  		}
   295  	}
   296  	if !foundDate {
   297  		t.Fatalf("%v: date header not found", logPrefix)
   298  	}
   299  	if !foundDummy {
   300  		t.Fatalf("%v: dummy header not found", logPrefix)
   301  	}
   302  	if secondEntry.err != nil {
   303  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
   304  	}
   305  }
   306  
   307  func TestLoggingConvertAmount(t *testing.T) {
   308  	logPrefix := "TestLoggingConvertAmount"
   309  
   310  	responseHeaders := map[string]string{
   311  		"Content-Type": "application/json",
   312  		"Dummy":        "dummy",
   313  	}
   314  	requestHeaders := map[string][]string{}
   315  
   316  	listener, sl, client, err := createTestEnvironment(
   317  		"/v1/1234/services/convert/amount",
   318  		createRecordRequest(http.StatusOK, convertAmountJSON, responseHeaders, requestHeaders))
   319  	if err != nil {
   320  		t.Fatalf("%v: %v", logPrefix, err)
   321  	}
   322  	defer listener.Close()
   323  	defer sl.Close()
   324  	defer client.Close()
   325  
   326  	logger := &testLogger{}
   327  	client.EnableLogging(logger)
   328  
   329  	var query services.ConvertAmountParams
   330  	amount := int64(1000)
   331  	query.Amount = &amount
   332  	source := "EUR"
   333  	query.Source = &source
   334  	target := "USD"
   335  	query.Target = &target
   336  
   337  	response, err := client.Merchant("1234").Services().ConvertAmount(query, nil)
   338  	if err != nil {
   339  		t.Fatalf("%v: %v", logPrefix, err)
   340  	}
   341  
   342  	if response.ConvertedAmount == nil {
   343  		t.Fatalf("%v: responseResult %v", logPrefix, response.ConvertedAmount)
   344  	}
   345  
   346  	if len(logger.entries) != 2 {
   347  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
   348  	}
   349  
   350  	firstEntry := logger.entries[0]
   351  	if firstEntry.request == nil {
   352  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
   353  	}
   354  	if firstEntry.request.Method() != "GET" {
   355  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
   356  	}
   357  	if firstEntry.request.URL().Path != "/v1/1234/services/convert/amount" {
   358  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
   359  	}
   360  	if firstEntry.request.Headers() == nil {
   361  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
   362  	}
   363  	if firstEntry.request.Body() != "" {
   364  		t.Fatalf("%v: firstEntryRequestBody %v", logPrefix, firstEntry.request.Body())
   365  	}
   366  	foundDate, foundMetainfo := false, false
   367  	for k, v := range firstEntry.request.Headers() {
   368  		switch k {
   369  		case "Authorization":
   370  			{
   371  				if v[0] != "********" {
   372  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
   373  				}
   374  
   375  				break
   376  			}
   377  		case "Date":
   378  			{
   379  				foundDate = true
   380  
   381  				break
   382  			}
   383  		case "X-GCS-ServerMetaInfo":
   384  			{
   385  				foundMetainfo = true
   386  
   387  				break
   388  			}
   389  		}
   390  	}
   391  	if !foundDate {
   392  		t.Fatalf("%v: date header not found", logPrefix)
   393  	}
   394  	if !foundMetainfo {
   395  		t.Fatalf("%v: meta info header not found", logPrefix)
   396  	}
   397  	if firstEntry.err != nil {
   398  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
   399  	}
   400  
   401  	secondEntry := logger.entries[1]
   402  	if secondEntry.response == nil {
   403  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
   404  	}
   405  	if secondEntry.response.StatusCode() != http.StatusOK {
   406  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
   407  	}
   408  	if secondEntry.response.ContentType() != "application/json" {
   409  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
   410  	}
   411  	if secondEntry.response.Headers() == nil {
   412  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
   413  	}
   414  	if secondEntry.response.Body() == "" {
   415  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body())
   416  	}
   417  	foundDate, foundDummy := false, false
   418  	for k := range secondEntry.response.Headers() {
   419  		switch k {
   420  		case "Date":
   421  			{
   422  				foundDate = true
   423  
   424  				break
   425  			}
   426  		case "Dummy":
   427  			{
   428  				foundDummy = true
   429  
   430  				break
   431  			}
   432  		}
   433  	}
   434  	if !foundDate {
   435  		t.Fatalf("%v: date header not found", logPrefix)
   436  	}
   437  	if !foundDummy {
   438  		t.Fatalf("%v: dummy header not found", logPrefix)
   439  	}
   440  	if secondEntry.err != nil {
   441  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
   442  	}
   443  }
   444  
   445  func TestDeleteToken(t *testing.T) {
   446  	logPrefix := "TestDeleteToken"
   447  
   448  	responseHeaders := map[string]string{
   449  		"Content-Type": "application/json",
   450  		"Dummy":        "dummy",
   451  	}
   452  	requestHeaders := map[string][]string{}
   453  
   454  	listener, sl, client, err := createTestEnvironment(
   455  		"/v1/1234/tokens/5678",
   456  		createRecordRequest(http.StatusNoContent, "", responseHeaders, requestHeaders))
   457  	if err != nil {
   458  		t.Fatalf("%v: %v", logPrefix, err)
   459  	}
   460  	defer listener.Close()
   461  	defer sl.Close()
   462  	defer client.Close()
   463  
   464  	logger := &testLogger{}
   465  	client.EnableLogging(logger)
   466  
   467  	var query tokens.DeleteParams
   468  
   469  	err = client.Merchant("1234").Tokens().Delete("5678", query, nil)
   470  	if err != nil {
   471  		t.Fatalf("%v: %v", logPrefix, err)
   472  	}
   473  
   474  	if len(logger.entries) != 2 {
   475  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
   476  	}
   477  
   478  	firstEntry := logger.entries[0]
   479  	if firstEntry.request == nil {
   480  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
   481  	}
   482  	if firstEntry.request.Method() != "DELETE" {
   483  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
   484  	}
   485  	if firstEntry.request.URL().Path != "/v1/1234/tokens/5678" {
   486  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
   487  	}
   488  	if firstEntry.request.Headers() == nil {
   489  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
   490  	}
   491  	if firstEntry.request.Body() != "" {
   492  		t.Fatalf("%v: firstEntryRequestBody %v", logPrefix, firstEntry.request.Body())
   493  	}
   494  	foundDate, foundMetainfo := false, false
   495  	for k, v := range firstEntry.request.Headers() {
   496  		switch k {
   497  		case "Authorization":
   498  			{
   499  				if v[0] != "********" {
   500  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
   501  				}
   502  
   503  				break
   504  			}
   505  		case "Date":
   506  			{
   507  				foundDate = true
   508  
   509  				break
   510  			}
   511  		case "X-GCS-ServerMetaInfo":
   512  			{
   513  				foundMetainfo = true
   514  
   515  				break
   516  			}
   517  		}
   518  	}
   519  	if !foundDate {
   520  		t.Fatalf("%v: date header not found", logPrefix)
   521  	}
   522  	if !foundMetainfo {
   523  		t.Fatalf("%v: meta info header not found", logPrefix)
   524  	}
   525  	if firstEntry.err != nil {
   526  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
   527  	}
   528  
   529  	secondEntry := logger.entries[1]
   530  	if secondEntry.response == nil {
   531  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
   532  	}
   533  	if secondEntry.response.StatusCode() != http.StatusNoContent {
   534  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
   535  	}
   536  	if secondEntry.response.ContentType() != "application/json" {
   537  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
   538  	}
   539  	if secondEntry.response.Headers() == nil {
   540  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
   541  	}
   542  	if secondEntry.response.Body() != "" {
   543  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body())
   544  	}
   545  	foundDate, foundDummy := false, false
   546  	for k := range secondEntry.response.Headers() {
   547  		switch k {
   548  		case "Date":
   549  			{
   550  				foundDate = true
   551  
   552  				break
   553  			}
   554  		case "Dummy":
   555  			{
   556  				foundDummy = true
   557  
   558  				break
   559  			}
   560  		}
   561  	}
   562  	if !foundDate {
   563  		t.Fatalf("%v: date header not found", logPrefix)
   564  	}
   565  	if !foundDummy {
   566  		t.Fatalf("%v: dummy header not found", logPrefix)
   567  	}
   568  	if secondEntry.err != nil {
   569  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
   570  	}
   571  }
   572  
   573  func TestLoggingCreatePaymentUnicode(t *testing.T) {
   574  	logPrefix := "TestLoggingCreatePayment"
   575  
   576  	responseHeaders := map[string]string{
   577  		"Content-Type": "application/json",
   578  		"Dummy":        "dummy",
   579  		"Location":     "http://localhost/v1/1234/payments/000000123410000595980000100001",
   580  	}
   581  	requestHeaders := map[string][]string{}
   582  
   583  	listener, sl, client, err := createTestEnvironment(
   584  		"/v1/1234/payments",
   585  		createRecordRequest(http.StatusCreated, createPaymentUnicodeJSON, responseHeaders, requestHeaders))
   586  	if err != nil {
   587  		t.Fatalf("%v: %v", logPrefix, err)
   588  	}
   589  	defer listener.Close()
   590  	defer sl.Close()
   591  	defer client.Close()
   592  
   593  	logger := &testLogger{}
   594  	client.EnableLogging(logger)
   595  
   596  	var card definitions.Card
   597  	card.CardNumber = newString("1234567890123456")
   598  	card.Cvv = newString("123")
   599  	card.ExpiryDate = newString("1220")
   600  
   601  	var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput
   602  	cardPaymentMethodSpecificInput.Card = &card
   603  	cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1)
   604  
   605  	var amountOfMoney definitions.AmountOfMoney
   606  	amountOfMoney.Amount = newInt64(2345)
   607  	amountOfMoney.CurrencyCode = newString("CAD")
   608  
   609  	var billingAddress definitions.Address
   610  	billingAddress.CountryCode = newString("CA")
   611  
   612  	var customer payment.Customer
   613  	customer.BillingAddress = &billingAddress
   614  
   615  	var order payment.Order
   616  	order.AmountOfMoney = &amountOfMoney
   617  	order.Customer = &customer
   618  
   619  	var reqBody payment.CreateRequest
   620  	reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput
   621  	reqBody.Order = &order
   622  
   623  	response, err := client.Merchant("1234").Payments().Create(reqBody, nil)
   624  	if err != nil {
   625  		t.Fatalf("%v: %v", logPrefix, err)
   626  	}
   627  
   628  	if len(logger.entries) != 2 {
   629  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
   630  	}
   631  
   632  	if response.Payment == nil {
   633  		t.Fatalf("%v: responsePayment nil", logPrefix)
   634  	}
   635  	if response.Payment.ID == nil {
   636  		t.Fatalf("%v: responsePaymentID nil", logPrefix)
   637  	}
   638  
   639  	firstEntry := logger.entries[0]
   640  	if firstEntry.request == nil {
   641  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
   642  	}
   643  	if firstEntry.request.Method() != "POST" {
   644  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
   645  	}
   646  	if firstEntry.request.URL().Path != "/v1/1234/payments" {
   647  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
   648  	}
   649  	if firstEntry.request.Headers() == nil {
   650  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
   651  	}
   652  	foundDate, foundMetainfo := false, false
   653  	for k, v := range firstEntry.request.Headers() {
   654  		switch k {
   655  		case "Authorization":
   656  			{
   657  				if v[0] != "********" {
   658  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
   659  				}
   660  
   661  				break
   662  			}
   663  		case "Date":
   664  			{
   665  				foundDate = true
   666  
   667  				break
   668  			}
   669  		case "X-GCS-ServerMetaInfo":
   670  			{
   671  				foundMetainfo = true
   672  
   673  				break
   674  			}
   675  		}
   676  	}
   677  	if !foundDate {
   678  		t.Fatalf("%v: date header not found", logPrefix)
   679  	}
   680  	if !foundMetainfo {
   681  		t.Fatalf("%v: meta info header not found", logPrefix)
   682  	}
   683  	if firstEntry.err != nil {
   684  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
   685  	}
   686  
   687  	secondEntry := logger.entries[1]
   688  	if !strings.Contains(secondEntry.response.Body(), "Schröder") {
   689  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
   690  	}
   691  	if secondEntry.response == nil {
   692  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
   693  	}
   694  	if secondEntry.response.StatusCode() != http.StatusCreated {
   695  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
   696  	}
   697  	if secondEntry.response.ContentType() != "application/json" {
   698  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
   699  	}
   700  	if secondEntry.response.Headers() == nil {
   701  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
   702  	}
   703  	if secondEntry.response.Body() == "" {
   704  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body())
   705  	}
   706  
   707  	foundDate, foundDummy := false, false
   708  	for k := range secondEntry.response.Headers() {
   709  		switch k {
   710  		case "Date":
   711  			{
   712  				foundDate = true
   713  
   714  				break
   715  			}
   716  		case "Dummy":
   717  			{
   718  				foundDummy = true
   719  
   720  				break
   721  			}
   722  		}
   723  	}
   724  	if !foundDate {
   725  		t.Fatalf("%v: date header not found", logPrefix)
   726  	}
   727  	if !foundDummy {
   728  		t.Fatalf("%v: dummy header not found", logPrefix)
   729  	}
   730  	if secondEntry.err != nil {
   731  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
   732  	}
   733  }
   734  func TestLoggingCreatePayment(t *testing.T) {
   735  	logPrefix := "TestLoggingCreatePayment"
   736  
   737  	responseHeaders := map[string]string{
   738  		"Content-Type": "application/json",
   739  		"Dummy":        "dummy",
   740  		"Location":     "http://localhost/v1/1234/payments/000000123410000595980000100001",
   741  	}
   742  	requestHeaders := map[string][]string{}
   743  
   744  	listener, sl, client, err := createTestEnvironment(
   745  		"/v1/1234/payments",
   746  		createRecordRequest(http.StatusCreated, createPaymentJSON, responseHeaders, requestHeaders))
   747  	if err != nil {
   748  		t.Fatalf("%v: %v", logPrefix, err)
   749  	}
   750  	defer listener.Close()
   751  	defer sl.Close()
   752  	defer client.Close()
   753  
   754  	logger := &testLogger{}
   755  	client.EnableLogging(logger)
   756  
   757  	var card definitions.Card
   758  	card.CardNumber = newString("1234567890123456")
   759  	card.Cvv = newString("123")
   760  	card.ExpiryDate = newString("1220")
   761  
   762  	var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput
   763  	cardPaymentMethodSpecificInput.Card = &card
   764  	cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1)
   765  
   766  	var amountOfMoney definitions.AmountOfMoney
   767  	amountOfMoney.Amount = newInt64(2345)
   768  	amountOfMoney.CurrencyCode = newString("CAD")
   769  
   770  	var billingAddress definitions.Address
   771  	billingAddress.CountryCode = newString("CA")
   772  
   773  	var customer payment.Customer
   774  	customer.BillingAddress = &billingAddress
   775  
   776  	var order payment.Order
   777  	order.AmountOfMoney = &amountOfMoney
   778  	order.Customer = &customer
   779  
   780  	var reqBody payment.CreateRequest
   781  	reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput
   782  	reqBody.Order = &order
   783  
   784  	response, err := client.Merchant("1234").Payments().Create(reqBody, nil)
   785  	if err != nil {
   786  		t.Fatalf("%v: %v", logPrefix, err)
   787  	}
   788  
   789  	if len(logger.entries) != 2 {
   790  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
   791  	}
   792  
   793  	if response.Payment == nil {
   794  		t.Fatalf("%v: responsePayment nil", logPrefix)
   795  	}
   796  	if response.Payment.ID == nil {
   797  		t.Fatalf("%v: responsePaymentID nil", logPrefix)
   798  	}
   799  
   800  	firstEntry := logger.entries[0]
   801  	if firstEntry.request == nil {
   802  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
   803  	}
   804  	if firstEntry.request.Method() != "POST" {
   805  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
   806  	}
   807  	if firstEntry.request.URL().Path != "/v1/1234/payments" {
   808  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
   809  	}
   810  	if firstEntry.request.Headers() == nil {
   811  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
   812  	}
   813  	foundDate, foundMetainfo := false, false
   814  	for k, v := range firstEntry.request.Headers() {
   815  		switch k {
   816  		case "Authorization":
   817  			{
   818  				if v[0] != "********" {
   819  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
   820  				}
   821  
   822  				break
   823  			}
   824  		case "Date":
   825  			{
   826  				foundDate = true
   827  
   828  				break
   829  			}
   830  		case "X-GCS-ServerMetaInfo":
   831  			{
   832  				foundMetainfo = true
   833  
   834  				break
   835  			}
   836  		}
   837  	}
   838  	if !foundDate {
   839  		t.Fatalf("%v: date header not found", logPrefix)
   840  	}
   841  	if !foundMetainfo {
   842  		t.Fatalf("%v: meta info header not found", logPrefix)
   843  	}
   844  	if firstEntry.err != nil {
   845  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
   846  	}
   847  
   848  	secondEntry := logger.entries[1]
   849  	if secondEntry.response == nil {
   850  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
   851  	}
   852  	if secondEntry.response.StatusCode() != http.StatusCreated {
   853  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
   854  	}
   855  	if secondEntry.response.ContentType() != "application/json" {
   856  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
   857  	}
   858  	if secondEntry.response.Headers() == nil {
   859  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
   860  	}
   861  	if secondEntry.response.Body() == "" {
   862  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body())
   863  	}
   864  
   865  	foundDate, foundDummy := false, false
   866  	for k := range secondEntry.response.Headers() {
   867  		switch k {
   868  		case "Date":
   869  			{
   870  				foundDate = true
   871  
   872  				break
   873  			}
   874  		case "Dummy":
   875  			{
   876  				foundDummy = true
   877  
   878  				break
   879  			}
   880  		}
   881  	}
   882  	if !foundDate {
   883  		t.Fatalf("%v: date header not found", logPrefix)
   884  	}
   885  	if !foundDummy {
   886  		t.Fatalf("%v: dummy header not found", logPrefix)
   887  	}
   888  	if secondEntry.err != nil {
   889  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
   890  	}
   891  }
   892  
   893  func TestCreatePaymentInvalidCardNumber(t *testing.T) {
   894  	logPrefix := "TestCreatePaymentInvalidCardNumber"
   895  
   896  	responseHeaders := map[string]string{
   897  		"Content-Type": "application/json",
   898  		"Dummy":        "dummy",
   899  	}
   900  	requestHeaders := map[string][]string{}
   901  
   902  	listener, sl, client, err := createTestEnvironment(
   903  		"/v1/1234/payments",
   904  		createRecordRequest(http.StatusBadRequest, createPaymentFailedInvalidCardNumberJSON, responseHeaders, requestHeaders))
   905  	if err != nil {
   906  		t.Fatalf("%v: %v", logPrefix, err)
   907  	}
   908  	defer listener.Close()
   909  	defer sl.Close()
   910  	defer client.Close()
   911  
   912  	logger := &testLogger{}
   913  	client.EnableLogging(logger)
   914  
   915  	var card definitions.Card
   916  	card.CardNumber = newString("1234567890123456")
   917  	card.Cvv = newString("123")
   918  	card.ExpiryDate = newString("1220")
   919  
   920  	var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput
   921  	cardPaymentMethodSpecificInput.Card = &card
   922  	cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1)
   923  
   924  	var amountOfMoney definitions.AmountOfMoney
   925  	amountOfMoney.Amount = newInt64(2345)
   926  	amountOfMoney.CurrencyCode = newString("CAD")
   927  
   928  	var billingAddress definitions.Address
   929  	billingAddress.CountryCode = newString("CA")
   930  
   931  	var customer payment.Customer
   932  	customer.BillingAddress = &billingAddress
   933  
   934  	var order payment.Order
   935  	order.AmountOfMoney = &amountOfMoney
   936  	order.Customer = &customer
   937  
   938  	var reqBody payment.CreateRequest
   939  	reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput
   940  	reqBody.Order = &order
   941  
   942  	_, err = client.Merchant("1234").Payments().Create(reqBody, nil)
   943  	switch ce := err.(type) {
   944  	case *sdkErrors.ValidateError:
   945  		{
   946  			if ce.StatusCode() != http.StatusBadRequest {
   947  				t.Fatalf("%v: statusCode %v", logPrefix, ce.StatusCode())
   948  			}
   949  			if ce.ResponseBody() != createPaymentFailedInvalidCardNumberJSON {
   950  				t.Fatalf("%v: responseBody %v", logPrefix, ce.ResponseBody())
   951  			}
   952  
   953  			break
   954  		}
   955  	default:
   956  		{
   957  			t.Fatalf("%v: %v", logPrefix, err)
   958  
   959  			break
   960  		}
   961  	}
   962  
   963  	if len(logger.entries) != 2 {
   964  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
   965  	}
   966  
   967  	firstEntry := logger.entries[0]
   968  	if firstEntry.request == nil {
   969  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
   970  	}
   971  	if firstEntry.request.Method() != "POST" {
   972  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
   973  	}
   974  	if firstEntry.request.URL().Path != "/v1/1234/payments" {
   975  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
   976  	}
   977  	if firstEntry.request.Headers() == nil {
   978  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
   979  	}
   980  	foundDate, foundMetainfo := false, false
   981  	for k, v := range firstEntry.request.Headers() {
   982  		switch k {
   983  		case "Authorization":
   984  			{
   985  				if v[0] != "********" {
   986  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
   987  				}
   988  
   989  				break
   990  			}
   991  		case "Date":
   992  			{
   993  				foundDate = true
   994  
   995  				break
   996  			}
   997  		case "X-GCS-ServerMetaInfo":
   998  			{
   999  				foundMetainfo = true
  1000  
  1001  				break
  1002  			}
  1003  		}
  1004  	}
  1005  	if !foundDate {
  1006  		t.Fatalf("%v: date header not found", logPrefix)
  1007  	}
  1008  	if !foundMetainfo {
  1009  		t.Fatalf("%v: meta info header not found", logPrefix)
  1010  	}
  1011  	if firstEntry.err != nil {
  1012  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
  1013  	}
  1014  
  1015  	secondEntry := logger.entries[1]
  1016  	if secondEntry.response == nil {
  1017  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
  1018  	}
  1019  	if secondEntry.response.StatusCode() != http.StatusBadRequest {
  1020  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
  1021  	}
  1022  	if secondEntry.response.ContentType() != "application/json" {
  1023  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
  1024  	}
  1025  	if secondEntry.response.Headers() == nil {
  1026  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
  1027  	}
  1028  	foundDate, foundDummy := false, false
  1029  	for k := range secondEntry.response.Headers() {
  1030  		switch k {
  1031  		case "Date":
  1032  			{
  1033  				foundDate = true
  1034  
  1035  				break
  1036  			}
  1037  		case "Dummy":
  1038  			{
  1039  				foundDummy = true
  1040  
  1041  				break
  1042  			}
  1043  		}
  1044  	}
  1045  	if !foundDate {
  1046  		t.Fatalf("%v: date header not found", logPrefix)
  1047  	}
  1048  	if !foundDummy {
  1049  		t.Fatalf("%v: dummy header not found", logPrefix)
  1050  	}
  1051  	if secondEntry.err != nil {
  1052  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
  1053  	}
  1054  }
  1055  
  1056  func TestCreatePaymentRejected(t *testing.T) {
  1057  	logPrefix := "TestCreatePaymentRejected"
  1058  
  1059  	responseHeaders := map[string]string{
  1060  		"Content-Type": "application/json",
  1061  		"Dummy":        "dummy",
  1062  	}
  1063  	requestHeaders := map[string][]string{}
  1064  
  1065  	listener, sl, client, err := createTestEnvironment(
  1066  		"/v1/1234/payments",
  1067  		createRecordRequest(http.StatusPaymentRequired, createPaymentFailedRejectedJSON, responseHeaders, requestHeaders))
  1068  	if err != nil {
  1069  		t.Fatalf("%v: %v", logPrefix, err)
  1070  	}
  1071  	defer listener.Close()
  1072  	defer sl.Close()
  1073  	defer client.Close()
  1074  
  1075  	logger := &testLogger{}
  1076  	client.EnableLogging(logger)
  1077  
  1078  	var card definitions.Card
  1079  	card.CardNumber = newString("1234567890123456")
  1080  	card.Cvv = newString("123")
  1081  	card.ExpiryDate = newString("1220")
  1082  
  1083  	var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput
  1084  	cardPaymentMethodSpecificInput.Card = &card
  1085  	cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1)
  1086  
  1087  	var amountOfMoney definitions.AmountOfMoney
  1088  	amountOfMoney.Amount = newInt64(2345)
  1089  	amountOfMoney.CurrencyCode = newString("CAD")
  1090  
  1091  	var billingAddress definitions.Address
  1092  	billingAddress.CountryCode = newString("CA")
  1093  
  1094  	var customer payment.Customer
  1095  	customer.BillingAddress = &billingAddress
  1096  
  1097  	var order payment.Order
  1098  	order.AmountOfMoney = &amountOfMoney
  1099  	order.Customer = &customer
  1100  
  1101  	var reqBody payment.CreateRequest
  1102  	reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput
  1103  	reqBody.Order = &order
  1104  
  1105  	_, err = client.Merchant("1234").Payments().Create(reqBody, nil)
  1106  	switch ce := err.(type) {
  1107  	case *sdkErrors.DeclinedPaymentError:
  1108  		{
  1109  			if ce.StatusCode() != http.StatusPaymentRequired {
  1110  				t.Fatalf("%v: statusCode %v", logPrefix, ce.StatusCode())
  1111  			}
  1112  			if ce.ResponseBody() != createPaymentFailedRejectedJSON {
  1113  				t.Fatalf("%v: responseBody %v", logPrefix, ce.ResponseBody())
  1114  			}
  1115  
  1116  			break
  1117  		}
  1118  	default:
  1119  		{
  1120  			t.Fatalf("%v: %v", logPrefix, err)
  1121  
  1122  			break
  1123  		}
  1124  	}
  1125  
  1126  	if len(logger.entries) != 2 {
  1127  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
  1128  	}
  1129  
  1130  	firstEntry := logger.entries[0]
  1131  	if firstEntry.request == nil {
  1132  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
  1133  	}
  1134  	if firstEntry.request.Method() != "POST" {
  1135  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
  1136  	}
  1137  	if firstEntry.request.URL().Path != "/v1/1234/payments" {
  1138  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
  1139  	}
  1140  	if firstEntry.request.Headers() == nil {
  1141  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
  1142  	}
  1143  	foundDate, foundMetainfo := false, false
  1144  	for k, v := range firstEntry.request.Headers() {
  1145  		switch k {
  1146  		case "Authorization":
  1147  			{
  1148  				if v[0] != "********" {
  1149  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
  1150  				}
  1151  
  1152  				break
  1153  			}
  1154  		case "Date":
  1155  			{
  1156  				foundDate = true
  1157  
  1158  				break
  1159  			}
  1160  		case "X-GCS-ServerMetaInfo":
  1161  			{
  1162  				foundMetainfo = true
  1163  
  1164  				break
  1165  			}
  1166  		}
  1167  	}
  1168  	if !foundDate {
  1169  		t.Fatalf("%v: date header not found", logPrefix)
  1170  	}
  1171  	if !foundMetainfo {
  1172  		t.Fatalf("%v: meta info header not found", logPrefix)
  1173  	}
  1174  	if firstEntry.err != nil {
  1175  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
  1176  	}
  1177  
  1178  	secondEntry := logger.entries[1]
  1179  	if secondEntry.response == nil {
  1180  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
  1181  	}
  1182  	if secondEntry.response.StatusCode() != http.StatusPaymentRequired {
  1183  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
  1184  	}
  1185  	if secondEntry.response.ContentType() != "application/json" {
  1186  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
  1187  	}
  1188  	if secondEntry.response.Headers() == nil {
  1189  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
  1190  	}
  1191  	foundDate, foundDummy := false, false
  1192  	for k := range secondEntry.response.Headers() {
  1193  		switch k {
  1194  		case "Date":
  1195  			{
  1196  				foundDate = true
  1197  
  1198  				break
  1199  			}
  1200  		case "Dummy":
  1201  			{
  1202  				foundDummy = true
  1203  
  1204  				break
  1205  			}
  1206  		}
  1207  	}
  1208  	if !foundDate {
  1209  		t.Fatalf("%v: date header not found", logPrefix)
  1210  	}
  1211  	if !foundDummy {
  1212  		t.Fatalf("%v: dummy header not found", logPrefix)
  1213  	}
  1214  	if secondEntry.err != nil {
  1215  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
  1216  	}
  1217  }
  1218  
  1219  func TestLoggingUnknownServerError(t *testing.T) {
  1220  	logPrefix := "TestLoggingUnknownServerError"
  1221  
  1222  	responseHeaders := map[string]string{
  1223  		"Content-Type": "application/json",
  1224  		"Dummy":        "dummy",
  1225  	}
  1226  	requestHeaders := map[string][]string{}
  1227  
  1228  	listener, sl, client, err := createTestEnvironment(
  1229  		"/v1/1234/services/testconnection",
  1230  		createRecordRequest(http.StatusInternalServerError, unknownServerErrorJSON, responseHeaders, requestHeaders))
  1231  	if err != nil {
  1232  		t.Fatalf("%v: %v", logPrefix, err)
  1233  	}
  1234  	defer listener.Close()
  1235  	defer sl.Close()
  1236  	defer client.Close()
  1237  
  1238  	logger := &testLogger{}
  1239  	client.EnableLogging(logger)
  1240  
  1241  	_, err = client.Merchant("1234").Services().Testconnection(nil)
  1242  	switch ce := err.(type) {
  1243  	case *sdkErrors.GlobalCollectError:
  1244  		{
  1245  			if ce.StatusCode() != http.StatusInternalServerError {
  1246  				t.Fatalf("%v: statusCode %v", logPrefix, ce.StatusCode())
  1247  			}
  1248  			if ce.ResponseBody() != unknownServerErrorJSON {
  1249  				t.Fatalf("%v: responseBody %v", logPrefix, ce.ResponseBody())
  1250  			}
  1251  
  1252  			break
  1253  		}
  1254  	default:
  1255  		{
  1256  			t.Fatalf("%v: %v", logPrefix, err)
  1257  
  1258  			break
  1259  		}
  1260  	}
  1261  
  1262  	if len(logger.entries) != 2 {
  1263  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
  1264  	}
  1265  
  1266  	firstEntry := logger.entries[0]
  1267  	if firstEntry.request == nil {
  1268  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
  1269  	}
  1270  	if firstEntry.request.Method() != "GET" {
  1271  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
  1272  	}
  1273  	if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" {
  1274  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
  1275  	}
  1276  	if firstEntry.request.Headers() == nil {
  1277  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
  1278  	}
  1279  	foundDate, foundMetainfo := false, false
  1280  	for k, v := range firstEntry.request.Headers() {
  1281  		switch k {
  1282  		case "Authorization":
  1283  			{
  1284  				if v[0] != "********" {
  1285  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
  1286  				}
  1287  
  1288  				break
  1289  			}
  1290  		case "Date":
  1291  			{
  1292  				foundDate = true
  1293  
  1294  				break
  1295  			}
  1296  		case "X-GCS-ServerMetaInfo":
  1297  			{
  1298  				foundMetainfo = true
  1299  
  1300  				break
  1301  			}
  1302  		}
  1303  	}
  1304  	if !foundDate {
  1305  		t.Fatalf("%v: date header not found", logPrefix)
  1306  	}
  1307  	if !foundMetainfo {
  1308  		t.Fatalf("%v: meta info header not found", logPrefix)
  1309  	}
  1310  	if firstEntry.err != nil {
  1311  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
  1312  	}
  1313  
  1314  	secondEntry := logger.entries[1]
  1315  	if secondEntry.response == nil {
  1316  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
  1317  	}
  1318  	if secondEntry.response.StatusCode() != http.StatusInternalServerError {
  1319  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
  1320  	}
  1321  	if secondEntry.response.ContentType() != "application/json" {
  1322  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType())
  1323  	}
  1324  	if secondEntry.response.Headers() == nil {
  1325  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
  1326  	}
  1327  	if secondEntry.response.Body() == "" {
  1328  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body())
  1329  	}
  1330  	foundDate, foundDummy := false, false
  1331  	for k := range secondEntry.response.Headers() {
  1332  		switch k {
  1333  		case "Date":
  1334  			{
  1335  				foundDate = true
  1336  
  1337  				break
  1338  			}
  1339  		case "Dummy":
  1340  			{
  1341  				foundDummy = true
  1342  
  1343  				break
  1344  			}
  1345  		}
  1346  	}
  1347  	if !foundDate {
  1348  		t.Fatalf("%v: date header not found", logPrefix)
  1349  	}
  1350  	if !foundDummy {
  1351  		t.Fatalf("%v: dummy header not found", logPrefix)
  1352  	}
  1353  	if secondEntry.err != nil {
  1354  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
  1355  	}
  1356  }
  1357  
  1358  func TestNonJson(t *testing.T) {
  1359  	logPrefix := "TestNonJson"
  1360  
  1361  	responseHeaders := map[string]string{
  1362  		"Dummy": "dummy",
  1363  	}
  1364  	requestHeaders := map[string][]string{}
  1365  
  1366  	listener, sl, client, err := createTestEnvironment(
  1367  		"/v1/1234/services/testconnection",
  1368  		createRecordRequest(http.StatusNotFound, notFoundErrorHTML, responseHeaders, requestHeaders))
  1369  	if err != nil {
  1370  		t.Fatalf("%v: %v", logPrefix, err)
  1371  	}
  1372  	defer listener.Close()
  1373  	defer sl.Close()
  1374  	defer client.Close()
  1375  
  1376  	logger := &testLogger{}
  1377  	client.EnableLogging(logger)
  1378  
  1379  	_, err = client.Merchant("1234").Services().Testconnection(nil)
  1380  	switch err.(type) {
  1381  	case *sdkErrors.NotFoundError:
  1382  		{
  1383  			break
  1384  		}
  1385  	default:
  1386  		{
  1387  			t.Fatalf("%v: %v", logPrefix, err)
  1388  
  1389  			break
  1390  		}
  1391  	}
  1392  
  1393  	if len(logger.entries) != 2 {
  1394  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
  1395  	}
  1396  
  1397  	firstEntry := logger.entries[0]
  1398  	if firstEntry.request == nil {
  1399  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
  1400  	}
  1401  	if firstEntry.request.Method() != "GET" {
  1402  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
  1403  	}
  1404  	if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" {
  1405  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
  1406  	}
  1407  	if firstEntry.request.Headers() == nil {
  1408  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
  1409  	}
  1410  	foundDate, foundMetainfo := false, false
  1411  	for k, v := range firstEntry.request.Headers() {
  1412  		switch k {
  1413  		case "Authorization":
  1414  			{
  1415  				if v[0] != "********" {
  1416  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
  1417  				}
  1418  
  1419  				break
  1420  			}
  1421  		case "Date":
  1422  			{
  1423  				foundDate = true
  1424  
  1425  				break
  1426  			}
  1427  		case "X-GCS-ServerMetaInfo":
  1428  			{
  1429  				foundMetainfo = true
  1430  
  1431  				break
  1432  			}
  1433  		}
  1434  	}
  1435  	if !foundDate {
  1436  		t.Fatalf("%v: date header not found", logPrefix)
  1437  	}
  1438  	if !foundMetainfo {
  1439  		t.Fatalf("%v: meta info header not found", logPrefix)
  1440  	}
  1441  	if firstEntry.err != nil {
  1442  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
  1443  	}
  1444  
  1445  	secondEntry := logger.entries[1]
  1446  	if secondEntry.response == nil {
  1447  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response)
  1448  	}
  1449  	if secondEntry.response.StatusCode() != http.StatusNotFound {
  1450  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode())
  1451  	}
  1452  	if secondEntry.response.Headers() == nil {
  1453  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers())
  1454  	}
  1455  	if secondEntry.response.Body() == "" {
  1456  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body())
  1457  	}
  1458  	foundDate, foundDummy := false, false
  1459  	for k := range secondEntry.response.Headers() {
  1460  		switch k {
  1461  		case "Date":
  1462  			{
  1463  				foundDate = true
  1464  
  1465  				break
  1466  			}
  1467  		case "Dummy":
  1468  			{
  1469  				foundDummy = true
  1470  
  1471  				break
  1472  			}
  1473  		}
  1474  	}
  1475  	if !foundDate {
  1476  		t.Fatalf("%v: date header not found", logPrefix)
  1477  	}
  1478  	if !foundDummy {
  1479  		t.Fatalf("%v: dummy header not found", logPrefix)
  1480  	}
  1481  	if secondEntry.err != nil {
  1482  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
  1483  	}
  1484  }
  1485  
  1486  func TestReadTimeout(t *testing.T) {
  1487  	logPrefix := "TestReadTimeout"
  1488  
  1489  	responseHeaders := map[string]string{
  1490  		"Content-Type": "application/json",
  1491  		"Dummy":        "dummy",
  1492  	}
  1493  	requestHeaders := map[string][]string{}
  1494  
  1495  	listener, sl, client, err := createTimedTestEnvironment(
  1496  		"/v1/1234/services/testconnection",
  1497  		createDelayedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, 1*time.Second),
  1498  		1*time.Millisecond,
  1499  		10*time.Millisecond)
  1500  	if err != nil {
  1501  		t.Fatalf("%v: %v", logPrefix, err)
  1502  	}
  1503  	defer listener.Close()
  1504  	defer sl.Close()
  1505  	defer client.Close()
  1506  
  1507  	logger := &testLogger{}
  1508  	client.EnableLogging(logger)
  1509  
  1510  	_, err = client.Merchant("1234").Services().Testconnection(nil)
  1511  	switch ce := err.(type) {
  1512  	case *sdkErrors.CommunicationError:
  1513  		{
  1514  			internalError := ce.InternalError()
  1515  
  1516  			if uErr, ok := internalError.(*url.Error); ok && uErr.Timeout() {
  1517  				break
  1518  			}
  1519  
  1520  			t.Fatalf("%v: %v", logPrefix, internalError)
  1521  
  1522  			break
  1523  		}
  1524  	default:
  1525  		{
  1526  			t.Fatalf("%v: %v", logPrefix, err)
  1527  
  1528  			break
  1529  		}
  1530  	}
  1531  
  1532  	if len(logger.entries) != 2 {
  1533  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
  1534  	}
  1535  
  1536  	firstEntry := logger.entries[0]
  1537  	if firstEntry.request == nil {
  1538  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request)
  1539  	}
  1540  	if firstEntry.request.Method() != "GET" {
  1541  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method())
  1542  	}
  1543  	if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" {
  1544  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path)
  1545  	}
  1546  	if firstEntry.request.Headers() == nil {
  1547  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers())
  1548  	}
  1549  	foundDate, foundMetainfo := false, false
  1550  	for k, v := range firstEntry.request.Headers() {
  1551  		switch k {
  1552  		case "Authorization":
  1553  			{
  1554  				if v[0] != "********" {
  1555  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
  1556  				}
  1557  
  1558  				break
  1559  			}
  1560  		case "Date":
  1561  			{
  1562  				foundDate = true
  1563  
  1564  				break
  1565  			}
  1566  		case "X-GCS-ServerMetaInfo":
  1567  			{
  1568  				foundMetainfo = true
  1569  
  1570  				break
  1571  			}
  1572  		}
  1573  	}
  1574  	if !foundDate {
  1575  		t.Fatalf("%v: date header not found", logPrefix)
  1576  	}
  1577  	if !foundMetainfo {
  1578  		t.Fatalf("%v: meta info header not found", logPrefix)
  1579  	}
  1580  	if firstEntry.err != nil {
  1581  		t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err)
  1582  	}
  1583  
  1584  	secondEntry := logger.entries[1]
  1585  	if secondEntry.err == nil {
  1586  		t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err)
  1587  	}
  1588  }
  1589  
  1590  func TestLogRequestOnly(t *testing.T) {
  1591  	logPrefix := "TestLogRequestOnly"
  1592  
  1593  	responseHeaders := map[string]string{
  1594  		"Content-Type": "application/json",
  1595  		"Dummy":        "dummy",
  1596  	}
  1597  	requestHeaders := map[string][]string{}
  1598  
  1599  	listener, sl, client, mux, err := createEmptyTestEnvironment()
  1600  	if err != nil {
  1601  		t.Fatalf("%v: %v", logPrefix, err)
  1602  	}
  1603  	defer listener.Close()
  1604  	defer sl.Close()
  1605  	defer client.Close()
  1606  
  1607  	mux.HandleFunc("/v1/1234/services/testconnection",
  1608  		createNonLoggedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, client))
  1609  
  1610  	logger := &testLogger{}
  1611  	client.EnableLogging(logger)
  1612  
  1613  	_, err = client.Merchant("1234").Services().Testconnection(nil)
  1614  	if err != nil {
  1615  		t.Fatalf("%v: %v", logPrefix, err)
  1616  	}
  1617  
  1618  	if len(logger.entries) != 1 {
  1619  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
  1620  	}
  1621  
  1622  	requestEntry := logger.entries[0]
  1623  	if requestEntry.request == nil {
  1624  		t.Fatalf("%v: firstEntryRequest %v", logPrefix, requestEntry.request)
  1625  	}
  1626  	if requestEntry.request.Method() != "GET" {
  1627  		t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, requestEntry.request.Method())
  1628  	}
  1629  	if requestEntry.request.URL().Path != "/v1/1234/services/testconnection" {
  1630  		t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, requestEntry.request.URL().Path)
  1631  	}
  1632  	if requestEntry.request.Headers() == nil {
  1633  		t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, requestEntry.request.Headers())
  1634  	}
  1635  	foundDate, foundMetainfo := false, false
  1636  	for k, v := range requestEntry.request.Headers() {
  1637  		switch k {
  1638  		case "Authorization":
  1639  			{
  1640  				if v[0] != "********" {
  1641  					t.Fatalf("%v: authorizationHeader %v", logPrefix, v)
  1642  				}
  1643  
  1644  				break
  1645  			}
  1646  		case "Date":
  1647  			{
  1648  				foundDate = true
  1649  
  1650  				break
  1651  			}
  1652  		case "X-GCS-ServerMetaInfo":
  1653  			{
  1654  				foundMetainfo = true
  1655  
  1656  				break
  1657  			}
  1658  		}
  1659  	}
  1660  	if !foundDate {
  1661  		t.Fatalf("%v: date header not found", logPrefix)
  1662  	}
  1663  	if !foundMetainfo {
  1664  		t.Fatalf("%v: meta info header not found", logPrefix)
  1665  	}
  1666  	if requestEntry.err != nil {
  1667  		t.Fatalf("%v: firstEntryErr %v", logPrefix, requestEntry.err)
  1668  	}
  1669  }
  1670  
  1671  func TestLogResponseOnly(t *testing.T) {
  1672  	logPrefix := "TestLogResponseOnly"
  1673  
  1674  	responseHeaders := map[string]string{
  1675  		"Content-Type": "application/json",
  1676  		"Dummy":        "dummy",
  1677  	}
  1678  	requestHeaders := map[string][]string{}
  1679  
  1680  	listener, sl, client, mux, err := createEmptyTestEnvironment()
  1681  	if err != nil {
  1682  		t.Fatalf("%v: %v", logPrefix, err)
  1683  	}
  1684  	defer listener.Close()
  1685  	defer sl.Close()
  1686  	defer client.Close()
  1687  
  1688  	logger := &testLogger{}
  1689  
  1690  	mux.HandleFunc("/v1/1234/services/testconnection",
  1691  		createLoggedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, client, logger))
  1692  
  1693  	_, err = client.Merchant("1234").Services().Testconnection(nil)
  1694  	if err != nil {
  1695  		t.Fatalf("%v: %v", logPrefix, err)
  1696  	}
  1697  
  1698  	if len(logger.entries) != 1 {
  1699  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
  1700  	}
  1701  
  1702  	responseEntry := logger.entries[0]
  1703  	if responseEntry.response == nil {
  1704  		t.Fatalf("%v: secondEntryResponse %v", logPrefix, responseEntry.response)
  1705  	}
  1706  	if responseEntry.response.StatusCode() != http.StatusOK {
  1707  		t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, responseEntry.response.StatusCode())
  1708  	}
  1709  	if responseEntry.response.ContentType() != "application/json" {
  1710  		t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, responseEntry.response.ContentType())
  1711  	}
  1712  	if responseEntry.response.Headers() == nil {
  1713  		t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, responseEntry.response.Headers())
  1714  	}
  1715  	if responseEntry.response.Body() == "" {
  1716  		t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, responseEntry.response.Body())
  1717  	}
  1718  	foundDate, foundDummy := false, false
  1719  	for k := range responseEntry.response.Headers() {
  1720  		switch k {
  1721  		case "Date":
  1722  			{
  1723  				foundDate = true
  1724  
  1725  				break
  1726  			}
  1727  		case "Dummy":
  1728  			{
  1729  				foundDummy = true
  1730  
  1731  				break
  1732  			}
  1733  		}
  1734  	}
  1735  	if !foundDate {
  1736  		t.Fatalf("%v: date header not found", logPrefix)
  1737  	}
  1738  	if !foundDummy {
  1739  		t.Fatalf("%v: dummy header not found", logPrefix)
  1740  	}
  1741  	if responseEntry.err != nil {
  1742  		t.Fatalf("%v: secondEntryErr %v", logPrefix, responseEntry.err)
  1743  	}
  1744  }
  1745  
  1746  func TestLogErrorOnly(t *testing.T) {
  1747  	logPrefix := "TestLogErrorOnly"
  1748  
  1749  	responseHeaders := map[string]string{
  1750  		"Content-Type": "application/json",
  1751  		"Dummy":        "dummy",
  1752  	}
  1753  	requestHeaders := map[string][]string{}
  1754  
  1755  	listener, sl, client, mux, err := createEmptyTimedTestEnvironment(
  1756  		20*time.Millisecond,
  1757  		50*time.Millisecond)
  1758  	if err != nil {
  1759  		t.Fatalf("%v: %v", logPrefix, err)
  1760  	}
  1761  	defer listener.Close()
  1762  	defer sl.Close()
  1763  	defer client.Close()
  1764  
  1765  	logger := &testLogger{}
  1766  
  1767  	mux.HandleFunc("/v1/1234/services/testconnection",
  1768  		createLoggedDelayedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, 1*time.Second, client, logger))
  1769  
  1770  	_, err = client.Merchant("1234").Services().Testconnection(nil)
  1771  	switch ce := err.(type) {
  1772  	case *sdkErrors.CommunicationError:
  1773  		{
  1774  			internalError := ce.InternalError()
  1775  
  1776  			if uErr, ok := internalError.(*url.Error); ok && uErr.Timeout() {
  1777  				break
  1778  			}
  1779  
  1780  			t.Fatalf("%v: %v", logPrefix, internalError)
  1781  
  1782  			break
  1783  		}
  1784  	default:
  1785  		{
  1786  			t.Fatalf("%v: %v", logPrefix, err)
  1787  
  1788  			break
  1789  		}
  1790  	}
  1791  
  1792  	if len(logger.entries) != 1 {
  1793  		t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries))
  1794  	}
  1795  
  1796  	errorEntry := logger.entries[0]
  1797  	if errorEntry.err == nil {
  1798  		t.Fatalf("%v: secondEntryErr %v", logPrefix, errorEntry.err)
  1799  	}
  1800  }
  1801  
  1802  func createNonLoggedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, client *Client) func(http.ResponseWriter, *http.Request) {
  1803  	return func(rw http.ResponseWriter, r *http.Request) {
  1804  		client.DisableLogging()
  1805  
  1806  		for k, v := range r.Header {
  1807  			if k == "X-Gcs-Idempotence-Key" {
  1808  				k = "X-GCS-Idempotence-Key"
  1809  			}
  1810  
  1811  			requestHeaders[k] = v
  1812  		}
  1813  
  1814  		for k, v := range responseHeaders {
  1815  			rw.Header()[k] = []string{v}
  1816  		}
  1817  
  1818  		rw.WriteHeader(statusCode)
  1819  
  1820  		rw.Write([]byte(body))
  1821  	}
  1822  }
  1823  
  1824  func createLoggedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, client *Client, logger logging.CommunicatorLogger) func(http.ResponseWriter, *http.Request) {
  1825  	return func(rw http.ResponseWriter, r *http.Request) {
  1826  		client.EnableLogging(logger)
  1827  
  1828  		for k, v := range r.Header {
  1829  			if k == "X-Gcs-Idempotence-Key" {
  1830  				k = "X-GCS-Idempotence-Key"
  1831  			}
  1832  
  1833  			requestHeaders[k] = v
  1834  		}
  1835  
  1836  		for k, v := range responseHeaders {
  1837  			rw.Header()[k] = []string{v}
  1838  		}
  1839  
  1840  		rw.WriteHeader(statusCode)
  1841  
  1842  		rw.Write([]byte(body))
  1843  	}
  1844  }
  1845  
  1846  func createDelayedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, delay time.Duration) func(http.ResponseWriter, *http.Request) {
  1847  	return func(rw http.ResponseWriter, r *http.Request) {
  1848  		time.Sleep(delay)
  1849  
  1850  		for k, v := range r.Header {
  1851  			if k == "X-Gcs-Idempotence-Key" {
  1852  				k = "X-GCS-Idempotence-Key"
  1853  			}
  1854  
  1855  			requestHeaders[k] = v
  1856  		}
  1857  
  1858  		for k, v := range responseHeaders {
  1859  			rw.Header()[k] = []string{v}
  1860  		}
  1861  
  1862  		rw.WriteHeader(statusCode)
  1863  
  1864  		rw.Write([]byte(body))
  1865  	}
  1866  }
  1867  
  1868  func createLoggedDelayedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, delay time.Duration, client *Client, logger logging.CommunicatorLogger) func(http.ResponseWriter, *http.Request) {
  1869  	return func(rw http.ResponseWriter, r *http.Request) {
  1870  		client.EnableLogging(logger)
  1871  		time.Sleep(delay)
  1872  
  1873  		for k, v := range r.Header {
  1874  			if k == "X-Gcs-Idempotence-Key" {
  1875  				k = "X-GCS-Idempotence-Key"
  1876  			}
  1877  
  1878  			requestHeaders[k] = v
  1879  		}
  1880  
  1881  		for k, v := range responseHeaders {
  1882  			rw.Header()[k] = []string{v}
  1883  		}
  1884  
  1885  		rw.WriteHeader(statusCode)
  1886  
  1887  		rw.Write([]byte(body))
  1888  	}
  1889  }
  1890  
  1891  func createTimedTestEnvironment(path string, handleFunc http.HandlerFunc, socketTimeout, connectTimeout time.Duration) (net.Listener, *stoppableListener, *Client, error) {
  1892  	mux := http.NewServeMux()
  1893  	mux.Handle(path, handleFunc)
  1894  
  1895  	httpServer := &http.Server{
  1896  		Handler: mux,
  1897  	}
  1898  
  1899  	randomPort := (1 << 12) + rand.Intn(1<<15)
  1900  	listener, err := net.Listen("tcp", ":"+strconv.Itoa(randomPort))
  1901  	if err != nil {
  1902  		return nil, nil, nil, err
  1903  	}
  1904  
  1905  	sl, err := mockServer(httpServer, listener)
  1906  	if err != nil {
  1907  		return nil, nil, nil, err
  1908  	}
  1909  
  1910  	client, err := createClient(socketTimeout, connectTimeout, randomPort)
  1911  	if err != nil {
  1912  		return nil, nil, nil, err
  1913  	}
  1914  
  1915  	return listener, sl, client, nil
  1916  }
  1917  
  1918  func createEmptyTestEnvironment() (net.Listener, *stoppableListener, *Client, *http.ServeMux, error) {
  1919  	mux := http.NewServeMux()
  1920  
  1921  	httpServer := &http.Server{
  1922  		Handler: mux,
  1923  	}
  1924  
  1925  	randomPort := (1 << 12) + rand.Intn(1<<15)
  1926  	listener, err := net.Listen("tcp", ":"+strconv.Itoa(randomPort))
  1927  	if err != nil {
  1928  		return nil, nil, nil, nil, err
  1929  	}
  1930  
  1931  	sl, err := mockServer(httpServer, listener)
  1932  	if err != nil {
  1933  		return nil, nil, nil, nil, err
  1934  	}
  1935  
  1936  	client, err := createClient(50*time.Second, 50*time.Second, randomPort)
  1937  	if err != nil {
  1938  		return nil, nil, nil, nil, err
  1939  	}
  1940  
  1941  	return listener, sl, client, mux, nil
  1942  }
  1943  
  1944  func createEmptyTimedTestEnvironment(socketTimeout, connectTimeout time.Duration) (net.Listener, *stoppableListener, *Client, *http.ServeMux, error) {
  1945  	mux := http.NewServeMux()
  1946  
  1947  	httpServer := &http.Server{
  1948  		Handler: mux,
  1949  	}
  1950  
  1951  	randomPort := (1 << 12) + rand.Intn(1<<15)
  1952  	listener, err := net.Listen("tcp", ":"+strconv.Itoa(randomPort))
  1953  	if err != nil {
  1954  		return nil, nil, nil, nil, err
  1955  	}
  1956  
  1957  	sl, err := mockServer(httpServer, listener)
  1958  	if err != nil {
  1959  		return nil, nil, nil, nil, err
  1960  	}
  1961  
  1962  	client, err := createClient(socketTimeout, connectTimeout, randomPort)
  1963  	if err != nil {
  1964  		return nil, nil, nil, nil, err
  1965  	}
  1966  
  1967  	return listener, sl, client, mux, nil
  1968  }
  1969  
  1970  type testLogger struct {
  1971  	entries []testLoggerEntry
  1972  }
  1973  
  1974  func (t *testLogger) Log(message string) {
  1975  	t.entries = append(t.entries, testLoggerEntry{message, nil, nil, nil})
  1976  }
  1977  
  1978  func (t *testLogger) LogError(message string, err error) {
  1979  	t.entries = append(t.entries, testLoggerEntry{message, err, nil, nil})
  1980  }
  1981  
  1982  func (t *testLogger) LogResponseLogMessage(response *logging.ResponseLogMessage) {
  1983  	t.entries = append(t.entries, testLoggerEntry{"", nil, response, nil})
  1984  }
  1985  
  1986  func (t *testLogger) LogRequestLogMessage(request *logging.RequestLogMessage) {
  1987  	t.entries = append(t.entries, testLoggerEntry{"", nil, nil, request})
  1988  }
  1989  
  1990  type testLoggerEntry struct {
  1991  	message  string
  1992  	err      error
  1993  	response *logging.ResponseLogMessage
  1994  	request  *logging.RequestLogMessage
  1995  }