github.com/keithballdotnet/deis@v1.0.1-0.20141111034523-a4511c46a6ce/tests/utils/utils.go (about)

     1  // Package utils contains commonly useful functions from Deis testing.
     2  
     3  package utils
     4  
     5  import (
     6  	"bufio"
     7  	"bytes"
     8  	"crypto/rand"
     9  	"fmt"
    10  	"io"
    11  	"net"
    12  	"os"
    13  	"os/exec"
    14  	"path/filepath"
    15  	"strings"
    16  	"syscall"
    17  	"time"
    18  )
    19  
    20  // BuildTag returns the $BUILD_TAG environment variable or `git rev-parse` output.
    21  func BuildTag() string {
    22  	var tag string
    23  	tag = os.Getenv("BUILD_TAG")
    24  	if tag == "" {
    25  		out, err := exec.Command("git", "rev-parse", "--short", "HEAD").Output()
    26  		if err != nil {
    27  			tag = "NOTAG"
    28  		}
    29  		tag = "git-" + string(out)
    30  	}
    31  	return strings.TrimSpace(tag)
    32  }
    33  
    34  // Chdir sets the current working directory to the relative path specified.
    35  func Chdir(app string) error {
    36  	var wd, _ = os.Getwd()
    37  	dir, _ := filepath.Abs(filepath.Join(wd, app))
    38  	err := os.Chdir(dir)
    39  	fmt.Println(dir)
    40  	return err
    41  }
    42  
    43  // CreateFile creates an empty file at the specified path.
    44  func CreateFile(path string) error {
    45  	fo, err := os.Create(path)
    46  	if err != nil {
    47  		return err
    48  	}
    49  	defer fo.Close()
    50  	return nil
    51  }
    52  
    53  // HostAddress returns the host IP for accessing etcd and Deis services.
    54  func HostAddress() string {
    55  	IP := os.Getenv("HOST_IPADDR")
    56  	if IP == "" {
    57  		IP = "172.17.8.100"
    58  	}
    59  	return IP
    60  }
    61  
    62  // Hostname returns the hostname of the machine running the container, *not* the local machine
    63  // We infer the hostname because we don't necessarily know how to log in.
    64  func Hostname() string {
    65  	switch HostAddress() {
    66  	case "172.17.8.100":
    67  		return "deis-1"
    68  	case "172.17.8.101":
    69  		return "deis-2"
    70  	case "172.17.8.102":
    71  		return "deis-3"
    72  	case "172.21.12.100":
    73  		return "docker-registry"
    74  	default:
    75  		return "boot2docker"
    76  	}
    77  }
    78  
    79  // NewID returns the first part of a random RFC 4122 UUID
    80  // See http://play.golang.org/p/4FkNSiUDMg
    81  func NewID() string {
    82  	uuid := make([]byte, 16)
    83  	io.ReadFull(rand.Reader, uuid)
    84  	// variant bits; see section 4.1.1
    85  	uuid[8] = uuid[8]&^0xc0 | 0x80
    86  	// version 4 (pseudo-random); see section 4.1.3
    87  	uuid[6] = uuid[6]&^0xf0 | 0x40
    88  	return fmt.Sprintf("%x", uuid[0:4])
    89  }
    90  
    91  // RandomPort returns an unused TCP listen port on the host.
    92  func RandomPort() string {
    93  	l, _ := net.Listen("tcp", "127.0.0.1:0") // listen on localhost
    94  	defer l.Close()
    95  	port := l.Addr()
    96  	return strings.Split(port.String(), ":")[1]
    97  }
    98  
    99  // Rmdir removes a directory and its contents.
   100  func Rmdir(app string) error {
   101  	var wd, _ = os.Getwd()
   102  	dir, _ := filepath.Abs(filepath.Join(wd, app))
   103  	err := os.RemoveAll(dir)
   104  	fmt.Println(dir)
   105  	return err
   106  }
   107  
   108  // streamOutput from a source to a destination buffer while also printing
   109  func streamOutput(src io.Reader, dst *bytes.Buffer, out io.Writer) error {
   110  
   111  	s := bufio.NewReader(src)
   112  
   113  	for {
   114  		var line []byte
   115  		line, err := s.ReadSlice('\n')
   116  		if err == io.EOF && len(line) == 0 {
   117  			break // done
   118  		}
   119  		if err == io.EOF {
   120  			return fmt.Errorf("Improper termination: %v", line)
   121  		}
   122  		if err != nil {
   123  			return err
   124  		}
   125  
   126  		// append to the buffer
   127  		dst.Write(line)
   128  
   129  		// write to stdout/stderr also
   130  		out.Write(line)
   131  	}
   132  
   133  	return nil
   134  }
   135  
   136  // RunCommandWithStdoutStderr execs a command and returns its output.
   137  func RunCommandWithStdoutStderr(cmd *exec.Cmd) (bytes.Buffer, bytes.Buffer, error) {
   138  	var stdout, stderr bytes.Buffer
   139  	stderrPipe, err := cmd.StderrPipe()
   140  	stdoutPipe, err := cmd.StdoutPipe()
   141  
   142  	cmd.Env = os.Environ()
   143  	if err != nil {
   144  		fmt.Println("error at io pipes")
   145  	}
   146  
   147  	err = cmd.Start()
   148  	if err != nil {
   149  		fmt.Println("error at command start")
   150  	}
   151  
   152  	go func() {
   153  		streamOutput(stdoutPipe, &stdout, os.Stdout)
   154  	}()
   155  	go func() {
   156  		streamOutput(stderrPipe, &stderr, os.Stderr)
   157  	}()
   158  	time.Sleep(2000 * time.Millisecond)
   159  	err = cmd.Wait()
   160  	if err != nil {
   161  		fmt.Println("error at command wait")
   162  	}
   163  	return stdout, stderr, err
   164  }
   165  
   166  func getExitCode(err error) (int, error) {
   167  	exitCode := 0
   168  	if exiterr, ok := err.(*exec.ExitError); ok {
   169  		if procExit := exiterr.Sys().(syscall.WaitStatus); ok {
   170  			return procExit.ExitStatus(), nil
   171  		}
   172  	}
   173  	return exitCode, fmt.Errorf("failed to get exit code")
   174  }