Skip to content

Commit 341c24b

Browse files
committed
test: add opt-in image-based domain shutdown acc test
1 parent 3028e9f commit 341c24b

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

Makefile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
.PHONY: help build install test testacc testacc-tofu sweep lint fmt clean generate
1+
.PHONY: help build install test testacc testacc-tofu sweep lint fmt clean generate testdeps-acc
22

33
# Default target
44
.DEFAULT_GOAL := help
55

66
# Version can be overridden
77
VERSION ?= dev
8+
CIRROS_VERSION ?= 0.6.2
9+
TEST_IMAGE_DIR ?= .cache/test-images
10+
CIRROS_IMAGE ?= $(TEST_IMAGE_DIR)/cirros-$(CIRROS_VERSION)-x86_64-disk.img
11+
CIRROS_URL ?= https://download.cirros-cloud.net/$(CIRROS_VERSION)/cirros-$(CIRROS_VERSION)-x86_64-disk.img
812

913
# Build flags
1014
LDFLAGS := -ldflags "-X main.version=$(VERSION)"
@@ -35,6 +39,17 @@ testacc: generate ## Run acceptance tests (requires running libvirt)
3539
@echo "Running acceptance tests..."
3640
@TF_ACC=1 go test -count=1 -v -timeout 10m ./internal/provider
3741

42+
testdeps-acc: ## Download/cache acceptance test image dependencies (CirrOS)
43+
@echo "Preparing acceptance test image dependencies..."
44+
@mkdir -p $(TEST_IMAGE_DIR)
45+
@if [ ! -f "$(CIRROS_IMAGE)" ]; then \
46+
echo "Downloading $(CIRROS_URL) -> $(CIRROS_IMAGE)"; \
47+
curl -fL --retry 3 --retry-delay 2 -o "$(CIRROS_IMAGE)" "$(CIRROS_URL)"; \
48+
else \
49+
echo "Using cached image: $(CIRROS_IMAGE)"; \
50+
fi
51+
@echo "Set LIBVIRT_TEST_ACPI_IMAGE=$(CIRROS_IMAGE) to run image-based shutdown ACC test."
52+
3853
testacc-tofu: ## Run acceptance tests with OpenTofu
3954
@TF_ACC_TERRAFORM_PATH=$$(which tofu) TF_ACC_PROVIDER_NAMESPACE=dmacvicar TF_ACC_PROVIDER_HOST=registry.terraform.io $(MAKE) testacc
4055

internal/provider/domain_resource_test.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package provider
33
import (
44
"context"
55
"fmt"
6+
"os"
67
"strings"
78
"testing"
9+
"time"
810

911
golibvirt "github.com/digitalocean/go-libvirt"
1012
libvirtclient "github.com/dmacvicar/terraform-provider-libvirt/v2/internal/libvirt"
@@ -456,6 +458,58 @@ func TestAccDomainResource_destroyShutdownStoppedDomainDefaultTimeout(t *testing
456458
})
457459
}
458460

461+
func TestAccDomainResource_destroyShutdownRunningWithImage(t *testing.T) {
462+
imagePath := os.Getenv("LIBVIRT_TEST_ACPI_IMAGE")
463+
if imagePath == "" {
464+
t.Skip("set LIBVIRT_TEST_ACPI_IMAGE to run shutdown test with a real guest image")
465+
}
466+
if _, err := os.Stat(imagePath); err != nil {
467+
t.Skipf("LIBVIRT_TEST_ACPI_IMAGE does not exist: %v", err)
468+
}
469+
testAccRequireDefaultPool(t)
470+
471+
resource.Test(t, resource.TestCase{
472+
PreCheck: func() { testAccPreCheck(t) },
473+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
474+
CheckDestroy: testAccCheckDomainDestroy,
475+
Steps: []resource.TestStep{
476+
{
477+
Config: testAccDomainResourceConfigDestroyShutdownRunningWithImage("test-domain-shutdown-image", "test-volume-shutdown-image", imagePath, 120),
478+
Check: resource.ComposeAggregateTestCheckFunc(
479+
resource.TestCheckResourceAttr("libvirt_domain.test", "name", "test-domain-shutdown-image"),
480+
resource.TestCheckResourceAttr("libvirt_domain.test", "running", "true"),
481+
testAccCheckDomainIsRunning("test-domain-shutdown-image"),
482+
),
483+
},
484+
{
485+
// Give the guest time to finish early boot before testing shutdown behavior.
486+
PreConfig: func() { time.Sleep(45 * time.Second) },
487+
Config: testAccDomainResourceConfigDestroyShutdownRunningWithImage("test-domain-shutdown-image", "test-volume-shutdown-image", imagePath, 120),
488+
Destroy: true,
489+
},
490+
},
491+
})
492+
}
493+
494+
func testAccRequireDefaultPool(t *testing.T) {
495+
t.Helper()
496+
497+
ctx := context.Background()
498+
client, err := libvirtclient.NewClient(ctx, testAccLibvirtURI())
499+
if err != nil {
500+
t.Skipf("failed to create libvirt client: %v", err)
501+
}
502+
defer func() { _ = client.Close() }()
503+
504+
pool, err := client.Libvirt().StoragePoolLookupByName("default")
505+
if err != nil {
506+
t.Skipf("default storage pool not available: %v", err)
507+
}
508+
509+
// Ignore error if pool is already active; we only need a usable pool.
510+
_ = client.Libvirt().StoragePoolCreate(pool, 0)
511+
}
512+
459513
func TestAccDomainResource_updateWithRunning(t *testing.T) {
460514
resource.Test(t, resource.TestCase{
461515
PreCheck: func() { testAccPreCheck(t) },
@@ -698,6 +752,79 @@ resource "libvirt_domain" "test" {
698752
`, name)
699753
}
700754

755+
func testAccDomainResourceConfigDestroyShutdownRunningWithImage(domainName, volumeName, imagePath string, timeout int64) string {
756+
return fmt.Sprintf(`
757+
resource "libvirt_volume" "test" {
758+
name = "%[2]s.qcow2"
759+
pool = "default"
760+
target = {
761+
format = {
762+
type = "qcow2"
763+
}
764+
}
765+
create = {
766+
content = {
767+
url = %[3]q
768+
}
769+
}
770+
}
771+
772+
resource "libvirt_domain" "test" {
773+
name = %[1]q
774+
memory = 512
775+
memory_unit = "MiB"
776+
vcpu = 1
777+
type = "kvm"
778+
running = true
779+
780+
destroy = {
781+
shutdown = {
782+
timeout = %[4]d
783+
}
784+
}
785+
786+
os = {
787+
type = "hvm"
788+
type_arch = "x86_64"
789+
type_machine = "q35"
790+
}
791+
792+
features = {
793+
acpi = true
794+
}
795+
796+
devices = {
797+
disks = [
798+
{
799+
source = {
800+
volume = {
801+
pool = "default"
802+
volume = libvirt_volume.test.name
803+
}
804+
}
805+
driver = {
806+
name = "qemu"
807+
type = "qcow2"
808+
}
809+
target = {
810+
dev = "sda"
811+
bus = "sata"
812+
}
813+
}
814+
]
815+
graphics = [
816+
{
817+
vnc = {
818+
auto_port = true
819+
listen = "0.0.0.0"
820+
}
821+
}
822+
]
823+
}
824+
}
825+
`, domainName, volumeName, imagePath, timeout)
826+
}
827+
701828
func testAccCheckDomainIsRunning(name string) resource.TestCheckFunc {
702829
return func(s *terraform.State) error {
703830
ctx := context.Background()

0 commit comments

Comments
 (0)