Add KVM provider pure builders: domain XML, volumes, seed ISO, metadata
Introduces internal/provider/kvm with the side-effect-free pieces of the provider: providerID format/parse, the namespaced <metadata> element that carries the GC contract, q35 domain XML over pool volumes, volume XML for overlays and raw seeds, the NoCloud seed ISO built with kdomanski/iso9660, and config defaults. All unit-tested. Step 2 of docs/plans/2026-09-04-1404-kvm-provider.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package kvm
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVolumeNames(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := overlayVolumeName("proxy-x"); got != "proxy-x.qcow2" {
|
||||
t.Errorf("overlayVolumeName = %q", got)
|
||||
}
|
||||
if got := seedVolumeName("proxy-x"); got != "proxy-x-seed.iso" {
|
||||
t.Errorf("seedVolumeName = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildVolumeXML_overlay(t *testing.T) {
|
||||
t.Parallel()
|
||||
raw, err := buildVolumeXML(overlayVolume("proxy-x", 10, "/var/lib/libvirt/images/base-debian-13.qcow2", "qcow2"))
|
||||
if err != nil {
|
||||
t.Fatalf("buildVolumeXML() error = %v", err)
|
||||
}
|
||||
var v volumeXML
|
||||
if err := xml.Unmarshal([]byte(raw), &v); err != nil {
|
||||
t.Fatalf("output is not well-formed XML: %v", err)
|
||||
}
|
||||
if v.Type != "file" || v.Name != "proxy-x.qcow2" {
|
||||
t.Errorf("type/name = %s/%s", v.Type, v.Name)
|
||||
}
|
||||
if v.Capacity.Unit != "bytes" || v.Capacity.Value != 10*bytesPerGiB {
|
||||
t.Errorf("capacity = %d %s, want %d bytes", v.Capacity.Value, v.Capacity.Unit, 10*bytesPerGiB)
|
||||
}
|
||||
if v.Target.Format.Type != "qcow2" {
|
||||
t.Errorf("format = %q", v.Target.Format.Type)
|
||||
}
|
||||
if v.BackingStore == nil {
|
||||
t.Fatalf("backingStore missing:\n%s", raw)
|
||||
}
|
||||
if v.BackingStore.Path != "/var/lib/libvirt/images/base-debian-13.qcow2" || v.BackingStore.Format.Type != "qcow2" {
|
||||
t.Errorf("backingStore = %+v", v.BackingStore)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildVolumeXML_rawHasNoBackingStore(t *testing.T) {
|
||||
t.Parallel()
|
||||
raw, err := buildVolumeXML(rawVolume("proxy-x-seed.iso", 372736))
|
||||
if err != nil {
|
||||
t.Fatalf("buildVolumeXML() error = %v", err)
|
||||
}
|
||||
if strings.Contains(raw, "backingStore") {
|
||||
t.Errorf("raw volume must not declare a backing store:\n%s", raw)
|
||||
}
|
||||
var v volumeXML
|
||||
if err := xml.Unmarshal([]byte(raw), &v); err != nil {
|
||||
t.Fatalf("output is not well-formed XML: %v", err)
|
||||
}
|
||||
if v.Name != "proxy-x-seed.iso" || v.Capacity.Value != 372736 || v.Target.Format.Type != "raw" {
|
||||
t.Errorf("volume = %+v", v)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user