Skip to content

How to perform a test of a terraform action #557

@remyleone

Description

@remyleone

terraform-plugin-testing version

github.com/hashicorp/terraform-plugin-testing v1.13.3

Relevant provider source code

package instance

import (
	"context"
	"fmt"

	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
	"github.com/hashicorp/terraform-plugin-framework/action"
	"github.com/hashicorp/terraform-plugin-framework/action/schema"
	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
	"github.com/scaleway/scaleway-sdk-go/scw"
)

var (
	_ action.Action = (*ServerAction)(nil)
)

type ServerAction struct {
	instanceAPI *instance.API
}

func (a *ServerAction) Configure(ctx context.Context, req action.ConfigureRequest, resp *action.ConfigureResponse) {
	if req.ProviderData == nil {
		return
	}

	client, ok := req.ProviderData.(*scw.Client)
	if !ok {
		resp.Diagnostics.AddError(
			"Unexpected Action Configure Type",
			fmt.Sprintf("Expected *scw.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
		)

		return
	}

	a.instanceAPI = instance.NewAPI(client)
}

func (a *ServerAction) Metadata(ctx context.Context, req action.MetadataRequest, resp *action.MetadataResponse) {
	resp.TypeName = req.ProviderTypeName + "_instance_server_reboot"
}

type ServerActionModel struct {
	ServerID types.String `tfsdk:"server_id"`
	Zone     types.String `tfsdk:"zone"`
	Wait     types.Bool   `tfsdk:"wait"`
	Action   types.String `tfsdk:"action"`
}

func NewServerAction() action.Action {
	return &ServerAction{}
}

func (a *ServerAction) Schema(ctx context.Context, req action.SchemaRequest, resp *action.SchemaResponse) {
	resp.Schema = schema.Schema{
		Attributes: map[string]schema.Attribute{
			"action": schema.StringAttribute{
				Required:    true,
				Description: "Type of action to perform",
				Validators: []validator.String{
					stringvalidator.ExactlyOneOf(instance.ServerAction.Values()),
				},
			},
			"server_id": schema.StringAttribute{
				Required:    true,
				Description: "Server id to reboot",
			},
			"zone": schema.StringAttribute{
				Optional:    true,
				Description: "Zone of server to reboot",
			},
			"wait": schema.BoolAttribute{
				Optional:    true,
				Description: "Wait for server to finish reboot",
			},
		},
	}
}

func (a *ServerAction) Invoke(ctx context.Context, req action.InvokeRequest, resp *action.InvokeResponse) {
	var data ServerActionModel
	// Read action config data into the model
	resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
	if resp.Diagnostics.HasError() {
		return
	}

	_, err := a.instanceAPI.ServerAction(&instance.ServerActionRequest{
		ServerID: data.ServerID.String(),
		Zone:     scw.Zone(data.Zone.String()),
		Action:   instance.ServerAction(data.Action.String()),
	})
	if err != nil {
		resp.Diagnostics.AddError(
			"error in server action",
			fmt.Sprintf("%s", err))
	}
	if data.Wait.ValueBool() {
		_, errWait := a.instanceAPI.WaitForServer(&instance.WaitForServerRequest{
			ServerID: data.ServerID.String(),
			Zone:     scw.Zone(data.Zone.String()),
		})
		if errWait != nil {
			resp.Diagnostics.AddError(
				"error in wait server",
				fmt.Sprintf("%s", err))
		}
	}
}

Terraform Configuration Files

Expected Behavior

I should have the action triggered or have a way to trigger it from the tests.

Actual Behavior

The test ignores my action and I don't know how to write a test that will test that an action is triggered.

Steps to Reproduce

Create a terraform action in a provider
Try to test it.

References

I have not found any examples of tests with terraform actions in the official documentation

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions