Skip to content

Commit

Permalink
Test readMetadataJSON
Browse files Browse the repository at this point in the history
A new testing helper is also added to ease object comparison.
  • Loading branch information
upils committed Sep 19, 2023
1 parent e3638bd commit 040e864
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 2 deletions.
10 changes: 10 additions & 0 deletions internal/helper/asserter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"runtime/debug"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
)

// Asserter for testing purposes
Expand Down Expand Up @@ -37,3 +39,11 @@ func (asserter *Asserter) AssertErrContains(err error, errString string) {
}
}
}

// AssertEqual asserts that two objects are equal using go-cmp
func (asserter *Asserter) AssertEqual(want, got interface{}, cmpOpts ...cmp.Option) {
diff := cmp.Diff(want, got, cmpOpts...)
if want != nil && diff != "" {
asserter.Errorf("mismatch (-want +got):\n%s", diff)
}
}
140 changes: 138 additions & 2 deletions internal/statemachine/state_machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"github.com/canonical/ubuntu-image/internal/helper"
diskfs "github.com/diskfs/go-diskfs"
"github.com/diskfs/go-diskfs/disk"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/invopop/jsonschema"
"github.com/snapcore/snapd/gadget"
"github.com/snapcore/snapd/gadget/quantity"
Expand All @@ -24,6 +26,10 @@ import (
"github.com/xeipuuv/gojsonschema"
)

const (
testDataDir = "testdata"
)

var testDir = "ubuntu-image-0615c8dd-d3af-4074-bfcb-c3d3c8392b06"

// for tests where we don't want to run actual states
Expand All @@ -49,6 +55,10 @@ var allTestStates = []stateFunc{
{"finish", (*StateMachine).finish},
}

func ptrToOffset(offset quantity.Offset) *quantity.Offset {
return &offset
}

// define some mocked versions of go package functions
func mockCopyBlob([]string) error {
return fmt.Errorf("Test Error")
Expand Down Expand Up @@ -267,7 +277,7 @@ func (TestStateMachine *testStateMachine) Setup() error {
}

// if --resume was passed, figure out where to start
if err := TestStateMachine.readMetadata(); err != nil {
if err := TestStateMachine.readMetadataGob(); err != nil {
return err
}

Expand Down Expand Up @@ -438,7 +448,7 @@ func TestFailedMetadataParse(t *testing.T) {
stateMachine.stateMachineFlags.Resume = true
stateMachine.stateMachineFlags.WorkDir = "testdata"

err := stateMachine.readMetadata()
err := stateMachine.readMetadataGob()
asserter.AssertErrContains(err, "failed to parse metadata file")
})
}
Expand Down Expand Up @@ -790,3 +800,129 @@ func TestFailedPostProcessGadgetYaml(t *testing.T) {
asserter.AssertErrContains(err, "disallowed for security purposes")
})
}

