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  }