Skip to content

Commit 0c9ac6f

Browse files
authored
fix(cluster/audit): compatible with old second based ts (#882)
1 parent 871ae58 commit 0c9ac6f

2 files changed

Lines changed: 104 additions & 8 deletions

File tree

pkg/cluster/audit/audit.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,10 @@ func ShowAuditList(dir string) error {
5656
if fi.IsDir() {
5757
continue
5858
}
59-
ts, err := base52.Decode(fi.Name())
59+
t, err := decodeAuditID(fi.Name())
6060
if err != nil {
6161
continue
6262
}
63-
t := time.Unix(ts/1e9, 0)
6463
cmd, err := firstLine(fi.Name())
6564
if err != nil {
6665
continue
@@ -93,7 +92,7 @@ func ShowAuditLog(dir string, auditID string) error {
9392
return errors.Errorf("cannot find the audit log '%s'", auditID)
9493
}
9594

96-
ts, err := base52.Decode(auditID)
95+
t, err := decodeAuditID(auditID)
9796
if err != nil {
9897
return errors.Annotatef(err, "unrecognized audit id '%s'", auditID)
9998
}
@@ -103,10 +102,23 @@ func ShowAuditLog(dir string, auditID string) error {
103102
return errors.Trace(err)
104103
}
105104

106-
t := time.Unix(ts/1e9, 0)
107105
hint := fmt.Sprintf("- OPERATION TIME: %s -", t.Format("2006-01-02T15:04:05"))
108106
line := strings.Repeat("-", len(hint))
109107
_, _ = os.Stdout.WriteString(color.MagentaString("%s\n%s\n%s\n", line, hint, line))
110108
_, _ = os.Stdout.Write(content)
111109
return nil
112110
}
111+
112+
//decodeAuditID decodes the auditID to unix timestamp
113+
func decodeAuditID(auditID string) (time.Time, error) {
114+
ts, err := base52.Decode(auditID)
115+
if err != nil {
116+
return time.Time{}, err
117+
}
118+
// compatible with old second based ts
119+
if ts>>32 > 0 {
120+
ts = ts / 1e9
121+
}
122+
t := time.Unix(ts, 0)
123+
return t, nil
124+
}

pkg/cluster/audit/audit_test.go

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,23 @@
1414
package audit
1515

1616
import (
17+
"fmt"
18+
"io/ioutil"
1719
"os"
1820
"path"
1921
"path/filepath"
2022
"runtime"
23+
"strings"
24+
"testing"
25+
"time"
2126

2227
. "github.com/pingcap/check"
28+
"github.com/pingcap/tiup/pkg/base52"
2329
"golang.org/x/sync/errgroup"
2430
)
2531

32+
func Test(t *testing.T) { TestingT(t) }
33+
2634
var _ = Suite(&testAuditSuite{})
2735

2836
type testAuditSuite struct{}
@@ -36,17 +44,29 @@ func auditDir() string {
3644
return path.Join(currentDir(), "testdata", "audit")
3745
}
3846

39-
func (s *testAuditSuite) SetUpSuite(c *C) {
47+
func resetDir() {
4048
_ = os.RemoveAll(auditDir())
4149
_ = os.MkdirAll(auditDir(), 0777)
4250
}
4351

52+
func readFakeStdout(f *os.File) string {
53+
_, _ = f.Seek(0, 0)
54+
read, _ := ioutil.ReadAll(f)
55+
return string(read)
56+
}
57+
58+
func (s *testAuditSuite) SetUpSuite(c *C) {
59+
resetDir()
60+
}
61+
4462
func (s *testAuditSuite) TearDownSuite(c *C) {
45-
_ = os.RemoveAll(auditDir())
63+
_ = os.RemoveAll(auditDir()) // path.Join(currentDir(), "testdata"))
4664
}
4765

4866
func (s *testAuditSuite) TestOutputAuditLog(c *C) {
4967
dir := auditDir()
68+
resetDir()
69+
5070
var g errgroup.Group
5171
for i := 0; i < 20; i++ {
5272
g.Go(func() error { return OutputAuditLog(dir, []byte("audit log")) })
@@ -56,10 +76,74 @@ func (s *testAuditSuite) TestOutputAuditLog(c *C) {
5676

5777
var paths []string
5878
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
59-
// simply filter the not relate files.
60-
paths = append(paths, path)
79+
if !info.IsDir() {
80+
paths = append(paths, path)
81+
}
6182
return nil
6283
})
6384
c.Assert(err, IsNil)
6485
c.Assert(len(paths), Equals, 20)
6586
}
87+
88+
func (s *testAuditSuite) TestShowAuditLog(c *C) {
89+
dir := auditDir()
90+
resetDir()
91+
92+
originStdout := os.Stdout
93+
defer func() {
94+
os.Stdout = originStdout
95+
}()
96+
97+
fakeStdout := path.Join(currentDir(), "fake-stdout")
98+
defer os.Remove(fakeStdout)
99+
100+
openStdout := func() *os.File {
101+
_ = os.Remove(fakeStdout)
102+
f, err := os.OpenFile(fakeStdout, os.O_CREATE|os.O_RDWR, 0644)
103+
c.Assert(err, IsNil)
104+
os.Stdout = f
105+
return f
106+
}
107+
108+
second := int64(1604413577)
109+
nanoSecond := int64(1604413624836105381)
110+
111+
fname := filepath.Join(dir, base52.Encode(second))
112+
c.Assert(ioutil.WriteFile(fname, []byte("test with second"), 0644), IsNil)
113+
fname = filepath.Join(dir, base52.Encode(nanoSecond))
114+
c.Assert(ioutil.WriteFile(fname, []byte("test with nanosecond"), 0644), IsNil)
115+
116+
f := openStdout()
117+
c.Assert(ShowAuditList(dir), IsNil)
118+
// tabby table size is based on column width, while time.RFC3339 maybe print out timezone like +08:00 or Z(UTC)
119+
// skip the first two lines
120+
list := strings.Join(strings.Split(readFakeStdout(f), "\n")[2:], "\n")
121+
c.Assert(list, Equals, fmt.Sprintf(`ftmpqzww84Q %s test with nanosecond
122+
4F7ZTL %s test with second
123+
`,
124+
time.Unix(nanoSecond/1e9, 0).Format(time.RFC3339),
125+
time.Unix(second, 0).Format(time.RFC3339),
126+
))
127+
f.Close()
128+
129+
f = openStdout()
130+
c.Assert(ShowAuditLog(dir, "4F7ZTL"), IsNil)
131+
c.Assert(readFakeStdout(f), Equals, fmt.Sprintf(`---------------------------------------
132+
- OPERATION TIME: %s -
133+
---------------------------------------
134+
test with second`,
135+
time.Unix(second, 0).Format("2006-01-02T15:04:05"),
136+
))
137+
138+
f.Close()
139+
140+
f = openStdout()
141+
c.Assert(ShowAuditLog(dir, "ftmpqzww84Q"), IsNil)
142+
c.Assert(readFakeStdout(f), Equals, fmt.Sprintf(`---------------------------------------
143+
- OPERATION TIME: %s -
144+
---------------------------------------
145+
test with nanosecond`,
146+
time.Unix(nanoSecond/1e9, 0).Format("2006-01-02T15:04:05"),
147+
))
148+
f.Close()
149+
}

0 commit comments

Comments
 (0)