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 }