github.com/hamba/avro/v2@v2.22.1-0.20240518180522-aff3955acf7d/protocol_test.go (about)

     1  package avro_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/hamba/avro/v2"
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestMustParseProtocol(t *testing.T) {
    12  	proto := avro.MustParseProtocol(`{"protocol":"test", "namespace": "org.hamba.avro", "doc": "docs"}`)
    13  
    14  	assert.IsType(t, &avro.Protocol{}, proto)
    15  }
    16  
    17  func TestMustParseProtocol_PanicsOnError(t *testing.T) {
    18  	assert.Panics(t, func() {
    19  		avro.MustParseProtocol("123")
    20  	})
    21  }
    22  
    23  func TestNewProtocol_ValidatesName(t *testing.T) {
    24  	_, err := avro.NewProtocol("0test", "", nil, nil)
    25  
    26  	assert.Error(t, err)
    27  }
    28  
    29  func TestNewMessage(t *testing.T) {
    30  	field, _ := avro.NewField("test", avro.NewPrimitiveSchema(avro.String, nil))
    31  	fields := []*avro.Field{field}
    32  	req, _ := avro.NewRecordSchema("test", "", fields)
    33  	resp := avro.NewPrimitiveSchema(avro.String, nil)
    34  	types := []avro.Schema{avro.NewPrimitiveSchema(avro.String, nil)}
    35  	errs, _ := avro.NewUnionSchema(types)
    36  
    37  	msg := avro.NewMessage(req, resp, errs, false)
    38  
    39  	assert.Equal(t, req, msg.Request())
    40  	assert.Equal(t, resp, msg.Response())
    41  	assert.Equal(t, errs, msg.Errors())
    42  	assert.False(t, msg.OneWay())
    43  }
    44  
    45  func TestParseProtocol(t *testing.T) {
    46  	tests := []struct {
    47  		name    string
    48  		schema  string
    49  		wantErr assert.ErrorAssertionFunc
    50  	}{
    51  		{
    52  			name:    "Valid",
    53  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "doc": "docs"}`,
    54  			wantErr: assert.NoError,
    55  		},
    56  		{
    57  			name:    "Invalid Json",
    58  			schema:  `{`,
    59  			wantErr: assert.Error,
    60  		},
    61  		{
    62  			name:    "Invalid Name First Char",
    63  			schema:  `{"protocol":"0test", "namespace": "org.hamba.avro"}`,
    64  			wantErr: assert.Error,
    65  		},
    66  		{
    67  			name:    "Invalid Name Other Char",
    68  			schema:  `{"protocol":"test+", "namespace": "org.hamba.avro"}`,
    69  			wantErr: assert.Error,
    70  		},
    71  		{
    72  			name:    "Empty Name",
    73  			schema:  `{"protocol":"", "namespace": "org.hamba.avro"}`,
    74  			wantErr: assert.Error,
    75  		},
    76  		{
    77  			name:    "No Name",
    78  			schema:  `{"namespace": "org.hamba.avro"}`,
    79  			wantErr: assert.Error,
    80  		},
    81  		{
    82  			name:    "Invalid Namespace",
    83  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro+"}`,
    84  			wantErr: assert.Error,
    85  		},
    86  		{
    87  			name:    "Empty Namespace",
    88  			schema:  `{"protocol":"test", "namespace": ""}`,
    89  			wantErr: assert.Error,
    90  		},
    91  		{
    92  			name:    "Invalid Type Schema",
    93  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "types":["test"]}`,
    94  			wantErr: assert.Error,
    95  		},
    96  		{
    97  			name:    "Type Not Named Schema",
    98  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "types":["string"]}`,
    99  			wantErr: assert.Error,
   100  		},
   101  		{
   102  			name:    "Message Not Object",
   103  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":["test"]}}`,
   104  			wantErr: assert.Error,
   105  		},
   106  		{
   107  			name:    "Message Request Invalid Request Json",
   108  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": "test"}}}`,
   109  			wantErr: assert.Error,
   110  		},
   111  		{
   112  			name:    "Message Request Invalid Field",
   113  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": [{"name": "foobar"}]}}}`,
   114  			wantErr: assert.Error,
   115  		},
   116  		{
   117  			name:    "Message Response Invalid Schema",
   118  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": [{"name": "foobar", "type": "string"}], "response": "test"}}}`,
   119  			wantErr: assert.Error,
   120  		},
   121  		{
   122  			name:    "Message Errors Invalid Schema",
   123  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": [{"name": "foobar", "type": "string"}], "errors": ["test"]}}}`,
   124  			wantErr: assert.Error,
   125  		},
   126  		{
   127  			name:    "Message Errors Record Not Error Schema",
   128  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": [{"name": "foobar", "type": "string"}], "errors": [{"type":"record", "name":"test", "fields":[{"name": "field", "type": "int"}]}]}}}`,
   129  			wantErr: assert.Error,
   130  		},
   131  		{
   132  			name:    "Message Errors Duplicate Schema",
   133  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": [{"name": "foobar", "type": "string"}], "errors": ["string"]}}}`,
   134  			wantErr: assert.Error,
   135  		},
   136  		{
   137  			name:    "Message One Way Invalid",
   138  			schema:  `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": [{"name": "foobar", "type": "string"}], "errors": ["int"], "one-way": true}}}`,
   139  			wantErr: assert.Error,
   140  		},
   141  	}
   142  
   143  	for _, test := range tests {
   144  		test := test
   145  		t.Run(test.name, func(t *testing.T) {
   146  			_, err := avro.ParseProtocol(test.schema)
   147  
   148  			test.wantErr(t, err)
   149  		})
   150  	}
   151  }
   152  
   153  func TestParseProtocol_DeterminesOneWayMessage(t *testing.T) {
   154  	schema := `{"protocol":"test", "namespace": "org.hamba.avro", "messages":{"test":{"request": [{"name": "foobar", "type": "string"}]}}}`
   155  
   156  	proto, err := avro.ParseProtocol(schema)
   157  
   158  	require.NoError(t, err)
   159  
   160  	msg := proto.Message("test")
   161  	require.NotNil(t, msg)
   162  	assert.True(t, msg.OneWay())
   163  }
   164  
   165  func TestParseProtocol_Docs(t *testing.T) {
   166  	schema := `{"protocol":"test", "doc": "foo", "messages":{"test":{"request": [{"name": "foobar", "type": "string"}], "doc": "bar"}}}`
   167  
   168  	proto, err := avro.ParseProtocol(schema)
   169  	require.NoError(t, err)
   170  
   171  	assert.Equal(t, "foo", proto.Doc())
   172  
   173  	msg := proto.Message("test")
   174  	require.NotNil(t, msg)
   175  	assert.Equal(t, "bar", msg.Doc())
   176  }
   177  
   178  func TestParseProtocolFile(t *testing.T) {
   179  	protocol, err := avro.ParseProtocolFile("testdata/echo.avpr")
   180  
   181  	want := `{"protocol":"Echo","namespace":"org.hamba.avro","types":[{"name":"org.hamba.avro.Ping","type":"record","fields":[{"name":"timestamp","type":"long"},{"name":"text","type":"string"}]},{"name":"org.hamba.avro.Pong","type":"record","fields":[{"name":"timestamp","type":"long"},{"name":"ping","type":"org.hamba.avro.Ping"}]},{"name":"org.hamba.avro.PongError","type":"error","fields":[{"name":"timestamp","type":"long"},{"name":"reason","type":"string"}]}],"messages":{"ping":{"request":[{"name":"ping","type":"org.hamba.avro.Ping"}],"response":"org.hamba.avro.Pong","errors":["org.hamba.avro.PongError"]}}}`
   182  	wantMD5 := "5bc594ae86fc8c209f553ce3bc4291a5"
   183  	require.NoError(t, err)
   184  	assert.Equal(t, want, protocol.String())
   185  	assert.Equal(t, wantMD5, protocol.Hash())
   186  }
   187  
   188  func TestParseProtocolFile_InvalidPath(t *testing.T) {
   189  	_, err := avro.ParseProtocolFile("test.avpr")
   190  
   191  	assert.Error(t, err)
   192  }
   193  
   194  func TestParseProtocol_Types(t *testing.T) {
   195  	protocol, err := avro.ParseProtocolFile("testdata/echo.avpr")
   196  
   197  	wantPing := `{"name":"org.hamba.avro.Ping","type":"record","fields":[{"name":"timestamp","type":"long"},{"name":"text","type":"string"}]}`
   198  	wantPong := `{"name":"org.hamba.avro.Pong","type":"record","fields":[{"name":"timestamp","type":"long"},{"name":"ping","type":"org.hamba.avro.Ping"}]}`
   199  	wantPongError := `{"name":"org.hamba.avro.PongError","type":"error","fields":[{"name":"timestamp","type":"long"},{"name":"reason","type":"string"}]}`
   200  	wantLen := 3
   201  	require.NoError(t, err)
   202  	assert.Equal(t, wantLen, len(protocol.Types()))
   203  	assert.Equal(t, wantPing, protocol.Types()[0].String())
   204  	assert.Equal(t, wantPong, protocol.Types()[1].String())
   205  	assert.Equal(t, wantPongError, protocol.Types()[2].String())
   206  }