github.com/ld86/docker@v1.7.1-rc3/integration-cli/docker_cli_history_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os/exec" 6 "regexp" 7 "strconv" 8 "strings" 9 10 "github.com/go-check/check" 11 ) 12 13 // This is a heisen-test. Because the created timestamp of images and the behavior of 14 // sort is not predictable it doesn't always fail. 15 func (s *DockerSuite) TestBuildHistory(c *check.C) { 16 name := "testbuildhistory" 17 _, err := buildImage(name, `FROM busybox 18 RUN echo "A" 19 RUN echo "B" 20 RUN echo "C" 21 RUN echo "D" 22 RUN echo "E" 23 RUN echo "F" 24 RUN echo "G" 25 RUN echo "H" 26 RUN echo "I" 27 RUN echo "J" 28 RUN echo "K" 29 RUN echo "L" 30 RUN echo "M" 31 RUN echo "N" 32 RUN echo "O" 33 RUN echo "P" 34 RUN echo "Q" 35 RUN echo "R" 36 RUN echo "S" 37 RUN echo "T" 38 RUN echo "U" 39 RUN echo "V" 40 RUN echo "W" 41 RUN echo "X" 42 RUN echo "Y" 43 RUN echo "Z"`, 44 true) 45 46 if err != nil { 47 c.Fatal(err) 48 } 49 50 out, exitCode, err := runCommandWithOutput(exec.Command(dockerBinary, "history", "testbuildhistory")) 51 if err != nil || exitCode != 0 { 52 c.Fatalf("failed to get image history: %s, %v", out, err) 53 } 54 55 actualValues := strings.Split(out, "\n")[1:27] 56 expectedValues := [26]string{"Z", "Y", "X", "W", "V", "U", "T", "S", "R", "Q", "P", "O", "N", "M", "L", "K", "J", "I", "H", "G", "F", "E", "D", "C", "B", "A"} 57 58 for i := 0; i < 26; i++ { 59 echoValue := fmt.Sprintf("echo \"%s\"", expectedValues[i]) 60 actualValue := actualValues[i] 61 62 if !strings.Contains(actualValue, echoValue) { 63 c.Fatalf("Expected layer \"%s\", but was: %s", expectedValues[i], actualValue) 64 } 65 } 66 67 } 68 69 func (s *DockerSuite) TestHistoryExistentImage(c *check.C) { 70 historyCmd := exec.Command(dockerBinary, "history", "busybox") 71 _, exitCode, err := runCommandWithOutput(historyCmd) 72 if err != nil || exitCode != 0 { 73 c.Fatal("failed to get image history") 74 } 75 } 76 77 func (s *DockerSuite) TestHistoryNonExistentImage(c *check.C) { 78 historyCmd := exec.Command(dockerBinary, "history", "testHistoryNonExistentImage") 79 _, exitCode, err := runCommandWithOutput(historyCmd) 80 if err == nil || exitCode == 0 { 81 c.Fatal("history on a non-existent image didn't result in a non-zero exit status") 82 } 83 } 84 85 func (s *DockerSuite) TestHistoryImageWithComment(c *check.C) { 86 name := "testhistoryimagewithcomment" 87 88 // make a image through docker commit <container id> [ -m messages ] 89 //runCmd := exec.Command(dockerBinary, "run", "-i", "-a", "stdin", "busybox", "echo", "foo") 90 runCmd := exec.Command(dockerBinary, "run", "--name", name, "busybox", "true") 91 out, _, err := runCommandWithOutput(runCmd) 92 if err != nil { 93 c.Fatalf("failed to run container: %s, %v", out, err) 94 } 95 96 waitCmd := exec.Command(dockerBinary, "wait", name) 97 if out, _, err := runCommandWithOutput(waitCmd); err != nil { 98 c.Fatalf("error thrown while waiting for container: %s, %v", out, err) 99 } 100 101 comment := "This_is_a_comment" 102 103 commitCmd := exec.Command(dockerBinary, "commit", "-m="+comment, name, name) 104 if out, _, err := runCommandWithOutput(commitCmd); err != nil { 105 c.Fatalf("failed to commit container to image: %s, %v", out, err) 106 } 107 108 // test docker history <image id> to check comment messages 109 historyCmd := exec.Command(dockerBinary, "history", name) 110 out, exitCode, err := runCommandWithOutput(historyCmd) 111 if err != nil || exitCode != 0 { 112 c.Fatalf("failed to get image history: %s, %v", out, err) 113 } 114 115 outputTabs := strings.Fields(strings.Split(out, "\n")[1]) 116 //outputTabs := regexp.MustCompile(" +").Split(outputLine, -1) 117 actualValue := outputTabs[len(outputTabs)-1] 118 119 if !strings.Contains(actualValue, comment) { 120 c.Fatalf("Expected comments %q, but found %q", comment, actualValue) 121 } 122 123 } 124 125 func (s *DockerSuite) TestHistoryHumanOptionFalse(c *check.C) { 126 out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "history", "--human=false", "busybox")) 127 lines := strings.Split(out, "\n") 128 sizeColumnRegex, _ := regexp.Compile("SIZE +") 129 indices := sizeColumnRegex.FindStringIndex(lines[0]) 130 startIndex := indices[0] 131 endIndex := indices[1] 132 for i := 1; i < len(lines)-1; i++ { 133 if endIndex > len(lines[i]) { 134 endIndex = len(lines[i]) 135 } 136 sizeString := lines[i][startIndex:endIndex] 137 if _, err := strconv.Atoi(strings.TrimSpace(sizeString)); err != nil { 138 c.Fatalf("The size '%s' was not an Integer", sizeString) 139 } 140 } 141 } 142 143 func (s *DockerSuite) TestHistoryHumanOptionTrue(c *check.C) { 144 out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "history", "--human=true", "busybox")) 145 lines := strings.Split(out, "\n") 146 sizeColumnRegex, _ := regexp.Compile("SIZE +") 147 humanSizeRegex, _ := regexp.Compile("^\\d+.*B$") // Matches human sizes like 10 MB, 3.2 KB, etc 148 indices := sizeColumnRegex.FindStringIndex(lines[0]) 149 startIndex := indices[0] 150 endIndex := indices[1] 151 for i := 1; i < len(lines)-1; i++ { 152 if endIndex > len(lines[i]) { 153 endIndex = len(lines[i]) 154 } 155 sizeString := lines[i][startIndex:endIndex] 156 if matchSuccess := humanSizeRegex.MatchString(strings.TrimSpace(sizeString)); !matchSuccess { 157 c.Fatalf("The size '%s' was not in human format", sizeString) 158 } 159 } 160 }