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 }