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