forked from Azure/skewer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fakes_test.go
190 lines (163 loc) · 5.55 KB
/
fakes_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package skewer
import (
"context"
"encoding/json"
"os"
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2022-03-01/compute" //nolint:staticcheck
)
// dataWrapper is a convenience wrapper for deserializing json testdata
type dataWrapper struct {
Value []compute.ResourceSku `json:"value,omitempty"`
}
// newDataWrapper takes a path to a list of compute skus and parses them
// to a dataWrapper for use in fake clients
func newDataWrapper(path string) (*dataWrapper, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
wrapper := new(dataWrapper)
if err := json.Unmarshal(data, wrapper); err != nil {
return nil, err
}
return wrapper, nil
}
// fakeClient is close to the simplest fake client implementation usable
// by the cache. It does not use pagination like Azure clients.
type fakeClient struct {
skus []compute.ResourceSku
err error
}
func (f *fakeClient) List(ctx context.Context, filter, includeExtendedLocations string) ([]compute.ResourceSku, error) {
if f.err != nil {
return nil, f.err
}
return f.skus, nil
}
// fakeResourceClient is a fake client for the real Azure types. It
// returns a result iterator and can test against arbitrary sequences of
// return pages, injecting failure.
type fakeResourceClient struct {
res compute.ResourceSkusResultIterator
err error
}
//nolint:lll
func (f *fakeResourceClient) ListComplete(ctx context.Context, filter, includeExtendedLocations string) (compute.ResourceSkusResultIterator, error) {
if f.err != nil {
return compute.ResourceSkusResultIterator{}, f.err
}
return f.res, nil
}
//nolint:deadcode,unused
func newFailingFakeResourceClient(reterr error) *fakeResourceClient {
return &fakeResourceClient{
res: compute.ResourceSkusResultIterator{},
err: reterr,
}
}
// newSuccessfulFakeResourceClient takes a list of sku lists and returns
// a ResourceClient which iterates over all of them, mapping each sku
// list to a page of values.
func newSuccessfulFakeResourceClient(skuLists [][]compute.ResourceSku) (*fakeResourceClient, error) {
iterator, err := newFakeResourceSkusResultIterator(skuLists)
if err != nil {
return nil, err
}
return &fakeResourceClient{
res: iterator,
err: nil,
}, nil
}
// fakeResourceProviderClient is a fake client for the real Azure types. It
// returns a result iterator and can test against arbitrary sequences of
// return pages, injecting failure. This uses the resource provider
// signature for testing purposes.
type fakeResourceProviderClient struct {
res compute.ResourceSkusResultPage
err error
}
//nolint:lll
func (f *fakeResourceProviderClient) List(ctx context.Context, filter, includeExtendedLocations string) (compute.ResourceSkusResultPage, error) {
if f.err != nil {
return compute.ResourceSkusResultPage{}, f.err
}
return f.res, nil
}
//nolint:deadcode,unused
func newFailingFakeResourceProviderClient(reterr error) *fakeResourceProviderClient {
return &fakeResourceProviderClient{
res: compute.ResourceSkusResultPage{},
err: reterr,
}
}
// newSuccessfulFakeResourceProviderClient takes a list of sku lists and returns
// a ResourceProviderClient which iterates over all of them, mapping each sku
// list to a page of values.
func newSuccessfulFakeResourceProviderClient(skuLists [][]compute.ResourceSku) (*fakeResourceProviderClient, error) {
page, err := newFakeResourceSkusResultPage(skuLists)
if err != nil {
return nil, err
}
return &fakeResourceProviderClient{
res: page,
err: nil,
}, nil
}
// newFakeResourceSkusResultPage takes a list of sku lists and
// returns an iterator over all items, mapping each sku
// list to a page of values.
func newFakeResourceSkusResultPage(skuLists [][]compute.ResourceSku) (compute.ResourceSkusResultPage, error) {
pages := newPageList(skuLists)
newPage := compute.NewResourceSkusResultPage(compute.ResourceSkusResult{}, pages.next)
if err := newPage.NextWithContext(context.Background()); err != nil {
return compute.ResourceSkusResultPage{}, err
}
return newPage, nil
}
// newFakeResourceSkusResultIterator takes a list of sku lists and
// returns an iterator over all items, mapping each sku
// list to a page of values.
func newFakeResourceSkusResultIterator(skuLists [][]compute.ResourceSku) (compute.ResourceSkusResultIterator, error) {
pages := newPageList(skuLists)
newPage := compute.NewResourceSkusResultPage(compute.ResourceSkusResult{}, pages.next)
if err := newPage.NextWithContext(context.Background()); err != nil {
return compute.ResourceSkusResultIterator{}, err
}
return compute.NewResourceSkusResultIterator(newPage), nil
}
// chunk divides a list into count pieces.
func chunk(skus []compute.ResourceSku, count int) [][]compute.ResourceSku {
divided := [][]compute.ResourceSku{}
size := (len(skus) + count - 1) / count
for i := 0; i < len(skus); i += size {
end := i + size
if end > len(skus) {
end = len(skus)
}
divided = append(divided, skus[i:end])
}
return divided
}
// pageList is a utility type to help construct ResourceSkusResultIterators.
type pageList struct {
cursor int
pages []compute.ResourceSkusResult
}
func newPageList(skuLists [][]compute.ResourceSku) *pageList {
list := &pageList{}
for i := 0; i < len(skuLists); i++ {
list.pages = append(list.pages, compute.ResourceSkusResult{
Value: &skuLists[i],
})
}
return list
}
// next underpins ResourceSkusResultIterator's NextWithDone() method.
func (p *pageList) next(context.Context, compute.ResourceSkusResult) (compute.ResourceSkusResult, error) {
if p.cursor >= len(p.pages) {
return compute.ResourceSkusResult{}, nil
}
old := p.cursor
p.cursor++
return p.pages[old], nil
}