@@ -15,22 +15,22 @@ import (
1515// readCloseSpy records whether Close was called.
1616type readCloseSpy struct {
1717 io.Reader
18- closed atomic.Bool
18+ closeCount atomic.Uint32
1919}
2020
2121func (r * readCloseSpy ) Close () error {
22- r .closed . Store ( true )
22+ r .closeCount . Add ( 1 )
2323 return nil
2424}
2525
2626// writeCloseSpy records whether Close was called.
2727type writeCloseSpy struct {
2828 io.Writer
29- closed atomic.Bool
29+ closeCount atomic.Uint32
3030}
3131
3232func (w * writeCloseSpy ) Close () error {
33- w .closed . Store ( true )
33+ w .closeCount . Add ( 1 )
3434 return nil
3535}
3636
@@ -63,28 +63,52 @@ func TestGoStageHonorsStreamOwnership(t *testing.T) {
6363 ))
6464 require .NoError (t , s .Wait ())
6565
66- assert .Equal (t , ! tc .leaveIn , in .closed .Load (), "closing stdin=%v" , ! tc .leaveIn )
67- assert .Equal (t , ! tc .leaveOut , out .closed .Load (), "closing stdout=%v" , ! tc .leaveOut )
66+ if tc .leaveIn {
67+ assert .EqualValues (t , 0 , in .closeCount .Load (), "closing stdin=%v" , ! tc .leaveIn )
68+ } else {
69+ assert .EqualValues (t , 1 , in .closeCount .Load (), "closing stdin=%v" , ! tc .leaveIn )
70+ }
71+ if tc .leaveOut {
72+ assert .EqualValues (t , 0 , out .closeCount .Load (), "closing stdout=%v" , ! tc .leaveOut )
73+ } else {
74+ assert .EqualValues (t , 1 , out .closeCount .Load (), "closing stdout=%v" , ! tc .leaveOut )
75+ }
6876 })
6977 }
7078}
7179
7280func TestStreamConstructorsPreserveOwnershipAndDynamicType (t * testing.T ) {
73- borrowedInput := strings .NewReader ("borrowed" )
74- assert .Same (t , borrowedInput , Input (borrowedInput ).Reader ())
75- assert .Nil (t , Input (borrowedInput ).Closer ())
76-
77- ownedInput := & readCloseSpy {Reader : strings .NewReader ("owned" )}
78- assert .Same (t , ownedInput , ClosingInput (ownedInput ).Reader ())
79- assert .Same (t , ownedInput , ClosingInput (ownedInput ).Closer ())
80-
81- borrowedOutput := & strings.Builder {}
82- assert .Same (t , borrowedOutput , Output (borrowedOutput ).Writer ())
83- assert .Nil (t , Output (borrowedOutput ).Closer ())
84-
85- ownedOutput := & writeCloseSpy {Writer : io .Discard }
86- assert .Same (t , ownedOutput , ClosingOutput (ownedOutput ).Writer ())
87- assert .Same (t , ownedOutput , ClosingOutput (ownedOutput ).Closer ())
81+ borrowedReader := & readCloseSpy {Reader : strings .NewReader ("borrowed" )}
82+ borrowedInput := Input (borrowedReader )
83+ assert .Same (t , borrowedReader , borrowedInput .Reader ())
84+ assert .NoError (t , borrowedInput .Close ())
85+ assert .EqualValues (t , 0 , borrowedReader .closeCount .Load ())
86+ assert .NoError (t , borrowedInput .Close ())
87+ assert .EqualValues (t , 0 , borrowedReader .closeCount .Load ())
88+
89+ ownedReader := & readCloseSpy {Reader : strings .NewReader ("owned" )}
90+ ownedInput := ClosingInput (ownedReader )
91+ assert .Same (t , ownedReader , ownedInput .Reader ())
92+ assert .NoError (t , ownedInput .Close ())
93+ assert .EqualValues (t , 1 , ownedReader .closeCount .Load ())
94+ assert .NoError (t , ownedInput .Close ())
95+ assert .EqualValues (t , 1 , ownedReader .closeCount .Load ())
96+
97+ borrowedWriter := & writeCloseSpy {Writer : & strings.Builder {}}
98+ borrowedOutput := Output (borrowedWriter )
99+ assert .Same (t , borrowedWriter , borrowedOutput .Writer ())
100+ assert .NoError (t , borrowedOutput .Close ())
101+ assert .EqualValues (t , 0 , borrowedWriter .closeCount .Load ())
102+ assert .NoError (t , borrowedOutput .Close ())
103+ assert .EqualValues (t , 0 , borrowedWriter .closeCount .Load ())
104+
105+ ownedWriter := & writeCloseSpy {Writer : & writeCloseSpy {Writer : io .Discard }}
106+ ownedOutput := ClosingOutput (ownedWriter )
107+ assert .Same (t , ownedWriter , ownedOutput .Writer ())
108+ assert .NoError (t , ownedOutput .Close ())
109+ assert .EqualValues (t , 1 , ownedWriter .closeCount .Load ())
110+ assert .NoError (t , ownedOutput .Close ())
111+ assert .EqualValues (t , 1 , ownedWriter .closeCount .Load ())
88112}
89113
90114// TestCommandStageHonorsCloseStdin verifies that a command stage closes a
@@ -109,7 +133,11 @@ func TestCommandStageHonorsCloseStdin(t *testing.T) {
109133 ))
110134 require .NoError (t , s .Wait ())
111135
112- assert .Equal (t , ! leave , in .closed .Load (), "closing stdin=%v" , ! leave )
136+ if leave {
137+ assert .EqualValues (t , 0 , in .closeCount .Load (), "closing stdin=%v" , ! leave )
138+ } else {
139+ assert .EqualValues (t , 1 , in .closeCount .Load (), "closing stdin=%v" , ! leave )
140+ }
113141 })
114142 }
115143}
@@ -136,19 +164,23 @@ func TestCommandStageHonorsCloseStdout(t *testing.T) {
136164 ))
137165 require .NoError (t , s .Wait ())
138166
139- assert .Equal (t , ! leave , out .closed .Load (), "closing stdout=%v" , ! leave )
167+ if leave {
168+ assert .EqualValues (t , 0 , out .closeCount .Load (), "closing stdout=%v" , ! leave )
169+ } else {
170+ assert .EqualValues (t , 1 , out .closeCount .Load (), "closing stdout=%v" , ! leave )
171+ }
140172 })
141173 }
142174}
143175
144- func inputForTest (r io.ReadCloser , closing bool ) InputStream {
176+ func inputForTest (r io.ReadCloser , closing bool ) * InputStream {
145177 if closing {
146178 return ClosingInput (r )
147179 }
148180 return Input (r )
149181}
150182
151- func outputForTest (w io.WriteCloser , closing bool ) OutputStream {
183+ func outputForTest (w io.WriteCloser , closing bool ) * OutputStream {
152184 if closing {
153185 return ClosingOutput (w )
154186 }
0 commit comments