github.com/abayer/test-infra@v0.0.5/prow/entrypoint/run_test.go (about)

     1  /*
     2  Copyright 2018 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 entrypoint
    18  
    19  import (
    20  	"io/ioutil"
    21  	"os"
    22  	"path"
    23  	"strconv"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/sirupsen/logrus"
    28  	"k8s.io/test-infra/prow/pod-utils/wrapper"
    29  )
    30  
    31  func TestOptions_Run(t *testing.T) {
    32  	var testCases = []struct {
    33  		name           string
    34  		args           []string
    35  		timeout        time.Duration
    36  		gracePeriod    time.Duration
    37  		expectedLog    string
    38  		expectedMarker string
    39  	}{
    40  		{
    41  			name:           "successful command",
    42  			args:           []string{"sh", "-c", "exit 0"},
    43  			expectedLog:    "",
    44  			expectedMarker: "0",
    45  		},
    46  		{
    47  			name:           "successful command with output",
    48  			args:           []string{"echo", "test"},
    49  			expectedLog:    "test\n",
    50  			expectedMarker: "0",
    51  		},
    52  		{
    53  			name:           "unsuccessful command",
    54  			args:           []string{"sh", "-c", "exit 12"},
    55  			expectedLog:    "",
    56  			expectedMarker: "12",
    57  		},
    58  		{
    59  			name:           "unsuccessful command with output",
    60  			args:           []string{"sh", "-c", "echo test && exit 12"},
    61  			expectedLog:    "test\n",
    62  			expectedMarker: "12",
    63  		},
    64  		{
    65  			name:           "command times out",
    66  			args:           []string{"sleep", "10"},
    67  			timeout:        1 * time.Second,
    68  			gracePeriod:    1 * time.Second,
    69  			expectedLog:    "level=error msg=\"Process did not finish before 1s timeout\" \nlevel=error msg=\"Process gracefully exited before 1s grace period\" \n",
    70  			expectedMarker: strconv.Itoa(InternalErrorCode),
    71  		},
    72  		{
    73  			name:           "command times out and ignores interrupt",
    74  			args:           []string{"bash", "-c", "trap 'sleep 10' EXIT; sleep 10"},
    75  			timeout:        1 * time.Second,
    76  			gracePeriod:    1 * time.Second,
    77  			expectedLog:    "level=error msg=\"Process did not finish before 1s timeout\" \nlevel=error msg=\"Process did not exit before 1s grace period\" \n",
    78  			expectedMarker: strconv.Itoa(InternalErrorCode),
    79  		},
    80  	}
    81  
    82  	// we write logs to the process log if wrapping fails
    83  	// and cannot write timestamps or we can't match text
    84  	logrus.SetFormatter(&logrus.TextFormatter{DisableTimestamp: true})
    85  
    86  	for _, testCase := range testCases {
    87  		t.Run(testCase.name, func(t *testing.T) {
    88  			tmpDir, err := ioutil.TempDir("", testCase.name)
    89  			if err != nil {
    90  				t.Errorf("%s: error creating temp dir: %v", testCase.name, err)
    91  			}
    92  			defer func() {
    93  				if err := os.RemoveAll(tmpDir); err != nil {
    94  					t.Errorf("%s: error cleaning up temp dir: %v", testCase.name, err)
    95  				}
    96  			}()
    97  
    98  			options := Options{
    99  				Args:        testCase.args,
   100  				Timeout:     testCase.timeout,
   101  				GracePeriod: testCase.gracePeriod,
   102  				Options: &wrapper.Options{
   103  					ProcessLog: path.Join(tmpDir, "process-log.txt"),
   104  					MarkerFile: path.Join(tmpDir, "marker-file.txt"),
   105  				},
   106  			}
   107  
   108  			if code := strconv.Itoa(options.Run()); code != testCase.expectedMarker {
   109  				t.Errorf("%s: exit code %q does not match expected marker file contents %q", testCase.name, code, testCase.expectedMarker)
   110  			}
   111  
   112  			compareFileContents(testCase.name, options.ProcessLog, testCase.expectedLog, t)
   113  			compareFileContents(testCase.name, options.MarkerFile, testCase.expectedMarker, t)
   114  		})
   115  	}
   116  }
   117  
   118  func compareFileContents(name, file, expected string, t *testing.T) {
   119  	data, err := ioutil.ReadFile(file)
   120  	if err != nil {
   121  		t.Fatalf("%s: could not read file: %v", name, err)
   122  	}
   123  	if string(data) != expected {
   124  		t.Errorf("%s: expected contents: %q, got %q", name, expected, data)
   125  	}
   126  }