1// +build functional
2
3package cri_containerd
4
5import (
6	"context"
7	"fmt"
8	"io/ioutil"
9	"os"
10	"path/filepath"
11	"testing"
12
13	"github.com/Microsoft/go-winio"
14	"github.com/Microsoft/hcsshim/osversion"
15	testutilities "github.com/Microsoft/hcsshim/test/functional/utilities"
16	runtime "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
17)
18
19func runCreateContainerTest(t *testing.T, runtimeHandler string, request *runtime.CreateContainerRequest) {
20	sandboxRequest := getRunPodSandboxRequest(t, runtimeHandler)
21	runCreateContainerTestWithSandbox(t, sandboxRequest, request)
22}
23
24func runCreateContainerTestWithSandbox(t *testing.T, sandboxRequest *runtime.RunPodSandboxRequest, request *runtime.CreateContainerRequest) {
25	client := newTestRuntimeClient(t)
26	ctx, cancel := context.WithCancel(context.Background())
27	defer cancel()
28
29	podID := runPodSandbox(t, client, ctx, sandboxRequest)
30	defer removePodSandbox(t, client, ctx, podID)
31	defer stopPodSandbox(t, client, ctx, podID)
32
33	request.PodSandboxId = podID
34	request.SandboxConfig = sandboxRequest.Config
35
36	containerID := createContainer(t, client, ctx, request)
37	defer removeContainer(t, client, ctx, containerID)
38
39	startContainer(t, client, ctx, containerID)
40	stopContainer(t, client, ctx, containerID)
41}
42
43func Test_CreateContainer_WCOW_Process(t *testing.T) {
44	requireFeatures(t, featureWCOWProcess)
45
46	pullRequiredImages(t, []string{imageWindowsNanoserver})
47
48	request := &runtime.CreateContainerRequest{
49		Config: &runtime.ContainerConfig{
50			Metadata: &runtime.ContainerMetadata{
51				Name: t.Name() + "-Container",
52			},
53			Image: &runtime.ImageSpec{
54				Image: imageWindowsNanoserver,
55			},
56			// Hold this command open until killed (pause for Windows)
57			Command: []string{
58				"cmd",
59				"/c",
60				"ping",
61				"-t",
62				"127.0.0.1",
63			},
64		},
65	}
66	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
67}
68
69func Test_CreateContainer_WCOW_Hypervisor(t *testing.T) {
70	requireFeatures(t, featureWCOWHypervisor)
71
72	pullRequiredImages(t, []string{imageWindowsNanoserver})
73
74	request := &runtime.CreateContainerRequest{
75		Config: &runtime.ContainerConfig{
76			Metadata: &runtime.ContainerMetadata{
77				Name: t.Name() + "-Container",
78			},
79			Image: &runtime.ImageSpec{
80				Image: imageWindowsNanoserver,
81			},
82			// Hold this command open until killed (pause for Windows)
83			Command: []string{
84				"cmd",
85				"/c",
86				"ping",
87				"-t",
88				"127.0.0.1",
89			},
90		},
91	}
92	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
93}
94
95func Test_CreateContainer_LCOW(t *testing.T) {
96	requireFeatures(t, featureLCOW)
97
98	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
99
100	request := &runtime.CreateContainerRequest{
101		Config: &runtime.ContainerConfig{
102			Metadata: &runtime.ContainerMetadata{
103				Name: t.Name() + "-Container",
104			},
105			Image: &runtime.ImageSpec{
106				Image: imageLcowAlpine,
107			},
108			// Hold this command open until killed
109			Command: []string{
110				"top",
111			},
112		},
113	}
114	runCreateContainerTest(t, lcowRuntimeHandler, request)
115}
116
117func Test_CreateContainer_WCOW_Process_Tty(t *testing.T) {
118	requireFeatures(t, featureWCOWProcess)
119
120	pullRequiredImages(t, []string{imageWindowsNanoserver})
121
122	request := &runtime.CreateContainerRequest{
123		Config: &runtime.ContainerConfig{
124			Metadata: &runtime.ContainerMetadata{
125				Name: t.Name() + "-Container",
126			},
127			Image: &runtime.ImageSpec{
128				Image: imageWindowsNanoserver,
129			},
130			// Tty will hold this open until killed.
131			Command: []string{
132				"cmd",
133			},
134			Tty: true,
135		},
136	}
137	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
138}
139
140func Test_CreateContainer_WCOW_Hypervisor_Tty(t *testing.T) {
141	requireFeatures(t, featureWCOWHypervisor)
142
143	pullRequiredImages(t, []string{imageWindowsNanoserver})
144
145	request := &runtime.CreateContainerRequest{
146		Config: &runtime.ContainerConfig{
147			Metadata: &runtime.ContainerMetadata{
148				Name: t.Name() + "-Container",
149			},
150			Image: &runtime.ImageSpec{
151				Image: imageWindowsNanoserver,
152			},
153			// Tty will hold this open until killed.
154			Command: []string{
155				"cmd",
156			},
157			Tty: true,
158		},
159	}
160	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
161}
162
163func Test_CreateContainer_LCOW_Tty(t *testing.T) {
164	requireFeatures(t, featureLCOW)
165
166	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
167
168	request := &runtime.CreateContainerRequest{
169		Config: &runtime.ContainerConfig{
170			Metadata: &runtime.ContainerMetadata{
171				Name: t.Name() + "-Container",
172			},
173			Image: &runtime.ImageSpec{
174				Image: imageLcowAlpine,
175			},
176			// Tty will hold this open until killed.
177			Command: []string{
178				"sh",
179			},
180			Tty: true,
181		},
182	}
183	runCreateContainerTest(t, lcowRuntimeHandler, request)
184}
185
186func Test_CreateContainer_LCOW_Privileged(t *testing.T) {
187	requireFeatures(t, featureLCOW)
188
189	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
190
191	sandboxRequest := getRunPodSandboxRequest(t, lcowRuntimeHandler)
192	sandboxRequest.Config.Linux = &runtime.LinuxPodSandboxConfig{
193		SecurityContext: &runtime.LinuxSandboxSecurityContext{
194			Privileged: true,
195		},
196	}
197
198	request := &runtime.CreateContainerRequest{
199		Config: &runtime.ContainerConfig{
200			Metadata: &runtime.ContainerMetadata{
201				Name: t.Name() + "-Container",
202			},
203			Image: &runtime.ImageSpec{
204				Image: imageLcowAlpine,
205			},
206			// Hold this command open until killed
207			Command: []string{
208				"top",
209			},
210			Linux: &runtime.LinuxContainerConfig{
211				SecurityContext: &runtime.LinuxContainerSecurityContext{
212					Privileged: true,
213				},
214			},
215		},
216	}
217	runCreateContainerTestWithSandbox(t, sandboxRequest, request)
218}
219
220func Test_CreateContainer_SandboxDevice_LCOW(t *testing.T) {
221	requireFeatures(t, featureLCOW)
222
223	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
224
225	sandboxRequest := getRunPodSandboxRequest(t, lcowRuntimeHandler)
226	sandboxRequest.Config.Linux = &runtime.LinuxPodSandboxConfig{
227		SecurityContext: &runtime.LinuxSandboxSecurityContext{
228			Privileged: true,
229		},
230	}
231
232	request := &runtime.CreateContainerRequest{
233		Config: &runtime.ContainerConfig{
234			Metadata: &runtime.ContainerMetadata{
235				Name: t.Name() + "-Container",
236			},
237			Image: &runtime.ImageSpec{
238				Image: imageLcowAlpine,
239			},
240			// Hold this command open until killed
241			Command: []string{
242				"top",
243			},
244			Devices: []*runtime.Device{
245				{
246					HostPath: "/dev/fuse",
247				},
248			},
249		},
250	}
251	runCreateContainerTestWithSandbox(t, sandboxRequest, request)
252}
253
254func Test_CreateContainer_MemorySize_Config_WCOW_Process(t *testing.T) {
255	requireFeatures(t, featureWCOWProcess)
256
257	pullRequiredImages(t, []string{imageWindowsNanoserver})
258
259	request := &runtime.CreateContainerRequest{
260		Config: &runtime.ContainerConfig{
261			Metadata: &runtime.ContainerMetadata{
262				Name: t.Name() + "-Container",
263			},
264			Image: &runtime.ImageSpec{
265				Image: imageWindowsNanoserver,
266			},
267			// Hold this command open until killed (pause for Windows)
268			Command: []string{
269				"cmd",
270				"/c",
271				"ping",
272				"-t",
273				"127.0.0.1",
274			},
275			Windows: &runtime.WindowsContainerConfig{
276				Resources: &runtime.WindowsContainerResources{
277					MemoryLimitInBytes: 768 * 1024 * 1024, // 768MB
278				},
279			},
280		},
281	}
282	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
283}
284
285func Test_CreateContainer_MemorySize_Annotation_WCOW_Process(t *testing.T) {
286	requireFeatures(t, featureWCOWProcess)
287
288	pullRequiredImages(t, []string{imageWindowsNanoserver})
289
290	request := &runtime.CreateContainerRequest{
291		Config: &runtime.ContainerConfig{
292			Metadata: &runtime.ContainerMetadata{
293				Name: t.Name() + "-Container",
294			},
295			Image: &runtime.ImageSpec{
296				Image: imageWindowsNanoserver,
297			},
298			// Hold this command open until killed (pause for Windows)
299			Command: []string{
300				"cmd",
301				"/c",
302				"ping",
303				"-t",
304				"127.0.0.1",
305			},
306			Annotations: map[string]string{
307				"io.microsoft.container.memory.sizeinmb": fmt.Sprintf("%d", 768*1024*1024), // 768MB
308			},
309		},
310	}
311	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
312}
313
314func Test_CreateContainer_MemorySize_Config_WCOW_Hypervisor(t *testing.T) {
315	requireFeatures(t, featureWCOWHypervisor)
316
317	pullRequiredImages(t, []string{imageWindowsNanoserver})
318
319	request := &runtime.CreateContainerRequest{
320		Config: &runtime.ContainerConfig{
321			Metadata: &runtime.ContainerMetadata{
322				Name: t.Name() + "-Container",
323			},
324			Image: &runtime.ImageSpec{
325				Image: imageWindowsNanoserver,
326			},
327			// Hold this command open until killed (pause for Windows)
328			Command: []string{
329				"cmd",
330				"/c",
331				"ping",
332				"-t",
333				"127.0.0.1",
334			},
335			Windows: &runtime.WindowsContainerConfig{
336				Resources: &runtime.WindowsContainerResources{
337					MemoryLimitInBytes: 768 * 1024 * 1024, // 768MB
338				},
339			},
340		},
341	}
342	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
343}
344
345func Test_CreateContainer_MemorySize_Annotation_WCOW_Hypervisor(t *testing.T) {
346	requireFeatures(t, featureWCOWHypervisor)
347
348	pullRequiredImages(t, []string{imageWindowsNanoserver})
349
350	request := &runtime.CreateContainerRequest{
351		Config: &runtime.ContainerConfig{
352			Metadata: &runtime.ContainerMetadata{
353				Name: t.Name() + "-Container",
354			},
355			Image: &runtime.ImageSpec{
356				Image: imageWindowsNanoserver,
357			},
358			// Hold this command open until killed (pause for Windows)
359			Command: []string{
360				"cmd",
361				"/c",
362				"ping",
363				"-t",
364				"127.0.0.1",
365			},
366			Annotations: map[string]string{
367				"io.microsoft.container.memory.sizeinmb": fmt.Sprintf("%d", 768*1024*1024), // 768MB
368			},
369		},
370	}
371	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
372}
373
374func Test_CreateContainer_MemorySize_LCOW(t *testing.T) {
375	requireFeatures(t, featureLCOW)
376
377	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
378
379	request := &runtime.CreateContainerRequest{
380		Config: &runtime.ContainerConfig{
381			Metadata: &runtime.ContainerMetadata{
382				Name: t.Name() + "-Container",
383			},
384			Image: &runtime.ImageSpec{
385				Image: imageLcowAlpine,
386			},
387			// Hold this command open until killed
388			Command: []string{
389				"top",
390			},
391			Linux: &runtime.LinuxContainerConfig{
392				Resources: &runtime.LinuxContainerResources{
393					MemoryLimitInBytes: 768 * 1024 * 1024, // 768MB
394				},
395			},
396		},
397	}
398	runCreateContainerTest(t, lcowRuntimeHandler, request)
399}
400
401func Test_CreateContainer_CPUCount_Config_WCOW_Process(t *testing.T) {
402	requireFeatures(t, featureWCOWProcess)
403
404	pullRequiredImages(t, []string{imageWindowsNanoserver})
405
406	request := &runtime.CreateContainerRequest{
407		Config: &runtime.ContainerConfig{
408			Metadata: &runtime.ContainerMetadata{
409				Name: t.Name() + "-Container",
410			},
411			Image: &runtime.ImageSpec{
412				Image: imageWindowsNanoserver,
413			},
414			// Hold this command open until killed (pause for Windows)
415			Command: []string{
416				"cmd",
417				"/c",
418				"ping",
419				"-t",
420				"127.0.0.1",
421			},
422			Windows: &runtime.WindowsContainerConfig{
423				Resources: &runtime.WindowsContainerResources{
424					CpuCount: 1,
425				},
426			},
427		},
428	}
429	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
430}
431
432func Test_CreateContainer_CPUCount_Annotation_WCOW_Process(t *testing.T) {
433	requireFeatures(t, featureWCOWProcess)
434
435	pullRequiredImages(t, []string{imageWindowsNanoserver})
436
437	request := &runtime.CreateContainerRequest{
438		Config: &runtime.ContainerConfig{
439			Metadata: &runtime.ContainerMetadata{
440				Name: t.Name() + "-Container",
441			},
442			Image: &runtime.ImageSpec{
443				Image: imageWindowsNanoserver,
444			},
445			// Hold this command open until killed (pause for Windows)
446			Command: []string{
447				"cmd",
448				"/c",
449				"ping",
450				"-t",
451				"127.0.0.1",
452			},
453			Annotations: map[string]string{
454				"io.microsoft.container.processor.count": "1",
455			},
456		},
457	}
458	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
459}
460
461func Test_CreateContainer_CPUCount_Config_WCOW_Hypervisor(t *testing.T) {
462	requireFeatures(t, featureWCOWHypervisor)
463
464	pullRequiredImages(t, []string{imageWindowsNanoserver})
465
466	request := &runtime.CreateContainerRequest{
467		Config: &runtime.ContainerConfig{
468			Metadata: &runtime.ContainerMetadata{
469				Name: t.Name() + "-Container",
470			},
471			Image: &runtime.ImageSpec{
472				Image: imageWindowsNanoserver,
473			},
474			// Hold this command open until killed (pause for Windows)
475			Command: []string{
476				"cmd",
477				"/c",
478				"ping",
479				"-t",
480				"127.0.0.1",
481			},
482			Windows: &runtime.WindowsContainerConfig{
483				Resources: &runtime.WindowsContainerResources{
484					CpuCount: 1,
485				},
486			},
487		},
488	}
489	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
490}
491
492func Test_CreateContainer_CPUCount_Annotation_WCOW_Hypervisor(t *testing.T) {
493	requireFeatures(t, featureWCOWHypervisor)
494
495	pullRequiredImages(t, []string{imageWindowsNanoserver})
496
497	request := &runtime.CreateContainerRequest{
498		Config: &runtime.ContainerConfig{
499			Metadata: &runtime.ContainerMetadata{
500				Name: t.Name() + "-Container",
501			},
502			Image: &runtime.ImageSpec{
503				Image: imageWindowsNanoserver,
504			},
505			// Hold this command open until killed (pause for Windows)
506			Command: []string{
507				"cmd",
508				"/c",
509				"ping",
510				"-t",
511				"127.0.0.1",
512			},
513			Annotations: map[string]string{
514				"io.microsoft.container.processor.count": "1",
515			},
516		},
517	}
518	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
519}
520
521func Test_CreateContainer_CPUCount_LCOW(t *testing.T) {
522	requireFeatures(t, featureLCOW)
523
524	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
525
526	request := &runtime.CreateContainerRequest{
527		Config: &runtime.ContainerConfig{
528			Metadata: &runtime.ContainerMetadata{
529				Name: t.Name() + "-Container",
530			},
531			Image: &runtime.ImageSpec{
532				Image: imageLcowAlpine,
533			},
534			// Hold this command open until killed
535			Command: []string{
536				"top",
537			},
538			Linux: &runtime.LinuxContainerConfig{
539				Resources: &runtime.LinuxContainerResources{
540					CpusetCpus: "0",
541				},
542			},
543		},
544	}
545	runCreateContainerTest(t, lcowRuntimeHandler, request)
546}
547
548func Test_CreateContainer_CPULimit_Config_WCOW_Process(t *testing.T) {
549	requireFeatures(t, featureWCOWProcess)
550
551	pullRequiredImages(t, []string{imageWindowsNanoserver})
552
553	request := &runtime.CreateContainerRequest{
554		Config: &runtime.ContainerConfig{
555			Metadata: &runtime.ContainerMetadata{
556				Name: t.Name() + "-Container",
557			},
558			Image: &runtime.ImageSpec{
559				Image: imageWindowsNanoserver,
560			},
561			// Hold this command open until killed (pause for Windows)
562			Command: []string{
563				"cmd",
564				"/c",
565				"ping",
566				"-t",
567				"127.0.0.1",
568			},
569			Windows: &runtime.WindowsContainerConfig{
570				Resources: &runtime.WindowsContainerResources{
571					CpuMaximum: 9000,
572				},
573			},
574		},
575	}
576	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
577}
578
579func Test_CreateContainer_CPULimit_Annotation_WCOW_Process(t *testing.T) {
580	requireFeatures(t, featureWCOWProcess)
581
582	pullRequiredImages(t, []string{imageWindowsNanoserver})
583
584	request := &runtime.CreateContainerRequest{
585		Config: &runtime.ContainerConfig{
586			Metadata: &runtime.ContainerMetadata{
587				Name: t.Name() + "-Container",
588			},
589			Image: &runtime.ImageSpec{
590				Image: imageWindowsNanoserver,
591			},
592			// Hold this command open until killed (pause for Windows)
593			Command: []string{
594				"cmd",
595				"/c",
596				"ping",
597				"-t",
598				"127.0.0.1",
599			},
600			Annotations: map[string]string{
601				"io.microsoft.container.processor.limit": "9000",
602			},
603		},
604	}
605	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
606}
607
608func Test_CreateContainer_CPULimit_Config_WCOW_Hypervisor(t *testing.T) {
609	requireFeatures(t, featureWCOWHypervisor)
610
611	pullRequiredImages(t, []string{imageWindowsNanoserver})
612
613	request := &runtime.CreateContainerRequest{
614		Config: &runtime.ContainerConfig{
615			Metadata: &runtime.ContainerMetadata{
616				Name: t.Name() + "-Container",
617			},
618			Image: &runtime.ImageSpec{
619				Image: imageWindowsNanoserver,
620			},
621			// Hold this command open until killed (pause for Windows)
622			Command: []string{
623				"cmd",
624				"/c",
625				"ping",
626				"-t",
627				"127.0.0.1",
628			},
629			Windows: &runtime.WindowsContainerConfig{
630				Resources: &runtime.WindowsContainerResources{
631					CpuMaximum: 9000,
632				},
633			},
634		},
635	}
636	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
637}
638
639func Test_CreateContainer_CPULimit_Annotation_WCOW_Hypervisor(t *testing.T) {
640	requireFeatures(t, featureWCOWHypervisor)
641
642	pullRequiredImages(t, []string{imageWindowsNanoserver})
643
644	request := &runtime.CreateContainerRequest{
645		Config: &runtime.ContainerConfig{
646			Metadata: &runtime.ContainerMetadata{
647				Name: t.Name() + "-Container",
648			},
649			Image: &runtime.ImageSpec{
650				Image: imageWindowsNanoserver,
651			},
652			// Hold this command open until killed (pause for Windows)
653			Command: []string{
654				"cmd",
655				"/c",
656				"ping",
657				"-t",
658				"127.0.0.1",
659			},
660			Annotations: map[string]string{
661				"io.microsoft.container.processor.limit": "9000",
662			},
663		},
664	}
665	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
666}
667
668func Test_CreateContainer_CPUQuota_LCOW(t *testing.T) {
669	requireFeatures(t, featureLCOW)
670
671	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
672
673	request := &runtime.CreateContainerRequest{
674		Config: &runtime.ContainerConfig{
675			Metadata: &runtime.ContainerMetadata{
676				Name: t.Name() + "-Container",
677			},
678			Image: &runtime.ImageSpec{
679				Image: imageLcowAlpine,
680			},
681			// Hold this command open until killed
682			Command: []string{
683				"top",
684			},
685			Linux: &runtime.LinuxContainerConfig{
686				Resources: &runtime.LinuxContainerResources{
687					CpuQuota:  1000000,
688					CpuPeriod: 500000,
689				},
690			},
691		},
692	}
693	runCreateContainerTest(t, lcowRuntimeHandler, request)
694}
695
696func Test_CreateContainer_CPUWeight_Config_WCOW_Process(t *testing.T) {
697	requireFeatures(t, featureWCOWProcess)
698
699	pullRequiredImages(t, []string{imageWindowsNanoserver})
700
701	request := &runtime.CreateContainerRequest{
702		Config: &runtime.ContainerConfig{
703			Metadata: &runtime.ContainerMetadata{
704				Name: t.Name() + "-Container",
705			},
706			Image: &runtime.ImageSpec{
707				Image: imageWindowsNanoserver,
708			},
709			// Hold this command open until killed (pause for Windows)
710			Command: []string{
711				"cmd",
712				"/c",
713				"ping",
714				"-t",
715				"127.0.0.1",
716			},
717			Windows: &runtime.WindowsContainerConfig{
718				Resources: &runtime.WindowsContainerResources{
719					CpuShares: 500,
720				},
721			},
722		},
723	}
724	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
725}
726
727func Test_CreateContainer_CPUWeight_Annotation_WCOW_Process(t *testing.T) {
728	requireFeatures(t, featureWCOWProcess)
729
730	pullRequiredImages(t, []string{imageWindowsNanoserver})
731
732	request := &runtime.CreateContainerRequest{
733		Config: &runtime.ContainerConfig{
734			Metadata: &runtime.ContainerMetadata{
735				Name: t.Name() + "-Container",
736			},
737			Image: &runtime.ImageSpec{
738				Image: imageWindowsNanoserver,
739			},
740			// Hold this command open until killed (pause for Windows)
741			Command: []string{
742				"cmd",
743				"/c",
744				"ping",
745				"-t",
746				"127.0.0.1",
747			},
748			Annotations: map[string]string{
749				"io.microsoft.container.processor.weight": "500",
750			},
751		},
752	}
753	runCreateContainerTest(t, wcowProcessRuntimeHandler, request)
754}
755
756func Test_CreateContainer_CPUWeight_Config_WCOW_Hypervisor(t *testing.T) {
757	requireFeatures(t, featureWCOWHypervisor)
758
759	pullRequiredImages(t, []string{imageWindowsNanoserver})
760
761	request := &runtime.CreateContainerRequest{
762		Config: &runtime.ContainerConfig{
763			Metadata: &runtime.ContainerMetadata{
764				Name: t.Name() + "-Container",
765			},
766			Image: &runtime.ImageSpec{
767				Image: imageWindowsNanoserver,
768			},
769			// Hold this command open until killed (pause for Windows)
770			Command: []string{
771				"cmd",
772				"/c",
773				"ping",
774				"-t",
775				"127.0.0.1",
776			},
777			Windows: &runtime.WindowsContainerConfig{
778				Resources: &runtime.WindowsContainerResources{
779					CpuMaximum: 500,
780				},
781			},
782		},
783	}
784	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
785}
786
787func Test_CreateContainer_CPUWeight_Annotation_WCOW_Hypervisor(t *testing.T) {
788	requireFeatures(t, featureWCOWHypervisor)
789
790	pullRequiredImages(t, []string{imageWindowsNanoserver})
791
792	request := &runtime.CreateContainerRequest{
793		Config: &runtime.ContainerConfig{
794			Metadata: &runtime.ContainerMetadata{
795				Name: t.Name() + "-Container",
796			},
797			Image: &runtime.ImageSpec{
798				Image: imageWindowsNanoserver,
799			},
800			// Hold this command open until killed (pause for Windows)
801			Command: []string{
802				"cmd",
803				"/c",
804				"ping",
805				"-t",
806				"127.0.0.1",
807			},
808			Annotations: map[string]string{
809				"io.microsoft.container.processor.limit": "500",
810			},
811		},
812	}
813	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
814}
815
816func Test_CreateContainer_CPUShares_LCOW(t *testing.T) {
817	requireFeatures(t, featureLCOW)
818
819	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
820
821	request := &runtime.CreateContainerRequest{
822		Config: &runtime.ContainerConfig{
823			Metadata: &runtime.ContainerMetadata{
824				Name: t.Name() + "-Container",
825			},
826			Image: &runtime.ImageSpec{
827				Image: imageLcowAlpine,
828			},
829			// Hold this command open until killed
830			Command: []string{
831				"top",
832			},
833			Linux: &runtime.LinuxContainerConfig{
834				Resources: &runtime.LinuxContainerResources{
835					CpuShares: 1024,
836				},
837			},
838		},
839	}
840	runCreateContainerTest(t, lcowRuntimeHandler, request)
841}
842
843func Test_CreateContainer_Mount_File_LCOW(t *testing.T) {
844	requireFeatures(t, featureLCOW)
845	testutilities.RequiresBuild(t, osversion.V19H1)
846
847	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
848
849	tempFile, err := ioutil.TempFile("", "test")
850
851	if err != nil {
852		t.Fatalf("Failed to create temp file: %s", err)
853	}
854
855	tempFile.Close()
856
857	defer func() {
858		if err := os.Remove(tempFile.Name()); err != nil {
859			t.Fatalf("Failed to remove temp file: %s", err)
860		}
861	}()
862
863	containerFilePath := "/foo/test.txt"
864
865	request := &runtime.CreateContainerRequest{
866		Config: &runtime.ContainerConfig{
867			Metadata: &runtime.ContainerMetadata{
868				Name: t.Name() + "-Container",
869			},
870			Mounts: []*runtime.Mount{
871				{
872					HostPath:      tempFile.Name(),
873					ContainerPath: containerFilePath,
874				},
875			},
876			Image: &runtime.ImageSpec{
877				Image: imageLcowAlpine,
878			},
879			Command: []string{
880				"top",
881			},
882			Linux: &runtime.LinuxContainerConfig{},
883		},
884	}
885	runCreateContainerTest(t, lcowRuntimeHandler, request)
886}
887
888func Test_CreateContainer_Mount_ReadOnlyFile_LCOW(t *testing.T) {
889	requireFeatures(t, featureLCOW)
890	testutilities.RequiresBuild(t, osversion.V19H1)
891
892	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
893
894	tempFile, err := ioutil.TempFile("", "test")
895
896	if err != nil {
897		t.Fatalf("Failed to create temp file: %s", err)
898	}
899
900	tempFile.Close()
901
902	defer func() {
903		if err := os.Remove(tempFile.Name()); err != nil {
904			t.Fatalf("Failed to remove temp file: %s", err)
905		}
906	}()
907
908	containerFilePath := "/foo/test.txt"
909
910	request := &runtime.CreateContainerRequest{
911		Config: &runtime.ContainerConfig{
912			Metadata: &runtime.ContainerMetadata{
913				Name: t.Name() + "-Container",
914			},
915			Mounts: []*runtime.Mount{
916				{
917					HostPath:      tempFile.Name(),
918					ContainerPath: containerFilePath,
919					Readonly:      true,
920				},
921			},
922			Image: &runtime.ImageSpec{
923				Image: imageLcowAlpine,
924			},
925			Command: []string{
926				"top",
927			},
928			Linux: &runtime.LinuxContainerConfig{},
929		},
930	}
931	runCreateContainerTest(t, lcowRuntimeHandler, request)
932}
933
934func Test_CreateContainer_Mount_Dir_LCOW(t *testing.T) {
935	requireFeatures(t, featureLCOW)
936
937	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
938
939	tempDir, err := ioutil.TempDir("", "")
940	if err != nil {
941		t.Fatalf("Failed to create temp dir: %s", err)
942	}
943	defer os.RemoveAll(tempDir)
944
945	containerFilePath := "/foo"
946
947	request := &runtime.CreateContainerRequest{
948		Config: &runtime.ContainerConfig{
949			Metadata: &runtime.ContainerMetadata{
950				Name: t.Name() + "-Container",
951			},
952			Mounts: []*runtime.Mount{
953				{
954					HostPath:      tempDir,
955					ContainerPath: containerFilePath,
956				},
957			},
958			Image: &runtime.ImageSpec{
959				Image: imageLcowAlpine,
960			},
961			Command: []string{
962				"top",
963			},
964			Linux: &runtime.LinuxContainerConfig{},
965		},
966	}
967	runCreateContainerTest(t, lcowRuntimeHandler, request)
968}
969
970func Test_CreateContainer_Mount_ReadOnlyDir_LCOW(t *testing.T) {
971	requireFeatures(t, featureLCOW)
972
973	pullRequiredLcowImages(t, []string{imageLcowK8sPause, imageLcowAlpine})
974
975	tempDir, err := ioutil.TempDir("", "")
976	if err != nil {
977		t.Fatalf("Failed to create temp dir: %s", err)
978	}
979	defer os.RemoveAll(tempDir)
980
981	containerFilePath := "/foo"
982
983	request := &runtime.CreateContainerRequest{
984		Config: &runtime.ContainerConfig{
985			Metadata: &runtime.ContainerMetadata{
986				Name: t.Name() + "-Container",
987			},
988			Mounts: []*runtime.Mount{
989				{
990					HostPath:      tempDir,
991					ContainerPath: containerFilePath,
992					Readonly:      true,
993				},
994			},
995			Image: &runtime.ImageSpec{
996				Image: imageLcowAlpine,
997			},
998			Command: []string{
999				"top",
1000			},
1001			Linux: &runtime.LinuxContainerConfig{},
1002		},
1003	}
1004	runCreateContainerTest(t, lcowRuntimeHandler, request)
1005}
1006
1007func Test_CreateContainer_Mount_File_WCOW(t *testing.T) {
1008	requireFeatures(t, featureWCOWHypervisor)
1009	pullRequiredImages(t, []string{imageWindowsNanoserver})
1010
1011	tempFile, err := ioutil.TempFile("", "test")
1012
1013	if err != nil {
1014		t.Fatalf("Failed to create temp file: %s", err)
1015	}
1016
1017	tempFile.Close()
1018
1019	defer func() {
1020		if err := os.Remove(tempFile.Name()); err != nil {
1021			t.Fatalf("Failed to remove temp file: %s", err)
1022		}
1023	}()
1024
1025	containerFilePath := `C:\foo\test`
1026
1027	request := &runtime.CreateContainerRequest{
1028		Config: &runtime.ContainerConfig{
1029			Metadata: &runtime.ContainerMetadata{
1030				Name: t.Name() + "-Container",
1031			},
1032			Mounts: []*runtime.Mount{
1033				{
1034					HostPath:      tempFile.Name(),
1035					ContainerPath: containerFilePath,
1036				},
1037			},
1038			Image: &runtime.ImageSpec{
1039				Image: imageWindowsNanoserver,
1040			},
1041			Command: []string{
1042				"ping",
1043				"-t",
1044				"127.0.0.1",
1045			},
1046		},
1047	}
1048	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
1049}
1050
1051func Test_CreateContainer_Mount_ReadOnlyFile_WCOW(t *testing.T) {
1052	requireFeatures(t, featureWCOWHypervisor)
1053
1054	pullRequiredImages(t, []string{imageWindowsNanoserver})
1055
1056	tempFile, err := ioutil.TempFile("", "test")
1057
1058	if err != nil {
1059		t.Fatalf("Failed to create temp file: %s", err)
1060	}
1061
1062	tempFile.Close()
1063
1064	defer func() {
1065		if err := os.Remove(tempFile.Name()); err != nil {
1066			t.Fatalf("Failed to remove temp file: %s", err)
1067		}
1068	}()
1069
1070	containerFilePath := `C:\foo\test`
1071
1072	request := &runtime.CreateContainerRequest{
1073		Config: &runtime.ContainerConfig{
1074			Metadata: &runtime.ContainerMetadata{
1075				Name: t.Name() + "-Container",
1076			},
1077			Mounts: []*runtime.Mount{
1078				{
1079					HostPath:      tempFile.Name(),
1080					ContainerPath: containerFilePath,
1081					Readonly:      true,
1082				},
1083			},
1084			Image: &runtime.ImageSpec{
1085				Image: imageWindowsNanoserver,
1086			},
1087			Command: []string{
1088				"ping",
1089				"-t",
1090				"127.0.0.1",
1091			},
1092		},
1093	}
1094	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
1095}
1096
1097func Test_CreateContainer_Mount_Dir_WCOW(t *testing.T) {
1098	requireFeatures(t, featureWCOWHypervisor)
1099
1100	pullRequiredImages(t, []string{imageWindowsNanoserver})
1101
1102	tempDir, err := ioutil.TempDir("", "")
1103	if err != nil {
1104		t.Fatalf("Failed to create temp dir: %s", err)
1105	}
1106	defer os.RemoveAll(tempDir)
1107
1108	containerFilePath := "C:\\foo"
1109
1110	request := &runtime.CreateContainerRequest{
1111		Config: &runtime.ContainerConfig{
1112			Metadata: &runtime.ContainerMetadata{
1113				Name: t.Name() + "-Container",
1114			},
1115			Mounts: []*runtime.Mount{
1116				{
1117					HostPath:      tempDir,
1118					ContainerPath: containerFilePath,
1119				},
1120			},
1121			Image: &runtime.ImageSpec{
1122				Image: imageWindowsNanoserver,
1123			},
1124			Command: []string{
1125				"ping",
1126				"-t",
1127				"127.0.0.1",
1128			},
1129		},
1130	}
1131	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
1132}
1133
1134func Test_CreateContainer_Mount_ReadOnlyDir_WCOW(t *testing.T) {
1135	requireFeatures(t, featureWCOWHypervisor)
1136
1137	pullRequiredImages(t, []string{imageWindowsNanoserver})
1138
1139	tempDir, err := ioutil.TempDir("", "")
1140	if err != nil {
1141		t.Fatalf("Failed to create temp dir: %s", err)
1142	}
1143	defer os.RemoveAll(tempDir)
1144
1145	containerFilePath := "C:\\foo"
1146
1147	request := &runtime.CreateContainerRequest{
1148		Config: &runtime.ContainerConfig{
1149			Metadata: &runtime.ContainerMetadata{
1150				Name: t.Name() + "-Container",
1151			},
1152			Mounts: []*runtime.Mount{
1153				{
1154					HostPath:      tempDir,
1155					ContainerPath: containerFilePath,
1156					Readonly:      true,
1157				},
1158			},
1159			Image: &runtime.ImageSpec{
1160				Image: imageWindowsNanoserver,
1161			},
1162			Command: []string{
1163				"ping",
1164				"-t",
1165				"127.0.0.1",
1166			},
1167		},
1168	}
1169	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
1170}
1171
1172func Test_CreateContainer_Mount_EmptyDir_WCOW(t *testing.T) {
1173	requireFeatures(t, featureWCOWHypervisor)
1174
1175	pullRequiredImages(t, []string{imageWindowsNanoserver})
1176
1177	tempDir, err := ioutil.TempDir("", "")
1178	if err != nil {
1179		t.Fatalf("Failed to create temp dir: %s", err)
1180	}
1181	defer os.RemoveAll(tempDir)
1182	path := filepath.Join(tempDir, "kubernetes.io~empty-dir", "volume1")
1183	if err := os.MkdirAll(path, 0); err != nil {
1184		t.Fatalf("Failed to create kubernetes.io~empty-dir volume path: %s", err)
1185	}
1186
1187	containerFilePath := `C:\foo`
1188
1189	request := &runtime.CreateContainerRequest{
1190		Config: &runtime.ContainerConfig{
1191			Metadata: &runtime.ContainerMetadata{
1192				Name: t.Name() + "-Container",
1193			},
1194			Mounts: []*runtime.Mount{
1195				{
1196					HostPath:      path,
1197					ContainerPath: containerFilePath,
1198				},
1199			},
1200			Image: &runtime.ImageSpec{
1201				Image: imageWindowsNanoserver,
1202			},
1203			Command: []string{
1204				"ping",
1205				"-t",
1206				"127.0.0.1",
1207			},
1208		},
1209	}
1210	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
1211}
1212
1213func Test_Mount_ReadOnlyDirReuse_WCOW(t *testing.T) {
1214	requireFeatures(t, featureWCOWHypervisor)
1215
1216	client := newTestRuntimeClient(t)
1217	ctx, cancel := context.WithCancel(context.Background())
1218	defer cancel()
1219
1220	pullRequiredImages(t, []string{imageWindowsNanoserver})
1221
1222	containerPath := `C:\foo`
1223
1224	tempDir, err := ioutil.TempDir("", "")
1225	if err != nil {
1226		t.Fatalf("Failed to create temp dir: %s", err)
1227	}
1228	defer os.RemoveAll(tempDir)
1229
1230	sandboxRequest := getRunPodSandboxRequest(t, wcowHypervisorRuntimeHandler)
1231
1232	podID := runPodSandbox(t, client, ctx, sandboxRequest)
1233	defer removePodSandbox(t, client, ctx, podID)
1234	defer stopPodSandbox(t, client, ctx, podID)
1235
1236	request := &runtime.CreateContainerRequest{
1237		PodSandboxId: podID,
1238		Config: &runtime.ContainerConfig{
1239			Metadata: &runtime.ContainerMetadata{},
1240			Image: &runtime.ImageSpec{
1241				Image: imageWindowsNanoserver,
1242			},
1243			Command: []string{
1244				"ping",
1245				"-t",
1246				"127.0.0.1",
1247			},
1248			Mounts: []*runtime.Mount{
1249				{
1250					HostPath:      tempDir,
1251					ContainerPath: containerPath,
1252				},
1253			},
1254		},
1255		SandboxConfig: sandboxRequest.Config,
1256	}
1257
1258	request.Config.Metadata.Name = request.Config.Metadata.Name + "-ro"
1259	request.Config.Mounts[0].Readonly = true
1260	c_ro := createContainer(t, client, ctx, request)
1261	defer removeContainer(t, client, ctx, c_ro)
1262	startContainer(t, client, ctx, c_ro)
1263	defer stopContainer(t, client, ctx, c_ro)
1264
1265	request.Config.Metadata.Name = request.Config.Metadata.Name + "-rw"
1266	request.Config.Mounts[0].Readonly = false
1267	c_rw := createContainer(t, client, ctx, request)
1268	defer removeContainer(t, client, ctx, c_rw)
1269	startContainer(t, client, ctx, c_rw)
1270	defer stopContainer(t, client, ctx, c_rw)
1271
1272	filePath := containerPath + `\tmp.txt`
1273	execCommand := []string{"cmd", "/c", "echo foo", ">", filePath}
1274
1275	_, errorMsg, exitCode := execContainer(t, client, ctx, c_rw, execCommand)
1276
1277	// Writing a file to the rw container mount should succeed.
1278	if exitCode != 0 || len(errorMsg) > 0 {
1279		t.Fatalf("Failed to write file to rw container mount: %s, exitcode: %v\n", errorMsg, exitCode)
1280	}
1281
1282	_, errorMsg, exitCode = execContainer(t, client, ctx, c_ro, execCommand)
1283
1284	// Writing a file to the ro container mount should fail.
1285	if exitCode == 0 && len(errorMsg) == 0 {
1286		t.Fatalf("Wrote file to ro container mount, should have failed: %s, exitcode: %v\n", errorMsg, exitCode)
1287	}
1288}
1289
1290func Test_CreateContainer_Mount_NamedPipe_WCOW(t *testing.T) {
1291	requireFeatures(t, featureWCOWHypervisor)
1292
1293	pullRequiredImages(t, []string{imageWindowsNanoserver})
1294
1295	path := `\\.\pipe\testpipe`
1296	pipe, err := winio.ListenPipe(path, nil)
1297	if err != nil {
1298		t.Fatal(err)
1299	}
1300	defer func() {
1301		if err := pipe.Close(); err != nil {
1302			t.Fatal(err)
1303		}
1304	}()
1305
1306	request := &runtime.CreateContainerRequest{
1307		Config: &runtime.ContainerConfig{
1308			Metadata: &runtime.ContainerMetadata{
1309				Name: t.Name() + "-Container",
1310			},
1311			Mounts: []*runtime.Mount{
1312				{
1313					HostPath:      path,
1314					ContainerPath: path,
1315				},
1316			},
1317			Image: &runtime.ImageSpec{
1318				Image: imageWindowsNanoserver,
1319			},
1320			Command: []string{
1321				"ping",
1322				"-t",
1323				"127.0.0.1",
1324			},
1325		},
1326	}
1327	runCreateContainerTest(t, wcowHypervisorRuntimeHandler, request)
1328}
1329