github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/pkg/integration/utils_test.go (about) 1 package integration 2 3 import ( 4 "io" 5 "io/ioutil" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "runtime" 10 "strings" 11 "testing" 12 "time" 13 ) 14 15 func TestIsKilledFalseWithNonKilledProcess(t *testing.T) { 16 var lsCmd *exec.Cmd 17 if runtime.GOOS != "windows" { 18 lsCmd = exec.Command("ls") 19 } else { 20 lsCmd = exec.Command("cmd", "/c", "dir") 21 } 22 23 err := lsCmd.Run() 24 if IsKilled(err) { 25 t.Fatalf("Expected the ls command to not be killed, was.") 26 } 27 } 28 29 func TestIsKilledTrueWithKilledProcess(t *testing.T) { 30 var longCmd *exec.Cmd 31 if runtime.GOOS != "windows" { 32 longCmd = exec.Command("top") 33 } else { 34 longCmd = exec.Command("powershell", "while ($true) { sleep 1 }") 35 } 36 37 // Start a command 38 err := longCmd.Start() 39 if err != nil { 40 t.Fatal(err) 41 } 42 // Capture the error when *dying* 43 done := make(chan error, 1) 44 go func() { 45 done <- longCmd.Wait() 46 }() 47 // Then kill it 48 longCmd.Process.Kill() 49 // Get the error 50 err = <-done 51 if !IsKilled(err) { 52 t.Fatalf("Expected the command to be killed, was not.") 53 } 54 } 55 56 func TestRunCommandPipelineWithOutputWithNotEnoughCmds(t *testing.T) { 57 _, _, err := RunCommandPipelineWithOutput(exec.Command("ls")) 58 expectedError := "pipeline does not have multiple cmds" 59 if err == nil || err.Error() != expectedError { 60 t.Fatalf("Expected an error with %s, got err:%s", expectedError, err) 61 } 62 } 63 64 func TestRunCommandPipelineWithOutputErrors(t *testing.T) { 65 p := "$PATH" 66 if runtime.GOOS == "windows" { 67 p = "%PATH%" 68 } 69 cmd1 := exec.Command("ls") 70 cmd1.Stdout = os.Stdout 71 cmd2 := exec.Command("anything really") 72 _, _, err := RunCommandPipelineWithOutput(cmd1, cmd2) 73 if err == nil || err.Error() != "cannot set stdout pipe for anything really: exec: Stdout already set" { 74 t.Fatalf("Expected an error, got %v", err) 75 } 76 77 cmdWithError := exec.Command("doesnotexists") 78 cmdCat := exec.Command("cat") 79 _, _, err = RunCommandPipelineWithOutput(cmdWithError, cmdCat) 80 if err == nil || err.Error() != `starting doesnotexists failed with error: exec: "doesnotexists": executable file not found in `+p { 81 t.Fatalf("Expected an error, got %v", err) 82 } 83 } 84 85 func TestRunCommandPipelineWithOutput(t *testing.T) { 86 cmds := []*exec.Cmd{ 87 // Print 2 characters 88 exec.Command("echo", "-n", "11"), 89 // Count the number or char from stdin (previous command) 90 exec.Command("wc", "-m"), 91 } 92 out, exitCode, err := RunCommandPipelineWithOutput(cmds...) 93 expectedOutput := "2\n" 94 if out != expectedOutput || exitCode != 0 || err != nil { 95 t.Fatalf("Expected %s for commands %v, got out:%s, exitCode:%d, err:%v", expectedOutput, cmds, out, exitCode, err) 96 } 97 } 98 99 func TestConvertSliceOfStringsToMap(t *testing.T) { 100 input := []string{"a", "b"} 101 actual := ConvertSliceOfStringsToMap(input) 102 for _, key := range input { 103 if _, ok := actual[key]; !ok { 104 t.Fatalf("Expected output to contains key %s, did not: %v", key, actual) 105 } 106 } 107 } 108 109 func TestCompareDirectoryEntries(t *testing.T) { 110 tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-compare-directories") 111 if err != nil { 112 t.Fatal(err) 113 } 114 defer os.RemoveAll(tmpFolder) 115 116 file1 := filepath.Join(tmpFolder, "file1") 117 file2 := filepath.Join(tmpFolder, "file2") 118 os.Create(file1) 119 os.Create(file2) 120 121 fi1, err := os.Stat(file1) 122 if err != nil { 123 t.Fatal(err) 124 } 125 fi1bis, err := os.Stat(file1) 126 if err != nil { 127 t.Fatal(err) 128 } 129 fi2, err := os.Stat(file2) 130 if err != nil { 131 t.Fatal(err) 132 } 133 134 cases := []struct { 135 e1 []os.FileInfo 136 e2 []os.FileInfo 137 shouldError bool 138 }{ 139 // Empty directories 140 { 141 []os.FileInfo{}, 142 []os.FileInfo{}, 143 false, 144 }, 145 // Same FileInfos 146 { 147 []os.FileInfo{fi1}, 148 []os.FileInfo{fi1}, 149 false, 150 }, 151 // Different FileInfos but same names 152 { 153 []os.FileInfo{fi1}, 154 []os.FileInfo{fi1bis}, 155 false, 156 }, 157 // Different FileInfos, different names 158 { 159 []os.FileInfo{fi1}, 160 []os.FileInfo{fi2}, 161 true, 162 }, 163 } 164 for _, elt := range cases { 165 err := CompareDirectoryEntries(elt.e1, elt.e2) 166 if elt.shouldError && err == nil { 167 t.Fatalf("Should have return an error, did not with %v and %v", elt.e1, elt.e2) 168 } 169 if !elt.shouldError && err != nil { 170 t.Fatalf("Should have not returned an error, but did : %v with %v and %v", err, elt.e1, elt.e2) 171 } 172 } 173 } 174 175 // FIXME make an "unhappy path" test for ListTar without "panicking" :-) 176 func TestListTar(t *testing.T) { 177 // TODO Windows: Figure out why this fails. Should be portable. 178 if runtime.GOOS == "windows" { 179 t.Skip("Failing on Windows - needs further investigation") 180 } 181 tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-list-tar") 182 if err != nil { 183 t.Fatal(err) 184 } 185 defer os.RemoveAll(tmpFolder) 186 187 // Let's create a Tar file 188 srcFile := filepath.Join(tmpFolder, "src") 189 tarFile := filepath.Join(tmpFolder, "src.tar") 190 os.Create(srcFile) 191 cmd := exec.Command("sh", "-c", "tar cf "+tarFile+" "+srcFile) 192 _, err = cmd.CombinedOutput() 193 if err != nil { 194 t.Fatal(err) 195 } 196 197 reader, err := os.Open(tarFile) 198 if err != nil { 199 t.Fatal(err) 200 } 201 defer reader.Close() 202 203 entries, err := ListTar(reader) 204 if err != nil { 205 t.Fatal(err) 206 } 207 if len(entries) != 1 && entries[0] != "src" { 208 t.Fatalf("Expected a tar file with 1 entry (%s), got %v", srcFile, entries) 209 } 210 } 211 212 func TestRandomTmpDirPath(t *testing.T) { 213 path := RandomTmpDirPath("something", runtime.GOOS) 214 215 prefix := "/tmp/something" 216 if runtime.GOOS == "windows" { 217 prefix = os.Getenv("TEMP") + `\something` 218 } 219 expectedSize := len(prefix) + 11 220 221 if !strings.HasPrefix(path, prefix) { 222 t.Fatalf("Expected generated path to have '%s' as prefix, got %s'", prefix, path) 223 } 224 if len(path) != expectedSize { 225 t.Fatalf("Expected generated path to be %d, got %d", expectedSize, len(path)) 226 } 227 } 228 229 func TestConsumeWithSpeed(t *testing.T) { 230 reader := strings.NewReader("1234567890") 231 chunksize := 2 232 233 bytes1, err := ConsumeWithSpeed(reader, chunksize, 1*time.Second, nil) 234 if err != nil { 235 t.Fatal(err) 236 } 237 238 if bytes1 != 10 { 239 t.Fatalf("Expected to have read 10 bytes, got %d", bytes1) 240 } 241 242 } 243 244 func TestConsumeWithSpeedWithStop(t *testing.T) { 245 reader := strings.NewReader("1234567890") 246 chunksize := 2 247 248 stopIt := make(chan bool) 249 250 go func() { 251 time.Sleep(1 * time.Millisecond) 252 stopIt <- true 253 }() 254 255 bytes1, err := ConsumeWithSpeed(reader, chunksize, 20*time.Millisecond, stopIt) 256 if err != nil { 257 t.Fatal(err) 258 } 259 260 if bytes1 != 2 { 261 t.Fatalf("Expected to have read 2 bytes, got %d", bytes1) 262 } 263 264 } 265 266 func TestParseCgroupPathsEmpty(t *testing.T) { 267 cgroupMap := ParseCgroupPaths("") 268 if len(cgroupMap) != 0 { 269 t.Fatalf("Expected an empty map, got %v", cgroupMap) 270 } 271 cgroupMap = ParseCgroupPaths("\n") 272 if len(cgroupMap) != 0 { 273 t.Fatalf("Expected an empty map, got %v", cgroupMap) 274 } 275 cgroupMap = ParseCgroupPaths("something:else\nagain:here") 276 if len(cgroupMap) != 0 { 277 t.Fatalf("Expected an empty map, got %v", cgroupMap) 278 } 279 } 280 281 func TestParseCgroupPaths(t *testing.T) { 282 cgroupMap := ParseCgroupPaths("2:memory:/a\n1:cpuset:/b") 283 if len(cgroupMap) != 2 { 284 t.Fatalf("Expected a map with 2 entries, got %v", cgroupMap) 285 } 286 if value, ok := cgroupMap["memory"]; !ok || value != "/a" { 287 t.Fatalf("Expected cgroupMap to contains an entry for 'memory' with value '/a', got %v", cgroupMap) 288 } 289 if value, ok := cgroupMap["cpuset"]; !ok || value != "/b" { 290 t.Fatalf("Expected cgroupMap to contains an entry for 'cpuset' with value '/b', got %v", cgroupMap) 291 } 292 } 293 294 func TestChannelBufferTimeout(t *testing.T) { 295 expected := "11" 296 297 buf := &ChannelBuffer{make(chan []byte, 1)} 298 defer buf.Close() 299 300 done := make(chan struct{}, 1) 301 go func() { 302 time.Sleep(100 * time.Millisecond) 303 io.Copy(buf, strings.NewReader(expected)) 304 done <- struct{}{} 305 }() 306 307 // Wait long enough 308 b := make([]byte, 2) 309 _, err := buf.ReadTimeout(b, 50*time.Millisecond) 310 if err == nil && err.Error() != "timeout reading from channel" { 311 t.Fatalf("Expected an error, got %s", err) 312 } 313 <-done 314 } 315 316 func TestChannelBuffer(t *testing.T) { 317 expected := "11" 318 319 buf := &ChannelBuffer{make(chan []byte, 1)} 320 defer buf.Close() 321 322 go func() { 323 time.Sleep(100 * time.Millisecond) 324 io.Copy(buf, strings.NewReader(expected)) 325 }() 326 327 // Wait long enough 328 b := make([]byte, 2) 329 _, err := buf.ReadTimeout(b, 200*time.Millisecond) 330 if err != nil { 331 t.Fatal(err) 332 } 333 334 if string(b) != expected { 335 t.Fatalf("Expected '%s', got '%s'", expected, string(b)) 336 } 337 } 338 339 // FIXME doesn't work 340 // func TestRunAtDifferentDate(t *testing.T) { 341 // var date string 342 343 // // Layout for date. MMDDhhmmYYYY 344 // const timeLayout = "20060102" 345 // expectedDate := "20100201" 346 // theDate, err := time.Parse(timeLayout, expectedDate) 347 // if err != nil { 348 // t.Fatal(err) 349 // } 350 351 // RunAtDifferentDate(theDate, func() { 352 // cmd := exec.Command("date", "+%Y%M%d") 353 // out, err := cmd.Output() 354 // if err != nil { 355 // t.Fatal(err) 356 // } 357 // date = string(out) 358 // }) 359 // }