blob: 7b3791ce2d892163d9d535c13bab118300fb0b1b [file] [log] [blame]
Dan Willemsen1e704462016-08-21 15:17:17 -07001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package logger
16
17import (
18 "bytes"
19 "fmt"
20 "io"
21 "io/ioutil"
22 "os"
23 "os/exec"
24 "path/filepath"
25 "reflect"
26 "sort"
27 "syscall"
28 "testing"
29)
30
31func TestCreateFileWithRotation(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -070032 t.Parallel()
Dan Willemsen1e704462016-08-21 15:17:17 -070033 dir, err := ioutil.TempDir("", "test-rotation")
34 if err != nil {
35 t.Fatalf("Failed to get TempDir: %v", err)
36 }
37 defer os.RemoveAll(dir)
38
39 file := filepath.Join(dir, "build.log")
40
41 writeFile := func(name string, data string) {
42 f, err := CreateFileWithRotation(name, 3)
43 if err != nil {
44 t.Fatalf("Failed to create file: %v", err)
45 }
46 if n, err := io.WriteString(f, data); err == nil && n < len(data) {
47 t.Fatalf("Short write")
48 } else if err != nil {
49 t.Fatalf("Failed to write: %v", err)
50 }
51 if err := f.Close(); err != nil {
52 t.Fatalf("Failed to close: %v", err)
53 }
54 }
55
56 writeFile(file, "a")
57 writeFile(file, "b")
58 writeFile(file, "c")
59 writeFile(file, "d")
60 writeFile(file, "e")
61
62 d, err := os.Open(dir)
63 if err != nil {
64 t.Fatalf("Failed to open dir: %v", err)
65 }
66 names, err := d.Readdirnames(0)
67 if err != nil {
68 t.Fatalf("Failed to read dir: %v", err)
69 }
70 sort.Strings(names)
Dan Willemsenca8feb32017-10-18 13:18:41 -070071 expected := []string{".lock_build.log", "build.1.log", "build.2.log", "build.3.log", "build.log"}
Dan Willemsen1e704462016-08-21 15:17:17 -070072 if !reflect.DeepEqual(names, expected) {
73 t.Errorf("File list does not match.")
74 t.Errorf(" got: %v", names)
75 t.Errorf("expected: %v", expected)
76 t.FailNow()
77 }
78
79 expectFileContents := func(name, expected string) {
80 data, err := ioutil.ReadFile(filepath.Join(dir, name))
81 if err != nil {
82 t.Errorf("Error reading file: %v", err)
83 return
84 }
85 str := string(data)
86 if str != expected {
87 t.Errorf("Contents of %v does not match.", name)
88 t.Errorf(" got: %v", data)
89 t.Errorf("expected: %v", expected)
90 }
91 }
92
93 expectFileContents("build.log", "e")
94 expectFileContents("build.1.log", "d")
95 expectFileContents("build.2.log", "c")
96 expectFileContents("build.3.log", "b")
97}
98
99func TestPanic(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700100 t.Parallel()
Dan Willemsen1e704462016-08-21 15:17:17 -0700101 if os.Getenv("ACTUALLY_PANIC") == "1" {
102 panicValue := "foo"
103 log := New(&bytes.Buffer{})
104
105 defer func() {
106 p := recover()
107
108 if p == panicValue {
109 os.Exit(42)
110 } else {
Colin Crossf46e37f2018-03-21 16:25:58 -0700111 fmt.Fprintf(os.Stderr, "Expected %q, got %v\n", panicValue, p)
Dan Willemsen1e704462016-08-21 15:17:17 -0700112 os.Exit(3)
113 }
114 }()
115 defer log.Cleanup()
116
117 log.Panic(panicValue)
118 os.Exit(2)
119 return
120 }
121
122 // Run this in an external process so that we don't pollute stderr
123 cmd := exec.Command(os.Args[0], "-test.run=TestPanic")
124 cmd.Env = append(os.Environ(), "ACTUALLY_PANIC=1")
125 err := cmd.Run()
126 if e, ok := err.(*exec.ExitError); ok && e.Sys().(syscall.WaitStatus).ExitStatus() == 42 {
127 return
128 }
129 t.Errorf("Expected process to exit with status 42, got %v", err)
130}
131
132func TestFatal(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700133 t.Parallel()
Dan Willemsen1e704462016-08-21 15:17:17 -0700134 if os.Getenv("ACTUALLY_FATAL") == "1" {
135 log := New(&bytes.Buffer{})
136 defer func() {
137 // Shouldn't get here
138 os.Exit(3)
139 }()
140 defer log.Cleanup()
141 log.Fatal("Test")
142 os.Exit(0)
143 return
144 }
145
146 cmd := exec.Command(os.Args[0], "-test.run=TestFatal")
147 cmd.Env = append(os.Environ(), "ACTUALLY_FATAL=1")
148 err := cmd.Run()
149 if e, ok := err.(*exec.ExitError); ok && e.Sys().(syscall.WaitStatus).ExitStatus() == 1 {
150 return
151 }
152 t.Errorf("Expected process to exit with status 1, got %v", err)
153}
154
155func TestNonFatal(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700156 t.Parallel()
Dan Willemsen1e704462016-08-21 15:17:17 -0700157 if os.Getenv("ACTUAL_TEST") == "1" {
158 log := New(&bytes.Buffer{})
159 defer log.Cleanup()
160 log.Println("Test")
161 return
162 }
163
164 cmd := exec.Command(os.Args[0], "-test.run=TestNonFatal")
165 cmd.Env = append(os.Environ(), "ACTUAL_TEST=1")
166 err := cmd.Run()
167 if e, ok := err.(*exec.ExitError); ok || (ok && !e.Success()) {
168 t.Errorf("Expected process to exit cleanly, got %v", err)
169 }
170}
171
172func TestRecoverFatal(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700173 t.Parallel()
Dan Willemsen1e704462016-08-21 15:17:17 -0700174 log := New(&bytes.Buffer{})
175 defer func() {
176 if p := recover(); p != nil {
177 t.Errorf("Unexpected panic: %#v", p)
178 }
179 }()
180 defer Recover(func(err error) {
181 if err.Error() != "Test" {
182 t.Errorf("Expected %q, but got %q", "Test", err.Error())
183 }
184 })
185 log.Fatal("Test")
186 t.Errorf("Should not get here")
187}
188
189func TestRecoverNonFatal(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700190 t.Parallel()
Dan Willemsen1e704462016-08-21 15:17:17 -0700191 log := New(&bytes.Buffer{})
192 defer func() {
193 if p := recover(); p == nil {
194 t.Errorf("Panic not thrown")
195 } else if p != "Test" {
196 t.Errorf("Expected %q, but got %#v", "Test", p)
197 }
198 }()
199 defer Recover(func(err error) {
200 t.Errorf("Recover function should not be called")
201 })
202 log.Panic("Test")
203 t.Errorf("Should not get here")
204}
Dan Willemsenef661b72019-01-28 20:00:01 -0800205
206func TestRuntimePanic(t *testing.T) {
Colin Cross323dc602020-09-18 14:25:31 -0700207 t.Parallel()
Dan Willemsenef661b72019-01-28 20:00:01 -0800208 defer func() {
209 if p := recover(); p == nil {
210 t.Errorf("Panic not thrown")
211 }
212 }()
213 defer Recover(func(err error) {
214 t.Errorf("Recover function should not be called")
215 })
216 var i *int
217 *i = 0
218 t.Errorf("Should not get here")
219}