github.com/aiven/aiven-go-client@v1.36.0/client_test.go (about)

     1  package aiven
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestClient_Init(t *testing.T) {
    16  	var c Client = Client{}
    17  	c.Init()
    18  }
    19  
    20  func TestClient_Context(t *testing.T) {
    21  	c, err := NewTokenClient("key", "user-agent")
    22  	require.NoError(t, err)
    23  
    24  	ctxC := c.WithContext(context.Background())
    25  	assert.Nil(t, c.ctx)
    26  	assert.NotNil(t, ctxC.ctx)
    27  	assert.Equal(t, c.Client, ctxC.Client)
    28  	assert.Equal(t, c.APIKey, ctxC.APIKey)
    29  	assert.Equal(t, c.UserAgent, ctxC.UserAgent)
    30  }
    31  
    32  func TestCheckRetry(t *testing.T) {
    33  	type option struct {
    34  		name     string // test name
    35  		code     int    // response status code
    36  		expected bool   // expected result
    37  		body     string
    38  		method   string
    39  	}
    40  
    41  	opts := []*option{
    42  		{
    43  			name:     "Retries 408",
    44  			code:     http.StatusRequestTimeout,
    45  			expected: true,
    46  		},
    47  		{
    48  			name:     "Retries 429",
    49  			code:     http.StatusTooManyRequests,
    50  			expected: true,
    51  		},
    52  		{
    53  			name:     "Retries 404",
    54  			code:     http.StatusNotFound,
    55  			body:     "Service 'test-foo' does not exist",
    56  			method:   "POST",
    57  			expected: true,
    58  		},
    59  		{
    60  			name:     "Does not retry 404 with different error message",
    61  			code:     http.StatusNotFound,
    62  			body:     "User 'test-foo' does not exist",
    63  			method:   "POST",
    64  			expected: false,
    65  		},
    66  		{
    67  			name:     "Retries deletion 417",
    68  			code:     http.StatusExpectationFailed,
    69  			method:   "DELETE",
    70  			expected: true,
    71  		},
    72  	}
    73  
    74  	doRetry := []int{500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511}
    75  	for _, code := range doRetry {
    76  		opts = append(opts, &option{
    77  			name:     fmt.Sprintf("Tests code %d, should retry", code),
    78  			code:     code,
    79  			expected: true,
    80  		})
    81  	}
    82  
    83  	// Except 408 and 429
    84  	doNotRetry := []int{
    85  		100, 101, 102, 103,
    86  		200, 201, 202, 203, 204, 205, 206, 207, 208, 226,
    87  		300, 301, 302, 303, 304, 305, 306, 307, 308,
    88  		400, 401, 402, 403, 404, 405, 406, 407, 409, 410, 411, 412, 413, 414,
    89  		415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 431, 451,
    90  	}
    91  
    92  	for _, code := range doNotRetry {
    93  		opts = append(opts, &option{
    94  			name:     fmt.Sprintf("Tests code %d, should not retry", code),
    95  			code:     code,
    96  			expected: false,
    97  		})
    98  	}
    99  
   100  	ctx := context.Background()
   101  	for _, opt := range opts {
   102  		t.Run(opt.name, func(t *testing.T) {
   103  			rsp := &http.Response{
   104  				Status:     fmt.Sprintf("%d", opt.code),
   105  				StatusCode: opt.code,
   106  				Body:       io.NopCloser(strings.NewReader(opt.body)),
   107  				Request:    &http.Request{Method: opt.method},
   108  			}
   109  			retry, err := checkRetry(ctx, rsp, nil)
   110  			assert.Equal(t, opt.expected, retry)
   111  			assert.Nil(t, err)
   112  		})
   113  	}
   114  }
   115  
   116  func TestIsServiceLagError(t *testing.T) {
   117  	cases := []struct {
   118  		body     string
   119  		method   string
   120  		expected bool
   121  	}{
   122  		{
   123  			body:     "Service lol does not exist",
   124  			method:   "POST",
   125  			expected: true,
   126  		},
   127  		{
   128  			// Invalid body
   129  			body:     "User lol does not exist",
   130  			method:   "POST",
   131  			expected: false,
   132  		},
   133  		{
   134  			// Invalid method
   135  			body:     "Service lol does not exist",
   136  			method:   "GET",
   137  			expected: false,
   138  		},
   139  	}
   140  
   141  	for i, opt := range cases {
   142  		t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
   143  			assert.Equal(t, opt.expected, isServiceLagError(opt.method, opt.body))
   144  		})
   145  	}
   146  }
   147  
   148  func TestIsUserError(t *testing.T) {
   149  	cases := []struct {
   150  		body     string
   151  		method   string
   152  		expected bool
   153  	}{
   154  		{
   155  			body:     "User avnadmin with component main not found",
   156  			method:   "",
   157  			expected: true,
   158  		},
   159  		{
   160  			body:     "User root with component main not found",
   161  			method:   "",
   162  			expected: true,
   163  		},
   164  		{
   165  			// Invalid user
   166  			body:     "User lol with component main not found",
   167  			method:   "",
   168  			expected: false,
   169  		},
   170  		{
   171  			// Invalid body
   172  			body:     "User root with component",
   173  			method:   "",
   174  			expected: false,
   175  		},
   176  	}
   177  
   178  	for i, opt := range cases {
   179  		t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
   180  			assert.Equal(t, opt.expected, isUserError(opt.method, opt.body))
   181  		})
   182  	}
   183  }