vitess.io/vitess@v0.16.2/go/mysql/binlog_event_json_test.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package mysql
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  func TestJSONTypes(t *testing.T) {
    28  	// most of these test cases have been taken from open source java/python adapters
    29  	// like https://github.com/shyiko/mysql-binlog-connector-java/pull/119/files
    30  	testcases := []struct {
    31  		name     string
    32  		data     []byte
    33  		expected string
    34  		isMap    bool
    35  	}{{
    36  		name:     "null",
    37  		data:     []byte{},
    38  		expected: `null`,
    39  	}, {
    40  		name:     "map, string value",
    41  		data:     []byte{0, 1, 0, 14, 0, 11, 0, 1, 0, 12, 12, 0, 97, 1, 98},
    42  		expected: `{"a":"b"}`,
    43  	}, {
    44  		name:     "map, int value",
    45  		data:     []byte{0, 1, 0, 12, 0, 11, 0, 1, 0, 5, 2, 0, 97},
    46  		expected: `{"a":2}`,
    47  	}, {
    48  		name:     "map, object value",
    49  		data:     []byte{0, 1, 0, 29, 0, 11, 0, 4, 0, 0, 15, 0, 97, 115, 100, 102, 1, 0, 14, 0, 11, 0, 3, 0, 5, 123, 0, 102, 111, 111},
    50  		expected: `{"asdf":{"foo":123}}`,
    51  	}, {
    52  		name:     "list of ints",
    53  		data:     []byte{2, 2, 0, 10, 0, 5, 1, 0, 5, 2, 0},
    54  		expected: `[1,2]`,
    55  	}, {
    56  		name:     "list of maps",
    57  		data:     []byte{0, 4, 0, 60, 0, 32, 0, 1, 0, 33, 0, 1, 0, 34, 0, 2, 0, 36, 0, 2, 0, 12, 38, 0, 12, 40, 0, 12, 42, 0, 2, 46, 0, 97, 99, 97, 98, 98, 99, 1, 98, 1, 100, 3, 97, 98, 99, 2, 0, 14, 0, 12, 10, 0, 12, 12, 0, 1, 120, 1, 121},
    58  		expected: `{"a":"b","c":"d","ab":"abc","bc":["x","y"]}`,
    59  		isMap:    true,
    60  	}, {
    61  		name:     "list with one string",
    62  		data:     []byte{2, 1, 0, 37, 0, 12, 8, 0, 0, 4, 104, 101, 114, 101},
    63  		expected: `["here"]`,
    64  	}, {
    65  		name:     "list varied",
    66  		data:     []byte{2, 3, 0, 37, 0, 12, 13, 0, 2, 18, 0, 12, 33, 0, 4, 104, 101, 114, 101, 2, 0, 15, 0, 12, 10, 0, 12, 12, 0, 1, 73, 2, 97, 109, 3, 33, 33, 33},
    67  		expected: `["here",["I","am"],"!!!"]`,
    68  	}, {
    69  		name:     "string",
    70  		data:     []byte{12, 13, 115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103},
    71  		expected: `"scalar string"`,
    72  	}, {
    73  		name:     "map, long string value",
    74  		data:     []byte{0, 1, 0, 149, 0, 11, 0, 6, 0, 12, 17, 0, 115, 99, 111, 112, 101, 115, 130, 1, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 69, 65, 65, 65, 65, 65, 65, 69, 65, 65, 65, 65, 65, 65, 56, 65, 65, 65, 66, 103, 65, 65, 65, 65, 65, 65, 66, 65, 65, 65, 65, 67, 65, 65, 65, 65, 65, 65, 65, 65, 65, 84, 216, 142, 184},
    75  		expected: `{"scopes":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAEAAAAAAEAAAAAA8AAABgAAAAAABAAAACAAAAAAAAA"}`,
    76  	}, {
    77  		// repeat the same string 10 times, to test the case where length of string
    78  		// requires 2 bytes to store
    79  		name: "long string",
    80  		data: []byte{12, 130, 1,
    81  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    82  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    83  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    84  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    85  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    86  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    87  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    88  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    89  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103,
    90  			115, 99, 97, 108, 97, 114, 32, 115, 116, 114, 105, 110, 103},
    91  		expected: `"scalar stringscalar stringscalar stringscalar stringscalar stringscalar stringscalar stringscalar stringscalar stringscalar string"`,
    92  	}, {
    93  		name:     "bool true",
    94  		data:     []byte{4, 1},
    95  		expected: `true`,
    96  	}, {
    97  		name:     "bool false",
    98  		data:     []byte{4, 2},
    99  		expected: `false`,
   100  	}, {
   101  		name:     "bool null",
   102  		data:     []byte{4, 0},
   103  		expected: `null`,
   104  	}, {
   105  		name:     "uint16 max",
   106  		data:     []byte{6, 255, 255},
   107  		expected: `65535`,
   108  	}, {
   109  		name:     "uint32 max",
   110  		data:     []byte{8, 255, 255, 255, 255},
   111  		expected: `4294967295`,
   112  	}, {
   113  		name:     "uint64 max",
   114  		data:     []byte{10, 255, 255, 255, 255, 255, 255, 255, 255},
   115  		expected: `18446744073709551615`,
   116  	}, {
   117  		name:     "int16 -1",
   118  		data:     []byte{5, 255, 255},
   119  		expected: `-1`,
   120  	}, {
   121  		name:     "int32 -1",
   122  		data:     []byte{7, 255, 255, 255, 255},
   123  		expected: `-1`,
   124  	}, {
   125  		name:     "int64 -1",
   126  		data:     []byte{9, 255, 255, 255, 255, 255, 255, 255, 255},
   127  		expected: `-1`,
   128  	}, {
   129  		name:     "int16 max",
   130  		data:     []byte{5, 255, 127},
   131  		expected: `32767`,
   132  	}, {
   133  		name:     "int32 max",
   134  		data:     []byte{7, 255, 255, 255, 127},
   135  		expected: `2147483647`,
   136  	}, {
   137  		name:     "int64 max",
   138  		data:     []byte{9, 255, 255, 255, 255, 255, 255, 255, 127},
   139  		expected: `9223372036854775807`,
   140  	}, {
   141  		name:     "uint16/1",
   142  		data:     []byte{6, 1, 0},
   143  		expected: `1`,
   144  	}, {
   145  		name:     "int32/32768",
   146  		data:     []byte{7, 0, 128, 0, 0},
   147  		expected: `32768`,
   148  	}, {
   149  		name:     "int16/neg",
   150  		data:     []byte{5, 0, 128},
   151  		expected: `-32768`,
   152  	}, {
   153  		name:     "int32/neg",
   154  		data:     []byte{7, 255, 127, 255, 255},
   155  		expected: `-32769`,
   156  	}, {
   157  		name:     "uint32",
   158  		data:     []byte{8, 0, 128, 0, 0},
   159  		expected: `32768`,
   160  	}, {
   161  		name:     "int64",
   162  		data:     []byte{9, 0, 0, 0, 128, 0, 0, 0, 0},
   163  		expected: `2147483648`,
   164  	}, {
   165  		name:     "int32/neg",
   166  		data:     []byte{7, 0, 0, 0, 128},
   167  		expected: `-2147483648`,
   168  	}, {
   169  		name:     "int64/neg",
   170  		data:     []byte{9, 255, 255, 255, 127, 255, 255, 255, 255},
   171  		expected: `-2147483649`,
   172  	}, {
   173  		name:     "uint64",
   174  		data:     []byte{10, 255, 255, 255, 255, 255, 255, 255, 255},
   175  		expected: `18446744073709551615`,
   176  	}, {
   177  		name:     "int64/neg",
   178  		data:     []byte{9, 0, 0, 0, 0, 0, 0, 0, 128},
   179  		expected: `-9223372036854775808`,
   180  	}, {
   181  		name:     "double",
   182  		data:     []byte{11, 110, 134, 27, 240, 249, 33, 9, 64},
   183  		expected: `3.14159`,
   184  	}, {
   185  		name:     "empty map",
   186  		data:     []byte{0, 0, 0, 4, 0},
   187  		expected: `{}`,
   188  	}, {
   189  		name:     "empty list",
   190  		data:     []byte{2, 0, 0, 4, 0},
   191  		expected: `[]`,
   192  	}, {
   193  		// opaque, datetime
   194  		name:     "datetime",
   195  		data:     []byte{15, 12, 8, 0, 0, 0, 25, 118, 31, 149, 25},
   196  		expected: `"2015-01-15 23:24:25.000000"`,
   197  	}, {
   198  		// opaque, time
   199  		name:     "time",
   200  		data:     []byte{15, 11, 8, 0, 0, 0, 25, 118, 1, 0, 0},
   201  		expected: `"23:24:25.000000"`,
   202  	}, {
   203  		// opaque, time
   204  		name:     "time2",
   205  		data:     []byte{15, 11, 8, 192, 212, 1, 25, 118, 1, 0, 0},
   206  		expected: `"23:24:25.120000"`,
   207  	}, {
   208  		// opaque, date
   209  		name:     "date",
   210  		data:     []byte{15, 10, 8, 0, 0, 0, 0, 0, 30, 149, 25},
   211  		expected: `"2015-01-15"`,
   212  	}, {
   213  		// opaque, decimal
   214  		name:     "decimal",
   215  		data:     []byte{15, 246, 8, 13, 4, 135, 91, 205, 21, 4, 210},
   216  		expected: `1.234567891234e+08`,
   217  	}, {
   218  		// opaque, bit field. Not yet implemented.
   219  		name:     "bitfield: unimplemented",
   220  		data:     []byte{15, 16, 2, 202, 254},
   221  		expected: `opaque type 16 is not supported yet, data [2 202 254]`,
   222  	}}
   223  	for _, tc := range testcases {
   224  		name := fmt.Sprintf("%s (%s)", tc.name, tc.expected)
   225  		t.Run(name, func(t *testing.T) {
   226  			val, err := getJSONValue(tc.data)
   227  			if err != nil {
   228  				require.Equal(t, tc.expected, err.Error())
   229  				return
   230  			}
   231  			if tc.isMap { // map keys sorting order is not guaranteed, so we convert back to golang maps and compare
   232  				var gotJSON, wantJSON map[string]any
   233  				err = json.Unmarshal([]byte(val), &gotJSON)
   234  				require.NoError(t, err)
   235  				err = json.Unmarshal([]byte(tc.expected), &wantJSON)
   236  				require.NoError(t, err)
   237  				require.EqualValues(t, wantJSON, gotJSON)
   238  				return
   239  			}
   240  			require.Equal(t, tc.expected, val)
   241  		})
   242  	}
   243  }