Skip to content

Commit 0ba3edf

Browse files
authored
Add waiters in git service for Create and Delete git instances
* Add waiters in git service for Create and Delete git instances
1 parent 5b13b7d commit 0ba3edf

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-0
lines changed

services/git/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/stackitcloud/stackit-sdk-go/services/git
33
go 1.21
44

55
require (
6+
github.com/google/go-cmp v0.7.0
67
github.com/google/uuid v1.6.0
78
github.com/stackitcloud/stackit-sdk-go/core v0.17.1
89
)

services/git/wait/wait.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package wait
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/stackitcloud/stackit-sdk-go/core/wait"
9+
"github.com/stackitcloud/stackit-sdk-go/services/git"
10+
)
11+
12+
const (
13+
CreateSuccess = "Ready"
14+
Creating = "Creating"
15+
CreateFail = "Error"
16+
)
17+
18+
// APIClientInterface Interfaces needed for tests
19+
type APIClientInterface interface {
20+
GetGitExecute(ctx context.Context, projectId string, instanceId string) (*git.Instance, error)
21+
}
22+
23+
func CreateGitInstanceWaitHandler(ctx context.Context, a APIClientInterface, projectId, instanceId string) *wait.AsyncActionHandler[git.Instance] {
24+
handler := wait.New(func() (waitFinished bool, response *git.Instance, err error) {
25+
instance, err := a.GetGitExecute(ctx, projectId, instanceId)
26+
if err != nil {
27+
return false, nil, err
28+
}
29+
if *instance.Id == "" || *instance.State == "" {
30+
return false, nil, fmt.Errorf("could not get Instance id or State from response for project %s and instanceId %s", projectId, instanceId)
31+
}
32+
if *instance.Id == instanceId && *instance.State == CreateSuccess {
33+
return true, instance, nil
34+
}
35+
if *instance.Id == instanceId && *instance.State == CreateFail {
36+
return true, instance, fmt.Errorf("create failed for Instance with id %s", instanceId)
37+
}
38+
return false, nil, nil
39+
})
40+
handler.SetTimeout(10 * time.Minute)
41+
return handler
42+
}
43+
44+
func DeleteGitInstanceWaitHandler(ctx context.Context, a APIClientInterface, projectId, instanceId string) *wait.AsyncActionHandler[git.Instance] {
45+
handler := wait.New(func() (waitFinished bool, response *git.Instance, err error) {
46+
instance, err := a.GetGitExecute(ctx, projectId, instanceId)
47+
if err != nil {
48+
return true, nil, err
49+
}
50+
if instance != nil {
51+
return true, instance, nil
52+
}
53+
return true, nil, nil
54+
})
55+
handler.SetTimeout(10 * time.Minute)
56+
return handler
57+
}

