github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/Godeps/_workspace/src/github.com/kardianos/osext/osext_test.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin linux freebsd netbsd windows
     6  
     7  package osext
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"io"
    13  	"os"
    14  	"os/exec"
    15  	"path/filepath"
    16  	"runtime"
    17  	"testing"
    18  )
    19  
    20  const (
    21  	executableEnvVar = "OSTEST_OUTPUT_EXECUTABLE"
    22  
    23  	executableEnvValueMatch  = "match"
    24  	executableEnvValueDelete = "delete"
    25  )
    26  
    27  func TestExecutableMatch(t *testing.T) {
    28  	ep, err := Executable()
    29  	if err != nil {
    30  		t.Fatalf("Executable failed: %v", err)
    31  	}
    32  
    33  	// fullpath to be of the form "dir/prog".
    34  	dir := filepath.Dir(filepath.Dir(ep))
    35  	fullpath, err := filepath.Rel(dir, ep)
    36  	if err != nil {
    37  		t.Fatalf("filepath.Rel: %v", err)
    38  	}
    39  	// Make child start with a relative program path.
    40  	// Alter argv[0] for child to verify getting real path without argv[0].
    41  	cmd := &exec.Cmd{
    42  		Dir:  dir,
    43  		Path: fullpath,
    44  		Env:  []string{fmt.Sprintf("%s=%s", executableEnvVar, executableEnvValueMatch)},
    45  	}
    46  	out, err := cmd.CombinedOutput()
    47  	if err != nil {
    48  		t.Fatalf("exec(self) failed: %v", err)
    49  	}
    50  	outs := string(out)
    51  	if !filepath.IsAbs(outs) {
    52  		t.Fatalf("Child returned %q, want an absolute path", out)
    53  	}
    54  	if !sameFile(outs, ep) {
    55  		t.Fatalf("Child returned %q, not the same file as %q", out, ep)
    56  	}
    57  }
    58  
    59  func TestExecutableDelete(t *testing.T) {
    60  	if runtime.GOOS != "linux" {
    61  		t.Skip()
    62  	}
    63  	fpath, err := Executable()
    64  	if err != nil {
    65  		t.Fatalf("Executable failed: %v", err)
    66  	}
    67  
    68  	r, w := io.Pipe()
    69  	stderrBuff := &bytes.Buffer{}
    70  	stdoutBuff := &bytes.Buffer{}
    71  	cmd := &exec.Cmd{
    72  		Path:   fpath,
    73  		Env:    []string{fmt.Sprintf("%s=%s", executableEnvVar, executableEnvValueDelete)},
    74  		Stdin:  r,
    75  		Stderr: stderrBuff,
    76  		Stdout: stdoutBuff,
    77  	}
    78  	err = cmd.Start()
    79  	if err != nil {
    80  		t.Fatalf("exec(self) start failed: %v", err)
    81  	}
    82  
    83  	tempPath := fpath + "_copy"
    84  	_ = os.Remove(tempPath)
    85  
    86  	err = copyFile(tempPath, fpath)
    87  	if err != nil {
    88  		t.Fatalf("copy file failed: %v", err)
    89  	}
    90  	err = os.Remove(fpath)
    91  	if err != nil {
    92  		t.Fatalf("remove running test file failed: %v", err)
    93  	}
    94  	err = os.Rename(tempPath, fpath)
    95  	if err != nil {
    96  		t.Fatalf("rename copy to previous name failed: %v", err)
    97  	}
    98  
    99  	w.Write([]byte{0})
   100  	w.Close()
   101  
   102  	err = cmd.Wait()
   103  	if err != nil {
   104  		t.Fatalf("exec wait failed: %v", err)
   105  	}
   106  
   107  	childPath := stderrBuff.String()
   108  	if !filepath.IsAbs(childPath) {
   109  		t.Fatalf("Child returned %q, want an absolute path", childPath)
   110  	}
   111  	if !sameFile(childPath, fpath) {
   112  		t.Fatalf("Child returned %q, not the same file as %q", childPath, fpath)
   113  	}
   114  }
   115  
   116  func sameFile(fn1, fn2 string) bool {
   117  	fi1, err := os.Stat(fn1)
   118  	if err != nil {
   119  		return false
   120  	}
   121  	fi2, err := os.Stat(fn2)
   122  	if err != nil {
   123  		return false
   124  	}
   125  	return os.SameFile(fi1, fi2)
   126  }
   127  func copyFile(dest, src string) error {
   128  	df, err := os.Create(dest)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	defer df.Close()
   133  
   134  	sf, err := os.Open(src)
   135  	if err != nil {
   136  		return err
   137  	}
   138  	defer sf.Close()
   139  
   140  	_, err = io.Copy(df, sf)
   141  	return err
   142  }
   143  
   144  func TestMain(m *testing.M) {
   145  	env := os.Getenv(executableEnvVar)
   146  	switch env {
   147  	case "":
   148  		os.Exit(m.Run())
   149  	case executableEnvValueMatch:
   150  		// First chdir to another path.
   151  		dir := "/"
   152  		if runtime.GOOS == "windows" {
   153  			dir = filepath.VolumeName(".")
   154  		}
   155  		os.Chdir(dir)
   156  		if ep, err := Executable(); err != nil {
   157  			fmt.Fprint(os.Stderr, "ERROR: ", err)
   158  		} else {
   159  			fmt.Fprint(os.Stderr, ep)
   160  		}
   161  	case executableEnvValueDelete:
   162  		bb := make([]byte, 1)
   163  		var err error
   164  		n, err := os.Stdin.Read(bb)
   165  		if err != nil {
   166  			fmt.Fprint(os.Stderr, "ERROR: ", err)
   167  			os.Exit(2)
   168  		}
   169  		if n != 1 {
   170  			fmt.Fprint(os.Stderr, "ERROR: n != 1, n == ", n)
   171  			os.Exit(2)
   172  		}
   173  		if ep, err := Executable(); err != nil {
   174  			fmt.Fprint(os.Stderr, "ERROR: ", err)
   175  		} else {
   176  			fmt.Fprint(os.Stderr, ep)
   177  		}
   178  	}
   179  	os.Exit(0)
   180  }