github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/errors/log_test.go (about) 1 package errors_test 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/fastly/cli/pkg/errors" 12 "github.com/fastly/cli/pkg/testutil" 13 ) 14 15 func TestLogAdd(t *testing.T) { 16 le := new(errors.LogEntries) 17 le.Add(fmt.Errorf("foo")) 18 le.Add(fmt.Errorf("bar")) 19 le.Add(fmt.Errorf("baz")) 20 21 m := make(map[string]any) 22 m["beep"] = "boop" 23 m["this"] = "that" 24 m["nums"] = 123 25 le.AddWithContext(fmt.Errorf("qux"), m) 26 27 want := 4 28 got := len(*le) 29 if got != want { 30 t.Fatalf("want length %d, got: %d", want, got) 31 } 32 } 33 34 func TestLogPersist(t *testing.T) { 35 var path string 36 37 // Create temp environment to run test code within. 38 { 39 wd, err := os.Getwd() 40 if err != nil { 41 t.Fatal(err) 42 } 43 44 rootdir := testutil.NewEnv(testutil.EnvOpts{ 45 T: t, 46 Write: []testutil.FileIO{ 47 {Src: string(""), Dst: "errors.log"}, 48 }, 49 Copy: []testutil.FileIO{ 50 { 51 Src: filepath.Join("testdata", "errors-expected.log"), 52 Dst: "errors-expected.log", 53 }, 54 }, 55 }) 56 path = filepath.Join(rootdir, "errors.log") 57 defer os.RemoveAll(rootdir) 58 59 if err := os.Chdir(rootdir); err != nil { 60 t.Fatal(err) 61 } 62 defer func() { 63 _ = os.Chdir(wd) 64 }() 65 } 66 67 errors.Now = func() (t time.Time) { 68 return t 69 } 70 71 le := new(errors.LogEntries) 72 le.Add(fmt.Errorf("foo")) 73 le.Add(fmt.Errorf("bar")) 74 le.Add(fmt.Errorf("baz")) 75 76 m := make(map[string]any) 77 m["beep"] = "boop" 78 m["this"] = "that" 79 m["nums"] = 123 80 le.AddWithContext(fmt.Errorf("qux"), m) 81 82 err := le.Persist(path, []string{"command", "one", "--example"}) 83 if err != nil { 84 t.Fatalf("unexpected error: %v", err) 85 } 86 err = le.Persist(path, []string{"command", "two", "--example"}) 87 if err != nil { 88 t.Fatalf("unexpected error: %v", err) 89 } 90 91 have, err := os.ReadFile(path) 92 if err != nil { 93 t.Fatal(err) 94 } 95 96 wantPath, err := filepath.Abs("errors-expected.log") 97 if err != nil { 98 t.Fatal(err) 99 } 100 want, err := os.ReadFile(wantPath) 101 if err != nil { 102 t.Fatal(err) 103 } 104 105 r := strings.NewReplacer("\n", "", "\r", "") 106 wanttrim := r.Replace(string(want)) 107 havetrim := r.Replace(string(have)) 108 109 testutil.AssertEqual(t, wanttrim, havetrim) 110 } 111 112 // TestLogPersistLogRotation validates that if an audit log file exceeds the 113 // specified threshold, then the file will be deleted and recreated. 114 // 115 // The way this is achieved is by creating an errors.log file that has a 116 // specific size, and then overriding the package level variable that 117 // determines the threshold so that it matches the size of the file we created. 118 // This means we can be sure our logic will trigger the file to be replaced 119 // with a new empty file, to which we'll then write our log content into. 120 func TestLogPersistLogRotation(t *testing.T) { 121 var ( 122 fi os.FileInfo 123 path string 124 ) 125 126 // Create temp environment to run test code within. 127 { 128 wd, err := os.Getwd() 129 if err != nil { 130 t.Fatal(err) 131 } 132 133 // We want to start off with an existing audit log file that we expect to 134 // be rotated because it exceeded our defined threshold. 135 seedPath, err := filepath.Abs(filepath.Join("testdata", "errors-expected.log")) 136 if err != nil { 137 t.Fatal(err) 138 } 139 seed, err := os.ReadFile(seedPath) 140 if err != nil { 141 t.Fatal(err) 142 } 143 f, err := os.Open(seedPath) 144 if err != nil { 145 t.Fatal(err) 146 } 147 defer f.Close() 148 fi, err = f.Stat() 149 if err != nil { 150 t.Fatal(err) 151 } 152 153 rootdir := testutil.NewEnv(testutil.EnvOpts{ 154 T: t, 155 Write: []testutil.FileIO{ 156 {Src: string(seed), Dst: "errors.log"}, 157 }, 158 Copy: []testutil.FileIO{ 159 { 160 Src: filepath.Join("testdata", "errors-expected-rotation.log"), 161 Dst: "errors-expected-rotation.log", 162 }, 163 }, 164 }) 165 path = filepath.Join(rootdir, "errors.log") 166 defer os.RemoveAll(rootdir) 167 168 if err := os.Chdir(rootdir); err != nil { 169 t.Fatal(err) 170 } 171 defer func() { 172 _ = os.Chdir(wd) 173 }() 174 } 175 176 errors.Now = func() (t time.Time) { 177 return t 178 } 179 errors.FileRotationSize = fi.Size() 180 181 le := new(errors.LogEntries) 182 le.Add(fmt.Errorf("foo")) 183 le.Add(fmt.Errorf("bar")) 184 le.Add(fmt.Errorf("baz")) 185 186 m := make(map[string]any) 187 m["beep"] = "boop" 188 m["this"] = "that" 189 m["nums"] = 123 190 le.AddWithContext(fmt.Errorf("qux"), m) 191 192 err := le.Persist(path, []string{"command", "one", "--example"}) 193 if err != nil { 194 t.Fatalf("unexpected error: %v", err) 195 } 196 197 have, err := os.ReadFile(path) 198 if err != nil { 199 t.Fatal(err) 200 } 201 202 wantPath, err := filepath.Abs("errors-expected-rotation.log") 203 if err != nil { 204 t.Fatal(err) 205 } 206 want, err := os.ReadFile(wantPath) 207 if err != nil { 208 t.Fatal(err) 209 } 210 211 r := strings.NewReplacer("\n", "", "\r", "") 212 wanttrim := r.Replace(string(want)) 213 havetrim := r.Replace(string(have)) 214 215 testutil.AssertEqual(t, wanttrim, havetrim) 216 }