11package loginterceptor_test
22
33import (
4- "bytes"
54 "io"
65 "regexp"
76 "sync"
@@ -12,45 +11,42 @@ import (
1211 "github.com/stretchr/testify/assert"
1312)
1413
14+ const (
15+ msg1 = "Log message without prefix\n "
16+ msg2 = "[Bitrise Analytics] Log message with prefixs\n "
17+ msg3 = "[Bitrise Build Cache] Log message with prefix\n "
18+ msg4 = "Stuff [Bitrise Build Cache] Log message without prefix\n "
19+ )
20+
1521func TestPrefixInterceptor (t * testing.T ) {
16- interceptReader , interceptWriter := io . Pipe ()
17- targetReader , targetWriter := io . Pipe ()
22+ interceptedMsgs := NewChanWriterCloser ()
23+ targetMsgs := NewChanWriterCloser ()
1824 re := regexp .MustCompile (`^\[Bitrise.*\].*` )
1925
20- sut := loginterceptor .NewPrefixInterceptor (re , interceptWriter , targetWriter , log .NewLogger ())
21-
22- msg1 := "Log message without prefix\n "
23- msg2 := "[Bitrise Analytics] Log message with prefix\n "
24- msg3 := "[Bitrise Build Cache] Log message with prefix\n "
25- msg4 := "Stuff [Bitrise Build Cache] Log message without prefix\n "
26+ sut := loginterceptor .NewPrefixInterceptor (re , & interceptedMsgs , & targetMsgs , log .NewLogger ())
2627
2728 go func () {
28- //nolint:errCheck
29- defer sut .Close ()
30-
29+ defer func () { _ = sut .Close () }()
3130 _ , _ = sut .Write ([]byte (msg1 ))
3231 _ , _ = sut .Write ([]byte (msg2 ))
3332 _ , _ = sut .Write ([]byte (msg3 ))
3433 _ , _ = sut .Write ([]byte (msg4 ))
3534 }()
3635
37- intercepted , target , err := readTwo (interceptReader , targetReader )
38- assert .NoError (t , err )
39- assert .Equal (t , msg2 + msg3 , string (intercepted ))
40- assert .Equal (t , msg1 + msg2 + msg3 + msg4 , string (target ))
36+ waitForBoth (sut )
37+ _ = interceptedMsgs .Close ()
38+ _ = targetMsgs .Close ()
39+
40+ assert .Equal (t , msg2 + msg3 , interceptedMsgs .Messages ())
41+ assert .Equal (t , msg1 + msg2 + msg3 + msg4 , targetMsgs .Messages ())
4142}
4243
4344func TestPrefixInterceptorWithPrematureClose (t * testing.T ) {
44- interceptReader , interceptWriter := io . Pipe ()
45- targetReader , targetWriter := io . Pipe ()
45+ interceptedMsgs := NewChanWriterCloser ()
46+ targetMsgs := NewChanWriterCloser ()
4647 re := regexp .MustCompile (`^\[Bitrise.*\].*` )
4748
48- sut := loginterceptor .NewPrefixInterceptor (re , interceptWriter , targetWriter , log .NewLogger ())
49-
50- msg1 := "Log message without prefix\n "
51- msg2 := "[Bitrise Analytics] Log message with prefix\n "
52- msg3 := "[Bitrise Build Cache] Log message with prefix\n "
53- msg4 := "Last message that won't be sent\n "
49+ sut := loginterceptor .NewPrefixInterceptor (re , & interceptedMsgs , & targetMsgs , log .NewLogger ())
5450
5551 go func () {
5652 _ , _ = sut .Write ([]byte (msg1 ))
@@ -60,71 +56,80 @@ func TestPrefixInterceptorWithPrematureClose(t *testing.T) {
6056 _ , _ = sut .Write ([]byte (msg4 ))
6157 }()
6258
63- intercepted , target , err := readTwo (interceptReader , targetReader )
64- assert .NoError (t , err )
65- assert .Equal (t , msg2 + msg3 , string (intercepted ))
66- assert .Equal (t , msg1 + msg2 + msg3 , string (target ))
59+ waitForBoth (sut )
60+ _ = interceptedMsgs .Close ()
61+ _ = targetMsgs .Close ()
62+
63+ assert .Equal (t , msg2 + msg3 , interceptedMsgs .Messages ())
64+ assert .Equal (t , msg1 + msg2 + msg3 , targetMsgs .Messages ())
6765}
6866
6967func TestPrefixInterceptorWithBlockedPipe (t * testing.T ) {
70- interceptReader , interceptWriter := io .Pipe ()
71- targetReader , targetWriter := io . Pipe ()
68+ _ , interceptWriter := io .Pipe ()
69+ targetMsgs := NewChanWriterCloser ()
7270 re := regexp .MustCompile (`^\[Bitrise.*\].*` )
7371
74- sut := loginterceptor .NewPrefixInterceptor (re , interceptWriter , targetWriter , log .NewLogger ())
75-
76- msg1 := "Log message without prefix\n "
77- msg2 := "[Bitrise Analytics] Log message with prefix\n "
78- msg3 := "[Bitrise Build Cache] Log message with prefix\n "
79- msg4 := "Stuff [Bitrise Build Cache] Log message without prefix\n "
72+ sut := loginterceptor .NewPrefixInterceptor (re , interceptWriter , & targetMsgs , log .NewLogger ())
8073
8174 go func () {
82- //nolint:errCheck
83- defer sut .Close ()
84-
8575 _ , _ = sut .Write ([]byte (msg1 ))
8676 _ , _ = sut .Write ([]byte (msg2 ))
8777 _ , _ = sut .Write ([]byte (msg3 ))
78+ _ = sut .Close ()
8879 _ , _ = sut .Write ([]byte (msg4 ))
8980 }()
9081
91- target , err := io .ReadAll (targetReader )
92- assert .NoError (t , err )
93- assert .Equal (t , msg1 + msg2 + msg3 + msg4 , string (target ))
82+ <- sut .TargetDelivered
83+ _ = targetMsgs .Close ()
9484
95- // Reading from interceptReader should block until targetWriter is read
96- intercepted , err := io .ReadAll (interceptReader )
97- assert .NoError (t , err )
98- assert .Equal (t , msg2 + msg3 , string (intercepted ))
85+ assert .Equal (t , msg1 + msg2 + msg3 , targetMsgs .Messages ())
9986}
10087
101- func readTwo ( r1 , r2 io. Reader ) ( out1 , out2 [] byte , err error ) {
102- var (
103- wg sync. WaitGroup
104- e1 , e2 error
105- )
88+ // --------------------------------
89+ // Helpers
90+ // --------------------------------
91+ func waitForBoth ( sut * loginterceptor. PrefixInterceptor ) {
92+ var wg sync. WaitGroup
10693 wg .Add (2 )
10794
108- var b1 , b2 bytes.Buffer
109-
110- go func () {
111- defer wg .Done ()
112- _ , e1 = io .Copy (& b1 , r1 )
113- }()
95+ go func (wg * sync.WaitGroup ) {
96+ <- sut .TargetDelivered
97+ wg .Done ()
98+ }(& wg )
11499
115- go func () {
116- defer wg . Done ()
117- _ , e2 = io . Copy ( & b2 , r2 )
118- }()
100+ go func (wg * sync. WaitGroup ) {
101+ <- sut . InterceptedDelivered
102+ wg . Done ( )
103+ }(& wg )
119104
120105 wg .Wait ()
106+ }
107+
108+ type ChanWriterCloser struct {
109+ channel chan string
110+ }
121111
122- // prefer to return the first non-nil error
123- if e1 != nil {
124- return b1 . Bytes (), b2 . Bytes (), e1
112+ func NewChanWriterCloser () ChanWriterCloser {
113+ return ChanWriterCloser {
114+ channel : make ( chan string , 1000 ),
125115 }
126- if e2 != nil {
127- return b1 .Bytes (), b2 .Bytes (), e2
116+ }
117+
118+ func (ch * ChanWriterCloser ) Write (p []byte ) (int , error ) {
119+ ch .channel <- string (p )
120+ return len (p ), nil
121+ }
122+
123+ // Close stops the interceptor and closes the pipe.
124+ func (ch * ChanWriterCloser ) Close () error {
125+ close (ch .channel )
126+ return nil
127+ }
128+
129+ func (ch * ChanWriterCloser ) Messages () string {
130+ var result string
131+ for msg := range ch .channel {
132+ result += msg
128133 }
129- return b1 . Bytes (), b2 . Bytes (), nil
134+ return result
130135}
0 commit comments