github.com/vmware/govmomi@v0.51.0/ovf/parser_test.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package ovf 6 7 import ( 8 "fmt" 9 "strings" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func TestValidInteger(t *testing.T) { 16 t.Run("Valid integer terms", func(t *testing.T) { 17 testCases := []string{ 18 "1", 19 "1024", 20 "1000", 21 "1000000000", 22 } 23 24 for _, tc := range testCases { 25 t.Run(tc, func(t *testing.T) { 26 assert.True(t, validIntegerString(tc)) 27 }) 28 } 29 }) 30 31 // while these all may not necessarily be invalid integer terms mathematically, they are either not valid per 32 // DSP0004, or not valid per our use-case 33 t.Run("Invalid integer terms", func(t *testing.T) { 34 testCases := []string{ 35 "05", 36 "1.5", 37 "2^10", 38 "-10", 39 "1,000", 40 "1,000,000", 41 } 42 43 for _, tc := range testCases { 44 t.Run(tc, func(t *testing.T) { 45 assert.False(t, validIntegerString(tc)) 46 }) 47 } 48 }) 49 } 50 51 func TestValidExponent(t *testing.T) { 52 t.Run("Acceptable exponential terms", func(t *testing.T) { 53 testCases := []string{ 54 "10^3", 55 "2^10", 56 } 57 58 for _, tc := range testCases { 59 t.Run(tc, func(t *testing.T) { 60 assert.True(t, validExponentString(tc)) 61 }) 62 } 63 }) 64 65 // while valid exponential terms mathematically, they are either not valid per DSP0004, or not valid per our 66 // use-case 67 t.Run("Unacceptable exponential terms", func(t *testing.T) { 68 testCases := []string{ 69 "1", 70 "1024", 71 "05", 72 "1.5", 73 "-10", 74 "0.5^2", 75 "-10^3", 76 "-2^10", 77 "1e6", 78 } 79 80 for _, tc := range testCases { 81 t.Run(tc, func(t *testing.T) { 82 assert.False(t, validExponentString(tc)) 83 }) 84 } 85 }) 86 } 87 88 func TestValidByteUnitString(t *testing.T) { 89 // Due to size constraints and our use-case, we only accept up to gigabyte 90 t.Run("Acceptable SI decimal prefixes", func(t *testing.T) { 91 testCases := []string{ 92 "byte", 93 "kilobyte", 94 "megabyte", 95 "gigabyte", 96 } 97 98 for _, tc := range testCases { 99 t.Run(tc, func(t *testing.T) { 100 assert.True(t, validByteUnitString(tc)) 101 }) 102 // plural is valid 103 plural := fmt.Sprintf("%ss", tc) 104 t.Run(plural, func(t *testing.T) { 105 assert.True(t, validByteUnitString(plural)) 106 }) 107 // function expects an already lowercased string, so capitalization is not valid 108 capitalized := strings.ToUpper(tc) 109 t.Run(capitalized, func(t *testing.T) { 110 assert.False(t, validByteUnitString(capitalized)) 111 }) 112 } 113 }) 114 115 // too large and/or currently don't fit use-case 116 t.Run("Unacceptable SI decimal prefixes", func(t *testing.T) { 117 testCases := []string{ 118 "terabyte", 119 "petabyte", 120 "exabyte", 121 "zettabyte", 122 "yottabyte", 123 } 124 125 for _, tc := range testCases { 126 t.Run(tc, func(t *testing.T) { 127 assert.False(t, validByteUnitString(tc)) 128 }) 129 } 130 }) 131 132 // due to size constraints and our use-case, we only accept up to gibibyte 133 t.Run("Acceptable IEC binary prefixes", func(t *testing.T) { 134 testCases := []string{ 135 "kibibyte", 136 "mebibyte", 137 "gibibyte", 138 } 139 140 for _, tc := range testCases { 141 t.Run(tc, func(t *testing.T) { 142 assert.True(t, validByteUnitString(tc)) 143 }) 144 // plural is valid 145 plural := fmt.Sprintf("%ss", tc) 146 t.Run(plural, func(t *testing.T) { 147 assert.True(t, validByteUnitString(plural)) 148 }) 149 // function expects an already-lowercased string, so capitalization is not valid 150 capitalized := strings.ToUpper(tc) 151 t.Run(capitalized, func(t *testing.T) { 152 assert.False(t, validByteUnitString(capitalized)) 153 }) 154 } 155 }) 156 157 // too large and/or currently don't fit use-case 158 t.Run("Unacceptable IEC binary prefixes", func(t *testing.T) { 159 testCases := []string{ 160 "tebibyte", 161 "pebibyte", 162 "exbibyte", 163 "zebibyte", 164 "yobibyte", 165 } 166 167 for _, tc := range testCases { 168 t.Run(tc, func(t *testing.T) { 169 assert.False(t, validByteUnitString(tc)) 170 }) 171 } 172 }) 173 } 174 175 func TestValidUnit(t *testing.T) { 176 t.Run("Valid unit strings", func(t *testing.T) { 177 testCases := []string{ 178 "", 179 "1024", 180 "2^10", 181 "10^3", 182 "byte", 183 "1024*byte", 184 "1024 * byte", 185 "byte*1024", 186 "byte * 1024", 187 "2^10*byte", 188 "2^10 * bytes", 189 "byte*2^10", 190 "byte * 2^10", 191 "1024 * 1024*1024", 192 "2^10*2^10 * 2^10", 193 "2^10 * 1024 * 2^10", 194 "2^10*1024 * byte", 195 "byte*2^10 * 1024", 196 "1000*byte * 1000 * 1000", 197 "gigabyte", 198 "Gigabyte", 199 "1024 * 1024 * kilobyte", 200 "Byte", 201 "1024*Byte", 202 "1024 * BYTE", 203 "BYTE*1024", 204 "Byte * 1024", 205 "2^10*Byte", 206 "2^10 * BYTE", 207 "BYTE*2^10", 208 "Byte * 2^10", 209 "1000000", 210 "1000000000*byte", 211 } 212 213 for _, tc := range testCases { 214 t.Run(tc, func(t *testing.T) { 215 assert.True(t, validCapacityString(tc)) 216 }) 217 } 218 }) 219 220 // either these do not abide by DSP0004, or they do not make sense in the context of our use-case 221 t.Run("Invalid unit strings", func(t *testing.T) { 222 testCases := []string{ 223 "1000*", 224 "*1024", 225 "* 1000 * byte", 226 "byte * 2^30 *", 227 "1000byte", 228 "1024*1024*", 229 "byte*byte", 230 "2^10/1024", 231 "1024*1024 / 1024", 232 "2 ^ 10", 233 "512 + 512", 234 "2048 - 1024", 235 "1,000,000", 236 "1,000,000,000*byte", 237 } 238 239 for _, tc := range testCases { 240 t.Run(tc, func(t *testing.T) { 241 assert.False(t, validCapacityString(tc)) 242 }) 243 } 244 }) 245 } 246 247 func TestParseCapacityAllocationUnits(t *testing.T) { 248 t.Run("Valid capacity allocation units multiplier is correctly parsed", func(t *testing.T) { 249 testCases := []struct { 250 s string 251 expected int64 252 }{ 253 {"", 1}, 254 {"byte", 1}, 255 {"kilobyte", 1000}, 256 {"kibibyte", 1024}, 257 {"megabyte", 1000 * 1000}, 258 {"mebibyte", 1024 * 1024}, 259 {"gigabyte", 1000 * 1000 * 1000}, 260 {"gibibyte", 1024 * 1024 * 1024}, 261 {"Byte", 1}, 262 {"Kilobyte", 1000}, 263 {"Kibibyte", 1024}, 264 {"Megabyte", 1000 * 1000}, 265 {"Mebibyte", 1024 * 1024}, 266 {"Gigabyte", 1000 * 1000 * 1000}, 267 {"Gibibyte", 1024 * 1024 * 1024}, 268 {"BYTE", 1}, 269 {"KILOBYTE", 1000}, 270 {"KIBIBYTE", 1024}, 271 {"MEGABYTE", 1000 * 1000}, 272 {"MEBIBYTE", 1024 * 1024}, 273 {"GIGABYTE", 1000 * 1000 * 1000}, 274 {"GIBIBYTE", 1024 * 1024 * 1024}, 275 {"10^3", 1000}, 276 {"1024", 1024}, 277 {"1000 * byte", 1000}, 278 {"2^10 * byte", 1024}, 279 {"byte * 2^10", 1024}, 280 {"10^9*byte", 1000 * 1000 * 1000}, 281 {"10^3 * megabyte", 1000 * 1000 * 1000}, 282 {"kibibyte * 2^10 * 1024", 1024 * 1024 * 1024}, 283 {"byte*2^10*2^10*1024", 1024 * 1024 * 1024}, 284 {"1000*byte*1000*10^3", 1000 * 1000 * 1000}, 285 } 286 287 for _, tc := range testCases { 288 t.Run(tc.s, func(t *testing.T) { 289 assert.Equal(t, tc.expected, ParseCapacityAllocationUnits(tc.s)) 290 }) 291 } 292 }) 293 294 // either these do not abide by DSP0004, or they do not make sense in the context of our use-case 295 t.Run("Invalid capacity allocation units should return zero", func(t *testing.T) { 296 testCases := []string{ 297 "bit", // the only unit, valid per DSP0004, that we care about is byte; this makes more sense than checking meter 298 "nibble", 299 "dataword", 300 "byte*byte", 301 "1000*", 302 "*1024", 303 "* 1000 * byte", 304 "byte * 2^30 *", 305 "1000byte", 306 "1024*1024*", 307 "byte*byte", 308 "2^10/1024", 309 "1024*1024 / 1024", 310 "2 ^ 10", 311 "512 + 512", 312 "2048 - 1024", 313 } 314 315 for _, tc := range testCases { 316 t.Run(tc, func(t *testing.T) { 317 assert.Equal(t, int64(0), ParseCapacityAllocationUnits(tc)) 318 }) 319 } 320 }) 321 }