github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/multiplexing/multiplexer_test.go (about)

     1  package multiplexing
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"sync"
     8  	"testing"
     9  
    10  	"golang.org/x/net/nettest"
    11  )
    12  
    13  // makeNetTestMakePipe constructs a nettest.MakePipe with a pair of multiplexers
    14  // operating in opener and acceptor roles.
    15  func makeNetTestMakePipe(opener, acceptor *Multiplexer) nettest.MakePipe {
    16  	return func() (c1, c2 net.Conn, stop func(), err error) {
    17  		var wait sync.WaitGroup
    18  		wait.Add(2)
    19  		var opened, accepted *Stream
    20  		var openErr, acceptErr error
    21  		go func() {
    22  			opened, openErr = opener.OpenStream(context.Background())
    23  			if openErr == ErrMultiplexerClosed {
    24  				if internalErr := opener.InternalError(); internalErr != nil {
    25  					openErr = fmt.Errorf("multiplexer closed due to internal error: %w", internalErr)
    26  				}
    27  			}
    28  			wait.Done()
    29  		}()
    30  		go func() {
    31  			accepted, acceptErr = acceptor.AcceptStream(context.Background())
    32  			if acceptErr == ErrMultiplexerClosed {
    33  				if internalErr := acceptor.InternalError(); internalErr != nil {
    34  					acceptErr = fmt.Errorf("multiplexer closed due to internal error: %w", internalErr)
    35  				}
    36  			}
    37  			wait.Done()
    38  		}()
    39  		wait.Wait()
    40  		if openErr != nil || acceptErr != nil {
    41  			if opened != nil {
    42  				opened.Close()
    43  			}
    44  			if accepted != nil {
    45  				accepted.Close()
    46  			}
    47  			if openErr != nil {
    48  				err = openErr
    49  			} else if acceptErr != nil {
    50  				err = acceptErr
    51  			}
    52  			stop = func() {}
    53  		} else {
    54  			c1 = opened
    55  			c2 = accepted
    56  			stop = func() {
    57  				opened.Close()
    58  				accepted.Close()
    59  			}
    60  		}
    61  		return
    62  	}
    63  }
    64  
    65  // TestMultiplexer tests Multiplexer.
    66  func TestMultiplexer(t *testing.T) {
    67  	// Create an in-memory pipe to multiplex.
    68  	p1, p2 := net.Pipe()
    69  
    70  	// Adapt the connections to serve as carriers.
    71  	p1Carrier := NewCarrierFromStream(p1)
    72  	p2Carrier := NewCarrierFromStream(p2)
    73  
    74  	// Perform multiplexing.
    75  	p1Mux := Multiplex(p1Carrier, false, nil)
    76  	p2Mux := Multiplex(p2Carrier, true, nil)
    77  
    78  	// Defer multiplexer shutdown.
    79  	defer func() {
    80  		p1Mux.Close()
    81  		p2Mux.Close()
    82  	}()
    83  
    84  	// Run tests from p1 to p2.
    85  	nettest.TestConn(t, makeNetTestMakePipe(p1Mux, p2Mux))
    86  
    87  	// Run tests from p2 to p1.
    88  	nettest.TestConn(t, makeNetTestMakePipe(p2Mux, p1Mux))
    89  }