Skip to content

Commit 264698b

Browse files
committed
test(serverLog): add test cases
1 parent 157bab7 commit 264698b

File tree

7 files changed

+359
-68
lines changed

7 files changed

+359
-68
lines changed

src/serverLog/fileDest.go

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,9 @@
11
package serverLog
22

33
import (
4-
"errors"
54
"os"
65
)
76

8-
func openLogFile(fsPath string) (*os.File, error) {
9-
return os.OpenFile(fsPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, fileMode)
10-
}
11-
12-
func getFileInfoIfNotMatch(fsPath string, match func(info os.FileInfo) bool) (file *os.File, info os.FileInfo, err error) {
13-
info, err = os.Stat(fsPath)
14-
15-
if os.IsNotExist(err) {
16-
file, err = openLogFile(fsPath)
17-
if err != nil {
18-
return nil, nil, err
19-
}
20-
21-
info, err = os.Stat(fsPath)
22-
if err != nil {
23-
file.Close()
24-
return nil, nil, err
25-
}
26-
27-
return
28-
}
29-
30-
if err != nil {
31-
return nil, nil, err
32-
}
33-
34-
if info.IsDir() {
35-
err = errors.New("should not be a directory")
36-
return nil, nil, err
37-
}
38-
39-
if match(info) {
40-
return nil, nil, err
41-
}
42-
43-
// use existing info, get file
44-
file, err = openLogFile(fsPath)
45-
if err != nil {
46-
return nil, nil, err
47-
}
48-
49-
return
50-
}
51-
527
type fileDest struct {
538
fsPath string
549
file *os.File
@@ -80,27 +35,6 @@ func (dest *fileDest) serve() {
8035
dest.file.Close()
8136
}
8237

83-
func (dest *fileDest) reopen() error {
84-
matched := false
85-
file, info, err := getFileInfoIfNotMatch(dest.fsPath, func(info os.FileInfo) bool {
86-
matched = os.SameFile(info, dest.info)
87-
return matched
88-
})
89-
90-
if err != nil {
91-
return err
92-
}
93-
94-
if matched {
95-
return nil
96-
}
97-
98-
oldFile := dest.file
99-
dest.info = info
100-
dest.file = file
101-
return oldFile.Close()
102-
}
103-
10438
func (dest *fileDest) close() {
10539
close(dest.ch)
10640
}

src/serverLog/fileDest_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package serverLog
2+
3+
import (
4+
"bytes"
5+
"os"
6+
"testing"
7+
)
8+
9+
func TestFileDest(t *testing.T) {
10+
file, err := os.CreateTemp("", "log-*")
11+
if err != nil {
12+
t.Fatal("create file failed")
13+
}
14+
defer func() {
15+
file.Close()
16+
os.Remove(file.Name())
17+
}()
18+
info, err := file.Stat()
19+
if err != nil {
20+
t.Fatal("stat file failed")
21+
}
22+
23+
dest := newFileDest(file.Name(), file, info)
24+
dest.ch <- []byte("hello")
25+
dest.ch <- []byte("world")
26+
27+
go dest.close()
28+
dest.serve()
29+
30+
logs, _ := os.ReadFile(file.Name())
31+
if !bytes.Equal(logs, []byte("hello\nworld\n")) {
32+
t.Error(string(logs))
33+
}
34+
}

src/serverLog/fileMan.go

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,50 @@ import (
88

99
const fileMode = 0660
1010

11+
func openLogFile(fsPath string) (*os.File, error) {
12+
return os.OpenFile(fsPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, fileMode)
13+
}
14+
15+
func matchOrOpenFile(fsPath string, match func(info os.FileInfo) bool) (file *os.File, info os.FileInfo, err error) {
16+
info, err = os.Stat(fsPath)
17+
18+
if os.IsNotExist(err) {
19+
file, err = openLogFile(fsPath)
20+
if err != nil {
21+
return nil, nil, err
22+
}
23+
24+
info, err = file.Stat()
25+
if err != nil {
26+
file.Close()
27+
return nil, nil, err
28+
}
29+
30+
return
31+
}
32+
33+
if err != nil {
34+
return nil, nil, err
35+
}
36+
37+
if info.IsDir() {
38+
err = errors.New("should not be a directory")
39+
return nil, nil, err
40+
}
41+
42+
if match(info) {
43+
return nil, nil, nil
44+
}
45+
46+
// use existing info, get file
47+
file, err = openLogFile(fsPath)
48+
if err != nil {
49+
return nil, nil, err
50+
}
51+
52+
return
53+
}
54+
1155
type FileMan struct {
1256
wg *sync.WaitGroup
1357
dests []*fileDest
@@ -17,9 +61,16 @@ func (fMan *FileMan) ReOpen() []error {
1761
var errs []error
1862

1963
for _, dest := range fMan.dests {
20-
err := dest.reopen()
64+
file, info, err := matchOrOpenFile(dest.fsPath, func(info os.FileInfo) bool {
65+
return os.SameFile(info, dest.info)
66+
})
2167
if err != nil {
2268
errs = append(errs, err)
69+
continue
70+
}
71+
if file != nil && info != nil {
72+
dest.file = file
73+
dest.info = info
2374
}
2475
}
2576

@@ -43,7 +94,7 @@ func (fMan *FileMan) getWritingCh(fsPath string) (chan<- []byte, error) {
4394
var err error
4495

4596
var ch chan<- []byte
46-
file, info, err = getFileInfoIfNotMatch(fsPath, func(info os.FileInfo) bool {
97+
file, info, err = matchOrOpenFile(fsPath, func(info os.FileInfo) bool {
4798
for _, dest := range fMan.dests {
4899
if os.SameFile(info, dest.info) {
49100
ch = dest.ch

src/serverLog/fileMan_test.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package serverLog
2+
3+
import (
4+
"bytes"
5+
"os"
6+
"testing"
7+
"time"
8+
)
9+
10+
func TestMatchOrOpenFile(t *testing.T) {
11+
var err error
12+
13+
f, err := os.CreateTemp("", "log-*")
14+
if err != nil {
15+
t.Fatal("create temp log file failed")
16+
}
17+
defer func() {
18+
f.Close()
19+
os.Remove(f.Name())
20+
}()
21+
22+
i, err := f.Stat()
23+
if err != nil {
24+
t.Fatal("stat temp log file failed")
25+
}
26+
27+
// matched, returns nil
28+
file, info, err := matchOrOpenFile(f.Name(), func(_info os.FileInfo) bool {
29+
if !os.SameFile(i, _info) {
30+
t.Error("callback `_info` should point to the same file as `i`")
31+
return false
32+
} else {
33+
return true
34+
}
35+
})
36+
if file != nil {
37+
t.Error("`file` should be nil since match func returns true")
38+
file.Close()
39+
}
40+
if info != nil {
41+
t.Error("`info` should be nil since match func returns true")
42+
}
43+
44+
// not matched, returns file/info
45+
file, info, err = matchOrOpenFile(f.Name(), func(_info os.FileInfo) bool {
46+
return false
47+
})
48+
if file == nil {
49+
t.Error()
50+
} else {
51+
file.Close()
52+
}
53+
if info == nil {
54+
t.Error()
55+
} else if !os.SameFile(i, info) {
56+
t.Error(i.Name(), info.Name())
57+
}
58+
59+
// target is directory, returns error
60+
file, info, err = matchOrOpenFile(os.TempDir(), func(_info os.FileInfo) bool {
61+
return false
62+
})
63+
if file != nil || info != nil || err == nil {
64+
t.Error()
65+
}
66+
67+
// create file and returns file/info if not exists
68+
file, info, err = matchOrOpenFile(f.Name()+"-1", func(_info os.FileInfo) bool {
69+
return os.SameFile(i, _info)
70+
})
71+
if file == nil {
72+
t.Error()
73+
} else {
74+
file.Close()
75+
os.Remove(file.Name())
76+
}
77+
if info == nil {
78+
t.Error()
79+
} else if os.SameFile(i, info) {
80+
t.Error(i.Name(), info.Name())
81+
}
82+
}
83+
84+
func TestFileManNewLogChan(t *testing.T) {
85+
var err error
86+
87+
file1, err := os.CreateTemp("", "log-*")
88+
if err != nil {
89+
t.Fatal("create log file 1 failed")
90+
}
91+
file1.Close()
92+
os.Remove(file1.Name())
93+
94+
file2, err := os.CreateTemp("", "log-*")
95+
if err != nil {
96+
t.Fatal("create log file 2 failed")
97+
}
98+
file2.Close()
99+
os.Remove(file2.Name())
100+
101+
man := NewFileMan()
102+
ch1a, _ := man.newLogChan(file1.Name())
103+
ch1b, _ := man.newLogChan(file1.Name())
104+
if ch1a != ch1b {
105+
t.Error()
106+
}
107+
108+
ch2, _ := man.newLogChan(file2.Name())
109+
if ch2 == ch1a {
110+
t.Error()
111+
}
112+
man.Close()
113+
}
114+
115+
func TestFileMan(t *testing.T) {
116+
var err error
117+
118+
accLogFile1, err := os.CreateTemp("", "log-*")
119+
if err != nil {
120+
t.Fatal("create log file 1 failed")
121+
}
122+
accLogFile1.Close()
123+
os.Remove(accLogFile1.Name())
124+
125+
accLogFile2, err := os.CreateTemp("", "log-*")
126+
if err != nil {
127+
t.Fatal("create log file 2 failed")
128+
}
129+
accLogFile2.Close()
130+
os.Remove(accLogFile2.Name())
131+
132+
errLogFile, err := os.CreateTemp("", "log-*")
133+
if err != nil {
134+
t.Fatal("create error log file failed")
135+
}
136+
errLogFile.Close()
137+
os.Remove(errLogFile.Name())
138+
139+
var es []error
140+
man := NewFileMan()
141+
logger1, es := man.NewLogger(accLogFile1.Name(), errLogFile.Name())
142+
if len(es) > 0 {
143+
t.Fatal(es)
144+
}
145+
logger2, es := man.NewLogger(accLogFile2.Name(), errLogFile.Name())
146+
if len(es) > 0 {
147+
t.Fatal(es)
148+
}
149+
150+
logger1.LogAccessString("host 1 access allowed")
151+
logger1.LogErrorString("host 1 access denied")
152+
logger2.LogAccess([]byte("host 2 access allowed"))
153+
logger2.LogError([]byte("host 2 access denied"))
154+
155+
time.Sleep(100 * time.Millisecond) // wait for log written
156+
man.ReOpen()
157+
logger1.LogAccessString("HOST 1 access allowed")
158+
logger1.LogErrorString("HOST 1 access denied")
159+
logger2.LogAccessString("HOST 2 access allowed")
160+
logger2.LogErrorString("HOST 2 access denied")
161+
162+
err = os.Rename(errLogFile.Name(), errLogFile.Name()+"-old")
163+
if err != nil {
164+
t.Fatal(err)
165+
}
166+
time.Sleep(100 * time.Millisecond) // wait for log written
167+
man.ReOpen()
168+
169+
logger1.LogErrorString("403 HOST I ACCESS DENIED")
170+
logger2.LogErrorString("403 HOST II ACCESS DENIED")
171+
man.Close()
172+
173+
accLog1, _ := os.ReadFile(accLogFile1.Name())
174+
if !bytes.Equal(accLog1, []byte("host 1 access allowed\nHOST 1 access allowed\n")) {
175+
t.Error(string(accLog1))
176+
}
177+
accLog2, _ := os.ReadFile(accLogFile2.Name())
178+
if !bytes.Equal(accLog2, []byte("host 2 access allowed\nHOST 2 access allowed\n")) {
179+
t.Error(string(accLog2))
180+
}
181+
182+
errLogOld, _ := os.ReadFile(errLogFile.Name() + "-old")
183+
if !bytes.Equal(errLogOld, []byte("host 1 access denied\nhost 2 access denied\nHOST 1 access denied\nHOST 2 access denied\n")) {
184+
t.Error(string(errLogOld))
185+
}
186+
errLogNew, _ := os.ReadFile(errLogFile.Name())
187+
if !bytes.Equal(errLogNew, []byte("403 HOST I ACCESS DENIED\n403 HOST II ACCESS DENIED\n")) {
188+
t.Error(string(errLogNew))
189+
}
190+
}

0 commit comments

Comments
 (0)