github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/container_list_windows_test.go (about) 1 /* 2 Copyright The containerd Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 "strings" 22 "testing" 23 24 "github.com/containerd/nerdctl/pkg/formatter" 25 "github.com/containerd/nerdctl/pkg/strutil" 26 "github.com/containerd/nerdctl/pkg/tabutil" 27 "github.com/containerd/nerdctl/pkg/testutil" 28 "gotest.tools/v3/assert" 29 ) 30 31 type psTestContainer struct { 32 name string 33 labels map[string]string 34 volumes []string 35 network string 36 } 37 38 func preparePsTestContainer(t *testing.T, identity string, restart bool, hyperv bool) (*testutil.Base, psTestContainer) { 39 base := testutil.NewBase(t) 40 41 base.Cmd("pull", testutil.NginxAlpineImage).AssertOK() 42 43 testContainerName := testutil.Identifier(t) + identity 44 t.Cleanup(func() { 45 base.Cmd("rm", "-f", testContainerName).AssertOK() 46 }) 47 48 // A container can have multiple labels. 49 // Therefore, this test container has multiple labels to check it. 50 testLabels := make(map[string]string) 51 keys := []string{ 52 testutil.Identifier(t) + identity, 53 testutil.Identifier(t) + identity, 54 } 55 // fill the value of testLabels 56 for _, k := range keys { 57 testLabels[k] = k 58 } 59 60 args := []string{ 61 "run", 62 "-d", 63 "--name", 64 testContainerName, 65 "--label", 66 formatter.FormatLabels(testLabels), 67 testutil.NginxAlpineImage, 68 } 69 if !restart { 70 args = append(args, "--restart=no") 71 } 72 if hyperv { 73 args = append(args[:3], args[1:]...) 74 args[1], args[2] = "--isolation", "hyperv" 75 } 76 77 base.Cmd(args...).AssertOK() 78 if restart { 79 base.EnsureContainerStarted(testContainerName) 80 } 81 82 return base, psTestContainer{ 83 name: testContainerName, 84 labels: testLabels, 85 network: testContainerName, 86 } 87 } 88 89 func TestListProcessContainer(t *testing.T) { 90 base, testContainer := preparePsTestContainer(t, "list", true, false) 91 92 // hope there are no tests running parallel 93 base.Cmd("ps", "-n", "1", "-s").AssertOutWithFunc(func(stdout string) error { 94 // An example of nerdctl/docker ps -n 1 -s 95 // CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE 96 // be8d386c991e docker.io/library/busybox:latest "top" 1 second ago Up c1 16.0 KiB (virtual 1.3 MiB) 97 98 lines := strings.Split(strings.TrimSpace(stdout), "\n") 99 if len(lines) < 2 { 100 return fmt.Errorf("expected at least 2 lines, got %d", len(lines)) 101 } 102 103 tab := tabutil.NewReader("CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES\tSIZE") 104 err := tab.ParseHeader(lines[0]) 105 if err != nil { 106 return fmt.Errorf("failed to parse header: %v", err) 107 } 108 109 container, _ := tab.ReadRow(lines[1], "NAMES") 110 assert.Equal(t, container, testContainer.name) 111 112 image, _ := tab.ReadRow(lines[1], "IMAGE") 113 assert.Equal(t, image, testutil.NginxAlpineImage) 114 115 size, _ := tab.ReadRow(lines[1], "SIZE") 116 117 // there is some difference between nerdctl and docker in calculating the size of the container 118 expectedSize := "36.0 MiB (virtual " 119 120 if !strings.Contains(size, expectedSize) { 121 return fmt.Errorf("expect container size %s, but got %s", expectedSize, size) 122 } 123 124 return nil 125 }) 126 } 127 128 func TestListHyperVContainer(t *testing.T) { 129 if !testutil.HyperVSupported() { 130 t.Skip("HyperV is not enabled, skipping test") 131 } 132 133 base, testContainer := preparePsTestContainer(t, "list", true, true) 134 inspect := base.InspectContainer(testContainer.name) 135 //check with HCS if the container is ineed a VM 136 isHypervContainer, err := testutil.HyperVContainer(inspect) 137 if err != nil { 138 t.Fatalf("unable to list HCS containers: %s", err) 139 } 140 assert.Assert(t, isHypervContainer, true) 141 142 // hope there are no tests running parallel 143 base.Cmd("ps", "-n", "1", "-s").AssertOutWithFunc(func(stdout string) error { 144 // An example of nerdctl/docker ps -n 1 -s 145 // CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE 146 // be8d386c991e docker.io/library/busybox:latest "top" 1 second ago Up c1 16.0 KiB (virtual 1.3 MiB) 147 148 lines := strings.Split(strings.TrimSpace(stdout), "\n") 149 if len(lines) < 2 { 150 return fmt.Errorf("expected at least 2 lines, got %d", len(lines)) 151 } 152 153 tab := tabutil.NewReader("CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES\tSIZE") 154 err := tab.ParseHeader(lines[0]) 155 if err != nil { 156 return fmt.Errorf("failed to parse header: %v", err) 157 } 158 159 container, _ := tab.ReadRow(lines[1], "NAMES") 160 assert.Equal(t, container, testContainer.name) 161 162 image, _ := tab.ReadRow(lines[1], "IMAGE") 163 assert.Equal(t, image, testutil.NginxAlpineImage) 164 165 size, _ := tab.ReadRow(lines[1], "SIZE") 166 167 // there is some difference between nerdctl and docker in calculating the size of the container 168 expectedSize := "72.0 MiB (virtual " 169 170 if !strings.Contains(size, expectedSize) { 171 return fmt.Errorf("expect container size %s, but got %s", expectedSize, size) 172 } 173 174 return nil 175 }) 176 } 177 178 func TestListProcessContainerWideMode(t *testing.T) { 179 testutil.DockerIncompatible(t) 180 base, testContainer := preparePsTestContainer(t, "listWithMode", true, false) 181 182 // hope there are no tests running parallel 183 base.Cmd("ps", "-n", "1", "--format", "wide").AssertOutWithFunc(func(stdout string) error { 184 185 // An example of nerdctl ps --format wide 186 // CONTAINER ID IMAGE PLATFORM COMMAND CREATED STATUS PORTS NAMES RUNTIME SIZE 187 // 17181f208b61 docker.io/library/busybox:latest linux/amd64 "top" About an hour ago Up busybox-17181 io.containerd.runc.v2 16.0 KiB (virtual 1.3 MiB) 188 189 lines := strings.Split(strings.TrimSpace(stdout), "\n") 190 if len(lines) < 2 { 191 return fmt.Errorf("expected at least 2 lines, got %d", len(lines)) 192 } 193 194 tab := tabutil.NewReader("CONTAINER ID\tIMAGE\tCOMMAND\tCREATED\tSTATUS\tPORTS\tNAMES\tRUNTIME\tPLATFORM\tSIZE") 195 err := tab.ParseHeader(lines[0]) 196 if err != nil { 197 return fmt.Errorf("failed to parse header: %v", err) 198 } 199 200 container, _ := tab.ReadRow(lines[1], "NAMES") 201 assert.Equal(t, container, testContainer.name) 202 203 image, _ := tab.ReadRow(lines[1], "IMAGE") 204 assert.Equal(t, image, testutil.NginxAlpineImage) 205 206 runtime, _ := tab.ReadRow(lines[1], "RUNTIME") 207 assert.Equal(t, runtime, "io.containerd.runhcs.v1") 208 209 size, _ := tab.ReadRow(lines[1], "SIZE") 210 expectedSize := "36.0 MiB (virtual " 211 if !strings.Contains(size, expectedSize) { 212 return fmt.Errorf("expect container size %s, but got %s", expectedSize, size) 213 } 214 return nil 215 }) 216 } 217 218 func TestListProcessContainerWithLabels(t *testing.T) { 219 base, testContainer := preparePsTestContainer(t, "listWithLabels", true, false) 220 221 // hope there are no tests running parallel 222 base.Cmd("ps", "-n", "1", "--format", "{{.Labels}}").AssertOutWithFunc(func(stdout string) error { 223 224 // An example of nerdctl ps --format "{{.Labels}}" 225 // key1=value1,key2=value2,key3=value3 226 lines := strings.Split(strings.TrimSpace(stdout), "\n") 227 if len(lines) != 1 { 228 return fmt.Errorf("expected 1 line, got %d", len(lines)) 229 } 230 231 // check labels using map 232 // 1. the results has no guarantee to show the same order. 233 // 2. the results has no guarantee to show only configured labels. 234 labelsMap, err := strutil.ParseCSVMap(lines[0]) 235 if err != nil { 236 return fmt.Errorf("failed to parse labels: %v", err) 237 } 238 239 for i := range testContainer.labels { 240 if value, ok := labelsMap[i]; ok { 241 assert.Equal(t, value, testContainer.labels[i]) 242 } 243 } 244 return nil 245 }) 246 }