-
Notifications
You must be signed in to change notification settings - Fork 20
/
disk_downloadimage_test.go
157 lines (135 loc) · 4.07 KB
/
disk_downloadimage_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package ovirtclient_test
import (
"bytes"
"embed"
"encoding/binary"
"fmt"
"io"
"testing"
ovirtclient "github.com/ovirt/go-ovirt-client/v3"
)
func TestImageDownload(t *testing.T) {
t.Parallel()
fh, size := getTestImageFile(t)
testImageData, _ := getTestImageData(t)
helper := getHelper(t)
client := helper.GetClient()
imageName := fmt.Sprintf("client_test_%s", helper.GenerateRandomID(5))
uploadResult, err := client.UploadToNewDisk(
helper.GetStorageDomainID(),
ovirtclient.ImageFormatRaw,
size,
ovirtclient.CreateDiskParams().MustWithSparse(true).MustWithAlias(imageName),
fh,
)
t.Cleanup(func() {
if uploadResult != nil {
disk := uploadResult.Disk()
if disk != nil {
diskID := uploadResult.Disk().ID()
if err := client.RemoveDisk(diskID); err != nil {
t.Fatal(fmt.Errorf("failed to remove disk (%w)", err))
}
}
}
})
if err != nil {
t.Fatal(fmt.Errorf("failed to upload image (%w)", err))
}
data := downloadImage(t, client, uploadResult)
// Note about this check: this will work only on RAW images. For QCOW images the blocks may
// be reordered, resulting in different files after download.
if !bytes.Equal(data[:len(testImageData)], testImageData) {
t.Fatal(fmt.Errorf("the downloaded image did not match the original upload"))
}
}
//go:embed testimage/*
var testImageFS embed.FS
//go:generate go run scripts/get_test_image/get_test_image.go
type qcowHeader struct {
Magic [4]byte
Version uint32
BackingFileOffset uint64
BackingFileSize uint32
ClusterBits uint32
Size uint64
CryptMethod uint32
L1Size uint32
L1TableOffset uint64
RefcountTableOffset uint64
RefcountTableClusters uint32
NBSnapshots uint32
SnapshotsOffset uint64
}
// getFullTestImage downloads a fully functional test image with the QEMU guest image to a temporary directory and
// offers it as a reader.
func getFullTestImage(t *testing.T) (io.ReadSeekCloser, uint64, uint64) {
fh, err := testImageFS.Open("testimage/full.qcow")
if err != nil {
t.Skipf("testimage/full.qcow not found in the test environment. Did you run go generate? (%v)", err)
}
defer func() {
_ = fh.Close()
}()
stat, err := fh.Stat()
if err != nil {
t.Skipf("testimage/full.qcow not found in the test environment. Did you run go generate? (%v)", err)
}
size := stat.Size()
fullTestImage, err := io.ReadAll(fh)
if err != nil {
t.Skipf("testimage/full.qcow not found in the test environment. Did you run go generate? (%v)", err)
}
header := &qcowHeader{}
if err := binary.Read(bytes.NewReader(fullTestImage), binary.BigEndian, header); err != nil {
t.Fatalf("cannot read QCOW header from full test image (%v)", err)
}
return &nopReadCloser{bytes.NewReader(fullTestImage)}, uint64(size), header.Size
}
func getTestImageFile(t *testing.T) (io.ReadSeekCloser, uint64) {
testImage, size := getTestImageData(t)
return &nopReadCloser{bytes.NewReader(testImage)}, size
}
type nopReadCloser struct {
io.ReadSeeker
}
func (n nopReadCloser) Close() error {
return nil
}
func getTestImageData(t *testing.T) ([]byte, uint64) {
fh, err := testImageFS.Open("testimage/image")
if err != nil {
t.Errorf("testimage/image not found in the test environment. (%v)", err)
}
defer func() {
_ = fh.Close()
}()
stat, err := fh.Stat()
if err != nil {
t.Errorf("testimage/image not found in the test environment. (%v)", err)
}
size := stat.Size()
testImage, err := io.ReadAll(fh)
if err != nil {
t.Errorf("testimage/image not found in the test environment. (%v)", err)
}
return testImage, uint64(size)
}
func downloadImage(
t *testing.T,
client ovirtclient.Client,
uploadResult ovirtclient.UploadImageResult,
) []byte {
imageDownload, err := client.DownloadDisk(uploadResult.Disk().ID(), ovirtclient.ImageFormatRaw)
if err != nil {
t.Fatal(fmt.Errorf("failed to download image (%w)", err))
}
defer func() {
_ = imageDownload.Close()
}()
data, err := io.ReadAll(imageDownload)
if err != nil {
t.Fatal(fmt.Errorf("failed to download image (%w)", err))
}
return data
}