|
- /*
- *
- * Copyright 2018 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
- package testutils_test
-
- import (
- "testing"
- "time"
-
- "google.golang.org/grpc/internal/testutils"
- )
-
- func TestPipeListener(t *testing.T) {
- pl := testutils.NewPipeListener()
- recvdBytes := make(chan []byte)
- const want = "hello world"
-
- go func() {
- c, err := pl.Accept()
- if err != nil {
- t.Error(err)
- }
-
- read := make([]byte, len(want))
- _, err = c.Read(read)
- if err != nil {
- t.Error(err)
- }
- recvdBytes <- read
- }()
-
- dl := pl.Dialer()
- conn, err := dl("", time.Duration(0))
- if err != nil {
- t.Fatal(err)
- }
-
- _, err = conn.Write([]byte(want))
- if err != nil {
- t.Fatal(err)
- }
-
- select {
- case gotBytes := <-recvdBytes:
- got := string(gotBytes)
- if got != want {
- t.Fatalf("expected to get %s, got %s", got, want)
- }
- case <-time.After(100 * time.Millisecond):
- t.Fatal("timed out waiting for server to receive bytes")
- }
- }
-
- func TestUnblocking(t *testing.T) {
- for _, test := range []struct {
- desc string
- blockFuncShouldError bool
- blockFunc func(*testutils.PipeListener, chan struct{}) error
- unblockFunc func(*testutils.PipeListener) error
- }{
- {
- desc: "Accept unblocks Dial",
- blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error {
- dl := pl.Dialer()
- _, err := dl("", time.Duration(0))
- close(done)
- return err
- },
- unblockFunc: func(pl *testutils.PipeListener) error {
- _, err := pl.Accept()
- return err
- },
- },
- {
- desc: "Close unblocks Dial",
- blockFuncShouldError: true, // because pl.Close will be called
- blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error {
- dl := pl.Dialer()
- _, err := dl("", time.Duration(0))
- close(done)
- return err
- },
- unblockFunc: func(pl *testutils.PipeListener) error {
- return pl.Close()
- },
- },
- {
- desc: "Dial unblocks Accept",
- blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error {
- _, err := pl.Accept()
- close(done)
- return err
- },
- unblockFunc: func(pl *testutils.PipeListener) error {
- dl := pl.Dialer()
- _, err := dl("", time.Duration(0))
- return err
- },
- },
- {
- desc: "Close unblocks Accept",
- blockFuncShouldError: true, // because pl.Close will be called
- blockFunc: func(pl *testutils.PipeListener, done chan struct{}) error {
- _, err := pl.Accept()
- close(done)
- return err
- },
- unblockFunc: func(pl *testutils.PipeListener) error {
- return pl.Close()
- },
- },
- } {
- t.Log(test.desc)
- testUnblocking(t, test.blockFunc, test.unblockFunc, test.blockFuncShouldError)
- }
- }
-
- func testUnblocking(t *testing.T, blockFunc func(*testutils.PipeListener, chan struct{}) error, unblockFunc func(*testutils.PipeListener) error, blockFuncShouldError bool) {
- pl := testutils.NewPipeListener()
- dialFinished := make(chan struct{})
-
- go func() {
- err := blockFunc(pl, dialFinished)
- if blockFuncShouldError && err == nil {
- t.Error("expected blocking func to return error because pl.Close was called, but got nil")
- }
-
- if !blockFuncShouldError && err != nil {
- t.Error(err)
- }
- }()
-
- select {
- case <-dialFinished:
- t.Fatal("expected Dial to block until pl.Close or pl.Accept")
- default:
- }
-
- if err := unblockFunc(pl); err != nil {
- t.Fatal(err)
- }
-
- select {
- case <-dialFinished:
- case <-time.After(100 * time.Millisecond):
- t.Fatal("expected Accept to unblock after pl.Accept was called")
- }
- }
|