...

Source file src/k8s.io/utils/exec/exec_test.go

Documentation: k8s.io/utils/exec

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package exec
    18  
    19  import (
    20  	"context"
    21  	"io"
    22  	"io/ioutil"
    23  	"os"
    24  	osexec "os/exec"
    25  	"testing"
    26  	"time"
    27  )
    28  
    29  func TestExecutorNoArgs(t *testing.T) {
    30  	ex := New()
    31  
    32  	cmd := ex.Command("true")
    33  	out, err := cmd.CombinedOutput()
    34  	if err != nil {
    35  		t.Errorf("expected success, got %v", err)
    36  	}
    37  	if len(out) != 0 {
    38  		t.Errorf("expected no output, got %q", string(out))
    39  	}
    40  
    41  	cmd = ex.Command("false")
    42  	out, err = cmd.CombinedOutput()
    43  	if err == nil {
    44  		t.Errorf("expected failure, got nil error")
    45  	}
    46  	if len(out) != 0 {
    47  		t.Errorf("expected no output, got %q", string(out))
    48  	}
    49  	ee, ok := err.(ExitError)
    50  	if !ok {
    51  		t.Errorf("expected an ExitError, got %+v", err)
    52  	}
    53  	if ee.Exited() {
    54  		if code := ee.ExitStatus(); code != 1 {
    55  			t.Errorf("expected exit status 1, got %d", code)
    56  		}
    57  	}
    58  
    59  	cmd = ex.Command("/does/not/exist")
    60  	_, err = cmd.CombinedOutput()
    61  	if err == nil {
    62  		t.Errorf("expected failure, got nil error")
    63  	}
    64  	if ee, ok := err.(ExitError); ok {
    65  		t.Errorf("expected non-ExitError, got %+v", ee)
    66  	}
    67  }
    68  
    69  func TestExecutorWithArgs(t *testing.T) {
    70  	ex := New()
    71  
    72  	cmd := ex.Command("echo", "stdout")
    73  	out, err := cmd.CombinedOutput()
    74  	if err != nil {
    75  		t.Errorf("expected success, got %+v", err)
    76  	}
    77  	if string(out) != "stdout\n" {
    78  		t.Errorf("unexpected output: %q", string(out))
    79  	}
    80  
    81  	cmd = ex.Command("/bin/sh", "-c", "echo stderr > /dev/stderr")
    82  	out, err = cmd.CombinedOutput()
    83  	if err != nil {
    84  		t.Errorf("expected success, got %+v", err)
    85  	}
    86  	if string(out) != "stderr\n" {
    87  		t.Errorf("unexpected output: %q", string(out))
    88  	}
    89  }
    90  
    91  func TestLookPath(t *testing.T) {
    92  	ex := New()
    93  
    94  	shExpected, _ := osexec.LookPath("sh")
    95  	sh, _ := ex.LookPath("sh")
    96  	if sh != shExpected {
    97  		t.Errorf("unexpected result for LookPath: got %s, expected %s", sh, shExpected)
    98  	}
    99  }
   100  
   101  func TestExecutableNotFound(t *testing.T) {
   102  	exec := New()
   103  
   104  	cmd := exec.Command("fake_executable_name")
   105  	_, err := cmd.CombinedOutput()
   106  	if err != ErrExecutableNotFound {
   107  		t.Errorf("cmd.CombinedOutput(): Expected error ErrExecutableNotFound but got %v", err)
   108  	}
   109  
   110  	cmd = exec.Command("fake_executable_name")
   111  	_, err = cmd.Output()
   112  	if err != ErrExecutableNotFound {
   113  		t.Errorf("cmd.Output(): Expected error ErrExecutableNotFound but got %v", err)
   114  	}
   115  
   116  	cmd = exec.Command("fake_executable_name")
   117  	err = cmd.Run()
   118  	if err != ErrExecutableNotFound {
   119  		t.Errorf("cmd.Run(): Expected error ErrExecutableNotFound but got %v", err)
   120  	}
   121  }
   122  
   123  func TestStopBeforeStart(t *testing.T) {
   124  	cmd := New().Command("echo", "hello")
   125  
   126  	// no panic calling Stop before calling Run
   127  	cmd.Stop()
   128  
   129  	cmd.Run()
   130  
   131  	// no panic calling Stop after command is done
   132  	cmd.Stop()
   133  }
   134  
   135  func TestTimeout(t *testing.T) {
   136  	exec := New()
   137  	ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
   138  	defer cancel()
   139  
   140  	err := exec.CommandContext(ctx, "sleep", "2").Run()
   141  	if err != context.DeadlineExceeded {
   142  		t.Errorf("expected %v but got %v", context.DeadlineExceeded, err)
   143  	}
   144  }
   145  
   146  func TestSetEnv(t *testing.T) {
   147  	ex := New()
   148  
   149  	out, err := ex.Command("/bin/sh", "-c", "echo $FOOBAR").CombinedOutput()
   150  	if err != nil {
   151  		t.Errorf("expected success, got %+v", err)
   152  	}
   153  	if string(out) != "\n" {
   154  		t.Errorf("unexpected output: %q", string(out))
   155  	}
   156  
   157  	cmd := ex.Command("/bin/sh", "-c", "echo $FOOBAR")
   158  	cmd.SetEnv([]string{"FOOBAR=baz"})
   159  	out, err = cmd.CombinedOutput()
   160  	if err != nil {
   161  		t.Errorf("expected success, got %+v", err)
   162  	}
   163  	if string(out) != "baz\n" {
   164  		t.Errorf("unexpected output: %q", string(out))
   165  	}
   166  }
   167  
   168  func TestStdIOPipes(t *testing.T) {
   169  	cmd := New().Command("/bin/sh", "-c", "echo 'OUT'>&1; echo 'ERR'>&2")
   170  
   171  	stdoutPipe, err := cmd.StdoutPipe()
   172  	if err != nil {
   173  		t.Fatalf("expected StdoutPipe() not to error, got: %v", err)
   174  	}
   175  	stderrPipe, err := cmd.StderrPipe()
   176  	if err != nil {
   177  		t.Fatalf("expected StderrPipe() not to error, got: %v", err)
   178  	}
   179  
   180  	stdout := make(chan string)
   181  	stderr := make(chan string)
   182  
   183  	go func() {
   184  		stdout <- readAll(t, stdoutPipe, "StdOut")
   185  	}()
   186  	go func() {
   187  		stderr <- readAll(t, stderrPipe, "StdErr")
   188  	}()
   189  
   190  	if err := cmd.Start(); err != nil {
   191  		t.Errorf("expected Start() not to error, got: %v", err)
   192  	}
   193  
   194  	if e, a := "OUT\n", <-stdout; e != a {
   195  		t.Errorf("expected StdOut to be '%s', got: '%v'", e, a)
   196  	}
   197  
   198  	if e, a := "ERR\n", <-stderr; e != a {
   199  		t.Errorf("expected StdErr to be '%s', got: '%v'", e, a)
   200  	}
   201  
   202  	if err := cmd.Wait(); err != nil {
   203  		t.Errorf("expected Wait() not to error, got: %v", err)
   204  	}
   205  }
   206  
   207  func readAll(t *testing.T, r io.Reader, n string) string {
   208  	t.Helper()
   209  
   210  	b, err := ioutil.ReadAll(r)
   211  	if err != nil {
   212  		t.Fatalf("unexpected error when reading from %s: %v", n, err)
   213  	}
   214  
   215  	return string(b)
   216  }
   217  
   218  func TestExecutorGo119LookPath(t *testing.T) {
   219  	orig := os.Getenv("PATH")
   220  	defer func() { os.Setenv("PATH", orig) }()
   221  
   222  	os.Setenv("PATH", "./testdata")
   223  
   224  	ex := New()
   225  	path, err := ex.LookPath("hello")
   226  	if err != nil {
   227  		t.Errorf("expected success, got %v", err)
   228  	}
   229  	if path != "testdata/hello" {
   230  		t.Errorf("expected relative path to hello script, got %v", path)
   231  	}
   232  
   233  	cmd := ex.Command("hello")
   234  	out, err := cmd.CombinedOutput()
   235  	if err != nil {
   236  		t.Errorf("expected success, got %v", err)
   237  	} else {
   238  		if len(out) != 5 {
   239  			t.Errorf("expected 'hello' output, got %q", string(out))
   240  		}
   241  	}
   242  
   243  	cmd = ex.CommandContext(context.Background(), "hello")
   244  	out, err = cmd.CombinedOutput()
   245  	if err != nil {
   246  		t.Errorf("expected success, got %v", err)
   247  	} else {
   248  		if len(out) != 5 {
   249  			t.Errorf("expected 'hello' output, got %q", string(out))
   250  		}
   251  	}
   252  }
   253  

View as plain text