0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-07-01 11:02:59 +00:00
terraform-provider-proxmox/fwprovider/nodes/apt/repo_test.go
Pavel Boldyrev d193abd33e
fix(vm): improve reliability of VM create / get operations (#1431)
* fix(vm): improve reliability of VM create / get operations

- Add retries to GET API calls, fix retrying on POST (VM create) API calls.
- Minor fix in acceptance tests

---------

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
2024-07-08 18:17:53 +00:00

460 lines
16 KiB
Go

//go:build acceptance || all
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package apt_test
import (
"fmt"
"regexp"
"strconv"
"strings"
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
"github.com/hashicorp/terraform-plugin-testing/statecheck"
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
"github.com/bpg/terraform-provider-proxmox/fwprovider/nodes/apt"
"github.com/bpg/terraform-provider-proxmox/fwprovider/test"
apitypes "github.com/bpg/terraform-provider-proxmox/proxmox/types/nodes/apt/repositories"
)
// Note that some "hard-coded" values must be used because of the way how the Proxmox VE API for APT repositories works.
const (
testAccResourceRepoSelector = "proxmox_virtual_environment_" + apt.ResourceRepoIDPrefix + ".test"
// By default, this should be the main Debian package repository on any (new) Proxmox VE node.
testAccResourceRepoIndex = 0
testAccResourceStandardRepoSelector = "proxmox_virtual_environment_" + apt.ResourceStandardRepoIDPrefix + ".test"
// Use an APT standard repository handle that is not enabled by default on any new Proxmox VE node.
testAccResourceStandardRepoHandle = "no-subscription"
)
func TestAccDataSourceRepo(t *testing.T) {
te := test.InitEnvironment(t)
tests := []struct {
name string
steps []resource.TestStep
}{
{
"read APT repository attributes",
[]resource.TestStep{
{
Config: fmt.Sprintf(
`
data %q %q {
%s = %q # file_path
%s = %d # index
%s = %q # node
}
`,
strings.Split(testAccResourceRepoSelector, ".")[0],
strings.Split(testAccResourceRepoSelector, ".")[1],
// To ensure stable acceptance tests we must use one of the Proxmox VE default source lists that always
// exists on any (new) Proxmox VE node.
apt.SchemaAttrNameFilePath, apitypes.StandardRepoFilePathMain,
apt.SchemaAttrNameIndex, testAccResourceRepoIndex,
apt.SchemaAttrNameNode, te.NodeName,
),
// The provided attributes and computed attributes should be set.
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
fmt.Sprintf("data.%s", testAccResourceRepoSelector),
apt.SchemaAttrNameComment,
// Expect any value or an empty string.
regexp.MustCompile(`(.*|^$)`),
),
resource.TestCheckResourceAttr(
fmt.Sprintf("data.%s", testAccResourceRepoSelector),
apt.SchemaAttrNameTerraformID,
fmt.Sprintf(
"%s_%s_%s_%d",
apt.ResourceRepoIDPrefix,
strings.ToLower(te.NodeName),
apt.RepoIDCharReplaceRegEx.ReplaceAllString(
strings.TrimPrefix(apitypes.StandardRepoFilePathMain, "/"),
"_",
),
testAccResourceRepoIndex,
),
),
test.ResourceAttributesSet(
fmt.Sprintf("data.%s", testAccResourceRepoSelector),
[]string{
fmt.Sprintf("%s.#", apt.SchemaAttrNameComponents),
apt.SchemaAttrNameEnabled,
apt.SchemaAttrNameFilePath,
apt.SchemaAttrNameIndex,
apt.SchemaAttrNameNode,
fmt.Sprintf("%s.#", apt.SchemaAttrNamePackageTypes),
fmt.Sprintf("%s.#", apt.SchemaAttrNameSuites),
fmt.Sprintf("%s.#", apt.SchemaAttrNameURIs),
},
),
),
},
},
},
}
for _, tt := range tests {
t.Run(
tt.name, func(t *testing.T) {
resource.ParallelTest(
t, resource.TestCase{
ProtoV6ProviderFactories: te.AccProviders,
Steps: tt.steps,
},
)
},
)
}
}
func TestAccDataSourceStandardRepo(t *testing.T) {
t.Helper()
t.Parallel()
te := test.InitEnvironment(t)
tests := []struct {
name string
steps []resource.TestStep
}{
{
"read APT standard repository attributes",
[]resource.TestStep{
{
Config: fmt.Sprintf(
`
data %q %q {
%s = %q # handle
%s = %q # node
}
`,
strings.Split(testAccResourceStandardRepoSelector, ".")[0],
strings.Split(testAccResourceStandardRepoSelector, ".")[1],
apt.SchemaAttrNameStandardHandle, apitypes.StandardRepoHandleKindNoSubscription,
apt.SchemaAttrNameNode, te.NodeName,
),
// The provided attributes and computed attributes should be set.
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
fmt.Sprintf("data.%s", testAccResourceStandardRepoSelector),
apt.SchemaAttrNameTerraformID,
fmt.Sprintf(
"%s_%s_%s",
apt.ResourceStandardRepoIDPrefix,
strings.ToLower(te.NodeName),
apt.RepoIDCharReplaceRegEx.ReplaceAllString(
strings.TrimPrefix(apitypes.StandardRepoHandleKindNoSubscription.String(), "/"),
"_",
),
),
),
test.ResourceAttributesSet(
fmt.Sprintf("data.%s", testAccResourceStandardRepoSelector),
// Note that we can not check for the following attributes because they are only available when the
// standard repository has been added to a source list:
//
// - apt.SchemaAttrNameFilePath (file_path) - will be set when parsing all configured repositories in all
// source list files.
// - apt.SchemaAttrNameIndex (index) - will be set when finding the repository within a source list file,
// based on the detected file path.
// - apt.SchemaAttrNameStandardStatus (status) - is only available when the standard has been configured.
[]string{
apt.SchemaAttrNameStandardDescription,
apt.SchemaAttrNameStandardHandle,
apt.SchemaAttrNameStandardName,
apt.SchemaAttrNameNode,
},
),
),
},
},
},
}
for _, tt := range tests {
t.Run(
tt.name, func(t *testing.T) {
resource.ParallelTest(
t, resource.TestCase{
ProtoV6ProviderFactories: te.AccProviders,
Steps: tt.steps,
},
)
},
)
}
}
// Run tests for APT repository resource definitions with valid input where all required attributes are specified.
// Only the [Create], [Read] and [Update] method implementations of the
// [github.com/hashicorp/terraform-plugin-framework/resource.Resource] interface are tested in sequential steps because
// [Delete] is no-op due to the non-existing capability of the Proxmox VE API of deleting configured APT repository.
//
// [Create]: https://developer.hashicorp.com/terraform/plugin/framework/resources/create
// [Delete]: https://developer.hashicorp.com/terraform/plugin/framework/resources/delete
// [Read]: https://developer.hashicorp.com/terraform/plugin/framework/resources/read
// [Update]: https://developer.hashicorp.com/terraform/plugin/framework/resources/update
func TestAccResourceRepoValidInput(t *testing.T) {
t.Parallel()
te := test.InitEnvironment(t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: te.AccProviders,
Steps: []resource.TestStep{
// Test the "Create" and "Read" implementations.
{
Config: fmt.Sprintf(
`
resource %q %q {
%s = %t # enabled
%s = %q # file_path
%s = %d # index
%s = %q # node
}
`,
strings.Split(testAccResourceRepoSelector, ".")[0],
strings.Split(testAccResourceRepoSelector, ".")[1],
apt.SchemaAttrNameEnabled, apt.ResourceRepoActivationStatus,
// To ensure stable acceptance tests we must use one of the Proxmox VE default source lists that always
// exists on any (new) Proxmox VE node.
apt.SchemaAttrNameFilePath, apitypes.StandardRepoFilePathMain,
apt.SchemaAttrNameIndex, testAccResourceRepoIndex,
apt.SchemaAttrNameNode, te.NodeName,
),
// The computed attributes should be set.
ConfigStateChecks: []statecheck.StateCheck{
statecheck.ExpectKnownValue(
testAccResourceRepoSelector,
tfjsonpath.New(apt.SchemaAttrNameComponents),
knownvalue.ListPartial(
map[int]knownvalue.Check{
// Use the same check for both entries because the sort order cannot be guaranteed.
0: knownvalue.StringRegexp(regexp.MustCompile(`(contrib|main)`)),
1: knownvalue.StringRegexp(regexp.MustCompile(`(contrib|main)`)),
},
),
),
statecheck.ExpectKnownValue(
testAccResourceRepoSelector,
tfjsonpath.New(apt.SchemaAttrNamePackageTypes),
knownvalue.ListPartial(
map[int]knownvalue.Check{
0: knownvalue.StringRegexp(regexp.MustCompile(`(deb)`)),
},
),
),
statecheck.ExpectKnownValue(
testAccResourceRepoSelector,
tfjsonpath.New(apt.SchemaAttrNameSuites),
knownvalue.ListPartial(
map[int]knownvalue.Check{
// The possible Debian version is based on the official table of the Proxmox VE FAQ page:
// - https://pve.proxmox.com/wiki/FAQ#faq-support-table
// - https://www.thomas-krenn.com/en/wiki/Proxmox_VE#Proxmox_VE_8.x
//
// The required Proxmox VE version for this provider is of course also taken into account:
// - https://github.com/bpg/terraform-provider-proxmox?tab=readme-ov-file#requirements
0: knownvalue.StringRegexp(regexp.MustCompile(`(bookworm)`)),
},
),
),
statecheck.ExpectKnownValue(
testAccResourceRepoSelector,
tfjsonpath.New(apt.SchemaAttrNameURIs),
knownvalue.ListPartial(
map[int]knownvalue.Check{
0: knownvalue.StringRegexp(regexp.MustCompile(`https?://ftp\.([a-z]+\.)?debian\.org/debian`)),
},
),
),
},
// The provided attributes and computed attributes should be set.
Check: resource.ComposeTestCheckFunc(
resource.TestMatchResourceAttr(
testAccResourceRepoSelector,
apt.SchemaAttrNameComment,
// Expect any value or an empty string.
regexp.MustCompile(`(.*|^$)`),
),
resource.TestCheckResourceAttr(
testAccResourceRepoSelector,
apt.SchemaAttrNameEnabled,
strconv.FormatBool(apt.ResourceRepoActivationStatus),
),
resource.TestCheckResourceAttr(
testAccResourceRepoSelector,
apt.SchemaAttrNameFilePath,
apitypes.StandardRepoFilePathMain,
),
resource.TestCheckResourceAttrSet(testAccResourceRepoSelector, apt.SchemaAttrNameFileType),
resource.TestCheckResourceAttr(
testAccResourceRepoSelector,
apt.SchemaAttrNameIndex,
strconv.FormatInt(testAccResourceRepoIndex, 10),
),
resource.TestCheckResourceAttr(testAccResourceRepoSelector, apt.SchemaAttrNameNode, te.NodeName),
resource.TestCheckResourceAttr(
testAccResourceRepoSelector,
apt.SchemaAttrNameTerraformID,
fmt.Sprintf(
"%s_%s_%s_%d",
apt.ResourceRepoIDPrefix,
strings.ToLower(te.NodeName),
apt.RepoIDCharReplaceRegEx.ReplaceAllString(
strings.TrimPrefix(apitypes.StandardRepoFilePathMain, "/"),
"_",
),
testAccResourceRepoIndex,
),
),
),
},
// Test the "ImportState" implementation.
{
ImportState: true,
ImportStateId: fmt.Sprintf(
"%s,%s,%d",
strings.ToLower(te.NodeName),
apitypes.StandardRepoFilePathMain,
testAccResourceRepoIndex,
),
ImportStateVerify: true,
ResourceName: testAccResourceRepoSelector,
},
// Test the "Update" implementation by toggling the activation status.
{
Config: fmt.Sprintf(
`
resource %q %q {
%s = %t # enabled
%s = %q # file_path
%s = %d # index
%s = %q # node
}
`,
strings.Split(testAccResourceRepoSelector, ".")[0],
strings.Split(testAccResourceRepoSelector, ".")[1],
// Disable the repository which is enabled by default for created or imported resources.
apt.SchemaAttrNameEnabled, !apt.ResourceRepoActivationStatus,
// To ensure stable acceptance tests we must use one of the Proxmox VE default source lists that always
// exists on any (new) Proxmox VE node.s
apt.SchemaAttrNameFilePath, apitypes.StandardRepoFilePathMain,
apt.SchemaAttrNameIndex, testAccResourceRepoIndex,
apt.SchemaAttrNameNode, te.NodeName,
),
// The provides attributes and some computed attributes should be set.
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
testAccResourceRepoSelector,
apt.SchemaAttrNameEnabled,
strconv.FormatBool(!apt.ResourceRepoActivationStatus),
),
),
},
},
},
)
}
// Run tests for APT standard repository resource definitions with valid input where all required attributes are
// specified.
// Only the [Create] and [Read] method implementations of the
// [github.com/hashicorp/terraform-plugin-framework/resource.Resource] interface are tested in sequential steps because
// [Delete] and [Update] are no-op due to the non-existing capability of the Proxmox VE API of deleting or updating a
// configured APT standard repository.
//
// [Create]: https://developer.hashicorp.com/terraform/plugin/framework/resources/create
// [Delete]: https://developer.hashicorp.com/terraform/plugin/framework/resources/delete
// [Read]: https://developer.hashicorp.com/terraform/plugin/framework/resources/read
// [Update]: https://developer.hashicorp.com/terraform/plugin/framework/resources/update
func TestAccResourceStandardRepoValidInput(t *testing.T) {
t.Helper()
t.Parallel()
te := test.InitEnvironment(t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: te.AccProviders,
Steps: []resource.TestStep{
// Test the "Create" and "Read" implementations.
{
Config: fmt.Sprintf(
`
resource %q %q {
%s = %q # handle
%s = %q # node
}
`,
strings.Split(testAccResourceStandardRepoSelector, ".")[0],
strings.Split(testAccResourceStandardRepoSelector, ".")[1],
apt.SchemaAttrNameStandardHandle, testAccResourceStandardRepoHandle,
apt.SchemaAttrNameNode, te.NodeName,
),
// The provided attributes and computed attributes should be set.
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
testAccResourceStandardRepoSelector,
apt.SchemaAttrNameStandardDescription,
),
resource.TestCheckResourceAttr(
testAccResourceStandardRepoSelector,
apt.SchemaAttrNameFilePath,
apitypes.StandardRepoFilePathMain,
),
resource.TestCheckResourceAttr(
testAccResourceStandardRepoSelector,
apt.SchemaAttrNameStandardHandle,
testAccResourceStandardRepoHandle,
),
resource.TestCheckResourceAttrSet(testAccResourceStandardRepoSelector, apt.SchemaAttrNameIndex),
resource.TestCheckResourceAttrSet(testAccResourceStandardRepoSelector, apt.SchemaAttrNameStandardName),
resource.TestCheckResourceAttr(testAccResourceStandardRepoSelector, apt.SchemaAttrNameNode, te.NodeName),
resource.TestCheckResourceAttr(
testAccResourceStandardRepoSelector,
apt.SchemaAttrNameStandardStatus,
// By default, newly added APT standard repositories are enabled.
strconv.Itoa(1),
),
resource.TestCheckResourceAttr(
testAccResourceStandardRepoSelector,
apt.SchemaAttrNameTerraformID,
fmt.Sprintf(
"%s_%s_%s",
apt.ResourceStandardRepoIDPrefix,
strings.ToLower(te.NodeName),
apt.RepoIDCharReplaceRegEx.ReplaceAllString(testAccResourceStandardRepoHandle, "_"),
),
),
),
},
// Test the "ImportState" implementation.
{
ImportState: true,
ImportStateId: fmt.Sprintf("%s,%s", strings.ToLower(te.NodeName), testAccResourceStandardRepoHandle),
ImportStateVerify: true,
ResourceName: testAccResourceStandardRepoSelector,
},
},
},
)
}