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 additional configuration to allow mock tests #2

Merged
merged 1 commit into from
May 14, 2024
Merged
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
2 changes: 1 addition & 1 deletion .task/checksum/docs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
aca40009b238058ed9f39142c729980
f7f04e4db1b11ccfe67e14765ab91cb3
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ go 1.22
toolchain go1.22.3

require (
github.com/go-chi/chi/v5 v5.0.12
github.com/hashicorp/terraform-plugin-docs v0.19.2
github.com/hashicorp/terraform-plugin-framework v1.8.0
github.com/hashicorp/terraform-plugin-go v0.22.2
github.com/hashicorp/terraform-plugin-testing v1.7.0
github.com/omc/bonsai-api-go/v2 v2.1.0
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -46,7 +48,6 @@ require (
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.20.0 // indirect
github.com/hashicorp/terraform-json v0.21.0 // indirect
github.com/hashicorp/terraform-plugin-go v0.22.2 // indirect
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
Expand Down
50 changes: 42 additions & 8 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ import (
"context"
"os"

"github.com/omc/bonsai-api-go/v2/bonsai"
"github.com/omc/terraform-provider-bonsai/internal/space"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/function"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/omc/bonsai-api-go/v2/bonsai"
"github.com/omc/terraform-provider-bonsai/internal/space"
)

// Ensure bonsaiProvider satisfies various provider interfaces.
Expand All @@ -29,6 +28,10 @@ type bonsaiProvider struct {
// provider is built and ran locally, and "test" when running acceptance
// testing.
version string
// bonsaiAPIClient is an optional override of the API Client used by
// Terraform to perform requests. Defaults to nil, and will use a
// default provided API Client.
bonsaiAPIClient *bonsai.Client
}

// bonsaiProviderModel maps provider schema data to a Go type.
Expand Down Expand Up @@ -88,18 +91,49 @@ func (p *bonsaiProvider) Functions(ctx context.Context) []func() function.Functi
return []func() function.Function{}
}

func New(version string) func() provider.Provider {
// BonsaiProviderOption is a functional option, used to configure Client.
type BonsaiProviderOption func(*bonsaiProvider)

// WithAPIClient configures the Bonsai API Client used to perform
// terraform action HTTP requests.
func WithAPIClient(c *bonsai.Client) BonsaiProviderOption {
return func(p *bonsaiProvider) {
p.bonsaiAPIClient = c
}
}

func WithVersion(version string) BonsaiProviderOption {
return func(p *bonsaiProvider) {
p.version = version
}
}

func New(options ...BonsaiProviderOption) func() provider.Provider {
return func() provider.Provider {
return &bonsaiProvider{
version: version,
p := &bonsaiProvider{}

// apply options
for _, option := range options {
option(p)
}

return p
}
}

func (p *bonsaiProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
// Retrieve provider data from configuration
var config bonsaiProviderModel

// Bonsai API Client has already been configured; skip all client configuration
if p.bonsaiAPIClient != nil {
// Make the Bonsai client available during DataSource and Resource
// type Configure methods.
resp.DataSourceData = p.bonsaiAPIClient
resp.ResourceData = p.bonsaiAPIClient
return
}

diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
Expand Down Expand Up @@ -194,7 +228,7 @@ func (p *bonsaiProvider) Configure(ctx context.Context, req provider.ConfigureRe
return
}

// Create a new HashiCups client using the configuration values
// Create a new Bonsai client using the configuration values
client := bonsai.NewClient(
bonsai.WithCredentialPair(
bonsai.CredentialPair{
Expand All @@ -204,7 +238,7 @@ func (p *bonsaiProvider) Configure(ctx context.Context, req provider.ConfigureRe
),
)

// Make the HashiCups client available during DataSource and Resource
// Make the Bonsai client available during DataSource and Resource
// type Configure methods.
resp.DataSourceData = client
resp.ResourceData = client
Expand Down
3 changes: 1 addition & 2 deletions internal/space/data_source_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package space_test

import (
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/omc/terraform-provider-bonsai/internal/test"
)

func (s *SpaceTestSuite) TestSpace_ListDataSource() {
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: test.ProtoV6ProviderFactories,
ProtoV6ProviderFactories: s.ProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: `
Expand Down
3 changes: 1 addition & 2 deletions internal/space/data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import (
"fmt"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/omc/terraform-provider-bonsai/internal/test"
)

func (s *SpaceTestSuite) TestSpace_DataSource() {
const spacePath = "omc/bonsai/eu-west-1/common"
resource.Test(s.T(), resource.TestCase{
ProtoV6ProviderFactories: test.ProtoV6ProviderFactories,
ProtoV6ProviderFactories: s.ProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
Expand Down
8 changes: 4 additions & 4 deletions internal/space/space_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import (
)

type SpaceTestSuite struct {
test.ProviderTestSuite
*test.ProviderTestSuite
}

func TestSpaceTestSuite(t *testing.T) {
suite.Run(t, &SpaceTestSuite{})
suite.Run(t, &SpaceTestSuite{ProviderTestSuite: &test.ProviderTestSuite{}})
}

func (s *SpaceTestSuite) SetupTest() {
suite.SetupAllSuite(s).SetupSuite()
func (s *SpaceTestSuite) SetupSuite() {
suite.SetupAllSuite(s.ProviderTestSuite).SetupSuite()
}
55 changes: 50 additions & 5 deletions internal/test/resource.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package test

import (
"net/http/httptest"

"github.com/go-chi/chi/v5"
"github.com/hashicorp/terraform-plugin-framework/providerserver"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/omc/bonsai-api-go/v2/bonsai"
Expand All @@ -9,10 +12,6 @@ import (
"github.com/stretchr/testify/suite"
)

var ProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"bonsai": providerserver.NewProtocol6WithError(provider.New("test")()),
}

type ClientTestSuite struct {
// Assertions embedded here allows all tests to reach through the suite to access assertion methods
*require.Assertions
Expand All @@ -21,6 +20,8 @@ type ClientTestSuite struct {

// client allows each test to have a reachable *bonsai.Client for testing
client *bonsai.Client

ProtoV6ProviderFactories map[string]func() (tfprotov6.ProviderServer, error)
}

// ProviderTestSuite is used for all provider acceptance tests.
Expand All @@ -29,11 +30,42 @@ type ProviderTestSuite struct {
}

func (s *ProviderTestSuite) SetupSuite() {
version := "0.1.0-test"

// configure terraform provider factory
s.ProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"bonsai": providerserver.NewProtocol6WithError(
provider.New(
provider.WithVersion(version),
)(),
),
}

// configure testify
s.Assertions = require.New(s.T())
}

// ProviderMockRequestTestSuite is used for tests where the target endpoints
// are mocked; allowing for isolating the terraform provider functionality,
// without requiring live responses from the production Bonsai API.
type ProviderMockRequestTestSuite struct {
ClientTestSuite
serveMux *chi.Mux
server *httptest.Server
}

func (s *ProviderMockRequestTestSuite) SetupSuite() {
version := "0.1.0-test"

// Configure http client and other miscellany
s.serveMux = chi.NewRouter()
s.server = httptest.NewServer(s.serveMux)
s.client = bonsai.NewClient(
bonsai.WithEndpoint(s.server.URL),
bonsai.WithApplication(
bonsai.Application{
Name: "terraform-provider-bonsai",
Version: "0.1.0-dev",
Version: version,
},
),
bonsai.WithCredentialPair(
Expand All @@ -43,6 +75,19 @@ func (s *ProviderTestSuite) SetupSuite() {
},
),
)

// configure terraform provider factory
s.ProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){
"bonsai": providerserver.NewProtocol6WithError(
provider.New(
provider.WithAPIClient(
s.client,
),
provider.WithVersion(version),
)(),
),
}

// configure testify
s.Assertions = require.New(s.T())
}
4 changes: 3 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ func main() {
Debug: debug,
}

err := providerserver.Serve(context.Background(), provider.New(version), opts)
err := providerserver.Serve(context.Background(), provider.New(
provider.WithVersion(version),
), opts)

if err != nil {
log.Fatal(err.Error())
Expand Down
Loading