github.com/phuslu/log@v1.0.100/file_test.go (about) 1 package log 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "testing" 8 "time" 9 ) 10 11 func TestFileWriter(t *testing.T) { 12 filename := "file-output.log" 13 text := "hello file writer!\n" 14 15 w := &FileWriter{ 16 Filename: filename, 17 } 18 _, err := wlprintf(w, InfoLevel, text) 19 if err != nil { 20 t.Fatalf("file writer error: %+v", err) 21 } 22 23 // _ = w.Rotate() 24 w.Close() 25 26 matches, err := filepath.Glob("file-output.*.log") 27 if err != nil { 28 t.Fatalf("filepath glob error: %+v", err) 29 } 30 if len(matches) == 0 { 31 t.Fatal("filepath glob return empty") 32 } 33 34 data, err := os.ReadFile(matches[0]) 35 if err != nil { 36 t.Fatalf("read file error: %+v", err) 37 } 38 39 if string(data) != text { 40 t.Fatalf("read file content mismath: data=[%s], text=[%s]", data, text) 41 } 42 43 err = os.Remove(matches[0]) 44 if err != nil { 45 t.Fatalf("os remove %s error: %+v", matches[0], err) 46 } 47 48 os.Remove(filename) 49 } 50 51 func TestFileWriterStderr(t *testing.T) { 52 text1 := "hello file writer!\n" 53 54 w := &FileWriter{} 55 56 _, err := wlprintf(w, InfoLevel, text1) 57 if err != nil { 58 t.Fatalf("file writer error: %+v", err) 59 } 60 } 61 62 func TestFileWriterCreate(t *testing.T) { 63 text1 := "hello file writer!\n" 64 65 w := &FileWriter{ 66 Filename: "/nonexists/output.log", 67 } 68 69 _, err := wlprintf(w, InfoLevel, text1) 70 if err == nil { 71 t.Fatalf("file writer should not write") 72 } 73 74 t.Logf("file writer return error: %+v", err) 75 } 76 77 func TestFileWriterEnsureFolder(t *testing.T) { 78 var remove = func(dirname string) { 79 matches, _ := filepath.Glob(dirname + "/*") 80 for i := range matches { 81 os.Remove(matches[i]) 82 } 83 os.Remove(dirname) 84 } 85 86 filename := "logs/file-hostname.log" 87 text1 := "1. hello file writer!\n" 88 text2 := "2. hello file writer!\n" 89 w := &FileWriter{ 90 Filename: filename, 91 EnsureFolder: true, 92 } 93 94 remove(filepath.Dir(filename)) 95 96 _, err := fmt.Fprint(w, text1) 97 if err != nil { 98 t.Logf("file writer return error: %+v", err) 99 } 100 101 _, err = fmt.Fprint(w, text2) 102 if err != nil { 103 t.Logf("file writer return error: %+v", err) 104 } 105 106 err = w.Close() 107 if err != nil { 108 t.Logf("file writer return error: %+v", err) 109 } 110 111 remove(filepath.Dir(filename)) 112 } 113 114 func TestFileWriterHostname(t *testing.T) { 115 filename := "file-hostname.log" 116 text1 := "1. hello file writer!\n" 117 text2 := "2. hello file writer!\n" 118 119 for _, hostname := range []bool{false, true} { 120 for _, pid := range []bool{false, true} { 121 w := &FileWriter{ 122 Filename: filename, 123 HostName: hostname, 124 ProcessID: pid, 125 } 126 127 _, err := wlprintf(w, InfoLevel, text1) 128 if err != nil { 129 t.Logf("file writer return error: %+v", err) 130 } 131 132 time.Sleep(time.Second) 133 os.Setenv("USER", "root") 134 _ = w.Rotate() 135 w.Close() 136 137 _, err = wlprintf(w, InfoLevel, text2) 138 if err != nil { 139 t.Logf("file writer return error: %+v", err) 140 } 141 142 w.Close() 143 144 matches, _ := filepath.Glob("file-hostname.*.log") 145 for i := range matches { 146 os.Remove(matches[i]) 147 } 148 149 os.Remove(filename) 150 } 151 } 152 } 153 154 func TestFileWriterRotate(t *testing.T) { 155 filename := "file-rotate.log" 156 header := "# I AM A FILEWRITER HEADER\n" 157 text1 := "hello file writer!\n" 158 text2 := "hello rotated file writer!\n" 159 160 // trigger chown 161 os.Setenv("USER", "root") 162 163 w := &FileWriter{ 164 Filename: filename, 165 MaxBackups: 2, 166 Header: func(_ os.FileInfo) []byte { 167 return []byte(header) 168 }, 169 } 170 171 // text 1 172 _, err := wlprintf(w, InfoLevel, text1) 173 if err != nil { 174 t.Fatalf("file writer error: %+v", err) 175 } 176 177 time.Sleep(time.Second) 178 _ = w.Rotate() 179 180 // text 2 181 _, err = wlprintf(w, InfoLevel, text2) 182 if err != nil { 183 t.Fatalf("file writer error: %+v", err) 184 } 185 186 w.Close() 187 188 matches, err := filepath.Glob("file-rotate.*.log") 189 if err != nil { 190 t.Fatalf("filepath glob error: %+v", err) 191 } 192 if len(matches) != 2 { 193 t.Fatalf("filepath glob return %+v number mismath", matches) 194 } 195 196 data, err := os.ReadFile(matches[0]) 197 if err != nil { 198 t.Fatalf("read file error: %+v", err) 199 } 200 201 if string(data) != header+text1 { 202 t.Fatalf("read file content mismath: data=[%s], text1=[%s]", data, text1) 203 } 204 205 data, err = os.ReadFile(matches[1]) 206 if err != nil { 207 t.Fatalf("read file error: %+v", err) 208 } 209 210 if string(data) != header+text2 { 211 t.Fatalf("read file content mismath: data=[%s], text2=[%s]", data, text2) 212 } 213 214 for i := range matches { 215 err = os.Remove(matches[i]) 216 if err != nil { 217 t.Fatalf("os remove %s error: %+v", matches[i], err) 218 } 219 } 220 221 os.Remove(filename) 222 } 223 224 func TestFileWriterRotateBySize(t *testing.T) { 225 filename := "file-rotate-by-size.log" 226 text := "hello file writer!\n" 227 228 w := &FileWriter{ 229 Filename: filename, 230 MaxSize: int64(len(text)) + 2, 231 MaxBackups: 2, 232 } 233 234 // text 1 235 _, err := wlprintf(w, InfoLevel, text) 236 if err != nil { 237 t.Fatalf("file writer error: %+v", err) 238 } 239 240 matches, err := filepath.Glob("file-rotate-by-size.*.log") 241 if err != nil { 242 t.Fatalf("filepath glob error: %+v", err) 243 } 244 if len(matches) != 1 { 245 t.Fatalf("filepath glob return %+v number mismath", matches) 246 } 247 248 time.Sleep(time.Second) 249 250 // text 2 251 _, err = wlprintf(w, InfoLevel, text) 252 if err != nil { 253 t.Fatalf("file writer error: %+v", err) 254 } 255 256 matches, err = filepath.Glob("file-rotate-by-size.*.log") 257 if err != nil { 258 t.Fatalf("filepath glob error: %+v", err) 259 } 260 if len(matches) != 2 { 261 t.Fatalf("filepath glob return %+v number mismath", matches) 262 } 263 264 // mock 265 os.Setenv("SUDO_UID", "1000") 266 os.Setenv("SUDO_GID", "1000") 267 268 // text 3 ~ 6 269 for i := 3; i <= 6; i++ { 270 _, err = wlprintf(w, InfoLevel, text) 271 time.Sleep(time.Second) 272 if err != nil { 273 t.Fatalf("file writer error: %+v", err) 274 } 275 } 276 277 matches, err = filepath.Glob("file-rotate-by-size.*.log") 278 if err != nil { 279 t.Fatalf("filepath glob error: %+v", err) 280 } 281 if len(matches) > w.MaxBackups+1 { 282 t.Fatalf("filepath glob return %+v number mismath", matches) 283 } 284 285 w.Close() 286 287 for i := range matches { 288 err = os.Remove(matches[i]) 289 if err != nil { 290 t.Fatalf("os remove %s error: %+v", matches[i], err) 291 } 292 } 293 294 os.Remove(filename) 295 } 296 297 func TestFileWriterBackups(t *testing.T) { 298 filename := "file-backup.log" 299 300 w := &FileWriter{ 301 Filename: filename, 302 MaxBackups: 1, 303 } 304 305 time.Sleep(time.Second) 306 _ = w.Rotate() 307 308 time.Sleep(time.Second) 309 _ = w.Rotate() 310 w.Close() 311 312 matches, err := filepath.Glob("file-backup.*.log") 313 if err != nil { 314 t.Fatalf("filepath glob error: %+v", err) 315 } 316 if len(matches) != 2 { 317 t.Fatalf("filepath glob return %+v number mismath", matches) 318 } 319 320 matches, _ = filepath.Glob("file-backup.*.log") 321 for i := range matches { 322 err = os.Remove(matches[i]) 323 if err != nil { 324 t.Fatalf("os remove %s error: %+v", matches[i], err) 325 } 326 } 327 328 os.Remove(filename) 329 } 330 331 func TestFileWriterFileargs(t *testing.T) { 332 filename := "file-output.log" 333 d := time.Date(2020, 8, 12, 16, 7, 0, 0, time.UTC) 334 335 t.Run("neither hostname nor pid appears", func(t *testing.T) { 336 w := &FileWriter{Filename: filename} 337 expected := "file-output.2020-08-12T16-07-00.log" 338 if name, _, _ := w.fileargs(d); name != expected { 339 t.Fatalf("expected: %q, actual: %q", expected, name) 340 } 341 }) 342 t.Run("hostname or pid appears", func(t *testing.T) { 343 origHost := hostname 344 hostname = "shire" 345 defer func() { hostname = origHost }() 346 origPid := pid 347 pid = 198400 348 defer func() { pid = origPid }() 349 350 w := &FileWriter{Filename: filename, HostName: true} 351 352 cases := []struct { 353 hostName bool 354 processID bool 355 expected string 356 }{ 357 {hostName: true, expected: "file-output.2020-08-12T16-07-00.shire.log"}, 358 {processID: true, expected: "file-output.2020-08-12T16-07-00.198400.log"}, 359 {hostName: true, processID: true, expected: "file-output.2020-08-12T16-07-00.shire-198400.log"}, 360 } 361 for _, c := range cases { 362 w.HostName = c.hostName 363 w.ProcessID = c.processID 364 if name, _, _ := w.fileargs(d); name != c.expected { 365 t.Fatalf("expected: %q, actual: %q", c.expected, name) 366 } 367 } 368 }) 369 }