func TestStateMachine_readMetadataJSON(t *testing.T) {
type args struct {
metadataFile string
}

cmpOpts := []cmp.Option{
cmp.AllowUnexported(
StateMachine{},
gadget.Info{},
temporaryDirectories{},
stateFunc{},
),
cmpopts.IgnoreFields(stateFunc{}, "function"),
cmpopts.IgnoreFields(gadget.VolumeStructure{}, "EnclosingVolume"),
}

testCases := []struct {
name string
wantStateMachine *StateMachine
args args
shouldPass bool
expectedError string
}{
{
name: "successful read",
args: args{
metadataFile: "successful_read.json",
},
wantStateMachine: &StateMachine{
stateMachineFlags: &commands.StateMachineOpts{
Resume: true,
WorkDir: filepath.Join(testDataDir, "metadata"),
},
CurrentStep: "",
StepsTaken: 2,
YamlFilePath: "/tmp/ubuntu-image-2329554237/unpack/gadget/meta/gadget.yaml",
IsSeeded: true,
SectorSize: quantity.Size(512),
RootfsSize: quantity.Size(775915520),
states: allTestStates[2:],
GadgetInfo: &gadget.Info{
Volumes: map[string]*gadget.Volume{
"pc": {
Schema: "gpt",
Bootloader: "grub",
Structure: []gadget.VolumeStructure{
{
Name: "mbr",
Offset: ptrToOffset(quantity.Offset(quantity.Size(0))),
MinSize: quantity.Size(440),
Size: quantity.Size(440),
Role: "mbr",
Type: "mbr",
Content: []gadget.VolumeContent{
{
Image: "pc-boot.img",
},
},
Update: gadget.VolumeUpdate{
Edition: 1,
},
},
},
},
},
},
ImageSizes: map[string]quantity.Size{"pc": 3155165184},
VolumeOrder: []string{"pc"},
VolumeNames: nil,
tempDirs: temporaryDirectories{
rootfs: filepath.Join(testDataDir, "metadata", "root"),
unpack: filepath.Join(testDataDir, "metadata", "unpack"),
volumes: filepath.Join(testDataDir, "metadata", "volumes"),
},
},
shouldPass: true,
},
{
name: "invalid format",
args: args{
metadataFile: "invalid_format.json",
},
wantStateMachine: nil,
shouldPass: false,
expectedError: "failed to parse metadata file",
},
{
name: "missing state file",
args: args{
metadataFile: "inexistent.json",
},
wantStateMachine: nil,
shouldPass: false,
expectedError: "error reading metadata file",
},
{
name: "state file with too many steps",
args: args{
metadataFile: "too_many_steps.json",
},
wantStateMachine: nil,
shouldPass: false,
expectedError: "invalid steps taken count",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
asserter := helper.Asserter{T: t}
gotStateMachine := &StateMachine{
stateMachineFlags: &commands.StateMachineOpts{
Resume: true,
WorkDir: filepath.Join(testDataDir, "metadata"),
},
states: allTestStates,
}

err := gotStateMachine.readMetadataJSON(tc.args.metadataFile)
if tc.shouldPass {
asserter.AssertEqual(tc.wantStateMachine, gotStateMachine, cmpOpts...)
} else {
asserter.AssertErrContains(err, tc.expectedError)
}
})
}
}
7 changes: 7 additions & 0 deletions internal/statemachine/testdata/metadata/invalid_format.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"CurrentStep": "",
"StepsTaken": 2,
"YamlFilePath": "/tmp/ubuntu-image-2329554237/unpack/gadget/meta/gadget.yaml",
"IsSeeded": true,
"SectorSize": 512,
"RootfsSize": 775915520,
59 changes: 59 additions & 0 deletions internal/statemachine/testdata/metadata/successful_read.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"CurrentStep": "",
"StepsTaken": 2,
"YamlFilePath": "/tmp/ubuntu-image-2329554237/unpack/gadget/meta/gadget.yaml",
"IsSeeded": true,
"SectorSize": 512,
"RootfsSize": 775915520,
"GadgetInfo": {
"Volumes": {
"pc": {
"schema": "gpt",
"bootloader": "grub",
"id": "",
"structure": [
{
"name": "mbr",
"filesystem-label": "",
"offset": 0,
"offset-write": null,
"min-size": 440,
"size": 440,
"type": "mbr",
"role": "mbr",
"id": "",
"filesystem": "",
"content": [
{
"source": "",
"target": "",
"image": "pc-boot.img",
"offset": null,
"size": 0,
"unpack": false
}
],
"update": {
"edition": 1,
"preserve": null
}
}
]
}
},
"Defaults": null,
"Connections": null,
"KernelCmdline": {
"Allow": null
}
},
"ImageSizes": {
"pc": 3155165184
},
"VolumeOrder": [
"pc"
],
"VolumeNames": {
"pc": "pc.img"
}
}
59 changes: 59 additions & 0 deletions internal/statemachine/testdata/metadata/too_many_steps.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"CurrentStep": "",
"StepsTaken": 30,
"YamlFilePath": "/tmp/ubuntu-image-2329554237/unpack/gadget/meta/gadget.yaml",
"IsSeeded": true,
"SectorSize": 512,
"RootfsSize": 775915520,
"GadgetInfo": {
"Volumes": {
"pc": {
"schema": "gpt",
"bootloader": "grub",
"id": "",
"structure": [
{
"name": "mbr",
"filesystem-label": "",
"offset": 0,
"offset-write": null,
"min-size": 440,
"size": 440,
"type": "mbr",
"role": "mbr",
"id": "",
"filesystem": "",
"content": [
{
"source": "",
"target": "",
"image": "pc-boot.img",
"offset": null,
"size": 0,
"unpack": false
}
],
"update": {
"edition": 1,
"preserve": null
}
}
]
}
},
"Defaults": null,
"Connections": null,
"KernelCmdline": {
"Allow": null
}
},
"ImageSizes": {
"pc": 3155165184
},
"VolumeOrder": [
"pc"
],
"VolumeNames": {
"pc": "pc.img"
}
}

0 comments on commit 040e864

Please sign in to comment.