hcloud-upload-image/hcloudimages/client_test.go
Julian Tölle 420dcf94c9
Some checks are pending
ci / lint (push) Waiting to run
ci / test (push) Waiting to run
ci / go-mod-tidy (push) Waiting to run
ci / cli-help-pages (push) Waiting to run
docs / deploy (push) Waiting to run
release-please / release-please (push) Waiting to run
fix: upload from local image generates broken command (#98)
While adding support for qcow2 images in #69 I broke support for local
images. Building a shell pipeline through string concatenation is not a
good idea...

The specific issue was fixed and I also moved building the shell
pipeline to a separate function and added unit tests for all cases, so
it should be easier to spot these issues in the future.

Closes #97
2025-05-09 21:22:24 +00:00

111 lines
2.8 KiB
Go

package hcloudimages
import (
"net/url"
"testing"
)
func mustParseURL(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
panic(err)
}
return u
}
func TestAssembleCommand(t *testing.T) {
tests := []struct {
name string
options UploadOptions
want string
wantErr bool
}{
{
name: "local raw",
options: UploadOptions{},
want: "bash -c 'set -euo pipefail && dd of=/dev/sda bs=4M && sync'",
},
{
name: "remote raw",
options: UploadOptions{
ImageURL: mustParseURL("https://example.com/image.xz"),
},
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.xz\" | dd of=/dev/sda bs=4M && sync'",
},
{
name: "local xz",
options: UploadOptions{
ImageCompression: CompressionXZ,
},
want: "bash -c 'set -euo pipefail && xz -cd | dd of=/dev/sda bs=4M && sync'",
},
{
name: "remote xz",
options: UploadOptions{
ImageURL: mustParseURL("https://example.com/image.xz"),
ImageCompression: CompressionXZ,
},
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.xz\" | xz -cd | dd of=/dev/sda bs=4M && sync'",
},
{
name: "local bz2",
options: UploadOptions{
ImageCompression: CompressionBZ2,
},
want: "bash -c 'set -euo pipefail && bzip2 -cd | dd of=/dev/sda bs=4M && sync'",
},
{
name: "remote bz2",
options: UploadOptions{
ImageURL: mustParseURL("https://example.com/image.bz2"),
ImageCompression: CompressionXZ,
},
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.bz2\" | xz -cd | dd of=/dev/sda bs=4M && sync'",
},
{
name: "local qcow2",
options: UploadOptions{
ImageFormat: FormatQCOW2,
},
want: "bash -c 'set -euo pipefail && tee image.qcow2 > /dev/null && qemu-img dd -f qcow2 -O raw if=image.qcow2 of=/dev/sda bs=4M && sync'",
},
{
name: "remote qcow2",
options: UploadOptions{
ImageURL: mustParseURL("https://example.com/image.qcow2"),
ImageFormat: FormatQCOW2,
},
want: "bash -c 'set -euo pipefail && wget --no-verbose -O - \"https://example.com/image.qcow2\" | tee image.qcow2 > /dev/null && qemu-img dd -f qcow2 -O raw if=image.qcow2 of=/dev/sda bs=4M && sync'",
},
{
name: "unknown compression",
options: UploadOptions{
ImageCompression: "noodle",
},
wantErr: true,
},
{
name: "unknown format",
options: UploadOptions{
ImageFormat: "poodle",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := assembleCommand(tt.options)
if (err != nil) != tt.wantErr {
t.Errorf("assembleCommand() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("assembleCommand() got = %v, want %v", got, tt.want)
}
})
}
}