Skip to content

Commit f259330

Browse files
committed
Merge branch 'codexRefactoring'
2 parents 46f94c9 + b077298 commit f259330

File tree

7 files changed

+263
-37
lines changed

7 files changed

+263
-37
lines changed

pkg/ant/ant.go

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,35 @@ type Admin struct {
3434
errorCount int // errorCount gets incremented by each started go routine on an error.
3535
}
3636

37+
func (p *Admin) addError() {
38+
p.Mutex.Lock()
39+
p.errorCount++
40+
p.Mutex.Unlock()
41+
}
42+
43+
func (p *Admin) getErrorCount() int {
44+
p.Mutex.RLock()
45+
defer p.Mutex.RUnlock()
46+
return p.errorCount
47+
}
48+
3749
// Walk performs p.action on each file in passed srcs and all sub trees.
3850
func (p *Admin) Walk(w io.Writer, fSys *afero.Afero) error {
51+
if fSys == nil {
52+
return errors.New("nil filesystem")
53+
}
54+
if w == nil {
55+
w = io.Discard
56+
}
57+
if p.MatchingFileName == nil {
58+
p.MatchingFileName = func(_ os.FileInfo) bool { return true }
59+
}
60+
if p.Action == nil {
61+
return errors.New("nil action")
62+
}
63+
p.Mutex.Lock()
64+
p.errorCount = 0
65+
p.Mutex.Unlock()
3966

4067
// processing tree list ...
4168
for _, path := range p.Trees {
@@ -45,8 +72,10 @@ func (p *Admin) Walk(w io.Writer, fSys *afero.Afero) error {
4572
go func() {
4673
defer p.wg.Done()
4774
err := fSys.Walk(path, visit(w, fSys, p))
48-
//msg.FatalInfoOnErr(err, "failed to walk tree")
49-
msg.InfoOnErr(err, "failed to walk tree")
75+
if err != nil {
76+
msg.InfoOnErr(err, "failed to walk tree")
77+
p.addError()
78+
}
5079
}()
5180
} else if os.IsNotExist(err) { // path does *not* exist
5281
fmt.Fprintln(w, path, "does not exist!")
@@ -60,8 +89,8 @@ func (p *Admin) Walk(w io.Writer, fSys *afero.Afero) error {
6089
// ...waiting
6190
p.wg.Wait()
6291

63-
if p.errorCount > 0 {
64-
return errors.New(fmt.Sprint(p.errorCount, " walk errors"))
92+
if c := p.getErrorCount(); c > 0 {
93+
return errors.New(fmt.Sprint(c, " walk errors"))
6594
}
6695
return nil
6796
}
@@ -111,8 +140,13 @@ func visit(w io.Writer, fSys *afero.Afero, jalan *Admin) filepath.WalkFunc {
111140
}
112141
}
113142

143+
matching := jalan.MatchingFileName
144+
if matching == nil {
145+
matching = func(_ os.FileInfo) bool { return true }
146+
}
147+
114148
// Skip directories and files that don't match the pattern
115-
if fileInfo.IsDir() || !jalan.MatchingFileName(fileInfo) {
149+
if fileInfo.IsDir() || !matching(fileInfo) {
116150
return nil
117151
}
118152

@@ -122,11 +156,7 @@ func visit(w io.Writer, fSys *afero.Afero, jalan *Admin) filepath.WalkFunc {
122156
err := jalan.Action(w, fSys, path, fileInfo, jalan)
123157
if err != nil {
124158
fmt.Fprintln(w, path, err)
125-
126-
// Safely increment errorCount
127-
jalan.Mutex.Lock()
128-
jalan.errorCount++
129-
jalan.Mutex.Unlock()
159+
jalan.addError()
130160
}
131161
}()
132162

pkg/ant/ant_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package ant
2+
3+
import (
4+
"errors"
5+
"io"
6+
"os"
7+
"strings"
8+
"sync/atomic"
9+
"testing"
10+
11+
"github.com/spf13/afero"
12+
)
13+
14+
func TestWalkRejectsNilAction(t *testing.T) {
15+
fSys := &afero.Afero{Fs: afero.NewMemMapFs()}
16+
if err := fSys.MkdirAll("root", 0o755); err != nil {
17+
t.Fatalf("mkdir failed: %v", err)
18+
}
19+
20+
a := &Admin{
21+
Trees: []string{"root"},
22+
}
23+
24+
err := a.Walk(io.Discard, fSys)
25+
if err == nil || !strings.Contains(err.Error(), "nil action") {
26+
t.Fatalf("expected nil action error, got: %v", err)
27+
}
28+
}
29+
30+
func TestWalkUsesDefaultMatcher(t *testing.T) {
31+
fSys := &afero.Afero{Fs: afero.NewMemMapFs()}
32+
if err := fSys.MkdirAll("root/sub", 0o755); err != nil {
33+
t.Fatalf("mkdir failed: %v", err)
34+
}
35+
if err := fSys.WriteFile("root/a.txt", []byte("a"), 0o644); err != nil {
36+
t.Fatalf("write failed: %v", err)
37+
}
38+
if err := fSys.WriteFile("root/sub/b.txt", []byte("b"), 0o644); err != nil {
39+
t.Fatalf("write failed: %v", err)
40+
}
41+
42+
var got int32
43+
a := &Admin{
44+
Trees: []string{"root"},
45+
Action: func(_ io.Writer, _ *afero.Afero, _ string, fi os.FileInfo, _ *Admin) error {
46+
if fi.IsDir() {
47+
t.Fatal("action must only be called for files")
48+
}
49+
atomic.AddInt32(&got, 1)
50+
return nil
51+
},
52+
}
53+
54+
if err := a.Walk(io.Discard, fSys); err != nil {
55+
t.Fatalf("walk failed: %v", err)
56+
}
57+
if got != 2 {
58+
t.Fatalf("expected action for 2 files, got %d", got)
59+
}
60+
}
61+
62+
func TestWalkIgnoresMissingTrees(t *testing.T) {
63+
fSys := &afero.Afero{Fs: afero.NewMemMapFs()}
64+
a := &Admin{
65+
Trees: []string{"missing"},
66+
MatchingFileName: func(_ os.FileInfo) bool { return true },
67+
Action: func(io.Writer, *afero.Afero, string, os.FileInfo, *Admin) error { return nil },
68+
}
69+
70+
err := a.Walk(io.Discard, fSys)
71+
if err != nil {
72+
t.Fatalf("expected missing tree to be non-fatal, got: %v", err)
73+
}
74+
}
75+
76+
func TestWalkResetsErrorCountPerRun(t *testing.T) {
77+
fSys := &afero.Afero{Fs: afero.NewMemMapFs()}
78+
if err := fSys.MkdirAll("root", 0o755); err != nil {
79+
t.Fatalf("mkdir failed: %v", err)
80+
}
81+
if err := fSys.WriteFile("root/a.txt", []byte("a"), 0o644); err != nil {
82+
t.Fatalf("write failed: %v", err)
83+
}
84+
85+
a := &Admin{
86+
Trees: []string{"root"},
87+
MatchingFileName: func(_ os.FileInfo) bool { return true },
88+
Action: func(io.Writer, *afero.Afero, string, os.FileInfo, *Admin) error { return errors.New("boom") },
89+
}
90+
91+
if err := a.Walk(io.Discard, fSys); err == nil {
92+
t.Fatal("expected first walk to fail")
93+
}
94+
95+
a.Action = func(io.Writer, *afero.Afero, string, os.FileInfo, *Admin) error { return nil }
96+
if err := a.Walk(io.Discard, fSys); err != nil {
97+
t.Fatalf("expected second walk to succeed, got: %v", err)
98+
}
99+
}
100+
101+
func TestWalkAggregatesActionErrors(t *testing.T) {
102+
fSys := &afero.Afero{Fs: afero.NewMemMapFs()}
103+
if err := fSys.MkdirAll("root", 0o755); err != nil {
104+
t.Fatalf("mkdir failed: %v", err)
105+
}
106+
if err := fSys.WriteFile("root/a.txt", []byte("a"), 0o644); err != nil {
107+
t.Fatalf("write failed: %v", err)
108+
}
109+
if err := fSys.WriteFile("root/b.txt", []byte("b"), 0o644); err != nil {
110+
t.Fatalf("write failed: %v", err)
111+
}
112+
113+
a := &Admin{
114+
Trees: []string{"root"},
115+
MatchingFileName: func(_ os.FileInfo) bool { return true },
116+
Action: func(io.Writer, *afero.Afero, string, os.FileInfo, *Admin) error {
117+
return errors.New("boom")
118+
},
119+
}
120+
121+
err := a.Walk(io.Discard, fSys)
122+
if err == nil || !strings.Contains(err.Error(), "2 walk errors") {
123+
t.Fatalf("expected 2 action errors, got: %v", err)
124+
}
125+
}

pkg/cipher/cipher.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func createCipher(w io.Writer) (*xtea.Cipher, bool, error) {
7272
return c, e, nil
7373
}
7474

75-
//! tested with little endian embedded device
75+
// tested with little endian embedded device
7676
func swap8Bytes(src []byte) []byte {
7777
b := make([]byte, 8)
7878
copy(b, src)
@@ -81,8 +81,7 @@ func swap8Bytes(src []byte) []byte {
8181

8282
// Encrypt8 translates a byte slice in a protected slice of length 8.
8383
//
84-
// Shorter slices are extended with 0x16 until length 8.
85-
// Longer slices are truncated to length 8.
84+
// The input must be exactly 8 bytes; otherwise the function logs an info message.
8685
func Encrypt8(b []byte) (e []byte) {
8786
msg.InfoOnFalse(8 == len(b), "Buffer len is not 8.")
8887
if enabled {
@@ -98,8 +97,7 @@ func Encrypt8(b []byte) (e []byte) {
9897

9998
// Decrypt8 translates an encryption protected byte slice back in a slice of length 8.
10099
//
101-
// Shorter slices are extended with 0 until length 8.
102-
// Longer slices are truncated to length 8.
100+
// The input must be exactly 8 bytes; otherwise the function logs an info message.
103101
func Decrypt8(b []byte) (d []byte) {
104102
msg.InfoOnFalse(8 == len(b), "Buffer len is not 8.")
105103
if enabled {
@@ -115,8 +113,7 @@ func Decrypt8(b []byte) (d []byte) {
115113

116114
// decrypt8 translates src, an encryption protected byte slice, back in dst, a byte slice of length 8.
117115
//
118-
// Shorter slices are extended with 0 until length 8.
119-
// Longer slices are truncated to length 8.
116+
// src and dst are expected to be exactly 8 bytes long.
120117
func decrypt8(dst, src []byte) {
121118
swap := src
122119
if enabled {
@@ -129,8 +126,7 @@ func decrypt8(dst, src []byte) {
129126

130127
// encrypt8 translates byte slice src, in an encryption protected byte slice dst.
131128
//
132-
// Shorter slices are extended with 0 until length 8.
133-
// Longer slices are truncated to length 8.
129+
// src and dst are expected to be exactly 8 bytes long.
134130
func encrypt8(dst, src []byte) {
135131
swap := src
136132
if enabled {

pkg/msg/msg.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -170,27 +170,33 @@ var (
170170
)
171171

172172
func fmtFMessage(w io.Writer, pc uintptr, fn string, line int, ok bool, err error) {
173-
if ok {
174-
funcName := runtime.FuncForPC(pc).Name()
175-
fileName := filepath.Base(fn)
176-
fmt.Fprintf(w, formatString+"\n", fileName, line, funcName, err)
177-
} else {
173+
if !ok {
178174
fmt.Fprintln(w, seriousError)
175+
return
176+
}
177+
fileName := filepath.Base(fn)
178+
funcName := "<unknown>"
179+
if f := runtime.FuncForPC(pc); f != nil {
180+
funcName = f.Name()
179181
}
182+
fmt.Fprintf(w, formatString+"\n", fileName, line, funcName, err)
180183
}
181184

182185
func fmtMessage(pc uintptr, fn string, line int, ok bool, err error) {
183186
fmtFMessage(os.Stdout, pc, fn, line, ok, err)
184187
}
185188

186189
func logMessage(pc uintptr, fn string, line int, ok bool, err error) {
187-
if ok {
188-
funcName := runtime.FuncForPC(pc).Name()
189-
fileName := filepath.Base(fn)
190-
logFatalf(formatString, fileName, line, funcName, err)
191-
} else {
190+
if !ok {
192191
logFatalf("%s", seriousError)
192+
return
193+
}
194+
fileName := filepath.Base(fn)
195+
funcName := "<unknown>"
196+
if f := runtime.FuncForPC(pc); f != nil {
197+
funcName = f.Name()
193198
}
199+
logFatalf(formatString, fileName, line, funcName, err)
194200
}
195201

196202
// -----------------------------------------------
@@ -210,7 +216,7 @@ func OsExitDisallow() (o OrigLogFatalf) {
210216

211217
logFatalf = func(format string, args ...interface{}) {
212218
if len(args) > 0 {
213-
fmt.Printf(format, args)
219+
fmt.Printf(format, args...)
214220
} else {
215221
fmt.Print(format)
216222
}

pkg/msg/msg_whitebox_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
package msg
55

66
import (
7+
"bytes"
78
"errors"
89
"fmt"
10+
"io"
11+
"os"
12+
"strings"
913
"testing"
1014
)
1115

@@ -86,3 +90,58 @@ func TestFatalInfoOnFalse(t *testing.T) {
8690
e = e[:0] // clear
8791

8892
}
93+
94+
func captureStdout(tb testing.TB, f func()) string {
95+
tb.Helper()
96+
old := os.Stdout
97+
r, w, err := os.Pipe()
98+
if err != nil {
99+
tb.Fatalf("pipe failed: %v", err)
100+
}
101+
os.Stdout = w
102+
done := make(chan string, 1)
103+
go func() {
104+
var b bytes.Buffer
105+
_, _ = io.Copy(&b, r)
106+
done <- b.String()
107+
}()
108+
f()
109+
_ = w.Close()
110+
os.Stdout = old
111+
return <-done
112+
}
113+
114+
func TestFmtFMessageHandlesMissingCallerInfo(t *testing.T) {
115+
var b bytes.Buffer
116+
fmtFMessage(&b, 0, "", 0, false, errors.New("x"))
117+
if !strings.Contains(b.String(), seriousError) {
118+
t.Fatalf("expected seriousError in output, got %q", b.String())
119+
}
120+
}
121+
122+
func TestLogMessageHandlesMissingCallerInfo(t *testing.T) {
123+
origLogFatalf := logFatalf
124+
defer func() { logFatalf = origLogFatalf }()
125+
126+
var got string
127+
logFatalf = func(format string, args ...interface{}) {
128+
got = fmt.Sprintf(format, args...)
129+
}
130+
131+
logMessage(0, "", 0, false, errors.New("x"))
132+
if !strings.Contains(got, seriousError) {
133+
t.Fatalf("expected seriousError in log output, got %q", got)
134+
}
135+
}
136+
137+
func TestOsExitDisallowFormatsVarArgs(t *testing.T) {
138+
o := OsExitDisallow()
139+
defer OsExitAllow(o)
140+
141+
out := captureStdout(t, func() {
142+
logFatalf("value=%d", 7)
143+
})
144+
if !strings.Contains(out, "value=7") {
145+
t.Fatalf("expected formatted output, got %q", out)
146+
}
147+
}

0 commit comments

Comments
 (0)