github.com/vmware/govmomi@v0.51.0/ovf/ovf_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 "bytes" 9 "encoding/json" 10 "fmt" 11 "os" 12 "path" 13 "strconv" 14 "testing" 15 "text/tabwriter" 16 17 "github.com/google/go-cmp/cmp" 18 "github.com/stretchr/testify/assert" 19 20 "github.com/vmware/govmomi/vim25/xml" 21 ) 22 23 func testEnvelope(t *testing.T, fn string) *Envelope { 24 f, err := os.Open(fn) 25 if err != nil { 26 t.Fatalf("error opening %s %s", fn, err) 27 } 28 defer f.Close() 29 30 e, err := Unmarshal(f) 31 if err != nil { 32 t.Fatalf("error unmarshaling test file %s", err) 33 } 34 35 if e == nil { 36 t.Fatal("empty envelope") 37 } 38 39 return e 40 } 41 42 func TestUnmarshal(t *testing.T) { 43 e := testEnvelope(t, "fixtures/ttylinux.ovf") 44 45 hw := e.VirtualSystem.VirtualHardware[0] 46 if n := len(hw.Config); n != 3 { 47 t.Errorf("Config=%d", n) 48 } 49 if n := len(hw.ExtraConfig); n != 2 { 50 t.Errorf("ExtraConfig=%d", n) 51 } 52 for i, c := range append(hw.Config, hw.ExtraConfig...) { 53 if *c.Required { 54 t.Errorf("%d: Required=%t", i, *c.Required) 55 } 56 if c.Key == "" { 57 t.Errorf("%d: key=''", i) 58 } 59 if c.Value == "" { 60 t.Errorf("%d: value=''", i) 61 } 62 } 63 } 64 65 func TestDeploymentOptions(t *testing.T) { 66 fn := os.Getenv("OVF_TEST_FILE") 67 if fn == "" { 68 t.Skip("OVF_TEST_FILE not specified") 69 } 70 e := testEnvelope(t, fn) 71 72 if e.DeploymentOption == nil { 73 t.Fatal("DeploymentOptionSection empty") 74 } 75 76 var b bytes.Buffer 77 tw := tabwriter.NewWriter(&b, 2, 0, 2, ' ', 0) 78 fmt.Fprintf(tw, "\n") 79 for _, c := range e.DeploymentOption.Configuration { 80 fmt.Fprintf(tw, "id=%s\t", c.ID) 81 fmt.Fprintf(tw, "label=%s\t", c.Label) 82 83 d := false 84 if c.Default != nil { 85 d = *c.Default 86 } 87 88 fmt.Fprintf(tw, "default=%t\t", d) 89 fmt.Fprintf(tw, "\n") 90 } 91 tw.Flush() 92 t.Log(b.String()) 93 } 94 95 func TestVirtualSystemCollection(t *testing.T) { 96 e := testEnvelope(t, "fixtures/virtualsystemcollection.ovf") 97 98 assert.Nil(t, e.VirtualSystem) 99 assert.NotNil(t, e.VirtualSystemCollection) 100 assert.Len(t, e.VirtualSystemCollection.VirtualSystem, 2) 101 assert.Equal(t, e.VirtualSystemCollection.VirtualSystem[0].ID, "storage server") 102 assert.Equal(t, e.VirtualSystemCollection.VirtualSystem[1].ID, "web-server") 103 } 104 105 func TestMultipleDeploymentConfigs(t *testing.T) { 106 e := testEnvelope(t, "fixtures/configspec.ovf") 107 108 assert.NotNil(t, e.VirtualSystem) 109 assert.Nil(t, e.VirtualSystemCollection) 110 assert.NotNil(t, e.DeploymentOption) 111 assert.Len(t, e.DeploymentOption.Configuration, 2) 112 113 assert.NotNil(t, e.DeploymentOption.Configuration[0].Default) 114 assert.True(t, *e.DeploymentOption.Configuration[0].Default) 115 assert.Equal(t, "default", e.DeploymentOption.Configuration[0].ID) 116 117 assert.Nil(t, e.DeploymentOption.Configuration[1].Default) 118 assert.Equal(t, "frontend", e.DeploymentOption.Configuration[1].ID) 119 120 assert.Len(t, e.VirtualSystem.VirtualHardware, 1) 121 assert.Len(t, e.VirtualSystem.VirtualHardware[0].Item, 24) 122 assert.Len(t, e.VirtualSystem.VirtualHardware[0].Item[2].Config, 1) 123 assert.NotNil(t, e.VirtualSystem.VirtualHardware[0].Item[2].Config[0].Required) 124 assert.False(t, *e.VirtualSystem.VirtualHardware[0].Item[2].Config[0].Required) 125 assert.Equal(t, "slotInfo.pciSlotNumber", e.VirtualSystem.VirtualHardware[0].Item[2].Config[0].Key) 126 assert.Equal(t, "128", e.VirtualSystem.VirtualHardware[0].Item[2].Config[0].Value) 127 } 128 129 func TestJSONEncoder(t *testing.T) { 130 t.Parallel() 131 132 testCases := []string{ 133 "fixtures/ttylinux.ovf", 134 "fixtures/configspec.ovf", 135 "fixtures/photon5.ovf", 136 "fixtures/ubuntu24.10.ovf", 137 "fixtures/virtualsystemcollection.ovf", 138 } 139 140 for i := range testCases { 141 tc := testCases[i] 142 143 t.Run(path.Base(tc), func(t *testing.T) { 144 145 t.Parallel() 146 147 // Unmarshal the OVF envelope from XML. 148 decodedFromXML := testEnvelope(t, tc) 149 150 // Marshal the OVF envelope to JSON. 151 data, err := json.MarshalIndent(decodedFromXML, "", " ") 152 153 if assert.NoError(t, err) { 154 155 if ok, _ := strconv.ParseBool(os.Getenv("DEBUG")); ok { 156 t.Log(string(data)) 157 } 158 159 // Unmarshal the OVF envelop from JSON. 160 var decodedFromJSON Envelope 161 if assert.NoError(t, json.Unmarshal(data, &decodedFromJSON)) { 162 163 // Assert the OVF envelopes unmarshaled from XML and from 164 // JSON are equal. 165 if assert.True( 166 t, 167 cmp.Equal(*decodedFromXML, decodedFromJSON), 168 cmp.Diff(*decodedFromXML, decodedFromJSON)) { 169 170 // Take the OVF envelope that was unmarshaled from 171 // JSON and marshal it *back* to XML. 172 data, err := xml.Marshal(decodedFromJSON) 173 if assert.NoError(t, err) { 174 175 // Take the OVF envelope that was unmarshaled from 176 // JSON, then back to XML, and unmarshal it from XML. 177 var decodedFromXMLFromJSON Envelope 178 if assert.NoError( 179 t, 180 xml.Unmarshal(data, &decodedFromXMLFromJSON)) { 181 182 // Assert this envelope is equal to the 183 // original. 184 assert.True( 185 t, 186 cmp.Equal(*decodedFromXML, decodedFromXMLFromJSON), 187 cmp.Diff(*decodedFromXML, decodedFromXMLFromJSON)) 188 } 189 } 190 } 191 } 192 } 193 }) 194 } 195 }