services/git/wait/wait_test.go

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
package wait
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"testing"
7+
"time"
8+
9+
"github.com/google/go-cmp/cmp"
10+
"github.com/google/uuid"
11+
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
12+
"github.com/stackitcloud/stackit-sdk-go/core/utils"
13+
"github.com/stackitcloud/stackit-sdk-go/services/git"
14+
)
15+
16+
type apiClientMocked struct {
17+
desc string
18+
getFails bool
19+
returnInstance bool
20+
wantErr bool
21+
created time.Time
22+
id string
23+
projectId string
24+
name string
25+
state string
26+
url string
27+
version string
28+
}
29+
30+
func (a *apiClientMocked) GetGitExecute(_ context.Context, _, _ string) (*git.Instance, error) {
31+
if a.getFails {
32+
return nil, &oapierror.GenericOpenAPIError{
33+
StatusCode: http.StatusInternalServerError,
34+
}
35+
}
36+
if !a.returnInstance {
37+
return nil, nil
38+
}
39+
return &git.Instance{
40+
Created: utils.Ptr(a.created),
41+
Id: utils.Ptr(a.id),
42+
Name: utils.Ptr(a.name),
43+
State: utils.Ptr(a.state),
44+
Url: utils.Ptr(a.url),
45+
Version: utils.Ptr(a.version),
46+
}, nil
47+
}
48+
49+
func TestCreateGitInstanceWaitHandler(t *testing.T) {
50+
tests := []struct {
51+
desc string
52+
getFails bool
53+
wantErr bool
54+
wantResp bool
55+
created time.Time
56+
id string
57+
projectId string
58+
name string
59+
state string
60+
url string
61+
version string
62+
returnInstance bool
63+
}{
64+
{
65+
desc: "Creation of an instance succeeded",
66+
getFails: false,
67+
wantErr: false,
68+
wantResp: true,
69+
created: time.Now(),
70+
id: uuid.New().String(),
71+
projectId: uuid.New().String(),
72+
name: "instance-test",
73+
state: CreateSuccess,
74+
url: "https://testing.git.onstackit.cloud",
75+
version: "v1.6.0",
76+
returnInstance: true,
77+
},
78+
{
79+
desc: "Creation of an instance Failed With Error",
80+
getFails: true,
81+
wantErr: true,
82+
wantResp: false,
83+
created: time.Now(),
84+
id: uuid.New().String(),
85+
projectId: uuid.New().String(),
86+
name: "instance-test",
87+
state: CreateFail,
88+
url: "https://testing.git.onstackit.cloud",
89+
version: "v1.6.0",
90+
returnInstance: true,
91+
},
92+
{
93+
desc: "Creation of an instance with response failed and without error",
94+
getFails: false,
95+
wantErr: true,
96+
wantResp: true,
97+
created: time.Now(),
98+
id: uuid.New().String(),
99+
projectId: uuid.New().String(),
100+
name: "instance-test",
101+
state: CreateFail,
102+
url: "https://testing.git.onstackit.cloud",
103+
version: "v1.6.0",
104+
returnInstance: true,
105+
},
106+
{
107+
desc: "Creation of an instance failed without id on the response",
108+
getFails: false,
109+
wantErr: true,
110+
wantResp: false,
111+
created: time.Now(),
112+
projectId: uuid.New().String(),
113+
name: "instance-test",
114+
state: CreateFail,
115+
url: "https://testing.git.onstackit.cloud",
116+
version: "v1.6.0",
117+
returnInstance: true,
118+
},
119+
120+
{
121+
desc: "Creation of an instance without state on the response",
122+
getFails: false,
123+
wantErr: true,
124+
wantResp: false,
125+
created: time.Now(),
126+
id: uuid.New().String(),
127+
projectId: uuid.New().String(),
128+
name: "instance-test",
129+
url: "https://testing.git.onstackit.cloud",
130+
version: "v1.6.0",
131+
returnInstance: true,
132+
},
133+
}
134+
for _, tt := range tests {
135+
t.Run(tt.desc, func(t *testing.T) {
136+
apiClient := &apiClientMocked{
137+
desc: tt.desc,
138+
getFails: tt.getFails,
139+
wantErr: tt.wantErr,
140+
created: tt.created,
141+
id: tt.id,
142+
projectId: tt.projectId,
143+
name: tt.name,
144+
state: tt.state,
145+
url: tt.url,
146+
version: tt.version,
147+
returnInstance: tt.returnInstance,
148+
}
149+
var instanceWanted *git.Instance
150+
if tt.wantResp {
151+
instanceWanted = &git.Instance{
152+
Created: utils.Ptr(tt.created),
153+
Id: utils.Ptr(tt.id),
154+
Name: utils.Ptr(tt.name),
155+
State: utils.Ptr(tt.state),
156+
Url: utils.Ptr(tt.url),
157+
Version: utils.Ptr(tt.version),
158+
}
159+
}
160+
161+
handler := CreateGitInstanceWaitHandler(context.Background(), apiClient, apiClient.projectId, apiClient.id)
162+
163+
response, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
164+
165+
if (err != nil) != tt.wantErr {
166+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
167+
}
168+
if !cmp.Equal(response, instanceWanted) {
169+
t.Fatalf("handler gotRes = %v, want %v", response, instanceWanted)
170+
}
171+
})
172+
}
173+
}
174+
175+
func TestDeleteGitInstanceWaitHandler(t *testing.T) {
176+
tests := []struct {
177+
desc string
178+
wantErr bool
179+
wantReturnedInstance bool
180+
getFails bool
181+
returnInstance bool
182+
created time.Time
183+
id string
184+
name string
185+
state string
186+
url string
187+
version string
188+
}{
189+
{
190+
desc: "Instance deletion failed with error",
191+
wantErr: true,
192+
getFails: true,
193+
},
194+
{
195+
desc: "Instance deletion failed returning existing instance",
196+
wantErr: false,
197+
getFails: false,
198+
wantReturnedInstance: true,
199+
created: time.Now(),
200+
id: uuid.New().String(),
201+
name: "instance-test",
202+
state: CreateSuccess,
203+
returnInstance: true,
204+
url: "https://testing.git.onstackit.cloud",
205+
version: "v1.6.0",
206+
},
207+
{
208+
desc: "Instance deletion succesfull",
209+
wantErr: false,
210+
getFails: false,
211+
wantReturnedInstance: false,
212+
returnInstance: false,
213+
},
214+
}
215+
for _, tt := range tests {
216+
t.Run(tt.desc, func(t *testing.T) {
217+
apiClient := &apiClientMocked{
218+
219+
projectId: uuid.New().String(),
220+
getFails: tt.getFails,
221+
created: tt.created,
222+
id: tt.id,
223+
name: tt.name,
224+
state: tt.state,
225+
url: tt.url,
226+
version: tt.version,
227+
returnInstance: tt.returnInstance,
228+
}
229+
230+
handler := DeleteGitInstanceWaitHandler(context.Background(), apiClient, apiClient.projectId, apiClient.id)
231+
response, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
232+
233+
if (err != nil) != tt.wantErr {
234+
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
235+
}
236+
if (response != nil) != tt.wantReturnedInstance {
237+
t.Fatalf("handler gotRes = %v, want nil", response)
238+
}
239+
})
240+
}
241+
}

0 commit comments

Comments
 (0)