github.com/zntrio/harp/v2@v2.0.9/pkg/container/codec_test.go (about) 1 // Licensed to Elasticsearch B.V. under one or more contributor 2 // license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright 4 // ownership. Elasticsearch B.V. licenses this file to you under 5 // the Apache License, Version 2.0 (the "License"); you may 6 // not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package container 19 20 import ( 21 "bytes" 22 "encoding/hex" 23 "io" 24 "testing" 25 26 "github.com/google/go-cmp/cmp" 27 "github.com/google/go-cmp/cmp/cmpopts" 28 fuzz "github.com/google/gofuzz" 29 30 containerv1 "github.com/zntrio/harp/v2/api/gen/go/harp/container/v1" 31 ) 32 33 var ( 34 opt = cmp.FilterPath( 35 func(p cmp.Path) bool { 36 // Remove ignoring of the fields below once go-cmp is able to ignore generated fields. 37 // See https://github.com/google/go-cmp/issues/153 38 ignoreXXXCache := 39 p.String() == "XXX_sizecache" || 40 p.String() == "Headers.XXX_sizecache" 41 return ignoreXXXCache 42 }, cmp.Ignore()) 43 44 ignoreOpts = []cmp.Option{ 45 cmpopts.IgnoreUnexported(containerv1.Container{}), 46 cmpopts.IgnoreUnexported(containerv1.Header{}), 47 opt, 48 } 49 ) 50 51 // ----------------------------------------------------------------------------- 52 53 func mustHexDecode(in string) []byte { 54 out, err := hex.DecodeString(in) 55 if err != nil { 56 panic(err) 57 } 58 return out 59 } 60 61 func TestDump(t *testing.T) { 62 type args struct { 63 c *containerv1.Container 64 } 65 tests := []struct { 66 name string 67 args args 68 wantW []byte 69 wantErr bool 70 }{ 71 { 72 name: "nil", 73 wantW: nil, 74 wantErr: true, 75 }, 76 { 77 name: "empty", 78 args: args{ 79 c: &containerv1.Container{}, 80 }, 81 wantW: mustHexDecode("53cb37010002"), 82 wantErr: false, 83 }, 84 { 85 name: "not empty", 86 args: args{ 87 c: &containerv1.Container{ 88 Headers: &containerv1.Header{ 89 ContentEncoding: "gzip", 90 ContentType: "harp.bundle.v1.Bundle", 91 }, 92 Raw: []byte{0x00, 0x00}, 93 }, 94 }, 95 wantW: mustHexDecode("53cb370100020a1d0a04677a69701215686172702e62756e646c652e76312e42756e646c6512020000"), 96 wantErr: false, 97 }, 98 } 99 for _, tt := range tests { 100 t.Run(tt.name, func(t *testing.T) { 101 w := &bytes.Buffer{} 102 if err := Dump(w, tt.args.c); (err != nil) != tt.wantErr { 103 t.Errorf("Dump() error = %v, wantErr %v", err, tt.wantErr) 104 return 105 } 106 gotW := w.Bytes() 107 if diff := cmp.Diff(gotW, tt.wantW, ignoreOpts...); diff != "" { 108 t.Errorf("Dump()\n-got/+want\ndiff %s", diff) 109 } 110 }) 111 } 112 } 113 114 func TestLoad(t *testing.T) { 115 type args struct { 116 r io.Reader 117 } 118 tests := []struct { 119 name string 120 args args 121 want *containerv1.Container 122 wantErr bool 123 }{ 124 { 125 name: "nil", 126 want: nil, 127 wantErr: true, 128 }, 129 { 130 name: "invalid magic", 131 args: args{ 132 r: bytes.NewReader(mustHexDecode("FFFFFFFF0001")), 133 }, 134 want: nil, 135 wantErr: true, 136 }, 137 { 138 name: "invalid version", 139 args: args{ 140 r: bytes.NewReader(mustHexDecode("53cb37010002")), 141 }, 142 want: nil, 143 wantErr: true, 144 }, 145 { 146 name: "empty container", 147 args: args{ 148 r: bytes.NewReader(mustHexDecode("53cb37010001")), 149 }, 150 want: nil, 151 wantErr: true, 152 }, 153 { 154 name: "invalid container", 155 args: args{ 156 r: bytes.NewReader(mustHexDecode("53cb370100010a")), 157 }, 158 want: nil, 159 wantErr: true, 160 }, 161 { 162 name: "valid", 163 args: args{ 164 r: bytes.NewReader(mustHexDecode("53cb370100020a1d0a04677a69701215686172702e62756e646c652e76312e42756e646c6512020000")), 165 }, 166 want: &containerv1.Container{ 167 Headers: &containerv1.Header{ 168 ContentEncoding: "gzip", 169 ContentType: "harp.bundle.v1.Bundle", 170 }, 171 Raw: []byte{0x00, 0x00}, 172 }, 173 wantErr: false, 174 }, 175 } 176 for _, tt := range tests { 177 t.Run(tt.name, func(t *testing.T) { 178 got, err := Load(tt.args.r) 179 if (err != nil) != tt.wantErr { 180 t.Errorf("Load() error = %v, wantErr %v", err, tt.wantErr) 181 return 182 } 183 if diff := cmp.Diff(got, tt.want, ignoreOpts...); diff != "" { 184 t.Errorf("Load()\n-got/+want\ndiff %s", diff) 185 } 186 }) 187 } 188 } 189 190 // ----------------------------------------------------------------------------- 191 192 func Test_Load_Fuzz(t *testing.T) { 193 // Making sure the function never panics 194 for i := 0; i < 50000; i++ { 195 f := fuzz.New() 196 197 // Prepare arguments 198 var ( 199 raw []byte 200 ) 201 202 f.Fuzz(&raw) 203 204 // Execute 205 Load(bytes.NewReader(raw)) 206 } 207 } 208 209 func Test_Dump_Fuzz(t *testing.T) { 210 // Making sure the function never panics 211 for i := 0; i < 50000; i++ { 212 f := fuzz.New() 213 214 // Prepare arguments 215 var ( 216 input containerv1.Container 217 ) 218 219 f.Fuzz(&input) 220 221 // Execute 222 Dump(io.Discard, &input) 223 } 224 }