3
3
package function_test
4
4
5
5
import (
6
+ "os"
7
+ "reflect"
8
+ "testing"
9
+ "time"
10
+
6
11
boson "github.com/boson-project/func"
12
+ "github.com/boson-project/func/buildpacks"
13
+ "github.com/boson-project/func/docker"
7
14
"github.com/boson-project/func/knative"
8
- "testing"
9
15
)
10
16
11
17
/*
@@ -35,7 +41,16 @@ import (
35
41
./hack/delete.sh
36
42
*/
37
43
38
- const DefaultNamespace = "func"
44
+ const (
45
+ // DefaultRegistry must contain both the registry host and
46
+ // registry namespace at this time. This will likely be
47
+ // split and defaulted to the forthcoming in-cluster registry.
48
+ DefaultRegistry = "localhost:5000/func"
49
+
50
+ // DefaultNamespace for the underlying deployments. Must be the same
51
+ // as is set up and configured (see hack/configure.sh)
52
+ DefaultNamespace = "func"
53
+ )
39
54
40
55
func TestList (t * testing.T ) {
41
56
verbose := true
@@ -60,3 +75,211 @@ func TestList(t *testing.T) {
60
75
t .Fatalf ("Expected no Functions, got %v" , names )
61
76
}
62
77
}
78
+
79
+ // TestNew creates
80
+ func TestNew (t * testing.T ) {
81
+ defer within (t , "testdata/example.com/testnew" )()
82
+ verbose := true
83
+
84
+ client := newClient (verbose )
85
+
86
+ // Act
87
+ if err := client .New (boson.Function {Name : "testnew" , Root : "." , Runtime : "go" }); err != nil {
88
+ t .Fatal (err )
89
+ }
90
+ defer del (t , client , "testnew" )
91
+
92
+ // Assert
93
+ names , err := client .List ()
94
+ if err != nil {
95
+ t .Fatal (err )
96
+ }
97
+ if ! reflect .DeepEqual (names , []string {"testnew" }) {
98
+ t .Fatalf ("Expected function list ['testnew'], got %v" , names )
99
+ }
100
+ }
101
+
102
+ // TestDeploy updates
103
+ func TestDeploy (t * testing.T ) {
104
+ defer within (t , "testdata/example.com/deploy" )()
105
+ verbose := true
106
+
107
+ client := newClient (verbose )
108
+
109
+ if err := client .New (boson.Function {Name : "deploy" , Root : "." , Runtime : "go" }); err != nil {
110
+ t .Fatal (err )
111
+ }
112
+ defer del (t , client , "deploy" )
113
+
114
+ if err := client .Deploy ("." ); err != nil {
115
+ t .Fatal (err )
116
+ }
117
+ }
118
+
119
+ // TestRemove deletes
120
+ func TestRemove (t * testing.T ) {
121
+ defer within (t , "testdata/example.com/remove" )()
122
+ verbose := true
123
+
124
+ client := newClient (verbose )
125
+
126
+ if err := client .New (boson.Function {Name : "remove" , Root : "." , Runtime : "go" }); err != nil {
127
+ t .Fatal (err )
128
+ }
129
+ waitFor (t , client , "remove" )
130
+
131
+ if err := client .Remove (boson.Function {Name : "remove" }); err != nil {
132
+ t .Fatal (err )
133
+ }
134
+
135
+ names , err := client .List ()
136
+ if err != nil {
137
+ t .Fatal (err )
138
+ }
139
+ if len (names ) != 0 {
140
+ t .Fatalf ("Expected empty Functions list, got %v" , names )
141
+ }
142
+ }
143
+
144
+ // ***********
145
+ // Helpers
146
+ // ***********
147
+
148
+ // newClient creates an instance of the func client whose concrete impls
149
+ // match those created by the kn func plugin CLI.
150
+ func newClient (verbose bool ) * boson.Client {
151
+ builder := buildpacks .NewBuilder ()
152
+ builder .Verbose = verbose
153
+
154
+ pusher := docker .NewPusher ()
155
+ pusher .Verbose = verbose
156
+
157
+ deployer , err := knative .NewDeployer (DefaultNamespace )
158
+ if err != nil {
159
+ panic (err ) // TODO: remove error from deployer constructor
160
+ }
161
+ deployer .Verbose = verbose
162
+
163
+ remover , err := knative .NewRemover (DefaultNamespace )
164
+ if err != nil {
165
+ panic (err ) // TODO: remove error from remover constructor
166
+ }
167
+ remover .Verbose = verbose
168
+
169
+ lister , err := knative .NewLister (DefaultNamespace )
170
+ if err != nil {
171
+ panic (err ) // TODO: remove error from lister constructor
172
+ }
173
+ lister .Verbose = verbose
174
+
175
+ return boson .New (
176
+ boson .WithRegistry (DefaultRegistry ),
177
+ boson .WithVerbose (verbose ),
178
+ boson .WithBuilder (builder ),
179
+ boson .WithPusher (pusher ),
180
+ boson .WithDeployer (deployer ),
181
+ boson .WithRemover (remover ),
182
+ boson .WithLister (lister ),
183
+ )
184
+ }
185
+
186
+ // Del cleans up after a test by removing a function by name.
187
+ // (test fails if the named function does not exist)
188
+ //
189
+ // Intended to be run in a defer statement immediately after creation, del
190
+ // works around the asynchronicity of the underlying platform's creation
191
+ // step by polling the provider until the names function becomes available
192
+ // (or the test times out), before firing off a deletion request.
193
+ // Of course, ideally this would be replaced by the use of a synchronous
194
+ // method, or at a minimum a way to register a callback/listener for the
195
+ // creation event. This is what we have for now, and the show must go on.
196
+ func del (t * testing.T , c * boson.Client , name string ) {
197
+ t .Helper ()
198
+ waitFor (t , c , name )
199
+ if err := c .Remove (boson.Function {Name : name }); err != nil {
200
+ t .Fatal (err )
201
+ }
202
+ }
203
+
204
+ // waitFor the named Function to become available in List output.
205
+ // TODO: the API should be synchronous, but that depends first on
206
+ // Create returning the derived name such that we can bake polling in.
207
+ // Ideally the Boson provider's Creaet would be made syncrhonous.
208
+ func waitFor (t * testing.T , c * boson.Client , name string ) {
209
+ t .Helper ()
210
+ var pollInterval = 2 * time .Second
211
+
212
+ for { // ever (i.e. defer to global test timeout)
213
+ nn , err := c .List ()
214
+ if err != nil {
215
+ t .Fatal (err )
216
+ }
217
+ for _ , n := range nn {
218
+ if n .Name == name {
219
+ return
220
+ }
221
+ }
222
+ time .Sleep (pollInterval )
223
+ }
224
+ }
225
+
226
+ // Create the given directory, CD to it, and return a function which can be
227
+ // run in a defer statement to return to the original directory and cleanup.
228
+ // Note must be executed, not deferred itself
229
+ // NO: defer within(t, "somedir")
230
+ // YES: defer within(t, "somedir")()
231
+ func within (t * testing.T , root string ) func () {
232
+ t .Helper ()
233
+ cwd := pwd (t )
234
+ mkdir (t , root )
235
+ cd (t , root )
236
+ return func () {
237
+ cd (t , cwd )
238
+ rm (t , root )
239
+ }
240
+ }
241
+
242
+ func pwd (t * testing.T ) string {
243
+ t .Helper ()
244
+ dir , err := os .Getwd ()
245
+ if err != nil {
246
+ t .Fatal (err )
247
+ }
248
+ return dir
249
+ }
250
+
251
+ func mkdir (t * testing.T , dir string ) {
252
+ t .Helper ()
253
+ if err := os .MkdirAll (dir , 0700 ); err != nil {
254
+ t .Fatal (err )
255
+ }
256
+ }
257
+
258
+ func cd (t * testing.T , dir string ) {
259
+ t .Helper ()
260
+ if err := os .Chdir (dir ); err != nil {
261
+ t .Fatal (err )
262
+ }
263
+ }
264
+
265
+ func rm (t * testing.T , dir string ) {
266
+ t .Helper ()
267
+ if err := os .RemoveAll (dir ); err != nil {
268
+ t .Fatal (err )
269
+ }
270
+ }
271
+
272
+ func touch (file string ) {
273
+ _ , err := os .Stat (file )
274
+ if os .IsNotExist (err ) {
275
+ f , err := os .Create (file )
276
+ if err != nil {
277
+ panic (err )
278
+ }
279
+ defer f .Close ()
280
+ }
281
+ t := time .Now ().Local ()
282
+ if err := os .Chtimes (file , t , t ); err != nil {
283
+ panic (err )
284
+ }
285
+ }
0 commit comments