google.golang.org/grpc@v1.62.1/internal/testutils/pipe_listener_test.go (about) 1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package testutils_test 20 21 import ( 22 "testing" 23 "time" 24 25 "google.golang.org/grpc/internal/grpctest" 26 "google.golang.org/grpc/internal/testutils" 27 ) 28 29 type s struct { 30 grpctest.Tester 31 } 32 33 func Test(t *testing.T) { 34 grpctest.RunSubTests(t, s{}) 35 } 36 37 func (s) TestPipeListener(t *testing.T) { 38 pl := testutils.NewPipeListener() 39 recvdBytes := make(chan []byte, 1) 40 const want = "hello world" 41 42 go func() { 43 c, err := pl.Accept() 44 if err != nil { 45 t.Error(err) 46 } 47 48 read := make([]byte, len(want)) 49 _, err = c.Read(read) 50 if err != nil { 51 t.Error(err) 52 } 53 recvdBytes <- read 54 }() 55 56 dl := pl.Dialer() 57 conn, err := dl("", time.Duration(0)) 58 if err != nil { 59 t.Fatal(err) 60 } 61 62 _, err = conn.Write([]byte(want)) 63 if err != nil { 64 t.Fatal(err) 65 } 66 67 select { 68 case gotBytes := <-recvdBytes: 69 got := string(gotBytes) 70 if got != want { 71 t.Fatalf("expected to get %s, got %s", got, want) 72 } 73 case <-time.After(100 * time.Millisecond): 74 t.Fatal("timed out waiting for server to receive bytes") 75 } 76 } 77 78 func (s) TestUnblocking(t *testing.T) { 79 for _, test := range []struct { 80 desc string 81 blockFuncShouldError bool 82 blockFunc func(*testutils.PipeListener, chan struct{}) error 83 unblockFunc func(*testutils.PipeListener) error 84 }{ 85 { 86 desc: "Accept unblocks Dial", 87 blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error { 88 dl := pl.Dialer() 89 _, err := dl("", time.Duration(0)) 90 close(done) 91 return err 92 }, 93 unblockFunc: func(pl *testutils.PipeListener) error { 94 _, err := pl.Accept() 95 return err 96 }, 97 }, 98 { 99 desc: "Close unblocks Dial", 100 blockFuncShouldError: true, // because pl.Close will be called 101 blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error { 102 dl := pl.Dialer() 103 _, err := dl("", time.Duration(0)) 104 close(done) 105 return err 106 }, 107 unblockFunc: func(pl *testutils.PipeListener) error { 108 return pl.Close() 109 }, 110 }, 111 { 112 desc: "Dial unblocks Accept", 113 blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error { 114 _, err := pl.Accept() 115 close(done) 116 return err 117 }, 118 unblockFunc: func(pl *testutils.PipeListener) error { 119 dl := pl.Dialer() 120 _, err := dl("", time.Duration(0)) 121 return err 122 }, 123 }, 124 { 125 desc: "Close unblocks Accept", 126 blockFuncShouldError: true, // because pl.Close will be called 127 blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error { 128 _, err := pl.Accept() 129 close(done) 130 return err 131 }, 132 unblockFunc: func(pl *testutils.PipeListener) error { 133 return pl.Close() 134 }, 135 }, 136 } { 137 t.Log(test.desc) 138 testUnblocking(t, test.blockFunc, test.unblockFunc, test.blockFuncShouldError) 139 } 140 } 141 142 func testUnblocking(t *testing.T, blockFunc func(*testutils.PipeListener, chan struct{}) error, unblockFunc func(*testutils.PipeListener) error, blockFuncShouldError bool) { 143 pl := testutils.NewPipeListener() 144 dialFinished := make(chan struct{}) 145 146 go func() { 147 err := blockFunc(pl, dialFinished) 148 if blockFuncShouldError && err == nil { 149 t.Error("expected blocking func to return error because pl.Close was called, but got nil") 150 } 151 152 if !blockFuncShouldError && err != nil { 153 t.Error(err) 154 } 155 }() 156 157 select { 158 case <-dialFinished: 159 t.Fatal("expected Dial to block until pl.Close or pl.Accept") 160 default: 161 } 162 163 if err := unblockFunc(pl); err != nil { 164 t.Fatal(err) 165 } 166 167 select { 168 case <-dialFinished: 169 case <-time.After(100 * time.Millisecond): 170 t.Fatal("expected Accept to unblock after pl.Accept was called") 171 } 172 }