|
@ -3,6 +3,7 @@ package dugong |
|
|
import ( |
|
|
import ( |
|
|
"bufio" |
|
|
"bufio" |
|
|
"encoding/json" |
|
|
"encoding/json" |
|
|
|
|
|
log "github.com/Sirupsen/logrus" |
|
|
"io/ioutil" |
|
|
"io/ioutil" |
|
|
"os" |
|
|
"os" |
|
|
"path/filepath" |
|
|
"path/filepath" |
|
@ -10,8 +11,7 @@ import ( |
|
|
"sync" |
|
|
"sync" |
|
|
"sync/atomic" |
|
|
"sync/atomic" |
|
|
"testing" |
|
|
"testing" |
|
|
|
|
|
|
|
|
log "github.com/Sirupsen/logrus" |
|
|
|
|
|
|
|
|
"time" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
const ( |
|
|
const ( |
|
@ -163,6 +163,108 @@ func TestFSHookConcurrent(t *testing.T) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestDailySchedule(t *testing.T) { |
|
|
|
|
|
loc, err := time.LoadLocation("UTC") |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatalf("Failed to load location UTC: %s", err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
logger, hook, wait, teardown := setupLogHook(t) |
|
|
|
|
|
defer teardown() |
|
|
|
|
|
hook.scheduler = &DailyRotationSchedule{} |
|
|
|
|
|
|
|
|
|
|
|
// Time ticks from 23:50 to 00:10 in 1 minute increments. Log each tick as 'counter'.
|
|
|
|
|
|
minutesGoneBy := 0 |
|
|
|
|
|
currentTime = func() time.Time { |
|
|
|
|
|
minutesGoneBy += 1 |
|
|
|
|
|
return time.Date(2016, 10, 26, 23, 50+minutesGoneBy, 00, 0, loc) |
|
|
|
|
|
} |
|
|
|
|
|
for i := 0; i < 20; i++ { |
|
|
|
|
|
t := time.Date(2016, 10, 26, 23, 50+i, 00, 0, loc) |
|
|
|
|
|
logger.WithField("counter", i).Info("BASE " + t.Format(time.ANSIC)) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
wait() |
|
|
|
|
|
|
|
|
|
|
|
// info.log.2016-10-26 should have 0 -> 9
|
|
|
|
|
|
checkFileHasSequentialCounts(t, hook.infoPath+".2016-10-26", 0, 9) |
|
|
|
|
|
|
|
|
|
|
|
// info.log should have 10 -> 19 inclusive
|
|
|
|
|
|
checkFileHasSequentialCounts(t, hook.infoPath, 10, 19) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestDailyScheduleMultipleRotations(t *testing.T) { |
|
|
|
|
|
loc, err := time.LoadLocation("UTC") |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatalf("Failed to load location UTC: %s", err) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
logger, hook, wait, teardown := setupLogHook(t) |
|
|
|
|
|
defer teardown() |
|
|
|
|
|
hook.scheduler = &DailyRotationSchedule{} |
|
|
|
|
|
|
|
|
|
|
|
// Time ticks every 12 hours from 13:37 -> 01:37 -> 13:37 -> ...
|
|
|
|
|
|
hoursGoneBy := 0 |
|
|
|
|
|
currentTime = func() time.Time { |
|
|
|
|
|
hoursGoneBy += 12 |
|
|
|
|
|
// Start from 10/29 01:37
|
|
|
|
|
|
return time.Date(2016, 10, 28, 13+hoursGoneBy, 37, 00, 0, loc) |
|
|
|
|
|
} |
|
|
|
|
|
// log 2 lines per file, to 4 files (so 8 log lines)
|
|
|
|
|
|
for i := 0; i < 8; i++ { |
|
|
|
|
|
ts := time.Date(2016, 10, 28, 13+((i+1)*12), 37, 00, 0, loc) |
|
|
|
|
|
logger.WithField("counter", i).Infof("The time is now %s", ts) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
wait() |
|
|
|
|
|
|
|
|
|
|
|
// info.log.2016-10-29 should have 0-1
|
|
|
|
|
|
checkFileHasSequentialCounts(t, hook.infoPath+".2016-10-29", 0, 1) |
|
|
|
|
|
|
|
|
|
|
|
// info.log.2016-10-30 should have 2-3
|
|
|
|
|
|
checkFileHasSequentialCounts(t, hook.infoPath+".2016-10-30", 2, 3) |
|
|
|
|
|
|
|
|
|
|
|
// info.log.2016-10-31 should have 4-5
|
|
|
|
|
|
checkFileHasSequentialCounts(t, hook.infoPath+".2016-10-31", 4, 5) |
|
|
|
|
|
|
|
|
|
|
|
// info.log should have 6-7 (current day is 11/01)
|
|
|
|
|
|
checkFileHasSequentialCounts(t, hook.infoPath, 6, 7) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// checkFileHasSequentialCounts based on a JSON "counter" key being a monotonically
|
|
|
|
|
|
// incrementing integer. from and to are both inclusive.
|
|
|
|
|
|
func checkFileHasSequentialCounts(t *testing.T, filepath string, from, to int) { |
|
|
|
|
|
t.Logf("checkFileHasSequentialCounts(%s,%d,%d)", filepath, from, to) |
|
|
|
|
|
|
|
|
|
|
|
file, err := os.Open(filepath) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
t.Fatalf("Failed to open file: %v", err) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
defer file.Close() |
|
|
|
|
|
scanner := bufio.NewScanner(file) |
|
|
|
|
|
count := from |
|
|
|
|
|
for scanner.Scan() { |
|
|
|
|
|
data := make(map[string]interface{}) |
|
|
|
|
|
if err := json.Unmarshal([]byte(scanner.Text()), &data); err != nil { |
|
|
|
|
|
t.Fatalf("%s : Failed to parse JSON: %v", file.Name(), err) |
|
|
|
|
|
} |
|
|
|
|
|
dataCounter := int(data["counter"].(float64)) |
|
|
|
|
|
t.Logf("%s want %d got %d", file.Name(), count, dataCounter) |
|
|
|
|
|
if count != dataCounter { |
|
|
|
|
|
t.Fatalf("%s : Counter: want %d got %d", file.Name(), count, dataCounter) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
count++ |
|
|
|
|
|
} |
|
|
|
|
|
count-- // never hit the next value
|
|
|
|
|
|
|
|
|
|
|
|
if count != to { |
|
|
|
|
|
t.Fatalf("%s EOF: Want count %d got %d", file.Name(), to, count) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
func setupLogHook(t *testing.T) (logger *log.Logger, hook *fsHook, wait func(), teardown func()) { |
|
|
func setupLogHook(t *testing.T) (logger *log.Logger, hook *fsHook, wait func(), teardown func()) { |
|
|
dir, err := ioutil.TempDir("", "TestFSHook") |
|
|
dir, err := ioutil.TempDir("", "TestFSHook") |
|
|
if err != nil { |
|
|
if err != nil { |
|
@ -173,7 +275,7 @@ func setupLogHook(t *testing.T) (logger *log.Logger, hook *fsHook, wait func(), |
|
|
warnPath := filepath.Join(dir, "warn.log") |
|
|
warnPath := filepath.Join(dir, "warn.log") |
|
|
errorPath := filepath.Join(dir, "error.log") |
|
|
errorPath := filepath.Join(dir, "error.log") |
|
|
|
|
|
|
|
|
hook = NewFSHook(infoPath, warnPath, errorPath).(*fsHook) |
|
|
|
|
|
|
|
|
hook = NewFSHook(infoPath, warnPath, errorPath, nil, nil).(*fsHook) |
|
|
|
|
|
|
|
|
logger = log.New() |
|
|
logger = log.New() |
|
|
logger.Hooks.Add(hook) |
|
|
logger.Hooks.Add(hook) |
|
|