github.com/Jeffail/benthos/v3@v3.65.0/lib/processor/protobuf_test.go (about) 1 package processor 2 3 import ( 4 "testing" 5 6 "github.com/Jeffail/benthos/v3/lib/log" 7 "github.com/Jeffail/benthos/v3/lib/message" 8 "github.com/Jeffail/benthos/v3/lib/metrics" 9 "github.com/Jeffail/benthos/v3/lib/types" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestProtobuf(t *testing.T) { 15 type testCase struct { 16 name string 17 operator string 18 message string 19 importPath string 20 input [][]byte 21 output [][]byte 22 } 23 24 tests := []testCase{ 25 { 26 name: "json to protobuf", 27 operator: "from_json", 28 message: "testing.Person", 29 importPath: "../../config/test/protobuf/schema", 30 input: [][]byte{ 31 []byte(`{"firstName":"john","lastName":"oates","age":10}`), 32 []byte(`{"firstName":"daryl","lastName":"hall"}`), 33 []byte(`{"firstName":"caleb","lastName":"quaye","email":"caleb@myspace.com"}`), 34 }, 35 output: [][]byte{ 36 {0x0a, 0x04, 0x6a, 0x6f, 0x68, 0x6e, 0x12, 0x05, 0x6f, 0x61, 0x74, 0x65, 0x73, 0x20, 0x0a}, 37 {0x0a, 0x05, 0x64, 0x61, 0x72, 0x79, 0x6c, 0x12, 0x04, 0x68, 0x61, 0x6c, 0x6c}, 38 { 39 0x0a, 0x05, 0x63, 0x61, 0x6c, 0x65, 0x62, 0x12, 0x05, 0x71, 0x75, 0x61, 0x79, 0x65, 0x32, 0x11, 40 0x63, 0x61, 0x6c, 0x65, 0x62, 0x40, 0x6d, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x63, 0x6f, 41 0x6d, 42 }, 43 }, 44 }, 45 { 46 name: "protobuf to json", 47 operator: "to_json", 48 message: "testing.Person", 49 importPath: "../../config/test/protobuf/schema", 50 input: [][]byte{ 51 {0x0a, 0x04, 0x6a, 0x6f, 0x68, 0x6e, 0x12, 0x05, 0x6f, 0x61, 0x74, 0x65, 0x73, 0x20, 0x0a}, 52 {0x0a, 0x05, 0x64, 0x61, 0x72, 0x79, 0x6c, 0x12, 0x04, 0x68, 0x61, 0x6c, 0x6c}, 53 { 54 0x0a, 0x05, 0x63, 0x61, 0x6c, 0x65, 0x62, 0x12, 0x05, 0x71, 0x75, 0x61, 0x79, 0x65, 0x32, 0x11, 55 0x63, 0x61, 0x6c, 0x65, 0x62, 0x40, 0x6d, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x63, 0x6f, 56 0x6d, 57 }, 58 }, 59 output: [][]byte{ 60 []byte(`{"firstName":"john","lastName":"oates","age":10}`), 61 []byte(`{"firstName":"daryl","lastName":"hall"}`), 62 []byte(`{"firstName":"caleb","lastName":"quaye","email":"caleb@myspace.com"}`), 63 }, 64 }, 65 { 66 name: "any: json to protobuf", 67 operator: "from_json", 68 message: "testing.Envelope", 69 importPath: "../../config/test/protobuf/schema", 70 input: [][]byte{ 71 []byte(`{"id":747,"content":{"@type":"type.googleapis.com/testing.Person","first_name":"bob"}}`), 72 []byte(`{"id":747,"content":{"@type":"type.googleapis.com/testing.House","address":"123"}}`), 73 }, 74 output: [][]byte{ 75 { 76 0x8, 0xeb, 0x5, 0x12, 0x2b, 0xa, 0x22, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 77 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 78 0x67, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x5, 0xa, 0x3, 0x62, 0x6f, 0x62, 79 }, 80 { 81 0x8, 0xeb, 0x5, 0x12, 0x2a, 0xa, 0x21, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 82 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 83 0x67, 0x2e, 0x48, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x5, 0x12, 0x3, 0x31, 0x32, 0x33, 84 }, 85 }, 86 }, 87 { 88 name: "any: protobuf to json", 89 operator: "to_json", 90 message: "testing.Envelope", 91 importPath: "../../config/test/protobuf/schema", 92 input: [][]byte{ 93 { 94 0x8, 0xeb, 0x5, 0x12, 0x2b, 0xa, 0x22, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 95 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 96 0x67, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x5, 0xa, 0x3, 0x62, 0x6f, 0x62, 97 }, 98 { 99 0x8, 0xeb, 0x5, 0x12, 0x2a, 0xa, 0x21, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 100 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 101 0x67, 0x2e, 0x48, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x5, 0x12, 0x3, 0x31, 0x32, 0x33, 102 }, 103 }, 104 output: [][]byte{ 105 []byte(`{"id":747,"content":{"@type":"type.googleapis.com/testing.Person","firstName":"bob"}}`), 106 []byte(`{"id":747,"content":{"@type":"type.googleapis.com/testing.House","address":"123"}}`), 107 }, 108 }, 109 } 110 111 for _, test := range tests { 112 t.Run(test.name, func(tt *testing.T) { 113 conf := NewConfig() 114 conf.Type = TypeProtobuf 115 conf.Protobuf.Operator = test.operator 116 conf.Protobuf.Message = test.message 117 conf.Protobuf.ImportPaths = []string{test.importPath} 118 119 proc, err := New(conf, nil, log.Noop(), metrics.Noop()) 120 require.NoError(t, err) 121 122 input := message.New(nil) 123 for _, p := range test.input { 124 input.Append(message.NewPart(p)) 125 } 126 127 msgs, res := proc.ProcessMessage(input) 128 require.Nil(t, res) 129 require.Len(t, msgs, 1) 130 131 assert.Equal(t, message.GetAllBytes(msgs[0]), test.output) 132 msgs[0].Iter(func(i int, part types.Part) error { 133 if fail := part.Metadata().Get(FailFlagKey); len(fail) > 0 { 134 tt.Error(fail) 135 } 136 return nil 137 }) 138 }) 139 } 140 } 141 142 func TestProtobufErrors(t *testing.T) { 143 type testCase struct { 144 name string 145 operator string 146 message string 147 importPath string 148 input [][]byte 149 output []string 150 } 151 152 tests := []testCase{ 153 { 154 name: "json to protobuf", 155 operator: "from_json", 156 message: "testing.Person", 157 importPath: "../../config/test/protobuf/schema", 158 input: [][]byte{ 159 []byte(`{"firstName":"john","lastName":"oates","ageFoo":10}`), 160 []byte(`not valid json`), 161 []byte(`{"firstName":5,"lastName":"quaye","email":"caleb@myspace.com"}`), 162 }, 163 output: []string{ 164 `failed to unmarshal JSON message: message type testing.Person has no known field named ageFoo`, 165 `failed to unmarshal JSON message: invalid character 'o' in literal null (expecting 'u')`, 166 `failed to unmarshal JSON message: bad input: expecting string ; instead got 5`, 167 }, 168 }, 169 } 170 171 for _, test := range tests { 172 t.Run(test.name, func(tt *testing.T) { 173 conf := NewConfig() 174 conf.Type = TypeProtobuf 175 conf.Protobuf.Operator = test.operator 176 conf.Protobuf.Message = test.message 177 conf.Protobuf.ImportPaths = []string{test.importPath} 178 179 proc, err := New(conf, nil, log.Noop(), metrics.Noop()) 180 require.NoError(t, err) 181 182 input := message.New(nil) 183 for _, p := range test.input { 184 input.Append(message.NewPart(p)) 185 } 186 187 msgs, res := proc.ProcessMessage(input) 188 require.Nil(t, res) 189 require.Len(t, msgs, 1) 190 191 errs := make([]string, msgs[0].Len()) 192 msgs[0].Iter(func(i int, part types.Part) error { 193 errs[i] = part.Metadata().Get(FailFlagKey) 194 return nil 195 }) 196 197 assert.Equal(t, test.output, errs) 198 }) 199 } 200 }