@@ -37,53 +37,49 @@ func testCatFileBatch(t *testing.T) {
3737 require .Error (t , err )
3838 })
3939
40- setupTerminatedBatch := func (t * testing.T ) (* catFileBatchCommunicator , func ()) {
41- t .Helper ()
40+ simulateQueryTerminated := func (t * testing.T , errBeforePipeClose , errAfterPipeClose error ) {
41+ readError := func (t * testing.T , r io.Reader , expectedErr error ) {
42+ if expectedErr == nil {
43+ return // expectedErr == nil means this read should be skipped
44+ }
45+ n , err := r .Read (make ([]byte , 100 ))
46+ assert .Zero (t , n )
47+ assert .ErrorIs (t , err , expectedErr )
48+ }
49+
4250 batch , err := NewBatch (t .Context (), filepath .Join (testReposDir , "repo1_bare" ))
4351 require .NoError (t , err )
44- _ , _ = batch .QueryInfo ("e2129701f1a4d54dc44f03c93bca0a2aec7c5449" )
45- var c * catFileBatchCommunicator
52+ _ , err = batch .QueryInfo ("e2129701f1a4d54dc44f03c93bca0a2aec7c5449" )
53+ require .NoError (t , err )
54+
55+ var batchComm * catFileBatchCommunicator
4656 switch b := batch .(type ) {
4757 case * catFileBatchLegacy :
48- c = b .batchCheck
49- _ , _ = c .reqWriter .Write ([]byte ("in-complete-line-" ))
58+ batchComm = b .batchCheck
59+ _ , _ = batchComm .reqWriter .Write ([]byte ("in-complete-line-" ))
5060 case * catFileBatchCommand :
51- c = b .batch
52- _ , _ = c .reqWriter .Write ([]byte ("info" ))
61+ batchComm = b .batch
62+ _ , _ = batchComm .reqWriter .Write ([]byte ("info" ))
5363 default :
5464 t .FailNow ()
5565 }
56- return c , func () { batch .Close () }
57- }
66+ defer batchComm .Close ()
67+
68+ require .True (t , (errBeforePipeClose != nil ) != (errAfterPipeClose != nil ), "must set exactly one of the expected errors" )
5869
70+ inceptor := batchComm .debugKill ()
71+ <- inceptor .beforeClose // wait for the command's Close to be called, the pipe is not closed yet
72+ readError (t , batchComm .respReader , errBeforePipeClose ) // then caller will read on an open pipe which will be closed soon
73+ close (inceptor .blockClose ) // continue to close the pipe
74+ <- inceptor .afterClose // wait for the pipe to be closed
75+ readError (t , batchComm .respReader , errAfterPipeClose ) // then caller will read on a closed pipe
76+ }
5977 t .Run ("QueryTerminated" , func (t * testing.T ) {
6078 t .Run ("PipeClosedBeforeRead" , func (t * testing.T ) {
61- closed := make (chan struct {})
62- hook := func (doClose func ()) { doClose (); close (closed ) }
63- c , cleanup := setupTerminatedBatch (t )
64- defer cleanup ()
65- catFileBatchDebugPipeClose .Store (& hook )
66- defer catFileBatchDebugPipeClose .Store (nil )
67- c .debugGitCmd .DebugKill ()
68- <- closed
69- n , err := c .respReader .Read (make ([]byte , 100 ))
70- assert .Zero (t , n )
71- assert .ErrorIs (t , err , os .ErrClosed )
79+ simulateQueryTerminated (t , io .EOF , nil )
7280 })
7381 t .Run ("ReadBeforePipeClose" , func (t * testing.T ) {
74- ready := make (chan struct {})
75- proceed := make (chan struct {})
76- hook := func (doClose func ()) { close (ready ); <- proceed ; doClose () }
77- c , cleanup := setupTerminatedBatch (t )
78- defer cleanup ()
79- catFileBatchDebugPipeClose .Store (& hook )
80- defer catFileBatchDebugPipeClose .Store (nil )
81- c .debugGitCmd .DebugKill ()
82- <- ready
83- n , err := c .respReader .Read (make ([]byte , 100 ))
84- assert .Zero (t , n )
85- assert .ErrorIs (t , err , io .EOF )
86- close (proceed )
82+ simulateQueryTerminated (t , nil , os .ErrClosed )
8783 })
8884 })
8985
0 commit comments