github.com/portworx/docker@v1.12.1/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  	"strconv"
    11  	"strings"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  func TestIsKilledFalseWithNonKilledProcess(t *testing.T) {
    17  	var lsCmd *exec.Cmd
    18  	if runtime.GOOS != "windows" {
    19  		lsCmd = exec.Command("ls")
    20  	} else {
    21  		lsCmd = exec.Command("cmd", "/c", "dir")
    22  	}
    23  
    24  	err := lsCmd.Run()
    25  	if IsKilled(err) {
    26  		t.Fatalf("Expected the ls command to not be killed, was.")
    27  	}
    28  }
    29  
    30  func TestIsKilledTrueWithKilledProcess(t *testing.T) {
    31  	var longCmd *exec.Cmd
    32  	if runtime.GOOS != "windows" {
    33  		longCmd = exec.Command("top")
    34  	} else {
    35  		longCmd = exec.Command("powershell", "while ($true) { sleep 1 }")
    36  	}
    37  
    38  	// Start a command
    39  	err := longCmd.Start()
    40  	if err != nil {
    41  		t.Fatal(err)
    42  	}
    43  	// Capture the error when *dying*
    44  	done := make(chan error, 1)
    45  	go func() {
    46  		done <- longCmd.Wait()
    47  	}()
    48  	// Then kill it
    49  	longCmd.Process.Kill()
    50  	// Get the error
    51  	err = <-done
    52  	if !IsKilled(err) {
    53  		t.Fatalf("Expected the command to be killed, was not.")
    54  	}
    55  }
    56  
    57  func TestRunCommandWithOutput(t *testing.T) {
    58  	var (
    59  		echoHelloWorldCmd *exec.Cmd
    60  		expected          string
    61  	)
    62  	if runtime.GOOS != "windows" {
    63  		echoHelloWorldCmd = exec.Command("echo", "hello", "world")
    64  		expected = "hello world\n"
    65  	} else {
    66  		echoHelloWorldCmd = exec.Command("cmd", "/s", "/c", "echo", "hello", "world")
    67  		expected = "hello world\r\n"
    68  	}
    69  
    70  	out, exitCode, err := RunCommandWithOutput(echoHelloWorldCmd)
    71  	if out != expected || exitCode != 0 || err != nil {
    72  		t.Fatalf("Expected command to output %s, got %s, %v with exitCode %v", expected, out, err, exitCode)
    73  	}
    74  }
    75  
    76  func TestRunCommandWithOutputError(t *testing.T) {
    77  	var (
    78  		p                string
    79  		wrongCmd         *exec.Cmd
    80  		expected         string
    81  		expectedExitCode int
    82  	)
    83  
    84  	if runtime.GOOS != "windows" {
    85  		p = "$PATH"
    86  		wrongCmd = exec.Command("ls", "-z")
    87  		expected = `ls: invalid option -- 'z'
    88  Try 'ls --help' for more information.
    89  `
    90  		expectedExitCode = 2
    91  	} else {
    92  		p = "%PATH%"
    93  		wrongCmd = exec.Command("cmd", "/s", "/c", "dir", "/Z")
    94  		expected = "Invalid switch - " + strconv.Quote("Z") + ".\r\n"
    95  		expectedExitCode = 1
    96  	}
    97  	cmd := exec.Command("doesnotexists")
    98  	out, exitCode, err := RunCommandWithOutput(cmd)
    99  	expectedError := `exec: "doesnotexists": executable file not found in ` + p
   100  	if out != "" || exitCode != 127 || err == nil || err.Error() != expectedError {
   101  		t.Fatalf("Expected command to output %s, got %s, %v with exitCode %v", expectedError, out, err, exitCode)
   102  	}
   103  
   104  	out, exitCode, err = RunCommandWithOutput(wrongCmd)
   105  
   106  	if out != expected || exitCode != expectedExitCode || err == nil || !strings.Contains(err.Error(), "exit status "+strconv.Itoa(expectedExitCode)) {
   107  		t.Fatalf("Expected command to output %s, got out:xxx%sxxx, err:%v with exitCode %v", expected, out, err, exitCode)
   108  	}
   109  }
   110  
   111  func TestRunCommandWithStdoutStderr(t *testing.T) {
   112  	echoHelloWorldCmd := exec.Command("echo", "hello", "world")
   113  	stdout, stderr, exitCode, err := RunCommandWithStdoutStderr(echoHelloWorldCmd)
   114  	expected := "hello world\n"
   115  	if stdout != expected || stderr != "" || exitCode != 0 || err != nil {
   116  		t.Fatalf("Expected command to output %s, got stdout:%s, stderr:%s, err:%v with exitCode %v", expected, stdout, stderr, err, exitCode)
   117  	}
   118  }
   119  
   120  func TestRunCommandWithStdoutStderrError(t *testing.T) {
   121  	p := "$PATH"
   122  	if runtime.GOOS == "windows" {
   123  		p = "%PATH%"
   124  	}
   125  	cmd := exec.Command("doesnotexists")
   126  	stdout, stderr, exitCode, err := RunCommandWithStdoutStderr(cmd)
   127  	expectedError := `exec: "doesnotexists": executable file not found in ` + p
   128  	if stdout != "" || stderr != "" || exitCode != 127 || err == nil || err.Error() != expectedError {
   129  		t.Fatalf("Expected command to output out:%s, stderr:%s, got stdout:%s, stderr:%s, err:%v with exitCode %v", "", "", stdout, stderr, err, exitCode)
   130  	}
   131  
   132  	wrongLsCmd := exec.Command("ls", "-z")
   133  	expected := `ls: invalid option -- 'z'
   134  Try 'ls --help' for more information.
   135  `
   136  
   137  	stdout, stderr, exitCode, err = RunCommandWithStdoutStderr(wrongLsCmd)
   138  	if stdout != "" && stderr != expected || exitCode != 2 || err == nil || err.Error() != "exit status 2" {
   139  		t.Fatalf("Expected command to output out:%s, stderr:%s, got stdout:%s, stderr:%s, err:%v with exitCode %v", "", expectedError, stdout, stderr, err, exitCode)
   140  	}
   141  }
   142  
   143  func TestRunCommandWithOutputForDurationFinished(t *testing.T) {
   144  	// TODO Windows: Port this test
   145  	if runtime.GOOS == "windows" {
   146  		t.Skip("Needs porting to Windows")
   147  	}
   148  
   149  	cmd := exec.Command("ls")
   150  	out, exitCode, timedOut, err := RunCommandWithOutputForDuration(cmd, 50*time.Millisecond)
   151  	if out == "" || exitCode != 0 || timedOut || err != nil {
   152  		t.Fatalf("Expected the command to run for less 50 milliseconds and thus not time out, but did not : out:[%s], exitCode:[%d], timedOut:[%v], err:[%v]", out, exitCode, timedOut, err)
   153  	}
   154  }
   155  
   156  func TestRunCommandWithOutputForDurationKilled(t *testing.T) {
   157  	// TODO Windows: Port this test
   158  	if runtime.GOOS == "windows" {
   159  		t.Skip("Needs porting to Windows")
   160  	}
   161  	cmd := exec.Command("sh", "-c", "while true ; do echo 1 ; sleep .1 ; done")
   162  	out, exitCode, timedOut, err := RunCommandWithOutputForDuration(cmd, 500*time.Millisecond)
   163  	ones := strings.Split(out, "\n")
   164  	if len(ones) != 6 || exitCode != 0 || !timedOut || err != nil {
   165  		t.Fatalf("Expected the command to run for 500 milliseconds (and thus print six lines (five with 1, one empty) and time out, but did not : out:[%s], exitCode:%d, timedOut:%v, err:%v", out, exitCode, timedOut, err)
   166  	}
   167  }
   168  
   169  func TestRunCommandWithOutputForDurationErrors(t *testing.T) {
   170  	cmd := exec.Command("ls")
   171  	cmd.Stdout = os.Stdout
   172  	if _, _, _, err := RunCommandWithOutputForDuration(cmd, 1*time.Millisecond); err == nil || err.Error() != "cmd.Stdout already set" {
   173  		t.Fatalf("Expected an error as cmd.Stdout was already set, did not (err:%s).", err)
   174  	}
   175  	cmd = exec.Command("ls")
   176  	cmd.Stderr = os.Stderr
   177  	if _, _, _, err := RunCommandWithOutputForDuration(cmd, 1*time.Millisecond); err == nil || err.Error() != "cmd.Stderr already set" {
   178  		t.Fatalf("Expected an error as cmd.Stderr was already set, did not (err:%s).", err)
   179  	}
   180  }
   181  
   182  func TestRunCommandWithOutputAndTimeoutFinished(t *testing.T) {
   183  	// TODO Windows: Port this test
   184  	if runtime.GOOS == "windows" {
   185  		t.Skip("Needs porting to Windows")
   186  	}
   187  
   188  	cmd := exec.Command("ls")
   189  	out, exitCode, err := RunCommandWithOutputAndTimeout(cmd, 50*time.Millisecond)
   190  	if out == "" || exitCode != 0 || err != nil {
   191  		t.Fatalf("Expected the command to run for less 50 milliseconds and thus not time out, but did not : out:[%s], exitCode:[%d], err:[%v]", out, exitCode, err)
   192  	}
   193  }
   194  
   195  func TestRunCommandWithOutputAndTimeoutKilled(t *testing.T) {
   196  	// TODO Windows: Port this test
   197  	if runtime.GOOS == "windows" {
   198  		t.Skip("Needs porting to Windows")
   199  	}
   200  
   201  	cmd := exec.Command("sh", "-c", "while true ; do echo 1 ; sleep .1 ; done")
   202  	out, exitCode, err := RunCommandWithOutputAndTimeout(cmd, 500*time.Millisecond)
   203  	ones := strings.Split(out, "\n")
   204  	if len(ones) != 6 || exitCode != 0 || err == nil || err.Error() != "command timed out" {
   205  		t.Fatalf("Expected the command to run for 500 milliseconds (and thus print six lines (five with 1, one empty) and time out with an error 'command timed out', but did not : out:[%s], exitCode:%d, err:%v", out, exitCode, err)
   206  	}
   207  }
   208  
   209  func TestRunCommandWithOutputAndTimeoutErrors(t *testing.T) {
   210  	cmd := exec.Command("ls")
   211  	cmd.Stdout = os.Stdout
   212  	if _, _, err := RunCommandWithOutputAndTimeout(cmd, 1*time.Millisecond); err == nil || err.Error() != "cmd.Stdout already set" {
   213  		t.Fatalf("Expected an error as cmd.Stdout was already set, did not (err:%s).", err)
   214  	}
   215  	cmd = exec.Command("ls")
   216  	cmd.Stderr = os.Stderr
   217  	if _, _, err := RunCommandWithOutputAndTimeout(cmd, 1*time.Millisecond); err == nil || err.Error() != "cmd.Stderr already set" {
   218  		t.Fatalf("Expected an error as cmd.Stderr was already set, did not (err:%s).", err)
   219  	}
   220  }
   221  
   222  func TestRunCommand(t *testing.T) {
   223  	// TODO Windows: Port this test
   224  	if runtime.GOOS == "windows" {
   225  		t.Skip("Needs porting to Windows")
   226  	}
   227  
   228  	p := "$PATH"
   229  	if runtime.GOOS == "windows" {
   230  		p = "%PATH%"
   231  	}
   232  	lsCmd := exec.Command("ls")
   233  	exitCode, err := RunCommand(lsCmd)
   234  	if exitCode != 0 || err != nil {
   235  		t.Fatalf("Expected runCommand to run the command successfully, got: exitCode:%d, err:%v", exitCode, err)
   236  	}
   237  
   238  	var expectedError string
   239  
   240  	exitCode, err = RunCommand(exec.Command("doesnotexists"))
   241  	expectedError = `exec: "doesnotexists": executable file not found in ` + p
   242  	if exitCode != 127 || err == nil || err.Error() != expectedError {
   243  		t.Fatalf("Expected runCommand to run the command successfully, got: exitCode:%d, err:%v", exitCode, err)
   244  	}
   245  	wrongLsCmd := exec.Command("ls", "-z")
   246  	expected := 2
   247  	expectedError = `exit status 2`
   248  	exitCode, err = RunCommand(wrongLsCmd)
   249  	if exitCode != expected || err == nil || err.Error() != expectedError {
   250  		t.Fatalf("Expected runCommand to run the command successfully, got: exitCode:%d, err:%v", exitCode, err)
   251  	}
   252  }
   253  
   254  func TestRunCommandPipelineWithOutputWithNotEnoughCmds(t *testing.T) {
   255  	_, _, err := RunCommandPipelineWithOutput(exec.Command("ls"))
   256  	expectedError := "pipeline does not have multiple cmds"
   257  	if err == nil || err.Error() != expectedError {
   258  		t.Fatalf("Expected an error with %s, got err:%s", expectedError, err)
   259  	}
   260  }
   261  
   262  func TestRunCommandPipelineWithOutputErrors(t *testing.T) {
   263  	p := "$PATH"
   264  	if runtime.GOOS == "windows" {
   265  		p = "%PATH%"
   266  	}
   267  	cmd1 := exec.Command("ls")
   268  	cmd1.Stdout = os.Stdout
   269  	cmd2 := exec.Command("anything really")
   270  	_, _, err := RunCommandPipelineWithOutput(cmd1, cmd2)
   271  	if err == nil || err.Error() != "cannot set stdout pipe for anything really: exec: Stdout already set" {
   272  		t.Fatalf("Expected an error, got %v", err)
   273  	}
   274  
   275  	cmdWithError := exec.Command("doesnotexists")
   276  	cmdCat := exec.Command("cat")
   277  	_, _, err = RunCommandPipelineWithOutput(cmdWithError, cmdCat)
   278  	if err == nil || err.Error() != `starting doesnotexists failed with error: exec: "doesnotexists": executable file not found in `+p {
   279  		t.Fatalf("Expected an error, got %v", err)
   280  	}
   281  }
   282  
   283  func TestRunCommandPipelineWithOutput(t *testing.T) {
   284  	cmds := []*exec.Cmd{
   285  		// Print 2 characters
   286  		exec.Command("echo", "-n", "11"),
   287  		// Count the number or char from stdin (previous command)
   288  		exec.Command("wc", "-m"),
   289  	}
   290  	out, exitCode, err := RunCommandPipelineWithOutput(cmds...)
   291  	expectedOutput := "2\n"
   292  	if out != expectedOutput || exitCode != 0 || err != nil {
   293  		t.Fatalf("Expected %s for commands %v, got out:%s, exitCode:%d, err:%v", expectedOutput, cmds, out, exitCode, err)
   294  	}
   295  }
   296  
   297  // Simple simple test as it is just a passthrough for json.Unmarshal
   298  func TestUnmarshalJSON(t *testing.T) {
   299  	emptyResult := struct{}{}
   300  	if err := UnmarshalJSON([]byte(""), &emptyResult); err == nil {
   301  		t.Fatalf("Expected an error, got nothing")
   302  	}
   303  	result := struct{ Name string }{}
   304  	if err := UnmarshalJSON([]byte(`{"name": "name"}`), &result); err != nil {
   305  		t.Fatal(err)
   306  	}
   307  	if result.Name != "name" {
   308  		t.Fatalf("Expected result.name to be 'name', was '%s'", result.Name)
   309  	}
   310  }
   311  
   312  func TestConvertSliceOfStringsToMap(t *testing.T) {
   313  	input := []string{"a", "b"}
   314  	actual := ConvertSliceOfStringsToMap(input)
   315  	for _, key := range input {
   316  		if _, ok := actual[key]; !ok {
   317  			t.Fatalf("Expected output to contains key %s, did not: %v", key, actual)
   318  		}
   319  	}
   320  }
   321  
   322  func TestCompareDirectoryEntries(t *testing.T) {
   323  	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-compare-directories")
   324  	if err != nil {
   325  		t.Fatal(err)
   326  	}
   327  	defer os.RemoveAll(tmpFolder)
   328  
   329  	file1 := filepath.Join(tmpFolder, "file1")
   330  	file2 := filepath.Join(tmpFolder, "file2")
   331  	os.Create(file1)
   332  	os.Create(file2)
   333  
   334  	fi1, err := os.Stat(file1)
   335  	if err != nil {
   336  		t.Fatal(err)
   337  	}
   338  	fi1bis, err := os.Stat(file1)
   339  	if err != nil {
   340  		t.Fatal(err)
   341  	}
   342  	fi2, err := os.Stat(file2)
   343  	if err != nil {
   344  		t.Fatal(err)
   345  	}
   346  
   347  	cases := []struct {
   348  		e1          []os.FileInfo
   349  		e2          []os.FileInfo
   350  		shouldError bool
   351  	}{
   352  		// Empty directories
   353  		{
   354  			[]os.FileInfo{},
   355  			[]os.FileInfo{},
   356  			false,
   357  		},
   358  		// Same FileInfos
   359  		{
   360  			[]os.FileInfo{fi1},
   361  			[]os.FileInfo{fi1},
   362  			false,
   363  		},
   364  		// Different FileInfos but same names
   365  		{
   366  			[]os.FileInfo{fi1},
   367  			[]os.FileInfo{fi1bis},
   368  			false,
   369  		},
   370  		// Different FileInfos, different names
   371  		{
   372  			[]os.FileInfo{fi1},
   373  			[]os.FileInfo{fi2},
   374  			true,
   375  		},
   376  	}
   377  	for _, elt := range cases {
   378  		err := CompareDirectoryEntries(elt.e1, elt.e2)
   379  		if elt.shouldError && err == nil {
   380  			t.Fatalf("Should have return an error, did not with %v and %v", elt.e1, elt.e2)
   381  		}
   382  		if !elt.shouldError && err != nil {
   383  			t.Fatalf("Should have not returned an error, but did : %v with %v and %v", err, elt.e1, elt.e2)
   384  		}
   385  	}
   386  }
   387  
   388  // FIXME make an "unhappy path" test for ListTar without "panicking" :-)
   389  func TestListTar(t *testing.T) {
   390  	// TODO Windows: Figure out why this fails. Should be portable.
   391  	if runtime.GOOS == "windows" {
   392  		t.Skip("Failing on Windows - needs further investigation")
   393  	}
   394  	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-list-tar")
   395  	if err != nil {
   396  		t.Fatal(err)
   397  	}
   398  	defer os.RemoveAll(tmpFolder)
   399  
   400  	// Let's create a Tar file
   401  	srcFile := filepath.Join(tmpFolder, "src")
   402  	tarFile := filepath.Join(tmpFolder, "src.tar")
   403  	os.Create(srcFile)
   404  	cmd := exec.Command("sh", "-c", "tar cf "+tarFile+" "+srcFile)
   405  	_, err = cmd.CombinedOutput()
   406  	if err != nil {
   407  		t.Fatal(err)
   408  	}
   409  
   410  	reader, err := os.Open(tarFile)
   411  	if err != nil {
   412  		t.Fatal(err)
   413  	}
   414  	defer reader.Close()
   415  
   416  	entries, err := ListTar(reader)
   417  	if err != nil {
   418  		t.Fatal(err)
   419  	}
   420  	if len(entries) != 1 && entries[0] != "src" {
   421  		t.Fatalf("Expected a tar file with 1 entry (%s), got %v", srcFile, entries)
   422  	}
   423  }
   424  
   425  func TestRandomTmpDirPath(t *testing.T) {
   426  	path := RandomTmpDirPath("something", runtime.GOOS)
   427  
   428  	prefix := "/tmp/something"
   429  	if runtime.GOOS == "windows" {
   430  		prefix = os.Getenv("TEMP") + `\something`
   431  	}
   432  	expectedSize := len(prefix) + 11
   433  
   434  	if !strings.HasPrefix(path, prefix) {
   435  		t.Fatalf("Expected generated path to have '%s' as prefix, got %s'", prefix, path)
   436  	}
   437  	if len(path) != expectedSize {
   438  		t.Fatalf("Expected generated path to be %d, got %d", expectedSize, len(path))
   439  	}
   440  }
   441  
   442  func TestConsumeWithSpeed(t *testing.T) {
   443  	reader := strings.NewReader("1234567890")
   444  	chunksize := 2
   445  
   446  	bytes1, err := ConsumeWithSpeed(reader, chunksize, 1*time.Second, nil)
   447  	if err != nil {
   448  		t.Fatal(err)
   449  	}
   450  
   451  	if bytes1 != 10 {
   452  		t.Fatalf("Expected to have read 10 bytes, got %d", bytes1)
   453  	}
   454  
   455  }
   456  
   457  func TestConsumeWithSpeedWithStop(t *testing.T) {
   458  	reader := strings.NewReader("1234567890")
   459  	chunksize := 2
   460  
   461  	stopIt := make(chan bool)
   462  
   463  	go func() {
   464  		time.Sleep(1 * time.Millisecond)
   465  		stopIt <- true
   466  	}()
   467  
   468  	bytes1, err := ConsumeWithSpeed(reader, chunksize, 20*time.Millisecond, stopIt)
   469  	if err != nil {
   470  		t.Fatal(err)
   471  	}
   472  
   473  	if bytes1 != 2 {
   474  		t.Fatalf("Expected to have read 2 bytes, got %d", bytes1)
   475  	}
   476  
   477  }
   478  
   479  func TestParseCgroupPathsEmpty(t *testing.T) {
   480  	cgroupMap := ParseCgroupPaths("")
   481  	if len(cgroupMap) != 0 {
   482  		t.Fatalf("Expected an empty map, got %v", cgroupMap)
   483  	}
   484  	cgroupMap = ParseCgroupPaths("\n")
   485  	if len(cgroupMap) != 0 {
   486  		t.Fatalf("Expected an empty map, got %v", cgroupMap)
   487  	}
   488  	cgroupMap = ParseCgroupPaths("something:else\nagain:here")
   489  	if len(cgroupMap) != 0 {
   490  		t.Fatalf("Expected an empty map, got %v", cgroupMap)
   491  	}
   492  }
   493  
   494  func TestParseCgroupPaths(t *testing.T) {
   495  	cgroupMap := ParseCgroupPaths("2:memory:/a\n1:cpuset:/b")
   496  	if len(cgroupMap) != 2 {
   497  		t.Fatalf("Expected a map with 2 entries, got %v", cgroupMap)
   498  	}
   499  	if value, ok := cgroupMap["memory"]; !ok || value != "/a" {
   500  		t.Fatalf("Expected cgroupMap to contains an entry for 'memory' with value '/a', got %v", cgroupMap)
   501  	}
   502  	if value, ok := cgroupMap["cpuset"]; !ok || value != "/b" {
   503  		t.Fatalf("Expected cgroupMap to contains an entry for 'cpuset' with value '/b', got %v", cgroupMap)
   504  	}
   505  }
   506  
   507  func TestChannelBufferTimeout(t *testing.T) {
   508  	expected := "11"
   509  
   510  	buf := &ChannelBuffer{make(chan []byte, 1)}
   511  	defer buf.Close()
   512  
   513  	done := make(chan struct{}, 1)
   514  	go func() {
   515  		time.Sleep(100 * time.Millisecond)
   516  		io.Copy(buf, strings.NewReader(expected))
   517  		done <- struct{}{}
   518  	}()
   519  
   520  	// Wait long enough
   521  	b := make([]byte, 2)
   522  	_, err := buf.ReadTimeout(b, 50*time.Millisecond)
   523  	if err == nil && err.Error() != "timeout reading from channel" {
   524  		t.Fatalf("Expected an error, got %s", err)
   525  	}
   526  	<-done
   527  }
   528  
   529  func TestChannelBuffer(t *testing.T) {
   530  	expected := "11"
   531  
   532  	buf := &ChannelBuffer{make(chan []byte, 1)}
   533  	defer buf.Close()
   534  
   535  	go func() {
   536  		time.Sleep(100 * time.Millisecond)
   537  		io.Copy(buf, strings.NewReader(expected))
   538  	}()
   539  
   540  	// Wait long enough
   541  	b := make([]byte, 2)
   542  	_, err := buf.ReadTimeout(b, 200*time.Millisecond)
   543  	if err != nil {
   544  		t.Fatal(err)
   545  	}
   546  
   547  	if string(b) != expected {
   548  		t.Fatalf("Expected '%s', got '%s'", expected, string(b))
   549  	}
   550  }
   551  
   552  // FIXME doesn't work
   553  // func TestRunAtDifferentDate(t *testing.T) {
   554  // 	var date string
   555  
   556  // 	// Layout for date. MMDDhhmmYYYY
   557  // 	const timeLayout = "20060102"
   558  // 	expectedDate := "20100201"
   559  // 	theDate, err := time.Parse(timeLayout, expectedDate)
   560  // 	if err != nil {
   561  // 		t.Fatal(err)
   562  // 	}
   563  
   564  // 	RunAtDifferentDate(theDate, func() {
   565  // 		cmd := exec.Command("date", "+%Y%M%d")
   566  // 		out, err := cmd.Output()
   567  // 		if err != nil {
   568  // 			t.Fatal(err)
   569  // 		}
   570  // 		date = string(out)
   571  // 	})
   572  // }