Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Acceptance Testing #50

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ modules-dev/
# Test exclusions
!command/test-fixtures/**/*.tfstate
!command/test-fixtures/**/.terraform/
/.env
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)
ACC_TEST?=$$(go list ./proxmoxtf/acceptancetests |grep -v 'vendor')
NAME=$$(grep TerraformProviderName proxmoxtf/version.go | grep -o -e 'terraform-provider-[a-z]*')
TARGETS=darwin linux windows
TERRAFORM_PLUGIN_EXTENSION=
Expand Down Expand Up @@ -59,6 +60,11 @@ targets: $(TARGETS)
test:
go test -v ./...

testacc:
@echo "==> Sourcing .env file if available"
if [ -f .env ]; then set -o allexport; . ./.env; set +o allexport; fi; \
TF_ACC=1 go test -timeout 120m -run ^TestAcc* -tags "${*:-all}" -v $(ACC_TEST) || echo "Build finished in error due to failed tests"

$(TARGETS):
GOOS=$@ GOARCH=amd64 CGO_ENABLED=0 go build \
-o "dist/$@/$(NAME)_v$(VERSION)-custom_x4" \
Expand Down
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,47 @@ $ $GOPATH/bin/terraform-provider-proxmox
If you wish to contribute to the provider, please see [CONTRIBUTING.md](CONTRIBUTING.md).

## Testing the Provider
In order to test the provider, you can simply run `make test`.

### Unit tests ###

In order to run unit tests for the provider, you can simply run

```sh
$ make test
```

Tests are limited to regression tests, ensuring backwards compability.

### Acceptance tests ###

Acceptance tests require available Proxmox Virtual Environment.
To run ant acceptance tests you need to set `PROXMOX_VE_ENDPOINT`, `PROXMOX_VE_USERNAME`,
`PROXMOX_VE_PASSWORD`, `PROXMOX_VE_INSECURE` environmental variables.

```sh
export PROXMOX_VE_ENDPOINT='<protocol>://<host>:<port>'
export PROXMOX_VE_USERNAME='<username>'
export PROXMOX_VE_PASSWORD='<password>'
export PROXMOX_VE_INSECURE='1'

$ make testacc
```

or create `.env` file in the root of the folder with the following content

```env
PROXMOX_VE_ENDPOINT='<protocol>://<host>:<port>'
PROXMOX_VE_USERNAME='<username>'
PROXMOX_VE_PASSWORD='<password>'
PROXMOX_VE_INSECURE='1'
```

```sh
$ make testacc
```

**Note:** Acceptance tests provision real resources

## Known issues

### Disk images cannot be imported by non-PAM accounts
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package acceptancetests

import (
"fmt"
"github.com/danitso/terraform-provider-proxmox/proxmoxtf"
"github.com/danitso/terraform-provider-proxmox/proxmoxtf/acceptancetests/testutils"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"strings"
"testing"
)


// Verifies that a role can be created and updated
func TestAccResourceVirtualEnvironmentRole_CreateAndUpdate(t *testing.T) {
roleId := testutils.GenerateResourceName()
privilegesFirst := []string{
"Datastore.Allocate",
"Datastore.AllocateSpace",
}

privilegesSecond := []string{
"Datastore.Audit",
}

tfNode := "proxmox_virtual_environment_role.role"

resource.Test(t, resource.TestCase{
PreCheck: func() { testutils.PreCheck(t, nil) },
Providers: testutils.GetProviders(),
CheckDestroy: CheckRoleDestroyed,
Steps: []resource.TestStep{
// Create role
{
Config: testutils.HclRoleResource(roleId, privilegesFirst),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(tfNode, "role_id", roleId),
testutils.CheckRole(privilegesFirst),
),
},
// Update role
{
Config: testutils.HclRoleResource(roleId, privilegesSecond),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(tfNode, "role_id", roleId),
testutils.CheckRole(privilegesSecond),
),
},
},
})
}

// CheckRoleDestroyed verifies that all roles referenced in the state
// are destroyed. This will be invoked *after* terraform destroys
// the resource but *before* the state is wiped clean
func CheckRoleDestroyed(s *terraform.State) error {
config := testutils.GetProvider().Meta().(proxmoxtf.ProviderConfiguration)

conn, err := config.GetVEClient()

if err != nil {
return err
}

// loop through the resource state
for _, rs := range s.RootModule().Resources {
if rs.Type != "proxmox_virtual_environment_role" {
continue
}

role, err := conn.GetRole(rs.Primary.ID)

if err == nil {
// if we still receiving role with privileges
if len(*role) != 0 {
return fmt.Errorf("Role with Name=`%s` should not exist", rs.Primary.ID)
}

return nil
}

if !strings.Contains(err.Error(), "does not exist") {
return err
}
}

return nil
}
50 changes: 50 additions & 0 deletions proxmoxtf/acceptancetests/testutils/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package testutils

import (
"github.com/danitso/terraform-provider-proxmox/proxmoxtf"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
"os"
"testing"
)

