github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/cache/serialization_test.go (about) 1 package cache 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 ) 8 9 // TestStruct is a test struct for serialization testing 10 type TestStruct struct { 11 ID int 12 Name string 13 Tags []string 14 } 15 16 func TestEncodeDecode(t *testing.T) { 17 t.Run("string", func(t *testing.T) { 18 original := "hello world" 19 encoded, err := encode(original) 20 require.NoError(t, err) 21 require.NotEmpty(t, encoded) 22 23 var decoded string 24 25 err = decode(encoded, &decoded) 26 require.NoError(t, err) 27 require.Equal(t, original, decoded) 28 }) 29 30 t.Run("int", func(t *testing.T) { 31 original := 42 32 encoded, err := encode(original) 33 require.NoError(t, err) 34 require.NotEmpty(t, encoded) 35 36 var decoded int 37 38 err = decode(encoded, &decoded) 39 require.NoError(t, err) 40 require.Equal(t, original, decoded) 41 }) 42 43 t.Run("struct", func(t *testing.T) { 44 original := TestStruct{ 45 ID: 123, 46 Name: "test", 47 Tags: []string{"a", "b", "c"}, 48 } 49 encoded, err := encode(original) 50 require.NoError(t, err) 51 require.NotEmpty(t, encoded) 52 53 var decoded TestStruct 54 55 err = decode(encoded, &decoded) 56 require.NoError(t, err) 57 require.Equal(t, original, decoded) 58 }) 59 60 t.Run("slice", func(t *testing.T) { 61 original := []string{"a", "b", "c"} 62 encoded, err := encode(original) 63 require.NoError(t, err) 64 require.NotEmpty(t, encoded) 65 66 var decoded []string 67 68 err = decode(encoded, &decoded) 69 require.NoError(t, err) 70 require.Equal(t, original, decoded) 71 }) 72 73 t.Run("map", func(t *testing.T) { 74 original := map[string]int{"a": 1, "b": 2} 75 encoded, err := encode(original) 76 require.NoError(t, err) 77 require.NotEmpty(t, encoded) 78 79 var decoded map[string]int 80 81 err = decode(encoded, &decoded) 82 require.NoError(t, err) 83 require.Equal(t, original, decoded) 84 }) 85 86 t.Run("pointer to struct", func(t *testing.T) { 87 original := &TestStruct{ 88 ID: 456, 89 Name: "pointer test", 90 Tags: []string{"x", "y"}, 91 } 92 encoded, err := encode(original) 93 require.NoError(t, err) 94 require.NotEmpty(t, encoded) 95 96 var decoded *TestStruct 97 98 err = decode(encoded, &decoded) 99 require.NoError(t, err) 100 require.Equal(t, original, decoded) 101 }) 102 } 103 104 func TestEncodeErrors(t *testing.T) { 105 testcases := map[string]struct { 106 value any 107 }{ 108 "channel": { 109 value: make(chan int), 110 }, 111 "function": { 112 value: func() {}, 113 }, 114 } 115 116 for name, tc := range testcases { 117 t.Run(name, func(t *testing.T) { 118 _, err := encode(tc.value) 119 require.Error(t, err) 120 }) 121 } 122 } 123 124 func TestDecodeErrors(t *testing.T) { 125 t.Run("invalid data", func(t *testing.T) { 126 var dest string 127 128 err := decode([]byte("invalid gob data"), &dest) 129 require.Error(t, err) 130 }) 131 132 t.Run("type mismatch", func(t *testing.T) { 133 // Encode a string 134 encoded, err := encode("hello") 135 require.NoError(t, err) 136 137 // Try to decode as int 138 var dest int 139 140 err = decode(encoded, &dest) 141 require.Error(t, err) 142 }) 143 144 t.Run("non-pointer destination", func(t *testing.T) { 145 encoded, err := encode("hello") 146 require.NoError(t, err) 147 148 // This should fail because dest is not a pointer 149 var dest string 150 // Note: We need to pass dest directly (not &dest) to test this 151 // But gob.Decode requires a pointer, so this will fail 152 err = decode(encoded, dest) 153 require.Error(t, err) 154 }) 155 } 156 157 func TestEncodeDecodeNil(t *testing.T) { 158 t.Run("nil slice", func(t *testing.T) { 159 var original []string 160 161 encoded, err := encode(original) 162 require.NoError(t, err) 163 require.NotEmpty(t, encoded) 164 165 var decoded []string 166 167 err = decode(encoded, &decoded) 168 require.NoError(t, err) 169 require.Nil(t, decoded) 170 }) 171 172 t.Run("nil map", func(t *testing.T) { 173 var original map[string]int 174 175 encoded, err := encode(original) 176 require.NoError(t, err) 177 require.NotEmpty(t, encoded) 178 179 var decoded map[string]int 180 181 err = decode(encoded, &decoded) 182 require.NoError(t, err) 183 // Note: gob decodes nil maps as empty maps, this is expected behavior 184 require.Empty(t, decoded) 185 }) 186 } 187 188 func TestEncodeDecodeComplexStruct(t *testing.T) { 189 type NestedStruct struct { 190 Data map[string][]int 191 Ptr *TestStruct 192 } 193 194 original := NestedStruct{ 195 Data: map[string][]int{ 196 "a": {1, 2, 3}, 197 "b": {4, 5, 6}, 198 }, 199 Ptr: &TestStruct{ 200 ID: 999, 201 Name: "nested", 202 Tags: []string{"nested", "test"}, 203 }, 204 } 205 206 encoded, err := encode(original) 207 require.NoError(t, err) 208 209 var decoded NestedStruct 210 211 err = decode(encoded, &decoded) 212 require.NoError(t, err) 213 require.Equal(t, original, decoded) 214 }