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

     1  package actor
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"testing"
     7  
     8  	core "github.com/awesome-flow/flow/pkg/corev1alpha1"
     9  	coretest "github.com/awesome-flow/flow/pkg/corev1alpha1/test"
    10  	"github.com/awesome-flow/flow/pkg/util"
    11  	testutil "github.com/awesome-flow/flow/pkg/util/test"
    12  	flowtest "github.com/awesome-flow/flow/pkg/util/test/corev1alpha1"
    13  )
    14  
    15  func TestNewCompressor(t *testing.T) {
    16  
    17  	var noopCoder = func(b []byte, l int) ([]byte, error) {
    18  		return b, nil
    19  	}
    20  
    21  	testCoders := map[string]CoderFunc{
    22  		"test-coder": noopCoder,
    23  	}
    24  
    25  	name := "test-compressor"
    26  
    27  	tests := []struct {
    28  		name     string
    29  		params   core.Params
    30  		experr   error
    31  		expcoder CoderFunc
    32  		explevel int
    33  	}{
    34  		{
    35  			name:   "missing compress config",
    36  			params: core.Params{},
    37  			experr: fmt.Errorf("compressor %q is missing `compress` config", name),
    38  		},
    39  		{
    40  			name: "unknown compress config",
    41  			params: core.Params{
    42  				"compress": "unknown-coder",
    43  			},
    44  			experr: fmt.Errorf("compressor %q: unknown compression algorithm %q", name, "unknown-coder"),
    45  		},
    46  		{
    47  			name: "no level provided",
    48  			params: core.Params{
    49  				"compress": "test-coder",
    50  			},
    51  			experr:   nil,
    52  			expcoder: noopCoder,
    53  			explevel: -1,
    54  		},
    55  		{
    56  			name: "level provided",
    57  			params: core.Params{
    58  				"compress": "test-coder",
    59  				"level":    42,
    60  			},
    61  			experr:   nil,
    62  			expcoder: noopCoder,
    63  			explevel: 42,
    64  		},
    65  		{
    66  			name: "malformed level provided",
    67  			params: core.Params{
    68  				"compress": "test-coder",
    69  				"level":    "asdf",
    70  			},
    71  			experr: fmt.Errorf("compressor %q: malformed compression level provided: got: %+v, want: an integer", name, "asdf"),
    72  		},
    73  	}
    74  
    75  	t.Parallel()
    76  
    77  	for _, testCase := range tests {
    78  		t.Run(testCase.name, func(t *testing.T) {
    79  			ctx, err := coretest.NewContextWithConfig(map[string]interface{}{})
    80  			if err != nil {
    81  				t.Fatalf("failed to create a context: %s", err)
    82  			}
    83  
    84  			if err := ctx.Start(); err != nil {
    85  				t.Fatalf("failed to start context: %s", err)
    86  			}
    87  			defer ctx.Stop()
    88  
    89  			compressor, err := NewCompressorWithCoders(name, ctx, testCase.params, testCoders)
    90  			if !coretest.EqErr(err, testCase.experr) {
    91  				t.Fatalf("unexpected error: got: %q, want: %q", err, testCase.experr)
    92  			}
    93  			if err != nil {
    94  				return
    95  			}
    96  
    97  			// functions are not addressable in Go, and this
    98  			// comparison is a super dummy way of getting func
    99  			// addresses. Better than nothing.
   100  			if fmt.Sprintf("%+v", compressor.(*Compressor).coder) != fmt.Sprintf("%+v", testCase.expcoder) {
   101  				t.Fatalf("unpexpected coder selected: got: %+v, want: %+v", compressor.(*Compressor).coder, testCase.expcoder)
   102  			}
   103  			if compressor.(*Compressor).level != testCase.explevel {
   104  				t.Fatalf("unexpected compression level: got: %d, want: %d", compressor.(*Compressor).level, testCase.explevel)
   105  			}
   106  		})
   107  	}
   108  }
   109  
   110  func TestCompressorReceive(t *testing.T) {
   111  	var workingCoder = func(b []byte, l int) ([]byte, error) {
   112  		return b, nil
   113  	}
   114  
   115  	var brokenCoder = func(b []byte, l int) ([]byte, error) {
   116  		return nil, fmt.Errorf("failed to encode")
   117  	}
   118  
   119  	testCoders := map[string]CoderFunc{
   120  		"working-coder": workingCoder,
   121  		"broken-coder":  brokenCoder,
   122  	}
   123  
   124  	name := "test-compressor"
   125  
   126  	tests := []struct {
   127  		name      string
   128  		codername string
   129  		experr    error
   130  		expstatus core.MsgStatus
   131  	}{
   132  		{
   133  			name:      "working coder",
   134  			codername: "working-coder",
   135  			experr:    nil,
   136  			expstatus: core.MsgStatusDone,
   137  		},
   138  		{
   139  			name:      "broken coder",
   140  			codername: "broken-coder",
   141  			experr:    fmt.Errorf("failed to encode"),
   142  		},
   143  	}
   144  
   145  	for _, testCase := range tests {
   146  		t.Run(testCase.name, func(t *testing.T) {
   147  			ctx, err := coretest.NewContextWithConfig(map[string]interface{}{
   148  				"system.maxprocs": rand.Intn(4) + 1,
   149  			})
   150  			if err != nil {
   151  				t.Fatalf("failed to create a context: %s", err)
   152  			}
   153  
   154  			if err := ctx.Start(); err != nil {
   155  				t.Fatalf("failed to start context: %s", err)
   156  			}
   157  
   158  			params := core.Params{
   159  				"compress": testCase.codername,
   160  			}
   161  
   162  			compressor, err := NewCompressorWithCoders(name, ctx, params, testCoders)
   163  
   164  			act, err := flowtest.NewTestActor("test-actor", ctx, core.Params{})
   165  			if err != nil {
   166  				t.Fatalf("failed to initialize test actor: %s", err)
   167  			}
   168  
   169  			act.(*flowtest.TestActor).OnReceive(func(msg *core.Message) {
   170  				msg.Complete(core.MsgStatusDone)
   171  				act.(*flowtest.TestActor).Flush()
   172  			})
   173  
   174  			if err := compressor.Connect(rand.Intn(4)+1, act); err != nil {
   175  				t.Fatalf("failed to connect compressor and test actor: %s", err)
   176  			}
   177  
   178  			if err := util.ExecEnsure(
   179  				act.Start,
   180  				compressor.Start,
   181  			); err != nil {
   182  				t.Fatalf("failed to start actors: %s", err)
   183  			}
   184  			defer util.ExecEnsure(
   185  				compressor.Stop,
   186  				act.Stop,
   187  			)
   188  
   189  			msg := core.NewMessage(testutil.RandBytes(1024))
   190  			err = compressor.Receive(msg)
   191  			if !eqErr(err, testCase.experr) {
   192  				t.Fatalf("unexpected error: got: %s, want: %s", err, testCase.experr)
   193  			}
   194  
   195  			if err != nil {
   196  				return
   197  			}
   198  
   199  			if s := msg.Await(); s != testCase.expstatus {
   200  				t.Fatalf("unexpected message status: got: %d, want: %d", s, testCase.expstatus)
   201  			}
   202  		})
   203  	}
   204  }