// initialize once, so it can be shared by each acceptance test
var provider = proxmoxtf.Provider()

// GetProvider returns the proxmox provider
func GetProvider() *schema.Provider {
return provider
}

// GetProviders returns a map of all providers needed for the project
func GetProviders() map[string]terraform.ResourceProvider {
return map[string]terraform.ResourceProvider{
"proxmox": GetProvider(),
}
}

// PreCheck checks that required environmental variables are set
func PreCheck(t *testing.T, extraEnvVars *[]string) {
requiredEnvVars := []string{
"PROXMOX_VE_USERNAME",
"PROXMOX_VE_PASSWORD",
"PROXMOX_VE_ENDPOINT",
}

if extraEnvVars != nil {
requiredEnvVars = append(requiredEnvVars, *extraEnvVars...)
}

for _, variable := range requiredEnvVars {
if _, ok := os.LookupEnv(variable); !ok {
t.Fatalf("`%s` must be set for acceptance testing", variable)
}
}
}

// GenerateResourceName generates a random name with a constant prefix
func GenerateResourceName() string {
return "test-" + acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
}

93 changes: 93 additions & 0 deletions proxmoxtf/acceptancetests/testutils/role.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package testutils

import (
"fmt"
"github.com/danitso/terraform-provider-proxmox/proxmox"
"github.com/danitso/terraform-provider-proxmox/proxmoxtf"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"sort"
)

// CheckRole Given the name of role, this will return a function that will check
// whether or not a role
// - (1) exists in the state
// - (2) exist in Proxmox VE
// - (3) has correct privileges
func CheckRole(expectedPrivileges []string) resource.TestCheckFunc {
return func (s *terraform.State) error {
res, ok := s.RootModule().Resources["proxmox_virtual_environment_role.role"]

if !ok {
return fmt.Errorf("Did not find the role in the TF state")
}

clients := GetProvider().Meta().(proxmoxtf.ProviderConfiguration)
id := res.Primary.ID
role, err := readRole(clients, id)

if err != nil {
return fmt.Errorf("Role with Name=`%s` cannot be found. Error %v", id, err)
}

if len(*role) != len(expectedPrivileges) {
return fmt.Errorf("Role with Name=`%s` should have `%d` privileges, but got `%d`", id, len(*role), len(expectedPrivileges))
}

sort.Strings(expectedPrivileges)

for i, v := range *role {
if v != expectedPrivileges[i] {
return fmt.Errorf("Role with Name=`%s` has privilege=`%s`, but expected `%s`", id, v, expectedPrivileges[i])
}
}

return nil

}
}

// readRole is a helper function that reads a role based on a given name
func readRole(clients proxmoxtf.ProviderConfiguration, identifier string) (*proxmox.CustomPrivileges, error) {
conn, err := clients.GetVEClient()

if err != nil {
return nil, err
}

response, err := conn.GetRole(identifier)

if err != nil {
return nil, err
}

return response, nil
}

// HclRoleResource HCL describing of a PVE role resource
func HclRoleResource(name string, privileges []string) string {

if name == "" {
panic("Parameter: `name` cannot be empty")
}

if len(privileges) <= 0 {
panic("Parameter: `privileges` cannot be empty")
}

p := ""

for _, v := range privileges {
p = p + fmt.Sprintf("%q,", v)
}

return fmt.Sprintf(`
resource "proxmox_virtual_environment_role" "role" {
role_id = "%[1]s"

privileges = [
%[2]s
]
}
`, name, p)
}
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_datastores.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func dataSourceVirtualEnvironmentDatastores() *schema.Resource {
}

func dataSourceVirtualEnvironmentDatastoresRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func dataSourceVirtualEnvironmentDNS() *schema.Resource {
}

func dataSourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func dataSourceVirtualEnvironmentGroup() *schema.Resource {
}

func dataSourceVirtualEnvironmentGroupRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func dataSourceVirtualEnvironmentGroups() *schema.Resource {
}

func dataSourceVirtualEnvironmentGroupsRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func dataSourceVirtualEnvironmentHosts() *schema.Resource {
}

func dataSourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func dataSourceVirtualEnvironmentNodes() *schema.Resource {
}

func dataSourceVirtualEnvironmentNodesRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func dataSourceVirtualEnvironmentPool() *schema.Resource {
}

func dataSourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func dataSourceVirtualEnvironmentPools() *schema.Resource {
}

func dataSourceVirtualEnvironmentPoolsRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func dataSourceVirtualEnvironmentRole() *schema.Resource {
}

func dataSourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion proxmoxtf/data_source_virtual_environment_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func dataSourceVirtualEnvironmentRoles() *schema.Resource {
}

func dataSourceVirtualEnvironmentRolesRead(d *schema.ResourceData, m interface{}) error {
config := m.(providerConfiguration)
config := m.(ProviderConfiguration)
veClient, err := config.GetVEClient()

if err != nil {
Expand Down
Loading