diff --git a/Makefile b/Makefile index a71580b..35c150b 100644 --- a/Makefile +++ b/Makefile @@ -51,4 +51,4 @@ coverage-full: test .PHONY: coverage-html coverage-html: coverage-full go tool cover -html=./coverage/coverage.out -o ./coverage/coverage.html - open ./coverage/coverage.html \ No newline at end of file + # open ./coverage/coverage.html \ No newline at end of file diff --git a/conf.go b/conf.go index 9919890..a757fec 100644 --- a/conf.go +++ b/conf.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "strings" + "sync" ) type parsedConf struct { @@ -19,6 +20,7 @@ type parsedConf struct { type Config struct { MappingFilePath string MappingRules ImportRulesMappings + sync.Mutex } type ImportRulesMappings struct { @@ -144,6 +146,8 @@ func checkIfSizeIsConfigured(fsize string) (bool, error) { func (c *Config) LoadMainConfigFile(fp string) (parsedConf, error) { var conf parsedConf var err error + c.Lock() + defer c.Unlock() ok := isFile(fp) if !ok { // generate config file diff --git a/conf_test.go b/conf_test.go index b2d83d7..9f5ff62 100644 --- a/conf_test.go +++ b/conf_test.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "os" + "strconv" "testing" "github.com/stretchr/testify/assert" @@ -124,3 +126,77 @@ func TestGenerateConfigFile(t *testing.T) { assert.Equal(t, ok, true) } + +func TestLoadMainConfigFile(t *testing.T) { + + t.Run("load the main config file correctly - default load", func(t *testing.T) { + tmpDir := t.TempDir() + + tempConfigDir := fmt.Sprintf("%s/tmp/config", tmpDir) + + mkDirForTest(t, tempConfigDir) + + hmDir, _ := os.UserConfigDir() + + oldConfigFile := fmt.Sprintf("%s/gocustomurls/config.json", hmDir) + t.Log("oldConfigFile: ", oldConfigFile) + newConfigFile := fmt.Sprintf("%s/config.json", tempConfigDir) + + ok := doesFileExist(oldConfigFile) + + if ok { + t.Log("cp old -> new") + cpFileForTest(t, oldConfigFile, newConfigFile) + } + + t.Cleanup(func() { + found := doesFileExist(newConfigFile) + if found { + t.Log("cp new -> old") + cpFileForTest(t, newConfigFile, oldConfigFile) + } else { + // Add a loop to wait until you find the old ConfigFile + ok := doesFileExist(oldConfigFile) + if ok { + t.Log("remove old") + removeFileForTest(t, oldConfigFile) + } + } + }) + + cfg := &Config{} + assert.Equal(t, cfg.MappingFilePath, "") + conf, err := cfg.LoadMainConfigFile("") + // time.Sleep(4 * time.Second) + assert.Equal(t, err, nil) + assert.NotEmpty(t, conf) + assert.NotEmpty(t, cfg.MappingFilePath) + }) + + t.Run("load the main config file correctly - load from a location", func(t *testing.T) { + t.SkipNow() + tmpDir := t.TempDir() + + tempConfigDir := fmt.Sprintf("%s/tmp", tmpDir) + tempLogsDir := fmt.Sprintf("%s/tmp/logs", tmpDir) + + mkDirForTest(t, tempConfigDir) + + defaultConfigJson := map[string]string{ + "rulesFp": fmt.Sprintf("%s/rules.json", tempConfigDir), + "logFp": fmt.Sprintf("%s/app.log", tempLogsDir), + "Port": "9005", + "Compression": strconv.FormatBool(false), + "SizeToRotate": "50MB", + } + + writeJsonForTest(t, defaultConfigJson, fmt.Sprintf("%s/confg.json", tempConfigDir)) + + cfg := &Config{} + assert.Equal(t, cfg.MappingFilePath, "") + conf, err := cfg.LoadMainConfigFile(fmt.Sprintf("%s/confg.json", tempConfigDir)) + assert.Equal(t, err, nil) + assert.NotEmpty(t, conf) + assert.NotEmpty(t, cfg.MappingFilePath) + }) +} diff --git a/logger.go b/logger.go index 46dc2ee..a89a6ef 100644 --- a/logger.go +++ b/logger.go @@ -139,11 +139,12 @@ func compressOldFile(fname string) error { return nil } -func (lf *LogFile) rotate() error { +func (lf *LogFile) rotate(canCompress bool) error { lf.fileLock.Lock() defer lf.fileLock.Unlock() - prefix := fmt.Sprintf("%s.%s", lf.handle.Name(), time.Now().Format("2006-01-02")) + // new file + newFilePrefix := fmt.Sprintf("%s.%s", lf.handle.Name(), time.Now().Format("2006-01-02")) // close file to allow for read-only access err := lf.handle.Close() @@ -152,15 +153,17 @@ func (lf *LogFile) rotate() error { } // make a copy of the old log file - err = lf.makeCopyTo(prefix) + err = lf.makeCopyTo(newFilePrefix) if err != nil { return err } // compress the new log file - err = compressOldFile(prefix) - if err != nil { - return err + if canCompress { + err = compressOldFile(newFilePrefix) + if err != nil { + return err + } } // truncate the old log file @@ -178,7 +181,7 @@ func (lf *LogFile) rotate() error { return nil } -func (lf *LogFile) open(maxSize string) error { +func (lf *LogFile) open(maxSize string, canCompress bool) error { f, err := os.OpenFile(lf.path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) if err != nil { return err @@ -188,8 +191,8 @@ func (lf *LogFile) open(maxSize string) error { return err } curSize := prettyByteSize(finfo.Size()) - if curSize > maxSize { - err = lf.rotate() + if len(strings.TrimSpace(maxSize)) != 0 && curSize > maxSize { + err = lf.rotate(canCompress) if err != nil { return err } @@ -199,7 +202,7 @@ func (lf *LogFile) open(maxSize string) error { return nil } -func newFileLogger(path string, maxSize string) (*LogFile, error) { +func newFileLogger(path string, maxSize string, canCompress bool) (*LogFile, error) { requestedFile := filepath.Clean(filepath.Join("/", path)) parentDir := filepath.Dir(requestedFile) err := os.MkdirAll(parentDir, 0755) @@ -209,7 +212,7 @@ func newFileLogger(path string, maxSize string) (*LogFile, error) { lf := &LogFile{ path: path, } - err = lf.open(maxSize) + err = lf.open(maxSize, canCompress) return lf, err // f, err := os.OpenFile(requestedFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) // if err != nil { diff --git a/main.go b/main.go index b6171d1..f2c14df 100644 --- a/main.go +++ b/main.go @@ -120,7 +120,7 @@ func main() { errorLog.Println(err) os.Exit(1) } - l, err := newFileLogger(pConf.LogFp, pConf.SizeToRotate) + l, err := newFileLogger(pConf.LogFp, pConf.SizeToRotate, pConf.Compression) if err != nil { errorLog.Println(err) os.Exit(1) diff --git a/testUtils_test.go b/testUtils_test.go index 187658a..2de5077 100644 --- a/testUtils_test.go +++ b/testUtils_test.go @@ -1,7 +1,10 @@ package main import ( + "encoding/json" + "errors" "io" + "io/fs" "os" "testing" ) @@ -20,8 +23,16 @@ func cpFileForTest(t *testing.T, src string, dst string) { var srcinfo os.FileInfo srcfd, err = os.Open(src) if err != nil { - t.Fatal(err) + if errors.Is(err, fs.ErrNotExist) { + return + } else { + t.Fatal(err) + } + } + // if err != nil { + // t.Fatal(err) + // } defer srcfd.Close() dstfd, err = os.Create(dst) if err != nil { @@ -63,3 +74,23 @@ func IsDirEmpty(t *testing.T, name string) bool { // and if the file is EOF... well, the dir is empty. return err == io.EOF } + +func doesFileExist(name string) bool { + _, err := os.Stat(name) + return !errors.Is(err, fs.ErrNotExist) +} + +func removeFileForTest(t *testing.T, name string) { + err := os.Remove(name) + if err != nil { + t.Fatal(err) + } +} + +func writeJsonForTest(t *testing.T, data map[string]string, fp string) { + jsonString, _ := json.Marshal(data) + err := os.WriteFile(fp, jsonString, os.ModePerm) + if err != nil { + t.Fatal(err) + } +}