github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/loadbalancer_test.go (about)

     1  package cloudlets
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestListOrigins(t *testing.T) {
    16  	tests := map[string]struct {
    17  		originType       ListOriginsRequest
    18  		responseStatus   int
    19  		responseBody     string
    20  		expectedPath     string
    21  		expectedResponse []OriginResponse
    22  		withError        func(*testing.T, error)
    23  	}{
    24  		"200 OK": {
    25  			originType:     ListOriginsRequest{},
    26  			responseStatus: http.StatusOK,
    27  			responseBody: `[
    28  				{
    29  					
    30  					"hostname": "",
    31  					"description": "ALB1",
    32  					"originId": "alb1",
    33  					"type": "APPLICATION_LOAD_BALANCER",
    34  					"akamaized": false
    35  				},
    36  				{
    37  					"hostname": "",
    38  					"description": "",
    39  					"originId": "alb2",
    40  					"type": "APPLICATION_LOAD_BALANCER",
    41  					"akamaized": false
    42  				},
    43  				{
    44  					"hostname": "dc1.foo.com",
    45  					"description": "",
    46  					"originId": "dc1",
    47  					"type": "CUSTOMER",
    48  					"akamaized": false
    49  				},
    50  				{
    51  					
    52  					"hostname": "dc2.foo.com",
    53  					"description": "",
    54  					"originId": "dc2",
    55  					"type": "CUSTOMER",
    56  					"akamaized": true
    57  				},
    58  				{
    59  					"hostname": "download.akamai.com/12345",
    60  					"description": "",
    61  					"originId": "ns1",
    62  					"type": "NETSTORAGE",
    63  					"akamaized": true
    64  				},
    65  				{
    66  					
    67  					"hostname": "download.akamai.com/12345",
    68  					"description": "",
    69  					"originId": "ns2",
    70  					"type": "NETSTORAGE",
    71  					"akamaized": true
    72  				}
    73  			]`,
    74  			expectedPath: "/cloudlets/api/v2/origins",
    75  			expectedResponse: []OriginResponse{
    76  				{
    77  					Hostname: "",
    78  					Origin: Origin{
    79  						OriginID:    "alb1",
    80  						Description: "ALB1",
    81  						Type:        "APPLICATION_LOAD_BALANCER",
    82  						Akamaized:   false,
    83  					},
    84  				},
    85  				{
    86  					Hostname: "",
    87  					Origin: Origin{
    88  						Description: "",
    89  						OriginID:    "alb2",
    90  						Type:        "APPLICATION_LOAD_BALANCER",
    91  						Akamaized:   false,
    92  					},
    93  				},
    94  				{
    95  					Hostname: "dc1.foo.com",
    96  					Origin: Origin{
    97  						Description: "",
    98  						OriginID:    "dc1",
    99  						Type:        "CUSTOMER",
   100  						Akamaized:   false,
   101  					},
   102  				},
   103  				{
   104  					Hostname: "dc2.foo.com",
   105  					Origin: Origin{
   106  						Description: "",
   107  						OriginID:    "dc2",
   108  						Type:        "CUSTOMER",
   109  						Akamaized:   true,
   110  					},
   111  				},
   112  				{
   113  					Hostname: "download.akamai.com/12345",
   114  					Origin: Origin{
   115  						Description: "",
   116  						OriginID:    "ns1",
   117  						Type:        "NETSTORAGE",
   118  						Akamaized:   true,
   119  					},
   120  				},
   121  				{
   122  					Hostname: "download.akamai.com/12345",
   123  					Origin: Origin{
   124  						Description: "",
   125  						OriginID:    "ns2",
   126  						Type:        "NETSTORAGE",
   127  						Akamaized:   true,
   128  					},
   129  				},
   130  			},
   131  		},
   132  		"200 ok with param": {
   133  			originType:     ListOriginsRequest{Type: OriginTypeCustomer},
   134  			responseStatus: http.StatusOK,
   135  			responseBody: `[
   136  				{
   137  					"hostname": "dc1.foo.com",
   138  					"description": "",
   139  					"originId": "dc1",
   140  					"type": "CUSTOMER",
   141  					"akamaized": false
   142  				},
   143  				{
   144  					
   145  					"hostname": "dc2.foo.com",
   146  					"description": "",
   147  					"originId": "dc2",
   148  					"type": "CUSTOMER",
   149  					"akamaized": true
   150  				}
   151  			]`,
   152  			expectedPath: "/cloudlets/api/v2/origins?type=CUSTOMER",
   153  			expectedResponse: []OriginResponse{
   154  				{
   155  					Hostname: "dc1.foo.com",
   156  					Origin: Origin{
   157  						Description: "",
   158  						OriginID:    "dc1",
   159  						Type:        "CUSTOMER",
   160  						Akamaized:   false,
   161  					},
   162  				},
   163  				{
   164  					Hostname: "dc2.foo.com",
   165  					Origin: Origin{
   166  						Description: "",
   167  						OriginID:    "dc2",
   168  						Type:        "CUSTOMER",
   169  						Akamaized:   true,
   170  					},
   171  				},
   172  			},
   173  		},
   174  		"500 internal server error": {
   175  			originType:     ListOriginsRequest{},
   176  			responseStatus: http.StatusInternalServerError,
   177  			responseBody: `{
   178  				"type": "internal_error",
   179  			   	"title": "Internal Server Error",
   180  			   	"detail": "Error making request",
   181  			   	"status": 500
   182  			}`,
   183  			expectedPath: "/cloudlets/api/v2/origins",
   184  			withError: func(t *testing.T, err error) {
   185  				want := &Error{
   186  					Type:       "internal_error",
   187  					Title:      "Internal Server Error",
   188  					Detail:     "Error making request",
   189  					StatusCode: http.StatusInternalServerError,
   190  				}
   191  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   192  			},
   193  		},
   194  	}
   195  
   196  	for name, test := range tests {
   197  		t.Run(name, func(t *testing.T) {
   198  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   199  				assert.Equal(t, test.expectedPath, r.URL.String())
   200  				assert.Equal(t, http.MethodGet, r.Method)
   201  				w.WriteHeader(test.responseStatus)
   202  				_, err := w.Write([]byte(test.responseBody))
   203  				assert.NoError(t, err)
   204  			}))
   205  			client := mockAPIClient(t, mockServer)
   206  			result, err := client.ListOrigins(context.Background(), test.originType)
   207  			if test.withError != nil {
   208  				test.withError(t, err)
   209  				return
   210  			}
   211  			require.NoError(t, err)
   212  			assert.Equal(t, test.expectedResponse, result)
   213  		})
   214  	}
   215  }
   216  
   217  func TestGetOrigin(t *testing.T) {
   218  	tests := map[string]struct {
   219  		originID         string
   220  		responseStatus   int
   221  		responseBody     string
   222  		expectedPath     string
   223  		expectedResponse *Origin
   224  		withError        func(*testing.T, error)
   225  	}{
   226  		"200 OK": {
   227  			originID:       "alb1",
   228  			responseStatus: http.StatusOK,
   229  			responseBody: `{
   230  				"description": "ALB1",
   231  				"originId": "alb1",
   232  				"type": "APPLICATION_LOAD_BALANCER",
   233  				"checksum": "abcdefg1111hijklmn22222fff76yae3"
   234  			}`,
   235  			expectedPath: "/cloudlets/api/v2/origins/alb1",
   236  			expectedResponse: &Origin{
   237  				Description: "ALB1",
   238  				OriginID:    "alb1",
   239  				Type:        OriginTypeApplicationLoadBalancer,
   240  				Checksum:    "abcdefg1111hijklmn22222fff76yae3",
   241  			},
   242  		},
   243  		"500 internal server error": {
   244  			originID:       "ALB1",
   245  			responseStatus: http.StatusInternalServerError,
   246  			responseBody: `{
   247  				"type": "internal_error",
   248  			   	"title": "Internal Server Error",
   249  			   	"detail": "Error making request",
   250  			   	"status": 500
   251  			}`,
   252  			expectedPath: "/cloudlets/api/v2/origins/ALB1",
   253  			withError: func(t *testing.T, err error) {
   254  				want := &Error{
   255  					Type:       "internal_error",
   256  					Title:      "Internal Server Error",
   257  					Detail:     "Error making request",
   258  					StatusCode: http.StatusInternalServerError,
   259  				}
   260  				assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err)
   261  			},
   262  		},
   263  	}
   264  
   265  	for name, test := range tests {
   266  		t.Run(name, func(t *testing.T) {
   267  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   268  				assert.Equal(t, test.expectedPath, r.URL.String())
   269  				assert.Equal(t, http.MethodGet, r.Method)
   270  				w.WriteHeader(test.responseStatus)
   271  				_, err := w.Write([]byte(test.responseBody))
   272  				assert.NoError(t, err)
   273  			}))
   274  			client := mockAPIClient(t, mockServer)
   275  			result, err := client.GetOrigin(context.Background(), GetOriginRequest{OriginID: test.originID})
   276  			if test.withError != nil {
   277  				test.withError(t, err)
   278  				return
   279  			}
   280  			require.NoError(t, err)
   281  			assert.Equal(t, test.expectedResponse, result)
   282  		})
   283  	}
   284  }
   285  
   286  func TestCreateOrigin(t *testing.T) {
   287  	tests := map[string]struct {
   288  		request             CreateOriginRequest
   289  		expectedRequestBody string
   290  		responseStatus      int
   291  		responseBody        string
   292  		expectedPath        string
   293  		expectedResponse    *Origin
   294  		withError           error
   295  	}{
   296  		"201 created": {
   297  			request: CreateOriginRequest{
   298  				OriginID:    "first",
   299  				Description: Description{"create first Origin"},
   300  			},
   301  			expectedRequestBody: `{"originId":"first","description":"create first Origin"}`,
   302  			responseStatus:      http.StatusCreated,
   303  			responseBody: `{
   304  			   "originId": "first",
   305  			   "akamaized": true,
   306  			   "checksum": "9c0fc1f3e9ea7eb2e090f2bf53709e45",
   307  			   "description": "create first Origin",
   308  			   "type": "APPLICATION_LOAD_BALANCER"
   309  			}`,
   310  			expectedPath: "/cloudlets/api/v2/origins",
   311  			expectedResponse: &Origin{
   312  				OriginID:    "first",
   313  				Description: "create first Origin",
   314  				Akamaized:   true,
   315  				Type:        OriginTypeApplicationLoadBalancer,
   316  				Checksum:    "9c0fc1f3e9ea7eb2e090f2bf53709e45",
   317  			},
   318  		},
   319  		"500 internal server error": {
   320  			request: CreateOriginRequest{
   321  				OriginID:    "second",
   322  				Description: Description{"create second Origin"},
   323  			},
   324  			responseStatus: http.StatusInternalServerError,
   325  			responseBody: `
   326  				{
   327  				  "type": "internal_error",
   328  				  "title": "Internal Server Error",
   329  				  "detail": "Error creating enrollment",
   330  				  "status": 500 
   331  				}`,
   332  			expectedPath: "/cloudlets/api/v2/origins",
   333  			withError: &Error{
   334  				Type:       "internal_error",
   335  				Title:      "Internal Server Error",
   336  				Detail:     "Error creating enrollment",
   337  				StatusCode: http.StatusInternalServerError,
   338  			},
   339  			expectedResponse: &Origin{
   340  				OriginID:    "first",
   341  				Description: "create first Origin",
   342  				Akamaized:   false,
   343  				Type:        OriginTypeApplicationLoadBalancer,
   344  				Checksum:    "9c0fc1f3e9ea7eb2e090f2bf53709e45",
   345  			},
   346  		},
   347  		"validation error": {
   348  			request:   CreateOriginRequest{},
   349  			withError: ErrStructValidation,
   350  		},
   351  	}
   352  
   353  	for name, test := range tests {
   354  		t.Run(name, func(t *testing.T) {
   355  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   356  				assert.Equal(t, test.expectedPath, r.URL.String())
   357  				assert.Equal(t, http.MethodPost, r.Method)
   358  				w.WriteHeader(test.responseStatus)
   359  				_, err := w.Write([]byte(test.responseBody))
   360  				assert.NoError(t, err)
   361  
   362  				if len(test.expectedRequestBody) > 0 {
   363  					body, err := ioutil.ReadAll(r.Body)
   364  					require.NoError(t, err)
   365  					assert.Equal(t, test.expectedRequestBody, string(body))
   366  				}
   367  			}))
   368  			client := mockAPIClient(t, mockServer)
   369  			result, err := client.CreateOrigin(context.Background(), test.request)
   370  			if test.withError != nil {
   371  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   372  				return
   373  			}
   374  			require.NoError(t, err)
   375  			assert.Equal(t, test.expectedResponse, result)
   376  		})
   377  	}
   378  }
   379  
   380  func TestCreateOriginValidation(t *testing.T) {
   381  	tests := map[string]struct {
   382  		request   CreateOriginRequest
   383  		withError error
   384  	}{
   385  		"validation error -  OriginID exceeds max length, which is 63": {
   386  			request: CreateOriginRequest{
   387  				OriginID: "ExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExce",
   388  			},
   389  			withError: ErrStructValidation,
   390  		},
   391  		"validation error - OriginID value less than min, which is 2": {
   392  			request: CreateOriginRequest{
   393  				OriginID: "E",
   394  			},
   395  			withError: ErrStructValidation,
   396  		},
   397  		"validation error - Description exceeds max length, which is 255": {
   398  			request: CreateOriginRequest{
   399  				OriginID: "first",
   400  				Description: Description{
   401  					"Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type,Test for creating exceed valu",
   402  				},
   403  			},
   404  			withError: ErrStructValidation,
   405  		},
   406  	}
   407  	for name, test := range tests {
   408  		t.Run(name, func(t *testing.T) {
   409  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
   410  			client := mockAPIClient(t, mockServer)
   411  			_, err := client.CreateOrigin(context.Background(), test.request)
   412  			assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   413  		})
   414  	}
   415  }
   416  
   417  func TestUpdateOrigin(t *testing.T) {
   418  	tests := map[string]struct {
   419  		request             UpdateOriginRequest
   420  		expectedRequestBody string
   421  		responseStatus      int
   422  		responseBody        string
   423  		expectedPath        string
   424  		expectedResponse    *Origin
   425  		withError           error
   426  	}{
   427  		"200 updated": {
   428  			request: UpdateOriginRequest{
   429  				OriginID:    "first",
   430  				Description: Description{"update first Origin"},
   431  			},
   432  			expectedRequestBody: `{"description":"update first Origin"}`,
   433  			responseStatus:      http.StatusOK,
   434  			responseBody: `{
   435  			   "originId": "first",
   436  			   "akamaized": true,
   437  			   "checksum": "9c0fc1f3e9ea7eb2e090f2bf53709e45",
   438  			   "description": "update first Origin",
   439  			   "type": "APPLICATION_LOAD_BALANCER"
   440  			}`,
   441  			expectedPath: "/cloudlets/api/v2/origins/first",
   442  			expectedResponse: &Origin{
   443  				OriginID:    "first",
   444  				Description: "update first Origin",
   445  				Akamaized:   true,
   446  				Type:        OriginTypeApplicationLoadBalancer,
   447  				Checksum:    "9c0fc1f3e9ea7eb2e090f2bf53709e45",
   448  			},
   449  		},
   450  		"500 internal server error": {
   451  			request: UpdateOriginRequest{
   452  				OriginID:    "second",
   453  				Description: Description{"create second Origin"},
   454  			},
   455  			responseStatus: http.StatusInternalServerError,
   456  			responseBody: `
   457  				{
   458  				  "type": "internal_error",
   459  				  "title": "Internal Server Error",
   460  				  "detail": "Error creating enrollment",
   461  				  "status": 500 
   462  				}`,
   463  			expectedPath: "/cloudlets/api/v2/origins/second",
   464  			withError: &Error{
   465  				Type:       "internal_error",
   466  				Title:      "Internal Server Error",
   467  				Detail:     "Error creating enrollment",
   468  				StatusCode: http.StatusInternalServerError,
   469  			},
   470  			expectedResponse: &Origin{
   471  				OriginID:    "second",
   472  				Description: "update first Origin",
   473  				Akamaized:   false,
   474  				Type:        OriginTypeApplicationLoadBalancer,
   475  				Checksum:    "9c0fc1f3e9ea7eb2e090f2bf53709e45",
   476  			},
   477  		},
   478  		"validation error": {
   479  			request:   UpdateOriginRequest{},
   480  			withError: ErrStructValidation,
   481  		},
   482  	}
   483  	for name, test := range tests {
   484  		t.Run(name, func(t *testing.T) {
   485  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   486  				assert.Equal(t, test.expectedPath, r.URL.String())
   487  				assert.Equal(t, http.MethodPut, r.Method)
   488  				w.WriteHeader(test.responseStatus)
   489  				_, err := w.Write([]byte(test.responseBody))
   490  				assert.NoError(t, err)
   491  
   492  				if len(test.expectedRequestBody) > 0 {
   493  					body, err := ioutil.ReadAll(r.Body)
   494  					require.NoError(t, err)
   495  					assert.Equal(t, test.expectedRequestBody, string(body))
   496  				}
   497  			}))
   498  			client := mockAPIClient(t, mockServer)
   499  			result, err := client.UpdateOrigin(context.Background(), test.request)
   500  			if test.withError != nil {
   501  				assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   502  				return
   503  			}
   504  			require.NoError(t, err)
   505  			assert.Equal(t, test.expectedResponse, result)
   506  		})
   507  	}
   508  }
   509  
   510  func TestUpdateOriginValidation(t *testing.T) {
   511  	tests := map[string]struct {
   512  		request   UpdateOriginRequest
   513  		withError error
   514  	}{
   515  		"validation error -  OriginID exceeds max length, which is 63": {
   516  			request: UpdateOriginRequest{
   517  				OriginID: "ExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExce",
   518  			},
   519  			withError: ErrStructValidation,
   520  		},
   521  		"validation error - OriginID value less than min, which is 2": {
   522  			request: UpdateOriginRequest{
   523  				OriginID: "E",
   524  			},
   525  			withError: ErrStructValidation,
   526  		},
   527  		"validation error - Description exceeds max length, which is 255": {
   528  			request: UpdateOriginRequest{
   529  				OriginID: "first",
   530  				Description: Description{
   531  					"Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type,Test for creating exceed valu",
   532  				},
   533  			},
   534  			withError: ErrStructValidation,
   535  		},
   536  	}
   537  	for name, test := range tests {
   538  		t.Run(name, func(t *testing.T) {
   539  			mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
   540  			client := mockAPIClient(t, mockServer)
   541  			_, err := client.UpdateOrigin(context.Background(), test.request)
   542  			assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err)
   543  		})
   544  	}
   545  }