github.com/vincentwoo/docker@v0.7.3-0.20160116130405-82401a4b13c0/integration-cli/docker_cli_inspect_test.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os/exec" 7 "strconv" 8 "strings" 9 "time" 10 11 "github.com/docker/docker/pkg/integration/checker" 12 "github.com/docker/engine-api/types" 13 "github.com/docker/engine-api/types/container" 14 "github.com/go-check/check" 15 ) 16 17 func checkValidGraphDriver(c *check.C, name string) { 18 if name != "devicemapper" && name != "overlay" && name != "vfs" && name != "zfs" && name != "btrfs" && name != "aufs" { 19 c.Fatalf("%v is not a valid graph driver name", name) 20 } 21 } 22 23 func (s *DockerSuite) TestInspectImage(c *check.C) { 24 testRequires(c, DaemonIsLinux) 25 imageTest := "emptyfs" 26 // It is important that this ID remain stable. If a code change causes 27 // it to be different, this is equivalent to a cache bust when pulling 28 // a legacy-format manifest. If the check at the end of this function 29 // fails, fix the difference in the image serialization instead of 30 // updating this hash. 31 imageTestID := "sha256:11f64303f0f7ffdc71f001788132bca5346831939a956e3e975c93267d89a16d" 32 id, err := inspectField(imageTest, "Id") 33 c.Assert(err, checker.IsNil) 34 35 c.Assert(id, checker.Equals, imageTestID) 36 } 37 38 func (s *DockerSuite) TestInspectInt64(c *check.C) { 39 testRequires(c, DaemonIsLinux) 40 41 dockerCmd(c, "run", "-d", "-m=300M", "--name", "inspectTest", "busybox", "true") 42 inspectOut, err := inspectField("inspectTest", "HostConfig.Memory") 43 c.Assert(err, check.IsNil) 44 c.Assert(inspectOut, checker.Equals, "314572800") 45 } 46 47 func (s *DockerSuite) TestInspectDefault(c *check.C) { 48 testRequires(c, DaemonIsLinux) 49 //Both the container and image are named busybox. docker inspect will fetch the container JSON. 50 //If the container JSON is not available, it will go for the image JSON. 51 52 out, _ := dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true") 53 containerID := strings.TrimSpace(out) 54 55 inspectOut, err := inspectField("busybox", "Id") 56 c.Assert(err, checker.IsNil) 57 c.Assert(strings.TrimSpace(inspectOut), checker.Equals, containerID) 58 } 59 60 func (s *DockerSuite) TestInspectStatus(c *check.C) { 61 defer unpauseAllContainers() 62 testRequires(c, DaemonIsLinux) 63 out, _ := dockerCmd(c, "run", "-d", "busybox", "top") 64 out = strings.TrimSpace(out) 65 66 inspectOut, err := inspectField(out, "State.Status") 67 c.Assert(err, checker.IsNil) 68 c.Assert(inspectOut, checker.Equals, "running") 69 70 dockerCmd(c, "pause", out) 71 inspectOut, err = inspectField(out, "State.Status") 72 c.Assert(err, checker.IsNil) 73 c.Assert(inspectOut, checker.Equals, "paused") 74 75 dockerCmd(c, "unpause", out) 76 inspectOut, err = inspectField(out, "State.Status") 77 c.Assert(err, checker.IsNil) 78 c.Assert(inspectOut, checker.Equals, "running") 79 80 dockerCmd(c, "stop", out) 81 inspectOut, err = inspectField(out, "State.Status") 82 c.Assert(err, checker.IsNil) 83 c.Assert(inspectOut, checker.Equals, "exited") 84 85 } 86 87 func (s *DockerSuite) TestInspectTypeFlagContainer(c *check.C) { 88 testRequires(c, DaemonIsLinux) 89 //Both the container and image are named busybox. docker inspect will fetch container 90 //JSON State.Running field. If the field is true, it's a container. 91 92 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") 93 94 formatStr := "--format='{{.State.Running}}'" 95 out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox") 96 c.Assert(out, checker.Equals, "true\n") // not a container JSON 97 } 98 99 func (s *DockerSuite) TestInspectTypeFlagWithNoContainer(c *check.C) { 100 testRequires(c, DaemonIsLinux) 101 //Run this test on an image named busybox. docker inspect will try to fetch container 102 //JSON. Since there is no container named busybox and --type=container, docker inspect will 103 //not try to get the image JSON. It will throw an error. 104 105 dockerCmd(c, "run", "-d", "busybox", "true") 106 107 _, _, err := dockerCmdWithError("inspect", "--type=container", "busybox") 108 // docker inspect should fail, as there is no container named busybox 109 c.Assert(err, checker.NotNil) 110 } 111 112 func (s *DockerSuite) TestInspectTypeFlagWithImage(c *check.C) { 113 testRequires(c, DaemonIsLinux) 114 //Both the container and image are named busybox. docker inspect will fetch image 115 //JSON as --type=image. if there is no image with name busybox, docker inspect 116 //will throw an error. 117 118 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true") 119 120 out, _ := dockerCmd(c, "inspect", "--type=image", "busybox") 121 c.Assert(out, checker.Not(checker.Contains), "State") // not an image JSON 122 } 123 124 func (s *DockerSuite) TestInspectTypeFlagWithInvalidValue(c *check.C) { 125 testRequires(c, DaemonIsLinux) 126 //Both the container and image are named busybox. docker inspect will fail 127 //as --type=foobar is not a valid value for the flag. 128 129 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "true") 130 131 out, exitCode, err := dockerCmdWithError("inspect", "--type=foobar", "busybox") 132 c.Assert(err, checker.NotNil, check.Commentf("%s", exitCode)) 133 c.Assert(exitCode, checker.Equals, 1, check.Commentf("%s", err)) 134 c.Assert(out, checker.Contains, "not a valid value for --type") 135 } 136 137 func (s *DockerSuite) TestInspectImageFilterInt(c *check.C) { 138 testRequires(c, DaemonIsLinux) 139 imageTest := "emptyfs" 140 out, err := inspectField(imageTest, "Size") 141 c.Assert(err, checker.IsNil) 142 143 size, err := strconv.Atoi(out) 144 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect size of the image: %s, %v", out, err)) 145 146 //now see if the size turns out to be the same 147 formatStr := fmt.Sprintf("--format='{{eq .Size %d}}'", size) 148 out, _ = dockerCmd(c, "inspect", formatStr, imageTest) 149 result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")) 150 c.Assert(err, checker.IsNil) 151 c.Assert(result, checker.Equals, true) 152 } 153 154 func (s *DockerSuite) TestInspectContainerFilterInt(c *check.C) { 155 testRequires(c, DaemonIsLinux) 156 runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "cat") 157 runCmd.Stdin = strings.NewReader("blahblah") 158 out, _, _, err := runCommandWithStdoutStderr(runCmd) 159 c.Assert(err, checker.IsNil, check.Commentf("failed to run container: %v, output: %q", err, out)) 160 161 id := strings.TrimSpace(out) 162 163 out, err = inspectField(id, "State.ExitCode") 164 c.Assert(err, checker.IsNil) 165 166 exitCode, err := strconv.Atoi(out) 167 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect exitcode of the container: %s, %v", out, err)) 168 169 //now get the exit code to verify 170 formatStr := fmt.Sprintf("--format='{{eq .State.ExitCode %d}}'", exitCode) 171 out, _ = dockerCmd(c, "inspect", formatStr, id) 172 result, err := strconv.ParseBool(strings.TrimSuffix(out, "\n")) 173 c.Assert(err, checker.IsNil) 174 c.Assert(result, checker.Equals, true) 175 } 176 177 func (s *DockerSuite) TestInspectImageGraphDriver(c *check.C) { 178 testRequires(c, DaemonIsLinux) 179 imageTest := "emptyfs" 180 name, err := inspectField(imageTest, "GraphDriver.Name") 181 c.Assert(err, checker.IsNil) 182 183 checkValidGraphDriver(c, name) 184 185 if name != "devicemapper" { 186 c.Skip("requires devicemapper graphdriver") 187 } 188 189 deviceID, err := inspectField(imageTest, "GraphDriver.Data.DeviceId") 190 c.Assert(err, checker.IsNil) 191 192 _, err = strconv.Atoi(deviceID) 193 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceId of the image: %s, %v", deviceID, err)) 194 195 deviceSize, err := inspectField(imageTest, "GraphDriver.Data.DeviceSize") 196 c.Assert(err, checker.IsNil) 197 198 _, err = strconv.ParseUint(deviceSize, 10, 64) 199 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceSize of the image: %s, %v", deviceSize, err)) 200 } 201 202 func (s *DockerSuite) TestInspectContainerGraphDriver(c *check.C) { 203 testRequires(c, DaemonIsLinux) 204 out, _ := dockerCmd(c, "run", "-d", "busybox", "true") 205 out = strings.TrimSpace(out) 206 207 name, err := inspectField(out, "GraphDriver.Name") 208 c.Assert(err, checker.IsNil) 209 210 checkValidGraphDriver(c, name) 211 212 if name != "devicemapper" { 213 return 214 } 215 216 imageDeviceID, err := inspectField("busybox", "GraphDriver.Data.DeviceId") 217 c.Assert(err, checker.IsNil) 218 219 deviceID, err := inspectField(out, "GraphDriver.Data.DeviceId") 220 c.Assert(err, checker.IsNil) 221 222 c.Assert(imageDeviceID, checker.Not(checker.Equals), deviceID) 223 224 _, err = strconv.Atoi(deviceID) 225 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceId of the image: %s, %v", deviceID, err)) 226 227 deviceSize, err := inspectField(out, "GraphDriver.Data.DeviceSize") 228 c.Assert(err, checker.IsNil) 229 230 _, err = strconv.ParseUint(deviceSize, 10, 64) 231 c.Assert(err, checker.IsNil, check.Commentf("failed to inspect DeviceSize of the image: %s, %v", deviceSize, err)) 232 } 233 234 func (s *DockerSuite) TestInspectBindMountPoint(c *check.C) { 235 testRequires(c, DaemonIsLinux) 236 dockerCmd(c, "run", "-d", "--name", "test", "-v", "/data:/data:ro,z", "busybox", "cat") 237 238 vol, err := inspectFieldJSON("test", "Mounts") 239 c.Assert(err, checker.IsNil) 240 241 var mp []types.MountPoint 242 err = unmarshalJSON([]byte(vol), &mp) 243 c.Assert(err, checker.IsNil) 244 245 // check that there is only one mountpoint 246 c.Assert(mp, check.HasLen, 1) 247 248 m := mp[0] 249 250 c.Assert(m.Name, checker.Equals, "") 251 c.Assert(m.Driver, checker.Equals, "") 252 c.Assert(m.Source, checker.Equals, "/data") 253 c.Assert(m.Destination, checker.Equals, "/data") 254 c.Assert(m.Mode, checker.Equals, "ro,z") 255 c.Assert(m.RW, checker.Equals, false) 256 } 257 258 // #14947 259 func (s *DockerSuite) TestInspectTimesAsRFC3339Nano(c *check.C) { 260 testRequires(c, DaemonIsLinux) 261 out, _ := dockerCmd(c, "run", "-d", "busybox", "true") 262 id := strings.TrimSpace(out) 263 startedAt, err := inspectField(id, "State.StartedAt") 264 c.Assert(err, checker.IsNil) 265 finishedAt, err := inspectField(id, "State.FinishedAt") 266 c.Assert(err, checker.IsNil) 267 created, err := inspectField(id, "Created") 268 c.Assert(err, checker.IsNil) 269 270 _, err = time.Parse(time.RFC3339Nano, startedAt) 271 c.Assert(err, checker.IsNil) 272 _, err = time.Parse(time.RFC3339Nano, finishedAt) 273 c.Assert(err, checker.IsNil) 274 _, err = time.Parse(time.RFC3339Nano, created) 275 c.Assert(err, checker.IsNil) 276 277 created, err = inspectField("busybox", "Created") 278 c.Assert(err, checker.IsNil) 279 280 _, err = time.Parse(time.RFC3339Nano, created) 281 c.Assert(err, checker.IsNil) 282 } 283 284 // #15633 285 func (s *DockerSuite) TestInspectLogConfigNoType(c *check.C) { 286 testRequires(c, DaemonIsLinux) 287 dockerCmd(c, "create", "--name=test", "--log-opt", "max-file=42", "busybox") 288 var logConfig container.LogConfig 289 290 out, err := inspectFieldJSON("test", "HostConfig.LogConfig") 291 c.Assert(err, checker.IsNil, check.Commentf("%v", out)) 292 293 err = json.NewDecoder(strings.NewReader(out)).Decode(&logConfig) 294 c.Assert(err, checker.IsNil, check.Commentf("%v", out)) 295 296 c.Assert(logConfig.Type, checker.Equals, "json-file") 297 c.Assert(logConfig.Config["max-file"], checker.Equals, "42", check.Commentf("%v", logConfig)) 298 } 299 300 func (s *DockerSuite) TestInspectNoSizeFlagContainer(c *check.C) { 301 302 //Both the container and image are named busybox. docker inspect will fetch container 303 //JSON SizeRw and SizeRootFs field. If there is no flag --size/-s, there are no size fields. 304 305 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") 306 307 formatStr := "--format='{{.SizeRw}},{{.SizeRootFs}}'" 308 out, _ := dockerCmd(c, "inspect", "--type=container", formatStr, "busybox") 309 c.Assert(strings.TrimSpace(out), check.Equals, "<nil>,<nil>", check.Commentf("Exepcted not to display size info: %s", out)) 310 } 311 312 func (s *DockerSuite) TestInspectSizeFlagContainer(c *check.C) { 313 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") 314 315 formatStr := "--format='{{.SizeRw}},{{.SizeRootFs}}'" 316 out, _ := dockerCmd(c, "inspect", "-s", "--type=container", formatStr, "busybox") 317 sz := strings.Split(out, ",") 318 319 c.Assert(strings.TrimSpace(sz[0]), check.Not(check.Equals), "<nil>") 320 c.Assert(strings.TrimSpace(sz[1]), check.Not(check.Equals), "<nil>") 321 } 322 323 func (s *DockerSuite) TestInspectSizeFlagImage(c *check.C) { 324 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") 325 326 formatStr := "--format='{{.SizeRw}},{{.SizeRootFs}}'" 327 out, _, err := dockerCmdWithError("inspect", "-s", "--type=image", formatStr, "busybox") 328 329 // Template error rather than <no value> 330 // This is a more correct behavior because images don't have sizes associated. 331 c.Assert(err, check.Not(check.IsNil)) 332 c.Assert(out, checker.Contains, "Template parsing error") 333 } 334 335 func (s *DockerSuite) TestInspectTempateError(c *check.C) { 336 // Template parsing error for both the container and image. 337 338 dockerCmd(c, "run", "--name=container1", "-d", "busybox", "top") 339 340 out, _, err := dockerCmdWithError("inspect", "--type=container", "--format='Format container: {{.ThisDoesNotExist}}'", "container1") 341 c.Assert(err, check.Not(check.IsNil)) 342 c.Assert(out, checker.Contains, "Template parsing error") 343 344 out, _, err = dockerCmdWithError("inspect", "--type=image", "--format='Format container: {{.ThisDoesNotExist}}'", "busybox") 345 c.Assert(err, check.Not(check.IsNil)) 346 c.Assert(out, checker.Contains, "Template parsing error") 347 } 348 349 func (s *DockerSuite) TestInspectJSONFields(c *check.C) { 350 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") 351 out, _, err := dockerCmdWithError("inspect", "--type=container", "--format='{{.HostConfig.Dns}}'", "busybox") 352 353 c.Assert(err, check.IsNil) 354 c.Assert(out, checker.Equals, "[]\n") 355 } 356 357 func (s *DockerSuite) TestInspectByPrefix(c *check.C) { 358 id, err := inspectField("busybox", "Id") 359 c.Assert(err, checker.IsNil) 360 c.Assert(id, checker.HasPrefix, "sha256:") 361 362 id2, err := inspectField(id[:12], "Id") 363 c.Assert(err, checker.IsNil) 364 c.Assert(id, checker.Equals, id2) 365 366 id3, err := inspectField(strings.TrimPrefix(id, "sha256:")[:12], "Id") 367 c.Assert(err, checker.IsNil) 368 c.Assert(id, checker.Equals, id3) 369 } 370 371 func (s *DockerSuite) TestInspectStopWhenNotFound(c *check.C) { 372 dockerCmd(c, "run", "--name=busybox", "-d", "busybox", "top") 373 dockerCmd(c, "run", "--name=not-shown", "-d", "busybox", "top") 374 out, _, err := dockerCmdWithError("inspect", "--type=container", "--format='{{.Name}}'", "busybox", "missing", "not-shown") 375 376 c.Assert(err, checker.Not(check.IsNil)) 377 c.Assert(out, checker.Contains, "busybox") 378 c.Assert(out, checker.Not(checker.Contains), "not-shown") 379 c.Assert(out, checker.Contains, "Error: No such container: missing") 380 } 381 382 func (s *DockerSuite) TestInspectHistory(c *check.C) { 383 testRequires(c, DaemonIsLinux) 384 dockerCmd(c, "run", "--name=testcont", "-d", "busybox", "top") 385 dockerCmd(c, "commit", "-m", "test comment", "testcont", "testimg") 386 out, _, err := dockerCmdWithError("inspect", "--format='{{.Comment}}'", "testimg") 387 388 c.Assert(err, check.IsNil) 389 c.Assert(out, checker.Contains, "test comment") 390 } 391 392 func (s *DockerSuite) TestInspectContainerNetworkDefault(c *check.C) { 393 testRequires(c, DaemonIsLinux) 394 395 contName := "test1" 396 dockerCmd(c, "run", "--name", contName, "-d", "busybox", "top") 397 netOut, _ := dockerCmd(c, "network", "inspect", "--format='{{.ID}}'", "bridge") 398 out, err := inspectField(contName, "NetworkSettings.Networks") 399 c.Assert(err, checker.IsNil) 400 c.Assert(out, checker.Contains, "bridge") 401 out, err = inspectField(contName, "NetworkSettings.Networks.bridge.NetworkID") 402 c.Assert(err, checker.IsNil) 403 c.Assert(strings.TrimSpace(out), checker.Equals, strings.TrimSpace(netOut)) 404 } 405 406 func (s *DockerSuite) TestInspectContainerNetworkCustom(c *check.C) { 407 testRequires(c, DaemonIsLinux) 408 409 netOut, _ := dockerCmd(c, "network", "create", "net1") 410 dockerCmd(c, "run", "--name=container1", "--net=net1", "-d", "busybox", "top") 411 out, err := inspectField("container1", "NetworkSettings.Networks") 412 c.Assert(err, checker.IsNil) 413 c.Assert(out, checker.Contains, "net1") 414 out, err = inspectField("container1", "NetworkSettings.Networks.net1.NetworkID") 415 c.Assert(err, checker.IsNil) 416 c.Assert(strings.TrimSpace(out), checker.Equals, strings.TrimSpace(netOut)) 417 }