0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-07-04 21:14:05 +00:00

chore: refactor acceptance tests (#1195)

* misc: refactor acceptance tests

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>

* moar refactoring

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>

* fix cleanup in TestAccResourceFile

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>

---------

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Pavel Boldyrev 2024-04-08 22:01:32 -04:00 committed by GitHub
parent 119fc8ad76
commit c772fb3cf6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 375 additions and 352 deletions

View File

@ -26,6 +26,7 @@
"cputype",
"cpuunits",
"customdiff",
"Datasource",
"deepcode",
"directsync",
"efidisk",

View File

@ -7,15 +7,12 @@
package tests
import (
"fmt"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)
func TestAccDatasourceNode(t *testing.T) {
t.Parallel()
te := initTestEnvironment(t)
tests := []struct {
@ -23,7 +20,7 @@ func TestAccDatasourceNode(t *testing.T) {
steps []resource.TestStep
}{
{"read node attributes", []resource.TestStep{{
Config: fmt.Sprintf(`data "proxmox_virtual_environment_node" "test" { node_name = "%s" }`, te.nodeName),
Config: te.renderConfig(`data "proxmox_virtual_environment_node" "test" { node_name = "{{.NodeName}}" }`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributesSet("data.proxmox_virtual_environment_node.test", []string{
"cpu_count",
@ -40,9 +37,7 @@ func TestAccDatasourceNode(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: te.accProviders,
Steps: tt.steps,
})

View File

@ -15,13 +15,11 @@ import (
)
func TestAccDatasourceVersion(t *testing.T) {
t.Parallel()
te := initTestEnvironment(t)
datasourceName := "data.proxmox_virtual_environment_version.test"
resource.Test(t, resource.TestCase{
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: te.accProviders,
Steps: []resource.TestStep{
// Read testing

View File

@ -38,11 +38,11 @@ func TestAccResourceContainer(t *testing.T) { //nolint:wsl
ProtoV6ProviderFactories: te.accProviders,
Steps: []resource.TestStep{
{
Config: testAccResourceContainerCreateConfig(te, false),
Config: te.renderConfig(testAccResourceContainerCreateConfig(te, false)),
Check: testAccResourceContainerCreateCheck(te),
},
{
Config: testAccResourceContainerCreateConfig(te, true) + testAccResourceContainerCreateCloneConfig(te),
Config: te.renderConfig(testAccResourceContainerCreateConfig(te, true) + testAccResourceContainerCreateCloneConfig(te)),
Check: testAccResourceContainerCreateCloneCheck(te),
},
},
@ -56,12 +56,12 @@ func testAccResourceContainerCreateConfig(te *testEnvironment, isTemplate bool)
resource "proxmox_virtual_environment_download_file" "ubuntu_container_template" {
content_type = "vztmpl"
datastore_id = "local"
node_name = "%[1]s"
node_name = "{{.NodeName}}"
url = "http://download.proxmox.com/images/system/ubuntu-23.04-standard_23.04-1_amd64.tar.zst"
overwrite_unmanaged = true
}
resource "proxmox_virtual_environment_container" "test_container" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
vm_id = %d
template = %t
@ -95,7 +95,7 @@ resource "proxmox_virtual_environment_container" "test_container" {
type = "ubuntu"
}
}
`, te.nodeName, accTestContainerID, isTemplate)
`, accTestContainerID, isTemplate)
}
func testAccResourceContainerCreateCheck(te *testEnvironment) resource.TestCheckFunc {
@ -118,8 +118,7 @@ func testAccResourceContainerCreateCloneConfig(te *testEnvironment) string {
return fmt.Sprintf(`
resource "proxmox_virtual_environment_container" "test_container_clone" {
depends_on = [proxmox_virtual_environment_container.test_container]
node_name = "%s"
node_name = "{{.NodeName}}"
vm_id = %d
clone {
@ -130,7 +129,7 @@ resource "proxmox_virtual_environment_container" "test_container_clone" {
hostname = "test-clone"
}
}
`, te.nodeName, accCloneContainerID)
`, accCloneContainerID)
}
func testAccResourceContainerCreateCloneCheck(te *testEnvironment) resource.TestCheckFunc {

View File

@ -8,7 +8,6 @@ package tests
import (
"context"
"fmt"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
@ -26,57 +25,33 @@ const (
func TestAccResourceDownloadFile(t *testing.T) {
te := initTestEnvironment(t)
te.addTemplateVars(map[string]interface{}{
"FakeFileISO": fakeFileISO,
"FakeFileQCOW2": fakeFileQCOW2,
})
tests := []struct {
name string
steps []resource.TestStep
}{
{"download iso file", []resource.TestStep{{
Config: fmt.Sprintf(`
resource "proxmox_virtual_environment_download_file" "iso_image" {
content_type = "iso"
node_name = "%s"
datastore_id = "%s"
url = "%s"
overwrite_unmanaged = true
}
`, te.nodeName, accTestStorageName, fakeFileISO),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_download_file.iso_image", map[string]string{
"id": "local:iso/fake_file.iso",
"node_name": te.nodeName,
"datastore_id": accTestStorageName,
"url": fakeFileISO,
"file_name": "fake_file.iso",
"upload_timeout": "600",
"size": "3",
"verify": "true",
}),
testNoResourceAttributesSet("proxmox_virtual_environment_download_file.iso_image", []string{
"checksum",
"checksum_algorithm",
"decompression_algorithm",
}),
),
}}},
{"download qcow2 file", []resource.TestStep{{
Config: fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_download_file" "qcow2_image" {
content_type = "iso"
node_name = "%s"
datastore_id = "%s"
node_name = "{{.NodeName}}"
datastore_id = "{{.DatastoreID}}"
file_name = "fake_qcow2_file.img"
url = "%s"
url = "{{.FakeFileQCOW2}}"
checksum = "688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6"
checksum_algorithm = "sha256"
overwrite_unmanaged = true
}
`, te.nodeName, accTestStorageName, fakeFileQCOW2),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_download_file.qcow2_image", map[string]string{
"id": "local:iso/fake_qcow2_file.img",
"content_type": "iso",
"node_name": te.nodeName,
"datastore_id": accTestStorageName,
"datastore_id": te.datastoreID,
"url": fakeFileQCOW2,
"file_name": "fake_qcow2_file.img",
"upload_timeout": "600",
@ -90,24 +65,51 @@ func TestAccResourceDownloadFile(t *testing.T) {
}),
),
}}},
{"update file", []resource.TestStep{{
Config: fmt.Sprintf(`
{"download & update iso file", []resource.TestStep{
{
Config: te.renderConfig(`
resource "proxmox_virtual_environment_download_file" "iso_image" {
content_type = "iso"
node_name = "%s"
datastore_id = "%s"
node_name = "{{.NodeName}}"
datastore_id = "{{.DatastoreID}}"
url = "{{.FakeFileISO}}"
overwrite_unmanaged = true
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_download_file.iso_image", map[string]string{
"id": "local:iso/fake_file.iso",
"node_name": te.nodeName,
"datastore_id": te.datastoreID,
"url": fakeFileISO,
"file_name": "fake_file.iso",
"upload_timeout": "600",
"size": "3",
"verify": "true",
}),
testNoResourceAttributesSet("proxmox_virtual_environment_download_file.iso_image", []string{
"checksum",
"checksum_algorithm",
"decompression_algorithm",
}),
),
},
{
Config: te.renderConfig(`
resource "proxmox_virtual_environment_download_file" "iso_image" {
content_type = "iso"
node_name = "{{.NodeName}}"
datastore_id = "{{.DatastoreID}}"
file_name = "fake_iso_file.img"
url = "%s"
url = "{{.FakeFileISO}}"
upload_timeout = 10000
overwrite_unmanaged = true
}
`, te.nodeName, accTestStorageName, fakeFileISO),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_download_file.iso_image", map[string]string{
"id": "local:iso/fake_iso_file.img",
"content_type": "iso",
"node_name": te.nodeName,
"datastore_id": accTestStorageName,
"datastore_id": te.datastoreID,
"url": fakeFileISO,
"file_name": "fake_iso_file.img",
"upload_timeout": "10000",
@ -120,14 +122,15 @@ func TestAccResourceDownloadFile(t *testing.T) {
"decompression_algorithm",
}),
),
}}},
},
}},
{"override unmanaged file", []resource.TestStep{{
PreConfig: func() {
err := te.nodeStorageClient().DownloadFileByURL(context.Background(), &storage.DownloadURLPostRequestBody{
Content: types.StrPtr("iso"),
FileName: types.StrPtr("fake_file.iso"),
Node: types.StrPtr(te.nodeName),
Storage: types.StrPtr(accTestStorageName),
Storage: types.StrPtr(te.datastoreID),
URL: types.StrPtr(fakeFileISO),
}, 600)
require.NoError(t, err)
@ -136,27 +139,27 @@ func TestAccResourceDownloadFile(t *testing.T) {
require.NoError(t, err)
})
},
Config: fmt.Sprintf(`
resource "proxmox_virtual_environment_download_file" "iso_image" {
Config: te.renderConfig(`
resource "proxmox_virtual_environment_download_file" "iso_image3" {
content_type = "iso"
node_name = "%s"
datastore_id = "%s"
url = "%s"
node_name = "{{.NodeName}}"
datastore_id = "{{.DatastoreID}}"
url = "{{.FakeFileISO}}"
file_name = "fake_iso_file3.iso"
overwrite_unmanaged = true
}
`, te.nodeName, accTestStorageName, fakeFileISO),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_download_file.iso_image", map[string]string{
"id": "local:iso/fake_file.iso",
testResourceAttributes("proxmox_virtual_environment_download_file.iso_image3", map[string]string{
"id": "local:iso/fake_iso_file3.iso",
"content_type": "iso",
"node_name": te.nodeName,
"datastore_id": accTestStorageName,
"datastore_id": te.datastoreID,
"url": fakeFileISO,
"file_name": "fake_file.iso",
"file_name": "fake_iso_file3.iso",
"size": "3",
"verify": "true",
}),
testNoResourceAttributesSet("proxmox_virtual_environment_download_file.iso_image", []string{
testNoResourceAttributesSet("proxmox_virtual_environment_download_file.iso_image3", []string{
"checksum",
"checksum_algorithm",
"decompression_algorithm",
@ -167,7 +170,7 @@ func TestAccResourceDownloadFile(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
resource.Test(t, resource.TestCase{
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: te.accProviders,
Steps: tt.steps,
})

View File

@ -27,11 +27,6 @@ import (
"github.com/bpg/terraform-provider-proxmox/utils"
)
const (
accTestFileRawName = "proxmox_virtual_environment_file.test_raw"
accTestFileName = "proxmox_virtual_environment_file.test"
)
type nodeResolver struct {
node ssh.ProxmoxNode
}
@ -41,84 +36,192 @@ func (c *nodeResolver) Resolve(_ context.Context, _ string) (ssh.ProxmoxNode, er
}
func TestAccResourceFile(t *testing.T) {
t.Parallel()
te := initTestEnvironment(t)
snippetRaw := fmt.Sprintf("snippet-raw-%s.txt", gofakeit.Word())
snippetURL := "https://raw.githubusercontent.com/yaml/yaml-test-suite/main/src/229Q.yaml"
snippetFile1 := createFile(t, "snippet-file-1-*.yaml", "test snippet 1 - file")
snippetFile2 := createFile(t, "snippet-file-2-*.yaml", "test snippet 2 - file")
fileISO := createFile(t, "file-*.iso", "pretend it is an ISO")
snippetFile1 := strings.ReplaceAll(createFile(t, "snippet-file-1-*.yaml", "test snippet 1 - file").Name(), `\`, `/`)
snippetFile2 := strings.ReplaceAll(createFile(t, "snippet-file-2-*.yaml", "test snippet 2 - file").Name(), `\`, `/`)
fileISO := strings.ReplaceAll(createFile(t, "file-*.iso", "pretend it is an ISO").Name(), `\`, `/`)
resource.Test(t, resource.TestCase{
te.addTemplateVars(map[string]interface{}{
"SnippetRaw": snippetRaw,
"SnippetURL": snippetURL,
"SnippetFile1": snippetFile1,
"SnippetFile2": snippetFile2,
"FileISO": fileISO,
})
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: te.accProviders,
PreCheck: func() {
uploadSnippetFile(t, snippetFile2)
t.Cleanup(func() {
deleteSnippet(te, filepath.Base(snippetFile1))
deleteSnippet(te, filepath.Base(snippetFile2))
_ = os.Remove(snippetFile1)
_ = os.Remove(snippetFile2)
_ = os.Remove(fileISO)
})
},
Steps: []resource.TestStep{
{
Config: testAccResourceFileSnippetRawCreatedConfig(te, snippetRaw),
Check: testAccResourceFileSnippetRawCreatedCheck(snippetRaw),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test_raw" {
content_type = "snippets"
datastore_id = "local"
node_name = "{{.NodeName}}"
source_raw {
data = <<EOF
test snippet
EOF
file_name = "{{.SnippetRaw}}"
}
}`),
Check: testResourceAttributes("proxmox_virtual_environment_file.test_raw", map[string]string{
"content_type": "snippets",
"file_name": snippetRaw,
"source_raw.0.file_name": snippetRaw,
"source_raw.0.data": "test snippet\n",
"id": fmt.Sprintf("local:snippets/%s", snippetRaw),
}),
},
{
Config: testAccResourceFileCreatedConfig(te, snippetFile1.Name()),
Check: testAccResourceFileCreatedCheck("snippets", snippetFile1.Name()),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetFile1}}"
}
}`),
Check: testResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetFile1),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetFile1)),
}),
},
{
Config: testAccResourceFileCreatedConfig(te, snippetURL),
Check: testAccResourceFileCreatedCheck("snippets", snippetURL),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetURL}}"
}
}`),
Check: testResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetURL),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetURL)),
}),
},
{
Config: testAccResourceFileCreatedConfig(te, fileISO.Name()),
Check: testAccResourceFileCreatedCheck("iso", fileISO.Name()),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.FileISO}}"
}
}`),
Check: testResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "iso",
"file_name": filepath.Base(fileISO),
"id": fmt.Sprintf("local:iso/%s", filepath.Base(fileISO)),
}),
},
{
Config: testAccResourceFileTwoSourcesCreatedConfig(te),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_raw {
data = <<EOF
test snippet
EOF
file_name = "foo.yaml"
}
source_file {
path = "bar.yaml"
}
}`),
ExpectError: regexp.MustCompile("please specify .* - not both"),
},
{
Config: testAccResourceFileCreatedConfig(te, "https://github.com", "content_type = \"iso\""),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
content_type = "iso"
source_file {
path = "https://github.com"
}
}`),
ExpectError: regexp.MustCompile("failed to determine file name from the URL"),
},
{
Config: testAccResourceFileMissingSourceConfig(te),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
}`),
ExpectError: regexp.MustCompile("missing argument"),
},
// Do not allow to overwrite the file
{
Config: testAccResourceFileCreatedConfig(te, snippetFile2.Name(), "overwrite = false"),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
overwrite = false
source_file {
path = "{{.SnippetFile2}}"
}
}`),
ExpectError: regexp.MustCompile("already exists"),
},
// Allow to overwrite the file by default
{
Config: testAccResourceFileCreatedConfig(te, snippetFile2.Name()),
Check: testAccResourceFileCreatedCheck("snippets", snippetFile2.Name()),
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetFile2}}"
}
}`),
Check: testResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetFile2),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetFile2)),
}),
},
// Update testing
{
PreConfig: func() {
deleteSnippet(te, filepath.Base(snippetFile1.Name()))
},
Config: testAccResourceFileSnippetUpdateConfig(te, snippetFile1.Name()),
Check: testAccResourceFileSnippetUpdatedCheck(snippetFile1.Name()),
},
// ImportState testing
{
ResourceName: accTestFileName,
ImportState: true,
ImportStateVerify: true,
ImportStateId: fmt.Sprintf("pve/local:snippets/%s", filepath.Base(snippetFile2.Name())),
SkipFunc: func() (bool, error) {
// doesn't work, not sure why
return true, nil
deleteSnippet(te, filepath.Base(snippetFile1))
},
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "{{.NodeName}}"
source_file {
path = "{{.SnippetFile1}}"
}
}`),
Check: testResourceAttributes("proxmox_virtual_environment_file.test", map[string]string{
"content_type": "snippets",
"file_name": filepath.Base(snippetFile1),
"id": fmt.Sprintf("local:snippets/%s", filepath.Base(snippetFile1)),
}),
},
},
})
}
func uploadSnippetFile(t *testing.T, file *os.File) {
func uploadSnippetFile(t *testing.T, fileName string) {
t.Helper()
endpoint := utils.GetAnyStringEnv("PROXMOX_VE_ENDPOINT")
@ -142,12 +245,12 @@ func uploadSnippetFile(t *testing.T, file *os.File) {
)
require.NoError(t, err)
f, err := os.Open(file.Name())
f, err := os.Open(fileName)
require.NoError(t, err)
defer f.Close()
fname := filepath.Base(file.Name())
fname := filepath.Base(fileName)
err = sshClient.NodeStreamUpload(context.Background(), "pve", "/var/lib/vz/",
&api.FileUploadRequest{
ContentType: "snippets",
@ -181,107 +284,3 @@ func deleteSnippet(te *testEnvironment, fname string) {
err := te.nodeStorageClient().DeleteDatastoreFile(context.Background(), fmt.Sprintf("snippets/%s", fname))
require.NoError(te.t, err)
}
func testAccResourceFileSnippetRawCreatedConfig(te *testEnvironment, fname string) string {
te.t.Helper()
return fmt.Sprintf(`%s
resource "proxmox_virtual_environment_file" "test_raw" {
content_type = "snippets"
datastore_id = "local"
node_name = "%s"
source_raw {
data = <<EOF
test snippet
EOF
file_name = "%s"
}
}
`, te.providerConfig, te.nodeName, fname)
}
func testAccResourceFileCreatedConfig(te *testEnvironment, fname string, extra ...string) string {
te.t.Helper()
return fmt.Sprintf(`%s
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "%s"
source_file {
path = "%s"
}
%s
}
`, te.providerConfig, te.nodeName, strings.ReplaceAll(fname, `\`, `/`), strings.Join(extra, "\n"))
}
func testAccResourceFileTwoSourcesCreatedConfig(te *testEnvironment) string {
te.t.Helper()
return fmt.Sprintf(`%s
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "%s"
source_raw {
data = <<EOF
test snippet
EOF
file_name = "foo.yaml"
}
source_file {
path = "bar.yaml"
}
}
`, te.providerConfig, te.nodeName)
}
func testAccResourceFileMissingSourceConfig(te *testEnvironment) string {
te.t.Helper()
return fmt.Sprintf(`%s
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "%s"
}
`, te.providerConfig, te.nodeName)
}
func testAccResourceFileSnippetRawCreatedCheck(fname string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(accTestFileRawName, "content_type", "snippets"),
resource.TestCheckResourceAttr(accTestFileRawName, "file_name", fname),
resource.TestCheckResourceAttr(accTestFileRawName, "source_raw.0.file_name", fname),
resource.TestCheckResourceAttr(accTestFileRawName, "source_raw.0.data", "test snippet\n"),
resource.TestCheckResourceAttr(accTestFileRawName, "id", fmt.Sprintf("local:snippets/%s", fname)),
)
}
func testAccResourceFileCreatedCheck(ctype string, fname string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(accTestFileName, "content_type", ctype),
resource.TestCheckResourceAttr(accTestFileName, "file_name", filepath.Base(fname)),
resource.TestCheckResourceAttr(accTestFileName, "id", fmt.Sprintf("local:%s/%s", ctype, filepath.Base(fname))),
)
}
func testAccResourceFileSnippetUpdateConfig(te *testEnvironment, fname string) string {
te.t.Helper()
return fmt.Sprintf(`%s
resource "proxmox_virtual_environment_file" "test" {
datastore_id = "local"
node_name = "%s"
source_file {
path = "%s"
}
}
`, te.providerConfig, te.nodeName, strings.ReplaceAll(fname, `\`, `/`))
}
func testAccResourceFileSnippetUpdatedCheck(fname string) resource.TestCheckFunc {
return resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(accTestFileName, "content_type", "snippets"),
resource.TestCheckResourceAttr(accTestFileName, "file_name", filepath.Base(fname)),
resource.TestCheckResourceAttr(accTestFileName, "id", fmt.Sprintf("local:%s/%s", "snippets", filepath.Base(fname))),
)
}

View File

@ -28,17 +28,17 @@ func TestAccResourceLinuxBridge(t *testing.T) {
Steps: []resource.TestStep{
// Create and Read testing
{
Config: fmt.Sprintf(`
Config: te.renderConfig(fmt.Sprintf(`
resource "proxmox_virtual_environment_network_linux_bridge" "test" {
address = "%s"
autostart = true
comment = "created by terraform"
mtu = 1499
name = "%s"
node_name = "%s"
node_name = "{{.NodeName}}"
vlan_aware = true
}
`, ipV4cidr1, iface, te.nodeName),
`, ipV4cidr1, iface)),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_network_linux_bridge.test", map[string]string{
"address": ipV4cidr1,
@ -55,7 +55,7 @@ func TestAccResourceLinuxBridge(t *testing.T) {
},
// Update testing
{
Config: fmt.Sprintf(`
Config: te.renderConfig(fmt.Sprintf(`
resource "proxmox_virtual_environment_network_linux_bridge" "test" {
address = "%s"
address6 = "%s"
@ -63,9 +63,9 @@ func TestAccResourceLinuxBridge(t *testing.T) {
comment = ""
mtu = null
name = "%s"
node_name = "%s"
node_name = "{{.NodeName}}"
vlan_aware = false
}`, ipV4cidr2, ipV6cidr, iface, te.nodeName),
}`, ipV4cidr2, ipV6cidr, iface)),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_network_linux_bridge.test", map[string]string{
"address": ipV4cidr2,

View File

@ -33,7 +33,7 @@ func TestAccResourceLinuxVLAN(t *testing.T) {
Steps: []resource.TestStep{
// Create and Read testing
{
Config: testAccResourceLinuxVLANCreatedConfig(te, iface, vlan1),
Config: te.renderConfig(testAccResourceLinuxVLANCreatedConfig(iface, vlan1)),
Check: testAccResourceLinuxVLANCreatedCheck(iface, vlan1),
},
// ImportState testing
@ -44,7 +44,7 @@ func TestAccResourceLinuxVLAN(t *testing.T) {
},
// Create and Read with a custom name
{
Config: testAccResourceLinuxVLANCustomNameCreatedConfig(te, customName, iface, vlan2),
Config: te.renderConfig(testAccResourceLinuxVLANCustomNameCreatedConfig(customName, iface, vlan2)),
Check: testAccResourceLinuxVLANCustomNameCreatedCheck(customName, iface, vlan2),
// PVE API is unreliable. Sometimes it returns a wrong VLAN ID for this second interface.
SkipFunc: func() (bool, error) {
@ -53,22 +53,22 @@ func TestAccResourceLinuxVLAN(t *testing.T) {
},
// Update testing
{
Config: testAccResourceLinuxVLANUpdatedConfig(te, iface, vlan1, ipV4cidr),
Config: te.renderConfig(testAccResourceLinuxVLANUpdatedConfig(iface, vlan1, ipV4cidr)),
Check: testAccResourceLinuxVLANUpdatedCheck(iface, vlan1, ipV4cidr),
},
},
})
}
func testAccResourceLinuxVLANCreatedConfig(te *testEnvironment, iface string, vlan int) string {
func testAccResourceLinuxVLANCreatedConfig(iface string, vlan int) string {
return fmt.Sprintf(`
resource "proxmox_virtual_environment_network_linux_vlan" "test" {
comment = "created by terraform"
mtu = 1499
name = "%s.%d"
node_name = "%s"
node_name = "{{.NodeName}}"
}
`, iface, vlan, te.nodeName)
`, iface, vlan)
}
func testAccResourceLinuxVLANCreatedCheck(iface string, vlan int) resource.TestCheckFunc {
@ -81,17 +81,17 @@ func testAccResourceLinuxVLANCreatedCheck(iface string, vlan int) resource.TestC
)
}
func testAccResourceLinuxVLANCustomNameCreatedConfig(te *testEnvironment, name string, iface string, vlan int) string {
func testAccResourceLinuxVLANCustomNameCreatedConfig(name string, iface string, vlan int) string {
return fmt.Sprintf(`
resource "proxmox_virtual_environment_network_linux_vlan" "%s" {
comment = "created by terraform"
interface = "%s"
mtu = 1499
name = "%s"
node_name = "%s"
node_name = "{{.NodeName}}"
vlan = %d
}
`, name, iface, name, te.nodeName, vlan)
`, name, iface, name, vlan)
}
func testAccResourceLinuxVLANCustomNameCreatedCheck(name string, iface string, vlan int) resource.TestCheckFunc {
@ -106,16 +106,16 @@ func testAccResourceLinuxVLANCustomNameCreatedCheck(name string, iface string, v
)
}
func testAccResourceLinuxVLANUpdatedConfig(te *testEnvironment, iface string, vlan int, ipV4cidr string) string {
func testAccResourceLinuxVLANUpdatedConfig(iface string, vlan int, ipV4cidr string) string {
return fmt.Sprintf(`
resource "proxmox_virtual_environment_network_linux_vlan" "test" {
address = "%s"
address6 = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329/64"
comment = "updated by terraform"
name = "%s.%d"
node_name = "%s"
node_name = "{{.NodeName}}"
}
`, ipV4cidr, iface, vlan, te.nodeName)
`, ipV4cidr, iface, vlan)
}
func testAccResourceLinuxVLANUpdatedCheck(iface string, vlan int, ipV4cidr string) resource.TestCheckFunc {

View File

@ -21,9 +21,9 @@ func TestAccResourceUser(t *testing.T) {
name string
steps []resource.TestStep
}{
{"create and update user", []resource.TestStep{{
Config: `
resource "proxmox_virtual_environment_user" "user1" {
{"create and update user", []resource.TestStep{
{
Config: `resource "proxmox_virtual_environment_user" "user1" {
comment = "Managed by Terraform"
email = "user1@pve"
enabled = true
@ -31,10 +31,8 @@ func TestAccResourceUser(t *testing.T) {
first_name = "First"
last_name = "Last"
user_id = "user1@pve"
}
`,
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_user.user1", map[string]string{
}`,
Check: testResourceAttributes("proxmox_virtual_environment_user.user1", map[string]string{
"comment": "Managed by Terraform",
"email": "user1@pve",
"enabled": "true",
@ -43,23 +41,22 @@ func TestAccResourceUser(t *testing.T) {
"last_name": "Last",
"user_id": "user1@pve",
}),
),
}, {
Config: `
resource "proxmox_virtual_environment_user" "user1" {
},
{
Config: `resource "proxmox_virtual_environment_user" "user1" {
enabled = false
expiration_date = "2035-01-01T22:00:00Z"
user_id = "user1@pve"
first_name = "First One"
}
`,
}`,
Check: testResourceAttributes("proxmox_virtual_environment_user.user1", map[string]string{
"enabled": "false",
"expiration_date": "2035-01-01T22:00:00Z",
"first_name": "First One",
"user_id": "user1@pve",
}),
}}},
},
}},
}
for _, tt := range tests {

View File

@ -7,7 +7,6 @@
package tests
import (
"fmt"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
@ -23,9 +22,9 @@ func TestAccResourceVM(t *testing.T) {
step []resource.TestStep
}{
{"multiline description", []resource.TestStep{{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm1" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
description = <<-EOT
@ -33,7 +32,7 @@ func TestAccResourceVM(t *testing.T) {
description
value
EOT
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm1", map[string]string{
"description": "my\ndescription\nvalue",
@ -41,13 +40,13 @@ func TestAccResourceVM(t *testing.T) {
),
}}},
{"single line description", []resource.TestStep{{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm2" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
description = "my description value"
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm2", map[string]string{
"description": "my description value",
@ -55,13 +54,13 @@ func TestAccResourceVM(t *testing.T) {
),
}}},
{"no description", []resource.TestStep{{
Config: fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm3" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
description = ""
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm3", map[string]string{
"description": "",
@ -70,26 +69,26 @@ func TestAccResourceVM(t *testing.T) {
}}},
{
"protection", []resource.TestStep{{
Config: fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm4" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
protection = true
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm4", map[string]string{
"protection": "true",
}),
),
}, {
Config: fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm4" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
protection = false
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm4", map[string]string{
"protection": "false",
@ -99,28 +98,30 @@ func TestAccResourceVM(t *testing.T) {
},
{
"update cpu block", []resource.TestStep{{
Config: fmt.Sprintf(`resource "proxmox_virtual_environment_vm" "test_vm5" {
node_name = "%s"
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm5" {
node_name = "{{.NodeName}}"
started = false
cpu {
cores = 2
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm5", map[string]string{
"cpu.0.sockets": "1",
}),
),
}, {
Config: fmt.Sprintf(`resource "proxmox_virtual_environment_vm" "test_vm5" {
node_name = "%s"
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm5" {
node_name = "{{.NodeName}}"
started = false
cpu {
cores = 1
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm5", map[string]string{
"cpu.0.sockets": "1",
@ -130,28 +131,30 @@ func TestAccResourceVM(t *testing.T) {
},
{
"update memory block", []resource.TestStep{{
Config: fmt.Sprintf(`resource "proxmox_virtual_environment_vm" "test_vm6" {
node_name = "%s"
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm6" {
node_name = "{{.NodeName}}"
started = false
memory {
dedicated = 2048
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm6", map[string]string{
"memory.0.dedicated": "2048",
}),
),
}, {
Config: fmt.Sprintf(`resource "proxmox_virtual_environment_vm" "test_vm6" {
node_name = "%s"
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm6" {
node_name = "{{.NodeName}}"
started = false
memory {
dedicated = 1024
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm6", map[string]string{
"memory.0.dedicated": "1024",
@ -181,11 +184,11 @@ func TestAccResourceVMInitialization(t *testing.T) {
step []resource.TestStep
}{
{"initialization works with cloud-init config provided over SCSI interface", []resource.TestStep{{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "cloud_config" {
content_type = "snippets"
datastore_id = "local"
node_name = "%[1]s"
node_name = "{{.NodeName}}"
source_raw {
data = <<EOF
#cloud-config
@ -200,7 +203,7 @@ EOF
}
resource "proxmox_virtual_environment_vm" "test_vm_network1" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
started = true
agent {
enabled = true
@ -238,10 +241,10 @@ EOF
resource "proxmox_virtual_environment_download_file" "ubuntu_cloud_image" {
content_type = "iso"
datastore_id = "local"
node_name = "%[1]s"
node_name = "{{.NodeName}}"
url = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
overwrite_unmanaged = true
}`, te.nodeName),
}`),
}}},
}
@ -263,11 +266,11 @@ func TestAccResourceVMNetwork(t *testing.T) {
step []resource.TestStep
}{
{"network interfaces", []resource.TestStep{{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_file" "cloud_config" {
content_type = "snippets"
datastore_id = "local"
node_name = "%[1]s"
node_name = "{{.NodeName}}"
source_raw {
data = <<EOF
#cloud-config
@ -282,7 +285,7 @@ EOF
}
resource "proxmox_virtual_environment_vm" "test_vm_network1" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
started = true
agent {
enabled = true
@ -318,10 +321,10 @@ EOF
resource "proxmox_virtual_environment_download_file" "ubuntu_cloud_image" {
content_type = "iso"
datastore_id = "local"
node_name = "%[1]s"
node_name = "{{.NodeName}}"
url = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
overwrite_unmanaged = true
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm_network1", map[string]string{
"ipv4_addresses.#": "2",
@ -332,15 +335,15 @@ EOF
),
}}},
{"network device disconnected", []resource.TestStep{{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm_network2" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
network_device {
bridge = "vmbr0"
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{
"network_device.0.bridge": "vmbr0",
@ -348,16 +351,16 @@ EOF
}),
),
}, {
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_vm_network2" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
network_device {
bridge = "vmbr0"
disconnected = true
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{
"network_device.0.bridge": "vmbr0",
@ -390,9 +393,9 @@ func TestAccResourceVMDisks(t *testing.T) {
}{
{"create disk with default parameters, then update it", []resource.TestStep{
{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_disk1" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
name = "test-disk1"
@ -403,7 +406,7 @@ func TestAccResourceVMDisks(t *testing.T) {
interface = "virtio0"
size = 8
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_disk1", map[string]string{
"disk.0.aio": "io_uring",
@ -423,9 +426,9 @@ func TestAccResourceVMDisks(t *testing.T) {
),
},
{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_disk1" {
node_name = "%s"
node_name = "{{.NodeName}}"
started = false
name = "test-disk1"
@ -444,7 +447,7 @@ func TestAccResourceVMDisks(t *testing.T) {
iops_write_burstable = 800
}
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_disk1", map[string]string{
"disk.0.aio": "native",
@ -469,16 +472,16 @@ func TestAccResourceVMDisks(t *testing.T) {
},
}},
{"create disk from an image", []resource.TestStep{{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_download_file" "test_disk2_image" {
content_type = "iso"
datastore_id = "local"
node_name = "%[1]s"
node_name = "{{.NodeName}}"
url = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
overwrite_unmanaged = true
}
resource "proxmox_virtual_environment_vm" "test_disk2" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
started = false
name = "test-disk2"
disk {
@ -489,7 +492,7 @@ func TestAccResourceVMDisks(t *testing.T) {
discard = "on"
size = 20
}
}`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_disk2", map[string]string{
"disk.0.cache": "none",
@ -506,9 +509,9 @@ func TestAccResourceVMDisks(t *testing.T) {
}}},
{"clone default disk without overrides", []resource.TestStep{
{
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_disk3_template" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
started = false
name = "test-disk3-template"
template = "true"
@ -521,15 +524,14 @@ func TestAccResourceVMDisks(t *testing.T) {
}
}
resource "proxmox_virtual_environment_vm" "test_disk3" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
started = false
name = "test-disk3"
clone {
vm_id = proxmox_virtual_environment_vm.test_disk3_template.id
}
}
`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
// fully cloned disk, does not have any attributes in state
resource.TestCheckNoResourceAttr("proxmox_virtual_environment_vm.test_disk3", "disk.0"),
@ -546,9 +548,9 @@ func TestAccResourceVMDisks(t *testing.T) {
// this test is failing because of https://github.com/bpg/terraform-provider-proxmox/issues/873
return true, nil
},
Config: te.providerConfig + fmt.Sprintf(`
Config: te.renderConfig(`
resource "proxmox_virtual_environment_vm" "test_disk3_template" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
started = false
name = "test-disk3-template"
template = "true"
@ -564,7 +566,7 @@ func TestAccResourceVMDisks(t *testing.T) {
}
}
resource "proxmox_virtual_environment_vm" "test_disk3" {
node_name = "%[1]s"
node_name = "{{.NodeName}}"
started = false
name = "test-disk3"
@ -576,8 +578,7 @@ func TestAccResourceVMDisks(t *testing.T) {
interface = "scsi0"
//size = 10
}
}
`, te.nodeName),
}`),
Check: resource.ComposeTestCheckFunc(
testResourceAttributes("proxmox_virtual_environment_vm.test_disk3", map[string]string{
"disk.0.datastore_id": "local-lvm",

View File

@ -1,11 +1,13 @@
package tests
import (
"bytes"
"context"
"fmt"
"net/url"
"sync"
"testing"
"text/template"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
@ -24,15 +26,14 @@ import (
"github.com/bpg/terraform-provider-proxmox/utils"
)
const (
accTestStorageName = "local"
)
type testEnvironment struct {
t *testing.T
templateVars map[string]any
providerConfig string
accProviders map[string]func() (tfprotov6.ProviderServer, error)
nodeName string
datastoreID string
accProviders map[string]func() (tfprotov6.ProviderServer, error)
once sync.Once
nc *nodes.Client
}
@ -71,14 +72,43 @@ provider "proxmox" {
}
`, nodeName, nodeAddress, nodePort)
const datastoreID = "local"
return &testEnvironment{
t: t,
templateVars: map[string]any{
"ProviderConfig": pc,
"NodeName": nodeName,
"DatastoreID": datastoreID,
},
providerConfig: pc,
accProviders: muxProviders(t),
nodeName: nodeName,
datastoreID: datastoreID,
accProviders: muxProviders(t),
}
}
// addTemplateVars adds the given variables to the template variables of the current test environment.
// Please note that NodeName and ProviderConfig are reserved keys, they are set by the test environment
// and cannot be overridden.
func (e *testEnvironment) addTemplateVars(vars map[string]any) {
for k, v := range vars {
e.templateVars[k] = v
}
}
// renderConfig renders the given configuration with for the current test environment using template engine.
func (e *testEnvironment) renderConfig(cfg string) string {
tmpl, err := template.New("config").Parse("{{.ProviderConfig}}" + cfg)
require.NoError(e.t, err)
var buf bytes.Buffer
err = tmpl.Execute(&buf, e.templateVars)
require.NoError(e.t, err)
return buf.String()
}
func (e *testEnvironment) nodeClient() *nodes.Client {
if e.nc == nil {
e.once.Do(
@ -112,7 +142,7 @@ func (e *testEnvironment) nodeClient() *nodes.Client {
func (e *testEnvironment) nodeStorageClient() *storage.Client {
nodesClient := e.nodeClient()
return &storage.Client{Client: nodesClient, StorageName: accTestStorageName}
return &storage.Client{Client: nodesClient, StorageName: e.datastoreID}
}
// testAccMuxProviders returns a map of mux servers for the acceptance tests.