Skip to content

Commit

Permalink
JSON Discriminators for vim25/types
Browse files Browse the repository at this point in the history
This patch adds support to GoVmomi for marshaling/unmarshaling
the vim25/types (and other VMODL1 types) to/from JSON using:

* a customized version of the Golang encoding/json package that
  relies upon...
* a new discriminator field added to every every complex object
  marshaled to JSON, the "_typeName" field. this field's value
  must match the value of the type's registered type name from
  the type registry
  • Loading branch information
akutz committed Dec 13, 2022
1 parent ed535ae commit 2e7fa94
Show file tree
Hide file tree
Showing 2 changed files with 797 additions and 0 deletions.
148 changes: 148 additions & 0 deletions vim25/types/json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
Copyright (c) 2022-2022 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package types

import (
"bytes"
"os"
"strings"
"testing"

"github.com/vmware/govmomi/vim25/json"
)

const discriminatorName = "_typeName"

func TestJSONMarshalVirtualMachineConfigSpec(t *testing.T) {
var w bytes.Buffer
enc := json.NewEncoder(&w)
enc.SetIndent("", " ")
enc.UseDiscriminator(discriminatorName)

if err := enc.Encode(VirtualMachineConfigSpec{
Name: "Hello, world.",
DeviceChange: []BaseVirtualDeviceConfigSpec{
&VirtualDeviceConfigSpec{
Operation: VirtualDeviceConfigSpecOperationAdd,
FileOperation: VirtualDeviceConfigSpecFileOperationCreate,
Device: &VirtualVmxnet3{
VirtualVmxnet: VirtualVmxnet{
VirtualEthernetCard: VirtualEthernetCard{
VirtualDevice: VirtualDevice{
Key: 3,
},
MacAddress: "00:11:22:33:44:55:66:88",
},
},
},
},
},
}); err != nil {
t.Fatal(err)
}
act, exp := w.String(), virtualMachineConfigSpecWithDeviceChangesJSON
if act != exp {
t.Errorf("act json != exp json\nact=%s\nexp=%s", act, exp)
}
}

func TestJSONUnmarshalVirtualMachineConfigSpec(t *testing.T) {
dec := json.NewDecoder(strings.NewReader(virtualMachineConfigSpecWithVAppConfigJSON))
dec.UseDiscriminator(discriminatorName, json.DiscriminatorToTypeFunc(TypeFunc()))

var obj VirtualMachineConfigSpec
if err := dec.Decode(&obj); err != nil {
t.Fatal(err)
}

var w bytes.Buffer
enc := json.NewEncoder(&w)
enc.SetIndent("", " ")
enc.UseDiscriminator(discriminatorName)

if err := enc.Encode(obj); err != nil {
t.Fatal(err)
}

act, exp := w.String(), virtualMachineConfigSpecWithVAppConfigJSON
if act != exp {
t.Errorf("act json != exp json\nact=%s\nexp=%s", act, exp)
}
}

func TestJSONUnmarshalVirtualMachineConfigInfo(t *testing.T) {
f, err := os.Open("./testdata/virtualMachineConfigInfo.json")
if err != nil {
t.Fatal(err)
}
defer f.Close()

dec := json.NewDecoder(f)
dec.UseDiscriminator(discriminatorName, json.DiscriminatorToTypeFunc(TypeFunc()))

var obj VirtualMachineConfigInfo
if err := dec.Decode(&obj); err != nil {
t.Fatal(err)
}

enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
enc.UseDiscriminator(discriminatorName)

if err := enc.Encode(obj); err != nil {
t.Fatal(err)
}
}

const virtualMachineConfigSpecWithDeviceChangesJSON = `{
"_typeName": "VirtualMachineConfigSpec",
"name": "Hello, world.",
"deviceChange": [
{
"_typeName": "VirtualDeviceConfigSpec",
"operation": "add",
"fileOperation": "create",
"device": {
"_typeName": "VirtualVmxnet3",
"key": 3,
"macAddress": "00:11:22:33:44:55:66:88"
}
}
]
}
`

const virtualMachineConfigSpecWithVAppConfigJSON = `{
"_typeName": "VirtualMachineConfigSpec",
"name": "Hello, world.",
"vAppConfig": {
"_typeName": "VmConfigSpec",
"product": [
{
"_typeName": "VAppProductSpec",
"operation": "add",
"info": {
"_typeName": "VAppProductInfo",
"key": 1,
"name": "p1"
}
}
],
"installBootRequired": false
}
}
`
Loading

0 comments on commit 2e7fa94

Please sign in to comment.