Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Aflynn50 committed Apr 18, 2024
1 parent 9c47595 commit c216fec
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 7 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ juju-unit-test:
.PHONY: envtestlxd
envtestlxd:
## envtestlxd: Under development - Include env var and run unit tests against lxd
JUJU_CONTROLLER_ADDRESSES=${CONTROLLER_ADDRESSES} JUJU_USERNAME=${USERNAME} JUJU_PASSWORD=${PASSWORD} JUJU_CA_CERT=${CA_CERT} TF_ACC=1 TEST_CLOUD=lxd go test ./... -v $(TESTARGS) -timeout 120m
JUJU_CONTROLLER_ADDRESSES=${CONTROLLER_ADDRESSES} \
JUJU_USERNAME=${USERNAME} JUJU_PASSWORD=${PASSWORD} \
JUJU_CA_CERT=${CA_CERT} TF_ACC=1 TEST_CLOUD=lxd go test ./... -v $(TESTARGS) -timeout 120m

.PHONY: testlxd
testlxd:
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/juju/ansiterm v1.0.0 // indirect
github.com/juju/blobstore/v3 v3.0.2 // indirect
github.com/juju/charm/v11 v11.1.0 // indirect
github.com/juju/description/v5 v5.0.4 // indirect
github.com/juju/featureflag v1.0.0 // indirect
github.com/juju/gnuflag v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ github.com/juju/ansiterm v1.0.0 h1:gmMvnZRq7JZJx6jkfSq9/+2LMrVEwGwt7UR6G+lmDEg=
github.com/juju/ansiterm v1.0.0/go.mod h1:PyXUpnI3olx3bsPcHt98FGPX/KCFZ1Fi+hw1XLI6384=
github.com/juju/blobstore/v3 v3.0.2 h1:roZ4YBuZYmWId6y/6ZLQSAMmNlHOclHD8PQAMOQer6E=
github.com/juju/blobstore/v3 v3.0.2/go.mod h1:NXEgMhrVH5744/zLfSkzsySlDQUpCgzvcNxjJJhICko=
github.com/juju/charm/v11 v11.1.0 h1:YTvFRugIhRMAe4z6Vr7Acw9oKnJBNfpwN9yTOqJv3r0=
github.com/juju/charm/v11 v11.1.0/go.mod h1:Mge5Ko3pPgocmk4v1pQgmBhF8BuBLGTCFu3jq83JvHk=
github.com/juju/charm/v12 v12.0.0 h1:/h3YRMqbgxT89QkQGgMS/myOxuHy/kzBLCDOvodsoFY=
github.com/juju/charm/v12 v12.0.0/go.mod h1:rX3no84EHT+qN+BGtwqPyvueC1Sxr0bXWxsbUd6i1iY=
github.com/juju/clock v1.0.3 h1:yJHIsWXeU8j3QcBdiess09SzfiXRRrsjKPn2whnMeds=
Expand Down
2 changes: 1 addition & 1 deletion internal/provider/resource_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func (r *applicationResource) Schema(_ context.Context, _ resource.SchemaRequest
stringplanmodifier.UseStateForUnknown(),
},
Validators: []validator.String{
stringIsChannelValidator{},
StringIsChannelValidator{},
},
},
"revision": schema.Int64Attribute{
Expand Down
17 changes: 12 additions & 5 deletions internal/provider/validator_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,33 @@ import (
"github.com/juju/charm/v11"
)

type stringIsChannelValidator struct{}
type StringIsChannelValidator struct{}

// Description returns a plain text description of the validator's behavior, suitable for a practitioner to understand its impact.
func (v stringIsChannelValidator) Description(context.Context) string {
func (v StringIsChannelValidator) Description(context.Context) string {
return "string must conform to track/risk or track/risk/branch e.g. latest/stable"
}

// MarkdownDescription returns a markdown formatted description of the validator's behavior, suitable for a practitioner to understand its impact.
func (v stringIsChannelValidator) MarkdownDescription(context.Context) string {
func (v StringIsChannelValidator) MarkdownDescription(context.Context) string {
return "string must conform to track/risk or track/risk/branch e.g. latest/stable"
}

// Validate runs the main validation logic of the validator, reading configuration data out of `req` and updating `resp` with diagnostics.
func (v stringIsChannelValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
func (v StringIsChannelValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
// If the value is unknown or null, there is nothing to validate.
if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() {
return
}

if channel, err := charm.ParseChannel(req.ConfigValue.ValueString()); err != nil || channel.Track == "" || channel.Risk == "" {
if channel, err := charm.ParseChannel(req.ConfigValue.ValueString()); err != nil {
resp.Diagnostics.AddAttributeError(
req.Path,
"Invalid Channel",
err.Error(),
)
return
} else if channel.Track == "" || channel.Risk == "" {
resp.Diagnostics.AddAttributeError(
req.Path,
"Invalid Channel",
Expand Down
73 changes: 73 additions & 0 deletions internal/provider/validator_channel_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2024 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package provider_test

import (
"context"
"testing"

"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/juju/terraform-provider-juju/internal/provider"
)

func TestChannelValidatorValid(t *testing.T) {
validChannels := []types.String{
types.StringValue("track/stable"),
types.StringValue("track/edge/branch"),
types.StringNull(),
types.StringUnknown(),
}

channelValidator := provider.StringIsChannelValidator{}
for _, channel := range validChannels {
req := validator.StringRequest{
ConfigValue: channel,
}
var resp validator.StringResponse
channelValidator.ValidateString(context.Background(), req, &resp)

if resp.Diagnostics.HasError() {
t.Errorf("errors %v", resp.Diagnostics.Errors())
}
}
}

func TestChannelValidatorInvalid(t *testing.T) {
invalidChannels := []struct {
str types.String
err string
}{{
str: types.StringValue("track"),
err: "String must conform to track/risk or track/risk/branch, e.g. latest/stable",
}, {
str: types.StringValue("edge"),
err: "String must conform to track/risk or track/risk/branch, e.g. latest/stable",
}, {
str: types.StringValue(`track\risk`),
err: "String must conform to track/risk or track/risk/branch, e.g. latest/stable",
}, {
str: types.StringValue(`track/invalidrisk`),
err: `risk in channel "track/invalidrisk" not valid`,
}, {
str: types.StringValue(`track/invalidrisk/branch`),
err: `risk in channel "track/invalidrisk/branch" not valid`,
}}

channelValidator := provider.StringIsChannelValidator{}
for _, test := range invalidChannels {
req := validator.StringRequest{
ConfigValue: test.str,
}
var resp validator.StringResponse
channelValidator.ValidateString(context.Background(), req, &resp)

if c := resp.Diagnostics.ErrorsCount(); c != 1 {
t.Errorf("expected one error, got %d", c)
}
if deets := resp.Diagnostics.Errors()[0].Detail(); deets != test.err {
t.Errorf("expected error %q, got %q", test.err, deets)
}
}
}

0 comments on commit c216fec

Please sign in to comment.