github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/message/event_test.go (about)

     1  // Copyright 2020 DataStax
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package message
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"net"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  
    25  	"github.com/datastax/go-cassandra-native-protocol/primitive"
    26  )
    27  
    28  func TestSchemaChangeEvent_DeepCopy(t *testing.T) {
    29  	msg := &SchemaChangeEvent{
    30  		ChangeType: primitive.SchemaChangeTypeCreated,
    31  		Target:     primitive.SchemaChangeTargetAggregate,
    32  		Keyspace:   "ks1",
    33  		Object:     "aggregate",
    34  		Arguments:  []string{"arg1"},
    35  	}
    36  
    37  	cloned := msg.DeepCopy()
    38  	assert.Equal(t, msg, cloned)
    39  
    40  	cloned.ChangeType = primitive.SchemaChangeTypeDropped
    41  	cloned.Target = primitive.SchemaChangeTargetFunction
    42  	cloned.Keyspace = "ks2"
    43  	cloned.Object = "function"
    44  	cloned.Arguments = []string{"arg2"}
    45  
    46  	assert.Equal(t, primitive.SchemaChangeTypeCreated, msg.ChangeType)
    47  	assert.Equal(t, primitive.SchemaChangeTargetAggregate, msg.Target)
    48  	assert.Equal(t, "ks1", msg.Keyspace)
    49  	assert.Equal(t, "aggregate", msg.Object)
    50  	assert.Equal(t, []string{"arg1"}, msg.Arguments)
    51  
    52  	assert.Equal(t, primitive.SchemaChangeTypeDropped, cloned.ChangeType)
    53  	assert.Equal(t, primitive.SchemaChangeTargetFunction, cloned.Target)
    54  	assert.Equal(t, "ks2", cloned.Keyspace)
    55  	assert.Equal(t, "function", cloned.Object)
    56  	assert.Equal(t, []string{"arg2"}, cloned.Arguments)
    57  }
    58  
    59  func TestStatusChangeEvent_DeepCopy(t *testing.T) {
    60  	msg := &StatusChangeEvent{
    61  		ChangeType: primitive.StatusChangeTypeDown,
    62  		Address: &primitive.Inet{
    63  			Addr: net.IP{0x01},
    64  			Port: 80,
    65  		},
    66  	}
    67  
    68  	cloned := msg.DeepCopy()
    69  	assert.Equal(t, msg, cloned)
    70  
    71  	cloned.ChangeType = primitive.StatusChangeTypeUp
    72  	cloned.Address = &primitive.Inet{
    73  		Addr: net.IP{0x02},
    74  		Port: 801,
    75  	}
    76  
    77  	assert.Equal(t, primitive.StatusChangeTypeDown, msg.ChangeType)
    78  	assert.Equal(t, net.IP{0x01}, msg.Address.Addr)
    79  	assert.EqualValues(t, 80, msg.Address.Port)
    80  
    81  	assert.Equal(t, primitive.StatusChangeTypeUp, cloned.ChangeType)
    82  	assert.Equal(t, net.IP{0x02}, cloned.Address.Addr)
    83  	assert.EqualValues(t, 801, cloned.Address.Port)
    84  }
    85  
    86  func TestTopologyChangeEvent_DeepCopy(t *testing.T) {
    87  	msg := &TopologyChangeEvent{
    88  		ChangeType: primitive.TopologyChangeTypeNewNode,
    89  		Address: &primitive.Inet{
    90  			Addr: net.IP{0x01},
    91  			Port: 80,
    92  		},
    93  	}
    94  
    95  	cloned := msg.DeepCopy()
    96  	assert.Equal(t, msg, cloned)
    97  
    98  	cloned.ChangeType = primitive.TopologyChangeTypeRemovedNode
    99  	cloned.Address = &primitive.Inet{
   100  		Addr: net.IP{0x02},
   101  		Port: 801,
   102  	}
   103  
   104  	assert.Equal(t, primitive.TopologyChangeTypeNewNode, msg.ChangeType)
   105  	assert.Equal(t, net.IP{0x01}, msg.Address.Addr)
   106  	assert.EqualValues(t, 80, msg.Address.Port)
   107  
   108  	assert.Equal(t, primitive.TopologyChangeTypeRemovedNode, cloned.ChangeType)
   109  	assert.Equal(t, net.IP{0x02}, cloned.Address.Addr)
   110  	assert.EqualValues(t, 801, cloned.Address.Port)
   111  }
   112  
   113  func TestEventCodec_Encode(test *testing.T) {
   114  	codec := &eventCodec{}
   115  	// version = 2
   116  	test.Run(primitive.ProtocolVersion2.String(), func(test *testing.T) {
   117  		tests := []encodeTestCase{
   118  			{
   119  				"schema change event keyspace",
   120  				&SchemaChangeEvent{
   121  					ChangeType: primitive.SchemaChangeTypeCreated,
   122  					Target:     primitive.SchemaChangeTargetKeyspace,
   123  					Keyspace:   "ks1",
   124  				},
   125  				[]byte{
   126  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   127  					0, 7, C, R, E, A, T, E, D,
   128  					0, 3, k, s, _1,
   129  					0, 0,
   130  				},
   131  				nil,
   132  			},
   133  			{
   134  				"schema change event table",
   135  				&SchemaChangeEvent{
   136  					ChangeType: primitive.SchemaChangeTypeCreated,
   137  					Target:     primitive.SchemaChangeTargetTable,
   138  					Keyspace:   "ks1",
   139  					Object:     "table1",
   140  				},
   141  				[]byte{
   142  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   143  					0, 7, C, R, E, A, T, E, D,
   144  					0, 3, k, s, _1,
   145  					0, 6, t, a, b, l, e, _1,
   146  				},
   147  				nil,
   148  			},
   149  			{
   150  				"schema change result type",
   151  				&SchemaChangeEvent{
   152  					ChangeType: primitive.SchemaChangeTypeCreated,
   153  					Target:     primitive.SchemaChangeTargetType,
   154  					Keyspace:   "ks1",
   155  					Object:     "udt1",
   156  				},
   157  				[]byte{
   158  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   159  					0, 7, C, R, E, A, T, E, D,
   160  				},
   161  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion2, primitive.SchemaChangeTargetType),
   162  			},
   163  			{
   164  				"schema change result function",
   165  				&SchemaChangeEvent{
   166  					ChangeType: primitive.SchemaChangeTypeCreated,
   167  					Target:     primitive.SchemaChangeTargetFunction,
   168  					Keyspace:   "ks1",
   169  					Object:     "func1",
   170  					Arguments:  []string{"int", "varchar"},
   171  				},
   172  				[]byte{
   173  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   174  					0, 7, C, R, E, A, T, E, D,
   175  				},
   176  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion2, primitive.SchemaChangeTargetFunction),
   177  			},
   178  			{
   179  				"schema change result aggregate",
   180  				&SchemaChangeEvent{
   181  					ChangeType: primitive.SchemaChangeTypeCreated,
   182  					Target:     primitive.SchemaChangeTargetAggregate,
   183  					Keyspace:   "ks1",
   184  					Object:     "agg1",
   185  					Arguments:  []string{"int", "varchar"},
   186  				},
   187  				[]byte{
   188  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   189  					0, 7, C, R, E, A, T, E, D,
   190  				},
   191  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion2, primitive.SchemaChangeTargetAggregate),
   192  			},
   193  			{
   194  				"status change event",
   195  				&StatusChangeEvent{
   196  					ChangeType: primitive.StatusChangeTypeUp,
   197  					Address: &primitive.Inet{
   198  						Addr: net.IPv4(192, 168, 1, 1),
   199  						Port: 9042,
   200  					},
   201  				},
   202  				[]byte{
   203  					0, 13, S, T, A, T, U, S, __, C, H, A, N, G, E,
   204  					0, 2, U, P,
   205  					4, 192, 168, 1, 1,
   206  					0, 0, 0x23, 0x52,
   207  				},
   208  				nil,
   209  			},
   210  			{
   211  				"topology change event",
   212  				&TopologyChangeEvent{
   213  					ChangeType: primitive.TopologyChangeTypeNewNode,
   214  					Address: &primitive.Inet{
   215  						Addr: net.IPv4(192, 168, 1, 1),
   216  						Port: 9042,
   217  					},
   218  				},
   219  				[]byte{
   220  					0, 15, T, O, P, O, L, O, G, Y, __, C, H, A, N, G, E,
   221  					0, 8, N, E, W, __, N, O, D, E,
   222  					4, 192, 168, 1, 1,
   223  					0, 0, 0x23, 0x52,
   224  				},
   225  				nil,
   226  			},
   227  		}
   228  		for _, tt := range tests {
   229  			test.Run(tt.name, func(t *testing.T) {
   230  				dest := &bytes.Buffer{}
   231  				err := codec.Encode(tt.input, dest, primitive.ProtocolVersion2)
   232  				assert.Equal(t, tt.expected, dest.Bytes())
   233  				assert.Equal(t, tt.err, err)
   234  			})
   235  		}
   236  	})
   237  	// version = 3
   238  	test.Run(primitive.ProtocolVersion3.String(), func(test *testing.T) {
   239  		tests := []encodeTestCase{
   240  			{
   241  				"schema change event keyspace",
   242  				&SchemaChangeEvent{
   243  					ChangeType: primitive.SchemaChangeTypeCreated,
   244  					Target:     primitive.SchemaChangeTargetKeyspace,
   245  					Keyspace:   "ks1",
   246  				},
   247  				[]byte{
   248  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   249  					0, 7, C, R, E, A, T, E, D,
   250  					0, 8, K, E, Y, S, P, A, C, E,
   251  					0, 3, k, s, _1,
   252  				},
   253  				nil,
   254  			},
   255  			{
   256  				"schema change event table",
   257  				&SchemaChangeEvent{
   258  					ChangeType: primitive.SchemaChangeTypeCreated,
   259  					Target:     primitive.SchemaChangeTargetTable,
   260  					Keyspace:   "ks1",
   261  					Object:     "table1",
   262  				},
   263  				[]byte{
   264  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   265  					0, 7, C, R, E, A, T, E, D,
   266  					0, 5, T, A, B, L, E,
   267  					0, 3, k, s, _1,
   268  					0, 6, t, a, b, l, e, _1,
   269  				},
   270  				nil,
   271  			},
   272  			{
   273  				"schema change event type",
   274  				&SchemaChangeEvent{
   275  					ChangeType: primitive.SchemaChangeTypeCreated,
   276  					Target:     primitive.SchemaChangeTargetType,
   277  					Keyspace:   "ks1",
   278  					Object:     "udt1",
   279  				},
   280  				[]byte{
   281  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   282  					0, 7, C, R, E, A, T, E, D,
   283  					0, 4, T, Y, P, E,
   284  					0, 3, k, s, _1,
   285  					0, 4, u, d, t, _1,
   286  				},
   287  				nil,
   288  			},
   289  			{
   290  				"schema change event function",
   291  				&SchemaChangeEvent{
   292  					ChangeType: primitive.SchemaChangeTypeCreated,
   293  					Target:     primitive.SchemaChangeTargetFunction,
   294  					Keyspace:   "ks1",
   295  					Object:     "func1",
   296  					Arguments:  []string{"int", "varchar"},
   297  				},
   298  				[]byte{
   299  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   300  					0, 7, C, R, E, A, T, E, D,
   301  				},
   302  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion3, primitive.SchemaChangeTargetFunction),
   303  			},
   304  			{
   305  				"schema change event aggregate",
   306  				&SchemaChangeEvent{
   307  					ChangeType: primitive.SchemaChangeTypeCreated,
   308  					Target:     primitive.SchemaChangeTargetAggregate,
   309  					Keyspace:   "ks1",
   310  					Object:     "agg1",
   311  					Arguments:  []string{"int", "varchar"},
   312  				},
   313  				[]byte{
   314  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   315  					0, 7, C, R, E, A, T, E, D,
   316  				},
   317  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion3, primitive.SchemaChangeTargetAggregate),
   318  			},
   319  			{
   320  				"status change event",
   321  				&StatusChangeEvent{
   322  					ChangeType: primitive.StatusChangeTypeUp,
   323  					Address: &primitive.Inet{
   324  						Addr: net.IPv4(192, 168, 1, 1),
   325  						Port: 9042,
   326  					},
   327  				},
   328  				[]byte{
   329  					0, 13, S, T, A, T, U, S, __, C, H, A, N, G, E,
   330  					0, 2, U, P,
   331  					4, 192, 168, 1, 1,
   332  					0, 0, 0x23, 0x52,
   333  				},
   334  				nil,
   335  			},
   336  			{
   337  				"topology change event",
   338  				&TopologyChangeEvent{
   339  					ChangeType: primitive.TopologyChangeTypeNewNode,
   340  					Address: &primitive.Inet{
   341  						Addr: net.IPv4(192, 168, 1, 1),
   342  						Port: 9042,
   343  					},
   344  				},
   345  				[]byte{
   346  					0, 15, T, O, P, O, L, O, G, Y, __, C, H, A, N, G, E,
   347  					0, 8, N, E, W, __, N, O, D, E,
   348  					4, 192, 168, 1, 1,
   349  					0, 0, 0x23, 0x52,
   350  				},
   351  				nil,
   352  			},
   353  		}
   354  		for _, tt := range tests {
   355  			test.Run(tt.name, func(t *testing.T) {
   356  				dest := &bytes.Buffer{}
   357  				err := codec.Encode(tt.input, dest, primitive.ProtocolVersion3)
   358  				assert.Equal(t, tt.expected, dest.Bytes())
   359  				assert.Equal(t, tt.err, err)
   360  			})
   361  		}
   362  	})
   363  	// versions >= 4
   364  	for _, version := range primitive.SupportedProtocolVersionsGreaterThanOrEqualTo(primitive.ProtocolVersion4) {
   365  		test.Run(version.String(), func(test *testing.T) {
   366  			tests := []encodeTestCase{
   367  				{
   368  					"schema change event keyspace",
   369  					&SchemaChangeEvent{
   370  						ChangeType: primitive.SchemaChangeTypeCreated,
   371  						Target:     primitive.SchemaChangeTargetKeyspace,
   372  						Keyspace:   "ks1",
   373  					},
   374  					[]byte{
   375  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   376  						0, 7, C, R, E, A, T, E, D,
   377  						0, 8, K, E, Y, S, P, A, C, E,
   378  						0, 3, k, s, _1,
   379  					},
   380  					nil,
   381  				},
   382  				{
   383  					"schema change event table",
   384  					&SchemaChangeEvent{
   385  						ChangeType: primitive.SchemaChangeTypeCreated,
   386  						Target:     primitive.SchemaChangeTargetTable,
   387  						Keyspace:   "ks1",
   388  						Object:     "table1",
   389  					},
   390  					[]byte{
   391  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   392  						0, 7, C, R, E, A, T, E, D,
   393  						0, 5, T, A, B, L, E,
   394  						0, 3, k, s, _1,
   395  						0, 6, t, a, b, l, e, _1,
   396  					},
   397  					nil,
   398  				},
   399  				{
   400  					"schema change event type",
   401  					&SchemaChangeEvent{
   402  						ChangeType: primitive.SchemaChangeTypeCreated,
   403  						Target:     primitive.SchemaChangeTargetType,
   404  						Keyspace:   "ks1",
   405  						Object:     "udt1",
   406  					},
   407  					[]byte{
   408  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   409  						0, 7, C, R, E, A, T, E, D,
   410  						0, 4, T, Y, P, E,
   411  						0, 3, k, s, _1,
   412  						0, 4, u, d, t, _1,
   413  					},
   414  					nil,
   415  				},
   416  				{
   417  					"schema change event function",
   418  					&SchemaChangeEvent{
   419  						ChangeType: primitive.SchemaChangeTypeCreated,
   420  						Target:     primitive.SchemaChangeTargetFunction,
   421  						Keyspace:   "ks1",
   422  						Object:     "func1",
   423  						Arguments:  []string{"int", "varchar"},
   424  					},
   425  					[]byte{
   426  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   427  						0, 7, C, R, E, A, T, E, D,
   428  						0, 8, F, U, N, C, T, I, O, N,
   429  						0, 3, k, s, _1,
   430  						0, 5, f, u, n, c, _1,
   431  						0, 2,
   432  						0, 3, i, n, t,
   433  						0, 7, v, a, r, c, h, a, r,
   434  					},
   435  					nil,
   436  				},
   437  				{
   438  					"schema change event aggregate",
   439  					&SchemaChangeEvent{
   440  						ChangeType: primitive.SchemaChangeTypeCreated,
   441  						Target:     primitive.SchemaChangeTargetAggregate,
   442  						Keyspace:   "ks1",
   443  						Object:     "agg1",
   444  						Arguments:  []string{"int", "varchar"},
   445  					},
   446  					[]byte{
   447  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   448  						0, 7, C, R, E, A, T, E, D,
   449  						0, 9, A, G, G, R, E, G, A, T, E,
   450  						0, 3, k, s, _1,
   451  						0, 4, a, g, g, _1,
   452  						0, 2,
   453  						0, 3, i, n, t,
   454  						0, 7, v, a, r, c, h, a, r,
   455  					},
   456  					nil,
   457  				},
   458  				{
   459  					"status change event",
   460  					&StatusChangeEvent{
   461  						ChangeType: primitive.StatusChangeTypeUp,
   462  						Address: &primitive.Inet{
   463  							Addr: net.IPv4(192, 168, 1, 1),
   464  							Port: 9042,
   465  						},
   466  					},
   467  					[]byte{
   468  						0, 13, S, T, A, T, U, S, __, C, H, A, N, G, E,
   469  						0, 2, U, P,
   470  						4, 192, 168, 1, 1,
   471  						0, 0, 0x23, 0x52,
   472  					},
   473  					nil,
   474  				},
   475  				{
   476  					"topology change event",
   477  					&TopologyChangeEvent{
   478  						ChangeType: primitive.TopologyChangeTypeNewNode,
   479  						Address: &primitive.Inet{
   480  							Addr: net.IPv4(192, 168, 1, 1),
   481  							Port: 9042,
   482  						},
   483  					},
   484  					[]byte{
   485  						0, 15, T, O, P, O, L, O, G, Y, __, C, H, A, N, G, E,
   486  						0, 8, N, E, W, __, N, O, D, E,
   487  						4, 192, 168, 1, 1,
   488  						0, 0, 0x23, 0x52,
   489  					},
   490  					nil,
   491  				},
   492  			}
   493  			for _, tt := range tests {
   494  				test.Run(tt.name, func(t *testing.T) {
   495  					dest := &bytes.Buffer{}
   496  					err := codec.Encode(tt.input, dest, version)
   497  					assert.Equal(t, tt.expected, dest.Bytes())
   498  					assert.Equal(t, tt.err, err)
   499  				})
   500  			}
   501  		})
   502  	}
   503  }
   504  
   505  func TestEventCodec_EncodedLength(test *testing.T) {
   506  	codec := &eventCodec{}
   507  	// version = 2
   508  	test.Run(primitive.ProtocolVersion2.String(), func(test *testing.T) {
   509  		tests := []encodedLengthTestCase{
   510  			{
   511  				"schema change event keyspace",
   512  				&SchemaChangeEvent{
   513  					ChangeType: primitive.SchemaChangeTypeCreated,
   514  					Target:     primitive.SchemaChangeTargetKeyspace,
   515  					Keyspace:   "ks1",
   516  				},
   517  				primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   518  					primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   519  					primitive.LengthOfString("ks1") +
   520  					primitive.LengthOfString(""),
   521  				nil,
   522  			},
   523  			{
   524  				"schema change event table",
   525  				&SchemaChangeEvent{
   526  					ChangeType: primitive.SchemaChangeTypeCreated,
   527  					Target:     primitive.SchemaChangeTargetTable,
   528  					Keyspace:   "ks1",
   529  					Object:     "table1",
   530  				},
   531  				primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   532  					primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   533  					primitive.LengthOfString("ks1") +
   534  					primitive.LengthOfString("table1"),
   535  				nil,
   536  			},
   537  			{
   538  				"status change event",
   539  				&StatusChangeEvent{
   540  					ChangeType: primitive.StatusChangeTypeUp,
   541  					Address: &primitive.Inet{
   542  						Addr: net.IPv4(192, 168, 1, 1),
   543  						Port: 9042,
   544  					},
   545  				},
   546  				primitive.LengthOfString(string(primitive.EventTypeStatusChange)) +
   547  					primitive.LengthOfString(string(primitive.StatusChangeTypeUp)) +
   548  					primitive.LengthOfByte + net.IPv4len +
   549  					primitive.LengthOfInt,
   550  				nil,
   551  			},
   552  			{
   553  				"topology change event",
   554  				&TopologyChangeEvent{
   555  					ChangeType: primitive.TopologyChangeTypeNewNode,
   556  					Address: &primitive.Inet{
   557  						Addr: net.IPv4(192, 168, 1, 1),
   558  						Port: 9042,
   559  					},
   560  				},
   561  				primitive.LengthOfString(string(primitive.EventTypeTopologyChange)) +
   562  					primitive.LengthOfString(string(primitive.TopologyChangeTypeNewNode)) +
   563  					primitive.LengthOfByte + net.IPv4len +
   564  					primitive.LengthOfInt,
   565  				nil,
   566  			},
   567  		}
   568  		for _, tt := range tests {
   569  			test.Run(tt.name, func(t *testing.T) {
   570  				actual, err := codec.EncodedLength(tt.input, primitive.ProtocolVersion2)
   571  				assert.Equal(t, tt.expected, actual)
   572  				assert.Equal(t, tt.err, err)
   573  			})
   574  		}
   575  	})
   576  	// version = 3
   577  	test.Run(primitive.ProtocolVersion3.String(), func(test *testing.T) {
   578  		tests := []encodedLengthTestCase{
   579  			{
   580  				"schema change event keyspace",
   581  				&SchemaChangeEvent{
   582  					ChangeType: primitive.SchemaChangeTypeCreated,
   583  					Target:     primitive.SchemaChangeTargetKeyspace,
   584  					Keyspace:   "ks1",
   585  				},
   586  				primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   587  					primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   588  					primitive.LengthOfString(string(primitive.SchemaChangeTargetKeyspace)) +
   589  					primitive.LengthOfString("ks1"),
   590  				nil,
   591  			},
   592  			{
   593  				"schema change event table",
   594  				&SchemaChangeEvent{
   595  					ChangeType: primitive.SchemaChangeTypeCreated,
   596  					Target:     primitive.SchemaChangeTargetTable,
   597  					Keyspace:   "ks1",
   598  					Object:     "table1",
   599  				},
   600  				primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   601  					primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   602  					primitive.LengthOfString(string(primitive.SchemaChangeTargetTable)) +
   603  					primitive.LengthOfString("ks1") +
   604  					primitive.LengthOfString("table1"),
   605  				nil,
   606  			},
   607  			{
   608  				"schema change event type",
   609  				&SchemaChangeEvent{
   610  					ChangeType: primitive.SchemaChangeTypeCreated,
   611  					Target:     primitive.SchemaChangeTargetType,
   612  					Keyspace:   "ks1",
   613  					Object:     "udt1",
   614  				},
   615  				primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   616  					primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   617  					primitive.LengthOfString(string(primitive.SchemaChangeTargetType)) +
   618  					primitive.LengthOfString("ks1") +
   619  					primitive.LengthOfString("udt1"),
   620  				nil,
   621  			},
   622  			{
   623  				"schema change event function",
   624  				&SchemaChangeEvent{
   625  					ChangeType: primitive.SchemaChangeTypeCreated,
   626  					Target:     primitive.SchemaChangeTargetFunction,
   627  					Keyspace:   "ks1",
   628  					Object:     "func1",
   629  					Arguments:  []string{"int", "varchar"},
   630  				},
   631  				-1,
   632  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion3, primitive.SchemaChangeTargetFunction),
   633  			},
   634  			{
   635  				"schema change event aggregate",
   636  				&SchemaChangeEvent{
   637  					ChangeType: primitive.SchemaChangeTypeCreated,
   638  					Target:     primitive.SchemaChangeTargetAggregate,
   639  					Keyspace:   "ks1",
   640  					Object:     "agg1",
   641  					Arguments:  []string{"int", "varchar"},
   642  				},
   643  				-1,
   644  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion3, primitive.SchemaChangeTargetAggregate),
   645  			},
   646  			{
   647  				"status change event",
   648  				&StatusChangeEvent{
   649  					ChangeType: primitive.StatusChangeTypeUp,
   650  					Address: &primitive.Inet{
   651  						Addr: net.IPv4(192, 168, 1, 1),
   652  						Port: 9042,
   653  					},
   654  				},
   655  				primitive.LengthOfString(string(primitive.EventTypeStatusChange)) +
   656  					primitive.LengthOfString(string(primitive.StatusChangeTypeUp)) +
   657  					primitive.LengthOfByte + net.IPv4len +
   658  					primitive.LengthOfInt,
   659  				nil,
   660  			},
   661  			{
   662  				"topology change event",
   663  				&TopologyChangeEvent{
   664  					ChangeType: primitive.TopologyChangeTypeNewNode,
   665  					Address: &primitive.Inet{
   666  						Addr: net.IPv4(192, 168, 1, 1),
   667  						Port: 9042,
   668  					},
   669  				},
   670  				primitive.LengthOfString(string(primitive.EventTypeTopologyChange)) +
   671  					primitive.LengthOfString(string(primitive.TopologyChangeTypeNewNode)) +
   672  					primitive.LengthOfByte + net.IPv4len +
   673  					primitive.LengthOfInt,
   674  				nil,
   675  			},
   676  		}
   677  		for _, tt := range tests {
   678  			test.Run(tt.name, func(t *testing.T) {
   679  				actual, err := codec.EncodedLength(tt.input, primitive.ProtocolVersion3)
   680  				assert.Equal(t, tt.expected, actual)
   681  				assert.Equal(t, tt.err, err)
   682  			})
   683  		}
   684  	})
   685  	// versions >= 4
   686  	for _, version := range primitive.SupportedProtocolVersionsGreaterThanOrEqualTo(primitive.ProtocolVersion4) {
   687  		test.Run(version.String(), func(test *testing.T) {
   688  			tests := []encodedLengthTestCase{
   689  				{
   690  					"schema change event keyspace",
   691  					&SchemaChangeEvent{
   692  						ChangeType: primitive.SchemaChangeTypeCreated,
   693  						Target:     primitive.SchemaChangeTargetKeyspace,
   694  						Keyspace:   "ks1",
   695  					},
   696  					primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   697  						primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   698  						primitive.LengthOfString(string(primitive.SchemaChangeTargetKeyspace)) +
   699  						primitive.LengthOfString("ks1"),
   700  					nil,
   701  				},
   702  				{
   703  					"schema change event table",
   704  					&SchemaChangeEvent{
   705  						ChangeType: primitive.SchemaChangeTypeCreated,
   706  						Target:     primitive.SchemaChangeTargetTable,
   707  						Keyspace:   "ks1",
   708  						Object:     "table1",
   709  					},
   710  					primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   711  						primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   712  						primitive.LengthOfString(string(primitive.SchemaChangeTargetTable)) +
   713  						primitive.LengthOfString("ks1") +
   714  						primitive.LengthOfString("table1"),
   715  					nil,
   716  				},
   717  				{
   718  					"schema change event type",
   719  					&SchemaChangeEvent{
   720  						ChangeType: primitive.SchemaChangeTypeCreated,
   721  						Target:     primitive.SchemaChangeTargetType,
   722  						Keyspace:   "ks1",
   723  						Object:     "udt1",
   724  					},
   725  					primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   726  						primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   727  						primitive.LengthOfString(string(primitive.SchemaChangeTargetType)) +
   728  						primitive.LengthOfString("ks1") +
   729  						primitive.LengthOfString("udt1"),
   730  					nil,
   731  				},
   732  				{
   733  					"schema change event function",
   734  					&SchemaChangeEvent{
   735  						ChangeType: primitive.SchemaChangeTypeCreated,
   736  						Target:     primitive.SchemaChangeTargetFunction,
   737  						Keyspace:   "ks1",
   738  						Object:     "func1",
   739  						Arguments:  []string{"int", "varchar"},
   740  					},
   741  					primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   742  						primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   743  						primitive.LengthOfString(string(primitive.SchemaChangeTargetFunction)) +
   744  						primitive.LengthOfString("ks1") +
   745  						primitive.LengthOfString("func1") +
   746  						primitive.LengthOfStringList([]string{"int", "varchar"}),
   747  					nil,
   748  				},
   749  				{
   750  					"schema change event aggregate",
   751  					&SchemaChangeEvent{
   752  						ChangeType: primitive.SchemaChangeTypeCreated,
   753  						Target:     primitive.SchemaChangeTargetAggregate,
   754  						Keyspace:   "ks1",
   755  						Object:     "agg1",
   756  						Arguments:  []string{"int", "varchar"},
   757  					},
   758  					primitive.LengthOfString(string(primitive.EventTypeSchemaChange)) +
   759  						primitive.LengthOfString(string(primitive.SchemaChangeTypeCreated)) +
   760  						primitive.LengthOfString(string(primitive.SchemaChangeTargetAggregate)) +
   761  						primitive.LengthOfString("ks1") +
   762  						primitive.LengthOfString("agg1") +
   763  						primitive.LengthOfStringList([]string{"int", "varchar"}),
   764  					nil,
   765  				},
   766  				{
   767  					"status change event",
   768  					&StatusChangeEvent{
   769  						ChangeType: primitive.StatusChangeTypeUp,
   770  						Address: &primitive.Inet{
   771  							Addr: net.IPv4(192, 168, 1, 1),
   772  							Port: 9042,
   773  						},
   774  					},
   775  					primitive.LengthOfString(string(primitive.EventTypeStatusChange)) +
   776  						primitive.LengthOfString(string(primitive.StatusChangeTypeUp)) +
   777  						primitive.LengthOfByte + net.IPv4len +
   778  						primitive.LengthOfInt,
   779  					nil,
   780  				},
   781  				{
   782  					"topology change event",
   783  					&TopologyChangeEvent{
   784  						ChangeType: primitive.TopologyChangeTypeNewNode,
   785  						Address: &primitive.Inet{
   786  							Addr: net.IPv4(192, 168, 1, 1),
   787  							Port: 9042,
   788  						},
   789  					},
   790  					primitive.LengthOfString(string(primitive.EventTypeTopologyChange)) +
   791  						primitive.LengthOfString(string(primitive.TopologyChangeTypeNewNode)) +
   792  						primitive.LengthOfByte + net.IPv4len +
   793  						primitive.LengthOfInt,
   794  					nil,
   795  				},
   796  			}
   797  			for _, tt := range tests {
   798  				test.Run(tt.name, func(t *testing.T) {
   799  					actual, err := codec.EncodedLength(tt.input, version)
   800  					assert.Equal(t, tt.expected, actual)
   801  					assert.Equal(t, tt.err, err)
   802  				})
   803  			}
   804  		})
   805  	}
   806  }
   807  
   808  func TestEventCodec_Decode(test *testing.T) {
   809  	codec := &eventCodec{}
   810  	// version = 2
   811  	test.Run(primitive.ProtocolVersion2.String(), func(test *testing.T) {
   812  		tests := []decodeTestCase{
   813  			{
   814  				"schema change event keyspace",
   815  				[]byte{
   816  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   817  					0, 7, C, R, E, A, T, E, D,
   818  					0, 3, k, s, _1,
   819  					0, 0,
   820  				},
   821  				&SchemaChangeEvent{
   822  					ChangeType: primitive.SchemaChangeTypeCreated,
   823  					Target:     primitive.SchemaChangeTargetKeyspace,
   824  					Keyspace:   "ks1",
   825  				},
   826  				nil,
   827  			},
   828  			{
   829  				"schema change event table",
   830  				[]byte{
   831  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   832  					0, 7, C, R, E, A, T, E, D,
   833  					0, 3, k, s, _1,
   834  					0, 6, t, a, b, l, e, _1,
   835  				},
   836  				&SchemaChangeEvent{
   837  					ChangeType: primitive.SchemaChangeTypeCreated,
   838  					Target:     primitive.SchemaChangeTargetTable,
   839  					Keyspace:   "ks1",
   840  					Object:     "table1",
   841  				},
   842  				nil,
   843  			},
   844  			{
   845  				"status change event",
   846  				[]byte{
   847  					0, 13, S, T, A, T, U, S, __, C, H, A, N, G, E,
   848  					0, 2, U, P,
   849  					4, 192, 168, 1, 1,
   850  					0, 0, 0x23, 0x52,
   851  				},
   852  				&StatusChangeEvent{
   853  					ChangeType: primitive.StatusChangeTypeUp,
   854  					Address: &primitive.Inet{
   855  						Addr: net.IPv4(192, 168, 1, 1),
   856  						Port: 9042,
   857  					},
   858  				},
   859  				nil,
   860  			},
   861  			{
   862  				"topology change event",
   863  				[]byte{
   864  					0, 15, T, O, P, O, L, O, G, Y, __, C, H, A, N, G, E,
   865  					0, 8, N, E, W, __, N, O, D, E,
   866  					4, 192, 168, 1, 1,
   867  					0, 0, 0x23, 0x52,
   868  				},
   869  				&TopologyChangeEvent{
   870  					ChangeType: primitive.TopologyChangeTypeNewNode,
   871  					Address: &primitive.Inet{
   872  						Addr: net.IPv4(192, 168, 1, 1),
   873  						Port: 9042,
   874  					},
   875  				},
   876  				nil,
   877  			},
   878  		}
   879  		for _, tt := range tests {
   880  			test.Run(tt.name, func(t *testing.T) {
   881  				source := bytes.NewBuffer(tt.input)
   882  				actual, err := codec.Decode(source, primitive.ProtocolVersion2)
   883  				assert.Equal(t, tt.expected, actual)
   884  				assert.Equal(t, tt.err, err)
   885  			})
   886  		}
   887  	})
   888  	// version = 3
   889  	test.Run(primitive.ProtocolVersion3.String(), func(test *testing.T) {
   890  		tests := []decodeTestCase{
   891  			{
   892  				"schema change event keyspace",
   893  				[]byte{
   894  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   895  					0, 7, C, R, E, A, T, E, D,
   896  					0, 8, K, E, Y, S, P, A, C, E,
   897  					0, 3, k, s, _1,
   898  				},
   899  				&SchemaChangeEvent{
   900  					ChangeType: primitive.SchemaChangeTypeCreated,
   901  					Target:     primitive.SchemaChangeTargetKeyspace,
   902  					Keyspace:   "ks1",
   903  				},
   904  				nil,
   905  			},
   906  			{
   907  				"schema change event table",
   908  				[]byte{
   909  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   910  					0, 7, C, R, E, A, T, E, D,
   911  					0, 5, T, A, B, L, E,
   912  					0, 3, k, s, _1,
   913  					0, 6, t, a, b, l, e, _1,
   914  				},
   915  				&SchemaChangeEvent{
   916  					ChangeType: primitive.SchemaChangeTypeCreated,
   917  					Target:     primitive.SchemaChangeTargetTable,
   918  					Keyspace:   "ks1",
   919  					Object:     "table1",
   920  				},
   921  				nil,
   922  			},
   923  			{
   924  				"schema change event type",
   925  				[]byte{
   926  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   927  					0, 7, C, R, E, A, T, E, D,
   928  					0, 4, T, Y, P, E,
   929  					0, 3, k, s, _1,
   930  					0, 4, u, d, t, _1,
   931  				},
   932  				&SchemaChangeEvent{
   933  					ChangeType: primitive.SchemaChangeTypeCreated,
   934  					Target:     primitive.SchemaChangeTargetType,
   935  					Keyspace:   "ks1",
   936  					Object:     "udt1",
   937  				},
   938  				nil,
   939  			},
   940  			{
   941  				"schema change event function",
   942  				[]byte{
   943  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   944  					0, 7, C, R, E, A, T, E, D,
   945  					0, 8, F, U, N, C, T, I, O, N,
   946  					0, 3, k, s, _1,
   947  				},
   948  				nil,
   949  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion3, primitive.SchemaChangeTargetFunction),
   950  			},
   951  			{
   952  				"schema change event aggregate",
   953  				[]byte{
   954  					0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
   955  					0, 7, C, R, E, A, T, E, D,
   956  					0, 9, A, G, G, R, E, G, A, T, E,
   957  					0, 3, k, s, _1,
   958  				},
   959  				nil,
   960  				fmt.Errorf("invalid schema change target for %v: %v", primitive.ProtocolVersion3, primitive.SchemaChangeTargetAggregate),
   961  			},
   962  			{
   963  				"status change event",
   964  				[]byte{
   965  					0, 13, S, T, A, T, U, S, __, C, H, A, N, G, E,
   966  					0, 2, U, P,
   967  					4, 192, 168, 1, 1,
   968  					0, 0, 0x23, 0x52,
   969  				},
   970  				&StatusChangeEvent{
   971  					ChangeType: primitive.StatusChangeTypeUp,
   972  					Address: &primitive.Inet{
   973  						Addr: net.IPv4(192, 168, 1, 1),
   974  						Port: 9042,
   975  					},
   976  				},
   977  				nil,
   978  			},
   979  			{
   980  				"topology change event",
   981  				[]byte{
   982  					0, 15, T, O, P, O, L, O, G, Y, __, C, H, A, N, G, E,
   983  					0, 8, N, E, W, __, N, O, D, E,
   984  					4, 192, 168, 1, 1,
   985  					0, 0, 0x23, 0x52,
   986  				},
   987  				&TopologyChangeEvent{
   988  					ChangeType: primitive.TopologyChangeTypeNewNode,
   989  					Address: &primitive.Inet{
   990  						Addr: net.IPv4(192, 168, 1, 1),
   991  						Port: 9042,
   992  					},
   993  				},
   994  				nil,
   995  			},
   996  		}
   997  		for _, tt := range tests {
   998  			test.Run(tt.name, func(t *testing.T) {
   999  				source := bytes.NewBuffer(tt.input)
  1000  				actual, err := codec.Decode(source, primitive.ProtocolVersion3)
  1001  				assert.Equal(t, tt.expected, actual)
  1002  				assert.Equal(t, tt.err, err)
  1003  			})
  1004  		}
  1005  	})
  1006  	// versions >= 4
  1007  	for _, version := range primitive.SupportedProtocolVersionsGreaterThanOrEqualTo(primitive.ProtocolVersion4) {
  1008  		test.Run(version.String(), func(test *testing.T) {
  1009  			tests := []decodeTestCase{
  1010  				{
  1011  					"schema change event keyspace",
  1012  					[]byte{
  1013  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
  1014  						0, 7, C, R, E, A, T, E, D,
  1015  						0, 8, K, E, Y, S, P, A, C, E,
  1016  						0, 3, k, s, _1,
  1017  					},
  1018  					&SchemaChangeEvent{
  1019  						ChangeType: primitive.SchemaChangeTypeCreated,
  1020  						Target:     primitive.SchemaChangeTargetKeyspace,
  1021  						Keyspace:   "ks1",
  1022  					},
  1023  					nil,
  1024  				},
  1025  				{
  1026  					"schema change event table",
  1027  					[]byte{
  1028  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
  1029  						0, 7, C, R, E, A, T, E, D,
  1030  						0, 5, T, A, B, L, E,
  1031  						0, 3, k, s, _1,
  1032  						0, 6, t, a, b, l, e, _1,
  1033  					},
  1034  					&SchemaChangeEvent{
  1035  						ChangeType: primitive.SchemaChangeTypeCreated,
  1036  						Target:     primitive.SchemaChangeTargetTable,
  1037  						Keyspace:   "ks1",
  1038  						Object:     "table1",
  1039  					},
  1040  					nil,
  1041  				},
  1042  				{
  1043  					"schema change event type",
  1044  					[]byte{
  1045  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
  1046  						0, 7, C, R, E, A, T, E, D,
  1047  						0, 4, T, Y, P, E,
  1048  						0, 3, k, s, _1,
  1049  						0, 4, u, d, t, _1,
  1050  					},
  1051  					&SchemaChangeEvent{
  1052  						ChangeType: primitive.SchemaChangeTypeCreated,
  1053  						Target:     primitive.SchemaChangeTargetType,
  1054  						Keyspace:   "ks1",
  1055  						Object:     "udt1",
  1056  					},
  1057  					nil,
  1058  				},
  1059  				{
  1060  					"schema change event function",
  1061  					[]byte{
  1062  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
  1063  						0, 7, C, R, E, A, T, E, D,
  1064  						0, 8, F, U, N, C, T, I, O, N,
  1065  						0, 3, k, s, _1,
  1066  						0, 5, f, u, n, c, _1,
  1067  						0, 2,
  1068  						0, 3, i, n, t,
  1069  						0, 7, v, a, r, c, h, a, r,
  1070  					},
  1071  					&SchemaChangeEvent{
  1072  						ChangeType: primitive.SchemaChangeTypeCreated,
  1073  						Target:     primitive.SchemaChangeTargetFunction,
  1074  						Keyspace:   "ks1",
  1075  						Object:     "func1",
  1076  						Arguments:  []string{"int", "varchar"},
  1077  					},
  1078  					nil,
  1079  				},
  1080  				{
  1081  					"schema change event aggregate",
  1082  					[]byte{
  1083  						0, 13, S, C, H, E, M, A, __, C, H, A, N, G, E,
  1084  						0, 7, C, R, E, A, T, E, D,
  1085  						0, 9, A, G, G, R, E, G, A, T, E,
  1086  						0, 3, k, s, _1,
  1087  						0, 4, a, g, g, _1,
  1088  						0, 2,
  1089  						0, 3, i, n, t,
  1090  						0, 7, v, a, r, c, h, a, r,
  1091  					},
  1092  					&SchemaChangeEvent{
  1093  						ChangeType: primitive.SchemaChangeTypeCreated,
  1094  						Target:     primitive.SchemaChangeTargetAggregate,
  1095  						Keyspace:   "ks1",
  1096  						Object:     "agg1",
  1097  						Arguments:  []string{"int", "varchar"},
  1098  					},
  1099  					nil,
  1100  				},
  1101  				{
  1102  					"status change event",
  1103  					[]byte{
  1104  						0, 13, S, T, A, T, U, S, __, C, H, A, N, G, E,
  1105  						0, 2, U, P,
  1106  						4, 192, 168, 1, 1,
  1107  						0, 0, 0x23, 0x52,
  1108  					},
  1109  					&StatusChangeEvent{
  1110  						ChangeType: primitive.StatusChangeTypeUp,
  1111  						Address: &primitive.Inet{
  1112  							Addr: net.IPv4(192, 168, 1, 1),
  1113  							Port: 9042,
  1114  						},
  1115  					},
  1116  					nil,
  1117  				},
  1118  				{
  1119  					"topology change event",
  1120  					[]byte{
  1121  						0, 15, T, O, P, O, L, O, G, Y, __, C, H, A, N, G, E,
  1122  						0, 8, N, E, W, __, N, O, D, E,
  1123  						4, 192, 168, 1, 1,
  1124  						0, 0, 0x23, 0x52,
  1125  					},
  1126  					&TopologyChangeEvent{
  1127  						ChangeType: primitive.TopologyChangeTypeNewNode,
  1128  						Address: &primitive.Inet{
  1129  							Addr: net.IPv4(192, 168, 1, 1),
  1130  							Port: 9042,
  1131  						},
  1132  					},
  1133  					nil,
  1134  				},
  1135  			}
  1136  			for _, tt := range tests {
  1137  				test.Run(tt.name, func(t *testing.T) {
  1138  					source := bytes.NewBuffer(tt.input)
  1139  					actual, err := codec.Decode(source, version)
  1140  					assert.Equal(t, tt.expected, actual)
  1141  					assert.Equal(t, tt.err, err)
  1142  				})
  1143  			}
  1144  		})
  1145  	}
  1146  }