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  // }