github.com/awesome-flow/flow@v0.0.3-0.20190918184116-508d75d68a2c/pkg/corev1alpha1/actor/sink_test.go (about)

     1  package actor
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/awesome-flow/flow/pkg/cfg"
    11  	core "github.com/awesome-flow/flow/pkg/corev1alpha1"
    12  	coretest "github.com/awesome-flow/flow/pkg/corev1alpha1/test"
    13  	testutil "github.com/awesome-flow/flow/pkg/util/test"
    14  )
    15  
    16  func TestSinkDoConnectHead(t *testing.T) {
    17  	ctx, err := coretest.NewContextWithConfig(map[string]interface{}{})
    18  	if err != nil {
    19  		t.Fatalf("failed to initialise context: %s", err)
    20  	}
    21  	if err := ctx.Start(); err != nil {
    22  		t.Fatalf("failed to start context: %s", err)
    23  	}
    24  	// addresses don't really matter
    25  	conn := newTestConn(
    26  		newTestAddr("tcp", "127.0.0.1:12345"),
    27  		newTestAddr("tcp", "127.0.0.1:23456"),
    28  	)
    29  	// connection builder fails once to exercise the retry mecahnism
    30  	failonce := 0
    31  	builder := func(addr *net.TCPAddr, timeout time.Duration) (net.Conn, error) {
    32  		if failonce > 0 {
    33  			return conn, nil
    34  		}
    35  		failonce++
    36  		return nil, fmt.Errorf("expected failure")
    37  	}
    38  	// this address would be a subject of a tcp host lookup, so keep it real
    39  	sink, err := NewSink("sink", ctx, core.Params{
    40  		"bind": "tcp://127.0.0.1:12345",
    41  	})
    42  	if err != nil {
    43  		t.Fatalf("failed to initialize sink: %s", err)
    44  	}
    45  	sink.(*Sink).head.(*SinkHeadTCP).connbuilder = builder
    46  	notify := make(chan struct{})
    47  	if wantnil := sink.(*Sink).head.(*SinkHeadTCP).conn; wantnil != nil {
    48  		t.Fatalf("unexpected connection value: got: %+v, want: nil", wantnil)
    49  
    50  	}
    51  	if err := sink.(*Sink).doConnectHead(notify); err != nil {
    52  		t.Fatalf("failed to connect sink head: %s", err)
    53  	}
    54  	<-notify
    55  	gotconn := sink.(*Sink).head.(*SinkHeadTCP).conn
    56  	if !reflect.DeepEqual(conn, gotconn) {
    57  		t.Fatalf("unexpected connection object: got: %+v, want: %+v", gotconn, conn)
    58  	}
    59  }
    60  
    61  func TestSinkStartStop(t *testing.T) {
    62  	ctx, err := coretest.NewContextWithConfig(map[string]interface{}{
    63  		cfg.SystemMaxprocs: 4,
    64  	})
    65  	if err != nil {
    66  		t.Fatalf("failed to initialise context: %s", err)
    67  	}
    68  	if err := ctx.Start(); err != nil {
    69  		t.Fatalf("failed to start context: %s", err)
    70  	}
    71  	// addresses don't really matter
    72  	conn := newTestConn(
    73  		newTestAddr("tcp", "127.0.0.1:12345"),
    74  		newTestAddr("tcp", "127.0.0.1:23456"),
    75  	)
    76  	// connection builder fails once to exercise the retry mecahnism
    77  	failonce := 0
    78  	builder := func(addr *net.TCPAddr, timeout time.Duration) (net.Conn, error) {
    79  		if failonce > 0 {
    80  			return conn, nil
    81  		}
    82  		failonce++
    83  		return nil, fmt.Errorf("expected failure")
    84  	}
    85  	// this address would be a subject of a tcp host lookup, so keep it real
    86  	sink, err := NewSink("sink", ctx, core.Params{
    87  		"bind": "tcp://127.0.0.1:12345",
    88  	})
    89  	if err != nil {
    90  		t.Fatalf("failed to initialize sink: %s", err)
    91  	}
    92  	sink.(*Sink).head.(*SinkHeadTCP).connbuilder = builder
    93  	if err := sink.Start(); err != nil {
    94  		t.Fatalf("failed to start sink: %s", err)
    95  	}
    96  	if err := sink.Stop(); err != nil {
    97  		t.Fatalf("failed to stop sink: %s", err)
    98  	}
    99  }
   100  
   101  func TestSinkReceive(t *testing.T) {
   102  	ctx, err := coretest.NewContextWithConfig(map[string]interface{}{
   103  		cfg.SystemMaxprocs: 4,
   104  	})
   105  	if err != nil {
   106  		t.Fatalf("failed to initialise context: %s", err)
   107  	}
   108  	if err := ctx.Start(); err != nil {
   109  		t.Fatalf("failed to start context: %s", err)
   110  	}
   111  	// addresses don't really matter
   112  	conn := newTestConn(
   113  		newTestAddr("tcp", "127.0.0.1:12345"),
   114  		newTestAddr("tcp", "127.0.0.1:23456"),
   115  	)
   116  	builder := func(addr *net.TCPAddr, timeout time.Duration) (net.Conn, error) {
   117  		return conn, nil
   118  	}
   119  	// this address would be a subject of a tcp host lookup, so keep it real
   120  	sink, err := NewSink("sink", ctx, core.Params{
   121  		"bind": "tcp://127.0.0.1:12345",
   122  	})
   123  	if err != nil {
   124  		t.Fatalf("failed to initialize sink: %s", err)
   125  	}
   126  	sink.(*Sink).head.(*SinkHeadTCP).connbuilder = builder
   127  	if err := sink.Start(); err != nil {
   128  		t.Fatalf("failed to start sink: %s", err)
   129  	}
   130  	data := testutil.RandBytes(1024)
   131  	msg := core.NewMessage(data)
   132  	if err := sink.Receive(msg); err != nil {
   133  		t.Fatalf("failed to send message: %s", err)
   134  	}
   135  	s := msg.Await()
   136  	if s != core.MsgStatusDone {
   137  		t.Fatalf("unexpected message send status: got: %d, want: %d", s, core.MsgStatusDone)
   138  	}
   139  	wantdata := append(data, []byte("\r\n")...)
   140  	gotdata := conn.buf
   141  	if !reflect.DeepEqual(gotdata, wantdata) {
   142  		t.Fatalf("unexpected buf contents: got: %q, want: %q", gotdata, wantdata)
   143  	}
   144  }