Skip to content

Commit 9ca7d24

Browse files
authored
Merge pull request #352 from wneessen/more-test-improvements
More test improvements
2 parents d7e0b48 + ec10e0b commit 9ca7d24

File tree

4 files changed

+241
-159
lines changed

4 files changed

+241
-159
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
check-latest: true
5151
- name: Install sendmail
5252
run: |
53-
sudo apt-get -y update >/dev/null && sudo apt-get -y upgrade >/dev/null && sudo DEBIAN_FRONTEND=noninteractive apt-get -y install nullmailer >/dev/null && which sendmail
53+
sudo apt-get -y update && sudo DEBIAN_FRONTEND=noninteractive apt-get -y install nullmailer && which sendmail
5454
- name: Run go test
5555
if: success()
5656
run: |

random_test.go

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,81 @@
55
package mail
66

77
import (
8+
"crypto/rand"
9+
"errors"
810
"strings"
911
"testing"
1012
)
1113

1214
// TestRandomStringSecure tests the randomStringSecure method
1315
func TestRandomStringSecure(t *testing.T) {
14-
tt := []struct {
15-
testName string
16-
length int
17-
mustNotMatch string
18-
}{
19-
{"20 chars", 20, "'"},
20-
{"100 chars", 100, "'"},
21-
{"1000 chars", 1000, "'"},
22-
}
16+
t.Run("randomStringSecure with varying length", func(t *testing.T) {
17+
tt := []struct {
18+
testName string
19+
length int
20+
mustNotMatch string
21+
}{
22+
{"20 chars", 20, "'"},
23+
{"100 chars", 100, "'"},
24+
{"1000 chars", 1000, "'"},
25+
}
2326

24-
for _, tc := range tt {
25-
t.Run(tc.testName, func(t *testing.T) {
26-
rs, err := randomStringSecure(tc.length)
27-
if err != nil {
28-
t.Errorf("random string generation failed: %s", err)
29-
}
30-
if strings.Contains(rs, tc.mustNotMatch) {
31-
t.Errorf("random string contains unexpected character. got: %s, not-expected: %s",
32-
rs, tc.mustNotMatch)
33-
}
34-
if len(rs) != tc.length {
35-
t.Errorf("random string length does not match. expected: %d, got: %d", tc.length, len(rs))
36-
}
37-
})
38-
}
27+
for _, tc := range tt {
28+
t.Run(tc.testName, func(t *testing.T) {
29+
rs, err := randomStringSecure(tc.length)
30+
if err != nil {
31+
t.Errorf("random string generation failed: %s", err)
32+
}
33+
if strings.Contains(rs, tc.mustNotMatch) {
34+
t.Errorf("random string contains unexpected character. got: %s, not-expected: %s",
35+
rs, tc.mustNotMatch)
36+
}
37+
if len(rs) != tc.length {
38+
t.Errorf("random string length does not match. expected: %d, got: %d", tc.length, len(rs))
39+
}
40+
})
41+
}
42+
})
43+
t.Run("randomStringSecure fails on broken rand Reader (first read)", func(t *testing.T) {
44+
defaultRandReader := rand.Reader
45+
t.Cleanup(func() { rand.Reader = defaultRandReader })
46+
rand.Reader = &randReader{failon: 1}
47+
if _, err := randomStringSecure(22); err == nil {
48+
t.Fatalf("expected failure on broken rand Reader")
49+
}
50+
})
51+
t.Run("randomStringSecure fails on broken rand Reader (second read)", func(t *testing.T) {
52+
defaultRandReader := rand.Reader
53+
t.Cleanup(func() { rand.Reader = defaultRandReader })
54+
rand.Reader = &randReader{failon: 0}
55+
if _, err := randomStringSecure(22); err == nil {
56+
t.Fatalf("expected failure on broken rand Reader")
57+
}
58+
})
3959
}
4060

4161
func BenchmarkGenerator_RandomStringSecure(b *testing.B) {
4262
b.ReportAllocs()
4363
for i := 0; i < b.N; i++ {
44-
_, err := randomStringSecure(22)
64+
_, err := randomStringSecure(10)
4565
if err != nil {
4666
b.Errorf("RandomStringFromCharRange() failed: %s", err)
4767
}
4868
}
4969
}
70+
71+
// randReader is type that satisfies the io.Reader interface. It can fail on a specific read
72+
// operations and is therefore useful to test consecutive reads with errors
73+
type randReader struct {
74+
failon uint8
75+
call uint8
76+
}
77+
78+
// Read implements the io.Reader interface for the randReader type
79+
func (r *randReader) Read(p []byte) (int, error) {
80+
if r.call == r.failon {
81+
r.call++
82+
return len(p), nil
83+
}
84+
return 0, errors.New("broken reader")
85+
}

senderror.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ type SendErrReason int
8181
// Returns:
8282
// - A string representing the error message.
8383
func (e *SendError) Error() string {
84-
if e.Reason > 10 {
84+
if e.Reason > ErrAmbiguous {
8585
return "unknown reason"
8686
}
8787

@@ -93,7 +93,7 @@ func (e *SendError) Error() string {
9393
errMessage.WriteRune(' ')
9494
errMessage.WriteString(e.errlist[i].Error())
9595
if i != len(e.errlist)-1 {
96-
errMessage.WriteString(", ")
96+
errMessage.WriteString(",")
9797
}
9898
}
9999
}

0 commit comments

Comments
 (0)