1// +build integration
2
3package hcn
4
5import (
6	"encoding/json"
7	"fmt"
8	"testing"
9
10	"github.com/Microsoft/go-winio/pkg/guid"
11	"github.com/Microsoft/hcsshim/internal/cni"
12)
13
14func newGUID(t *testing.T) guid.GUID {
15	g, err := guid.NewV4()
16	if err != nil {
17		t.Fatal(err)
18	}
19	return g
20}
21
22func TestNewNamespace(t *testing.T) {
23	_ = NewNamespace(NamespaceTypeHost)
24	_ = NewNamespace(NamespaceTypeHostDefault)
25	_ = NewNamespace(NamespaceTypeGuest)
26	_ = NewNamespace(NamespaceTypeGuestDefault)
27}
28
29func TestCreateDeleteNamespace(t *testing.T) {
30	namespace, err := HcnCreateTestNamespace()
31	if err != nil {
32		t.Fatal(err)
33	}
34
35	jsonString, err := json.Marshal(namespace)
36	if err != nil {
37		t.Fatal(err)
38	}
39	fmt.Printf("Namespace JSON:\n%s \n", jsonString)
40
41	err = namespace.Delete()
42	if err != nil {
43		t.Fatal(err)
44	}
45}
46
47func TestCreateDeleteNamespaceGuest(t *testing.T) {
48	namespace := &HostComputeNamespace{
49		Type: NamespaceTypeGuestDefault,
50		SchemaVersion: SchemaVersion{
51			Major: 2,
52			Minor: 0,
53		},
54	}
55
56	hnsNamespace, err := namespace.Create()
57	if err != nil {
58		t.Fatal(err)
59	}
60
61	err = hnsNamespace.Delete()
62	if err != nil {
63		t.Fatal(err)
64	}
65}
66
67func TestGetNamespaceById(t *testing.T) {
68	namespace, err := HcnCreateTestNamespace()
69	if err != nil {
70		t.Fatal(err)
71	}
72
73	foundNamespace, err := GetNamespaceByID(namespace.Id)
74	if err != nil {
75		t.Fatal(err)
76	}
77	if foundNamespace == nil {
78		t.Fatal("No namespace found")
79	}
80
81	err = namespace.Delete()
82	if err != nil {
83		t.Fatal(err)
84	}
85}
86
87func TestListNamespaces(t *testing.T) {
88	namespace, err := HcnCreateTestNamespace()
89	if err != nil {
90		t.Fatal(err)
91	}
92
93	foundNamespaces, err := ListNamespaces()
94	if err != nil {
95		t.Fatal(err)
96	}
97	if len(foundNamespaces) == 0 {
98		t.Fatal("No Namespaces found")
99	}
100
101	err = namespace.Delete()
102	if err != nil {
103		t.Fatal(err)
104	}
105}
106
107func TestGetNamespaceEndpointIds(t *testing.T) {
108	network, err := HcnCreateTestNATNetwork()
109	if err != nil {
110		t.Fatal(err)
111	}
112	endpoint, err := HcnCreateTestEndpoint(network)
113	if err != nil {
114		t.Fatal(err)
115	}
116	namespace, err := HcnCreateTestNamespace()
117	if err != nil {
118		t.Fatal(err)
119	}
120
121	err = endpoint.NamespaceAttach(namespace.Id)
122	if err != nil {
123		t.Fatal(err)
124	}
125	foundEndpoints, err := GetNamespaceEndpointIds(namespace.Id)
126	if err != nil {
127		t.Fatal(err)
128	}
129	if len(foundEndpoints) == 0 {
130		t.Fatal("No Endpoint found")
131	}
132	err = endpoint.NamespaceDetach(namespace.Id)
133	if err != nil {
134		t.Fatal(err)
135	}
136
137	err = namespace.Delete()
138	if err != nil {
139		t.Fatal(err)
140	}
141	err = endpoint.Delete()
142	if err != nil {
143		t.Fatal(err)
144	}
145	err = network.Delete()
146	if err != nil {
147		t.Fatal(err)
148	}
149}
150
151func TestGetNamespaceContainers(t *testing.T) {
152	namespace, err := HcnCreateTestNamespace()
153	if err != nil {
154		t.Fatal(err)
155	}
156
157	foundEndpoints, err := GetNamespaceContainerIds(namespace.Id)
158	if err != nil {
159		t.Fatal(err)
160	}
161	if len(foundEndpoints) != 0 {
162		t.Fatal("Found containers when none should exist")
163	}
164
165	err = namespace.Delete()
166	if err != nil {
167		t.Fatal(err)
168	}
169}
170
171func TestAddRemoveNamespaceEndpoint(t *testing.T) {
172	network, err := HcnCreateTestNATNetwork()
173	if err != nil {
174		t.Fatal(err)
175	}
176	endpoint, err := HcnCreateTestEndpoint(network)
177	if err != nil {
178		t.Fatal(err)
179	}
180	namespace, err := HcnCreateTestNamespace()
181	if err != nil {
182		t.Fatal(err)
183	}
184
185	err = AddNamespaceEndpoint(namespace.Id, endpoint.Id)
186	if err != nil {
187		t.Fatal(err)
188	}
189	foundEndpoints, err := GetNamespaceEndpointIds(namespace.Id)
190	if err != nil {
191		t.Fatal(err)
192	}
193	if len(foundEndpoints) == 0 {
194		t.Fatal("No Endpoint found")
195	}
196	err = RemoveNamespaceEndpoint(namespace.Id, endpoint.Id)
197	if err != nil {
198		t.Fatal(err)
199	}
200
201	err = namespace.Delete()
202	if err != nil {
203		t.Fatal(err)
204	}
205	err = endpoint.Delete()
206	if err != nil {
207		t.Fatal(err)
208	}
209	err = network.Delete()
210	if err != nil {
211		t.Fatal(err)
212	}
213}
214
215func TestModifyNamespaceSettings(t *testing.T) {
216	network, err := HcnCreateTestNATNetwork()
217	if err != nil {
218		t.Fatal(err)
219	}
220	endpoint, err := HcnCreateTestEndpoint(network)
221	if err != nil {
222		t.Fatal(err)
223	}
224	namespace, err := HcnCreateTestNamespace()
225	if err != nil {
226		t.Fatal(err)
227	}
228
229	mapA := map[string]string{"EndpointId": endpoint.Id}
230	settingsJson, err := json.Marshal(mapA)
231	if err != nil {
232		t.Fatal(err)
233	}
234	requestMessage := &ModifyNamespaceSettingRequest{
235		ResourceType: NamespaceResourceTypeEndpoint,
236		RequestType:  RequestTypeAdd,
237		Settings:     settingsJson,
238	}
239
240	err = ModifyNamespaceSettings(namespace.Id, requestMessage)
241	if err != nil {
242		t.Fatal(err)
243	}
244	foundEndpoints, err := GetNamespaceEndpointIds(namespace.Id)
245	if err != nil {
246		t.Fatal(err)
247	}
248	if len(foundEndpoints) == 0 {
249		t.Fatal("No Endpoint found")
250	}
251	err = RemoveNamespaceEndpoint(namespace.Id, endpoint.Id)
252	if err != nil {
253		t.Fatal(err)
254	}
255
256	err = namespace.Delete()
257	if err != nil {
258		t.Fatal(err)
259	}
260	err = endpoint.Delete()
261	if err != nil {
262		t.Fatal(err)
263	}
264	err = network.Delete()
265	if err != nil {
266		t.Fatal(err)
267	}
268}
269
270// Sync Tests
271
272func TestSyncNamespaceHostDefault(t *testing.T) {
273	namespace := &HostComputeNamespace{
274		Type:        NamespaceTypeHostDefault,
275		NamespaceId: 5,
276		SchemaVersion: SchemaVersion{
277			Major: 2,
278			Minor: 0,
279		},
280	}
281
282	hnsNamespace, err := namespace.Create()
283	if err != nil {
284		t.Fatal(err)
285	}
286
287	// Host namespace types should be no-op success
288	err = hnsNamespace.Sync()
289	if err != nil {
290		t.Fatal(err)
291	}
292
293	err = hnsNamespace.Delete()
294	if err != nil {
295		t.Fatal(err)
296	}
297}
298
299func TestSyncNamespaceHost(t *testing.T) {
300	namespace := &HostComputeNamespace{
301		Type:        NamespaceTypeHost,
302		NamespaceId: 5,
303		SchemaVersion: SchemaVersion{
304			Major: 2,
305			Minor: 0,
306		},
307	}
308
309	hnsNamespace, err := namespace.Create()
310	if err != nil {
311		t.Fatal(err)
312	}
313
314	// Host namespace types should be no-op success
315	err = hnsNamespace.Sync()
316	if err != nil {
317		t.Fatal(err)
318	}
319
320	err = hnsNamespace.Delete()
321	if err != nil {
322		t.Fatal(err)
323	}
324}
325
326func TestSyncNamespaceGuestNoReg(t *testing.T) {
327	namespace := &HostComputeNamespace{
328		Type:        NamespaceTypeGuest,
329		NamespaceId: 5,
330		SchemaVersion: SchemaVersion{
331			Major: 2,
332			Minor: 0,
333		},
334	}
335
336	hnsNamespace, err := namespace.Create()
337	if err != nil {
338		t.Fatal(err)
339	}
340
341	// Guest namespace type with out reg state should be no-op success
342	err = hnsNamespace.Sync()
343	if err != nil {
344		t.Fatal(err)
345	}
346
347	err = hnsNamespace.Delete()
348	if err != nil {
349		t.Fatal(err)
350	}
351}
352
353func TestSyncNamespaceGuestDefaultNoReg(t *testing.T) {
354	namespace := &HostComputeNamespace{
355		Type:        NamespaceTypeGuestDefault,
356		NamespaceId: 5,
357		SchemaVersion: SchemaVersion{
358			Major: 2,
359			Minor: 0,
360		},
361	}
362
363	hnsNamespace, err := namespace.Create()
364	if err != nil {
365		t.Fatal(err)
366	}
367
368	// Guest namespace type with out reg state should be no-op success
369	err = hnsNamespace.Sync()
370	if err != nil {
371		t.Fatal(err)
372	}
373
374	err = hnsNamespace.Delete()
375	if err != nil {
376		t.Fatal(err)
377	}
378}
379
380func TestSyncNamespaceGuest(t *testing.T) {
381	namespace := &HostComputeNamespace{
382		Type:        NamespaceTypeGuest,
383		NamespaceId: 5,
384		SchemaVersion: SchemaVersion{
385			Major: 2,
386			Minor: 0,
387		},
388	}
389
390	hnsNamespace, err := namespace.Create()
391
392	if err != nil {
393		t.Fatal(err)
394	}
395
396	// Create registry state
397	pnc := cni.NewPersistedNamespaceConfig(t.Name(), "test-container", newGUID(t))
398	err = pnc.Store()
399	if err != nil {
400		pnc.Remove()
401		t.Fatal(err)
402	}
403
404	// Guest namespace type with reg state but not Vm shim should pass...
405	// after trying to connect to VM shim that it doesn't find and remove the Key so it doesn't look again.
406	err = hnsNamespace.Sync()
407	if err != nil {
408		t.Fatal(err)
409	}
410
411	err = pnc.Remove()
412	if err != nil {
413		t.Fatal(err)
414	}
415	err = hnsNamespace.Delete()
416	if err != nil {
417		t.Fatal(err)
418	}
419}
420
421func TestSyncNamespaceGuestDefault(t *testing.T) {
422	namespace := &HostComputeNamespace{
423		Type:        NamespaceTypeGuestDefault,
424		NamespaceId: 5,
425		SchemaVersion: SchemaVersion{
426			Major: 2,
427			Minor: 0,
428		},
429	}
430
431	hnsNamespace, err := namespace.Create()
432	if err != nil {
433		t.Fatal(err)
434	}
435
436	// Create registry state
437	pnc := cni.NewPersistedNamespaceConfig(t.Name(), "test-container", newGUID(t))
438	err = pnc.Store()
439	if err != nil {
440		pnc.Remove()
441		t.Fatal(err)
442	}
443
444	// Guest namespace type with reg state but not Vm shim should pass...
445	// after trying to connect to VM shim that it doesn't find and remove the Key so it doesn't look again.
446	err = hnsNamespace.Sync()
447	if err != nil {
448		t.Fatal(err)
449	}
450
451	err = pnc.Remove()
452	if err != nil {
453		t.Fatal(err)
454	}
455	err = hnsNamespace.Delete()
456	if err != nil {
457		t.Fatal(err)
458	}
459}
460