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  }