Skip to content

Commit afc4991

Browse files
committed
Enhance GitHub Actions workflow and improve error handling in client tests
- Added 'fail-fast: false' to the Go CI workflow to allow all jobs to complete even if one fails. - Implemented retry logic with exponential backoff for network and IP service creation in client tests to handle rate limiting (HTTP 429) more gracefully. Signed-off-by: Denis Arslanbekov <[email protected]>
1 parent 65cf82d commit afc4991

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
environment: TestingEnv
2525
runs-on: ubuntu-latest
2626
strategy:
27+
fail-fast: false
2728
matrix:
2829
go:
2930
- "1.23"

e2e/client_test.go

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -292,16 +292,34 @@ func TestCreateNetwork(t *testing.T) {
292292
Connectors: []cloudconnexa.NetworkConnector{connector},
293293
TunnelingProtocol: "OPENVPN",
294294
}
295-
response, err := c.Networks.Create(network)
296-
require.NoError(t, err)
295+
296+
// Create network with 429 retry/backoff
297+
var response *cloudconnexa.Network
298+
var lastErr error
299+
for backoff, attempts := 200*time.Millisecond, 0; attempts < 8; attempts++ {
300+
response, err = c.Networks.Create(network)
301+
if err == nil {
302+
break
303+
}
304+
lastErr = err
305+
var apiErr *cloudconnexa.ErrClientResponse
306+
if errors.As(err, &apiErr) && apiErr.StatusCode() == 429 {
307+
time.Sleep(backoff)
308+
backoff *= 2
309+
continue
310+
}
311+
require.NoError(t, err)
312+
}
313+
require.NoError(t, lastErr)
314+
require.NotNil(t, response)
297315
fmt.Printf("created %s network\n", response.ID)
298316
// Ensure cleanup even if subsequent steps fail
299317
defer func() { _ = c.Networks.Delete(response.ID) }()
300318

301319
// Attempt to create a non-overlapping route with retries to avoid CI matrix collisions
302320
var testRoute *cloudconnexa.Route
303-
var lastErr error
304-
for attempts := 0; attempts < 20; attempts++ {
321+
lastErr = nil
322+
for backoff, attempts := 200*time.Millisecond, 0; attempts < 20; attempts++ {
305323
subnet, serr := findAvailableIPv4Subnet(c)
306324
require.NoError(t, serr)
307325
route := cloudconnexa.Route{
@@ -317,13 +335,16 @@ func TestCreateNetwork(t *testing.T) {
317335
lastErr = err
318336
var apiErr *cloudconnexa.ErrClientResponse
319337
if errors.As(err, &apiErr) {
320-
if apiErr.StatusCode() == 400 {
321-
// Overlap or validation error, refresh and retry
322-
time.Sleep(500 * time.Millisecond)
338+
if apiErr.StatusCode() == 400 { // overlap/validation
339+
time.Sleep(300 * time.Millisecond)
340+
continue
341+
}
342+
if apiErr.StatusCode() == 429 { // rate limit
343+
time.Sleep(backoff)
344+
backoff *= 2
323345
continue
324346
}
325347
}
326-
// Unexpected error
327348
require.NoError(t, err)
328349
}
329350
require.NoError(t, lastErr)
@@ -345,8 +366,26 @@ func TestCreateNetwork(t *testing.T) {
345366
Config: &serviceConfig,
346367
Routes: []*cloudconnexa.IPServiceRoute{&ipServiceRoute},
347368
}
348-
s, err := c.NetworkIPServices.Create(&service)
349-
require.NoError(t, err)
369+
370+
// Create IP service with 429 retry/backoff
371+
var s *cloudconnexa.NetworkIPServiceResponse
372+
lastErr = nil
373+
for backoff, attempts := 200*time.Millisecond, 0; attempts < 8; attempts++ {
374+
s, err = c.NetworkIPServices.Create(&service)
375+
if err == nil {
376+
break
377+
}
378+
lastErr = err
379+
var apiErr *cloudconnexa.ErrClientResponse
380+
if errors.As(err, &apiErr) && apiErr.StatusCode() == 429 {
381+
time.Sleep(backoff)
382+
backoff *= 2
383+
continue
384+
}
385+
require.NoError(t, err)
386+
}
387+
require.NoError(t, lastErr)
388+
require.NotNil(t, s)
350389
fmt.Printf("created %s service\n", s.ID)
351390
err = c.Networks.Delete(response.ID)
352391
require.NoError(t, err)

0 commit comments

Comments
 (0)