@@ -3,8 +3,10 @@ package provider
33import (
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+
459513func 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+
701828func testAccCheckDomainIsRunning (name string ) resource.TestCheckFunc {
702829 return func (s * terraform.State ) error {
703830 ctx := context .Background ()
0 commit comments