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  }