Skip to content

Commit

Permalink
Merge pull request #781 from hashicorp/hashimoon/TF-7737-pmr-tests
Browse files Browse the repository at this point in the history
[TF-7737] Add fields for Registry Module Testing
  • Loading branch information
hashimoon authored Oct 6, 2023
2 parents c4b9321 + bd4b955 commit bd95d23
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 15 deletions.
6 changes: 3 additions & 3 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ var (

ErrRequiredAgentPoolID = errors.New("'agent' execution mode requires an agent pool ID to be specified")

ErrRequiredAgentMode = errors.New("specifying an agent pool ID requires 'agent' execution mode")

ErrRequiredCategory = errors.New("category is required")
ErrRequiredAgentMode = errors.New("specifying an agent pool ID requires 'agent' execution mode")
ErrRequiredBranchWhenTestsEnabled = errors.New("VCS branch is required when enabling tests")
ErrRequiredCategory = errors.New("category is required")

ErrRequiredDestinationType = errors.New("destination type is required")

Expand Down
66 changes: 54 additions & 12 deletions registry_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ const (
RegistryModuleVersionStatusOk RegistryModuleVersionStatus = "ok"
)

type PublishingMechanism string

const (
PublishingMechanismBranch PublishingMechanism = "branch"
PublishingMechanismTag PublishingMechanism = "git_tag"
)

// RegistryModuleID represents the set of IDs that identify a RegistryModule
type RegistryModuleID struct {
// The organization the module belongs to, see RegistryModule.Organization.Name
Expand Down Expand Up @@ -124,18 +131,20 @@ type CommitList struct {

// RegistryModule represents a registry module
type RegistryModule struct {
ID string `jsonapi:"primary,registry-modules"`
Name string `jsonapi:"attr,name"`
Provider string `jsonapi:"attr,provider"`
RegistryName RegistryName `jsonapi:"attr,registry-name"`
Namespace string `jsonapi:"attr,namespace"`
NoCode bool `jsonapi:"attr,no-code"`
Permissions *RegistryModulePermissions `jsonapi:"attr,permissions"`
Status RegistryModuleStatus `jsonapi:"attr,status"`
VCSRepo *VCSRepo `jsonapi:"attr,vcs-repo"`
VersionStatuses []RegistryModuleVersionStatuses `jsonapi:"attr,version-statuses"`
CreatedAt string `jsonapi:"attr,created-at"`
UpdatedAt string `jsonapi:"attr,updated-at"`
ID string `jsonapi:"primary,registry-modules"`
Name string `jsonapi:"attr,name"`
Provider string `jsonapi:"attr,provider"`
RegistryName RegistryName `jsonapi:"attr,registry-name"`
Namespace string `jsonapi:"attr,namespace"`
NoCode bool `jsonapi:"attr,no-code"`
Permissions *RegistryModulePermissions `jsonapi:"attr,permissions"`
PublishingMechanism PublishingMechanism `jsonapi:"attr,publishing-mechanism"`
Status RegistryModuleStatus `jsonapi:"attr,status"`
TestConfig *TestConfig `jsonapi:"attr,test-config"`
VCSRepo *VCSRepo `jsonapi:"attr,vcs-repo"`
VersionStatuses []RegistryModuleVersionStatuses `jsonapi:"attr,version-statuses"`
CreatedAt string `jsonapi:"attr,created-at"`
UpdatedAt string `jsonapi:"attr,updated-at"`

// Relations
Organization *Organization `jsonapi:"relation,organization"`
Expand Down Expand Up @@ -239,6 +248,10 @@ type RegistryModuleCreateWithVCSConnectionOptions struct {
//
// **Note: This field is still in BETA and subject to change.**
InitialVersion *string `jsonapi:"attr,initial-version,omitempty"`

// Optional: Flag to enable tests for the module
// **Note: This field is still in BETA and subject to change.**
TestConfig *RegistryModuleTestConfigOptions `jsonapi:"attr,test-config,omitempty"`
}

// RegistryModuleCreateVersionOptions is used when updating a registry module
Expand All @@ -252,6 +265,16 @@ type RegistryModuleUpdateOptions struct {
// Optional: Flag to enable no-code provisioning for the whole module.
// **Note: This field is still in BETA and subject to change.**
NoCode *bool `jsonapi:"attr,no-code,omitempty"`

// Optional: Flag to enable tests for the module
// **Note: This field is still in BETA and subject to change.**
TestConfig *RegistryModuleTestConfigOptions `jsonapi:"attr,test-config,omitempty"`

VCSRepo *RegistryModuleVCSRepoUpdateOptions `jsonapi:"attr-vcs-repo,omitempty"`
}

type RegistryModuleTestConfigOptions struct {
TestsEnabled *bool `jsonapi:"attr,tests-enabled,omitempty"`
}

type RegistryModuleVCSRepoOptions struct {
Expand All @@ -268,6 +291,16 @@ type RegistryModuleVCSRepoOptions struct {
Branch *string `json:"branch,omitempty"`
}

type RegistryModuleVCSRepoUpdateOptions struct {
// The Branch and Tag fields are used to determine
// the PublishingMechanism for a RegistryModule that has a VCS a connection.
// When a value for Branch is provided, the Tags field is removed on the server
// When a value for Tags is provided, the Branch field is removed on the server
// **Note: This field is still in BETA and subject to change.**
Branch *string `json:"branch,omitempty"`
Tags *string `json:"tags,omitempty"`
}

// List all the registory modules within an organization.
func (r *registryModules) List(ctx context.Context, organization string, options *RegistryModuleListOptions) (*RegistryModuleList, error) {
if !validStringID(&organization) {
Expand Down Expand Up @@ -696,6 +729,15 @@ func (o RegistryModuleCreateWithVCSConnectionOptions) valid() error {
if o.VCSRepo == nil {
return ErrRequiredVCSRepo
}

if o.TestConfig != nil && o.TestConfig.TestsEnabled != nil {
if *o.TestConfig.TestsEnabled {
if !validString(o.VCSRepo.Branch) {
return ErrRequiredBranchWhenTestsEnabled
}
}
}

return o.VCSRepo.valid()
}

Expand Down
194 changes: 194 additions & 0 deletions registry_module_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,120 @@ func TestRegistryModuleUpdate(t *testing.T) {
})
}

func TestRegistryModuleUpdateWithVCSConnection(t *testing.T) {
skipUnlessBeta(t)
githubBranch := os.Getenv("GITHUB_REGISTRY_MODULE_BRANCH")
if githubBranch == "" {
githubBranch = "main"
}

githubIdentifier := os.Getenv("GITHUB_REGISTRY_MODULE_IDENTIFIER")
if githubIdentifier == "" {
t.Skip("Export a valid GITHUB_REGISTRY_MODULE_IDENTIFIER before running this test")
}

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

oauthTokenTest, oauthTokenTestCleanup := createOAuthToken(t, client, orgTest)
defer oauthTokenTestCleanup()

options := RegistryModuleCreateWithVCSConnectionOptions{
VCSRepo: &RegistryModuleVCSRepoOptions{
OrganizationName: String(orgTest.Name),
Identifier: String(githubIdentifier),
OAuthTokenID: String(oauthTokenTest.ID),
DisplayIdentifier: String(githubIdentifier),
},
}
rm, err := client.RegistryModules.CreateWithVCSConnection(ctx, options)
require.NoError(t, err)
assert.NotEmpty(t, rm.ID)

t.Run("enable no-code", func(t *testing.T) {
options := RegistryModuleUpdateOptions{
NoCode: Bool(true),
}
rm, err := client.RegistryModules.Update(ctx, RegistryModuleID{
Organization: orgTest.Name,
Name: rm.Name,
Provider: rm.Provider,
Namespace: rm.Namespace,
RegistryName: rm.RegistryName,
}, options)
require.NoError(t, err)
assert.True(t, rm.NoCode)
})

t.Run("disable no-code", func(t *testing.T) {
options := RegistryModuleUpdateOptions{
NoCode: Bool(false),
}
rm, err := client.RegistryModules.Update(ctx, RegistryModuleID{
Organization: orgTest.Name,
Name: rm.Name,
Provider: rm.Provider,
Namespace: rm.Namespace,
RegistryName: rm.RegistryName,
}, options)
require.NoError(t, err)
assert.False(t, rm.NoCode)
})

t.Run("toggle between git tag-based and branch-based publishing", func(t *testing.T) {
assert.Equal(t, "git_tag", rm.PublishingMechanism)

options := RegistryModuleUpdateOptions{
VCSRepo: &RegistryModuleVCSRepoUpdateOptions{
Branch: String(githubBranch),
},
}
rm, err := client.RegistryModules.Update(ctx, RegistryModuleID{
Organization: orgTest.Name,
Name: rm.Name,
Provider: rm.Provider,
Namespace: rm.Namespace,
RegistryName: rm.RegistryName,
}, options)
require.NoError(t, err)
assert.Equal(t, "branch", rm.PublishingMechanism)

options = RegistryModuleUpdateOptions{
VCSRepo: &RegistryModuleVCSRepoUpdateOptions{
Tags: String("1.0.0"),
},
}
rm, err = client.RegistryModules.Update(ctx, RegistryModuleID{
Organization: orgTest.Name,
Name: rm.Name,
Provider: rm.Provider,
Namespace: rm.Namespace,
RegistryName: rm.RegistryName,
}, options)
require.NoError(t, err)

assert.Equal(t, "git_tag", rm.PublishingMechanism)

options = RegistryModuleUpdateOptions{
VCSRepo: &RegistryModuleVCSRepoUpdateOptions{
Branch: String(githubBranch),
},
}
rm, err = client.RegistryModules.Update(ctx, RegistryModuleID{
Organization: orgTest.Name,
Name: rm.Name,
Provider: rm.Provider,
Namespace: rm.Namespace,
RegistryName: rm.RegistryName,
}, options)
require.NoError(t, err)
assert.Equal(t, "branch", rm.PublishingMechanism)
})
}

func TestRegistryModulesCreateVersion(t *testing.T) {
client := testClient(t)
ctx := context.Background()
Expand Down Expand Up @@ -762,6 +876,86 @@ func TestRegistryModulesCreateBranchBasedWithVCSConnection(t *testing.T) {
})
}

func TestRegistryModulesCreateBranchBasedWithVCSConnectionWithTesting(t *testing.T) {
skipUnlessBeta(t)

githubIdentifier := os.Getenv("GITHUB_REGISTRY_MODULE_IDENTIFIER")
if githubIdentifier == "" {
t.Skip("Export a valid GITHUB_REGISTRY_MODULE_IDENTIFIER before running this test")
}
repositoryName := strings.Split(githubIdentifier, "/")[1]
registryModuleProvider := strings.SplitN(repositoryName, "-", 3)[1]
registryModuleName := strings.SplitN(repositoryName, "-", 3)[2]

githubBranch := os.Getenv("GITHUB_REGISTRY_MODULE_BRANCH")
if githubBranch == "" {
githubBranch = "main"
}

client := testClient(t)
ctx := context.Background()

orgTest, orgTestCleanup := createOrganization(t, client)
defer orgTestCleanup()

oauthTokenTest, oauthTokenTestCleanup := createOAuthToken(t, client, orgTest)
defer oauthTokenTestCleanup()

t.Run("with valid options", func(t *testing.T) {
options := RegistryModuleCreateWithVCSConnectionOptions{
VCSRepo: &RegistryModuleVCSRepoOptions{
OrganizationName: String(orgTest.Name),
Identifier: String(githubIdentifier),
OAuthTokenID: String(oauthTokenTest.ID),
DisplayIdentifier: String(githubIdentifier),
Branch: String(githubBranch),
},
TestConfig: &RegistryModuleTestConfigOptions{
TestsEnabled: Bool(true),
},
}
rm, err := client.RegistryModules.CreateWithVCSConnection(ctx, options)
require.NoError(t, err)
assert.NotEmpty(t, rm.ID)
assert.Equal(t, registryModuleName, rm.Name)
assert.Equal(t, registryModuleProvider, rm.Provider)
assert.Equal(t, githubBranch, rm.VCSRepo.Branch)

t.Run("tests are enabled", func(t *testing.T) {
assert.NotEmpty(t, rm.TestConfig)
assert.True(t, rm.TestConfig.TestsEnabled)
})
})

t.Run("with invalid options", func(t *testing.T) {
options := RegistryModuleCreateWithVCSConnectionOptions{
VCSRepo: &RegistryModuleVCSRepoOptions{
Identifier: String(githubIdentifier),
OAuthTokenID: String(oauthTokenTest.ID),
DisplayIdentifier: String(githubIdentifier),
Branch: String(githubBranch),
},
}
_, err := client.RegistryModules.CreateWithVCSConnection(ctx, options)
require.Equal(t, err, ErrInvalidOrg)

t.Run("when the the module is not branch based and test are enabled", func(t *testing.T) {
options := RegistryModuleCreateWithVCSConnectionOptions{
VCSRepo: &RegistryModuleVCSRepoOptions{
Identifier: String(githubIdentifier),
OAuthTokenID: String(oauthTokenTest.ID),
DisplayIdentifier: String(githubIdentifier),
},
TestConfig: &RegistryModuleTestConfigOptions{
TestsEnabled: Bool(true),
},
}
_, err := client.RegistryModules.CreateWithVCSConnection(ctx, options)
require.Equal(t, err, ErrRequiredBranchWhenTestsEnabled)
})
})
}

func TestRegistryModulesCreateWithGithubApp(t *testing.T) {
githubIdentifier := os.Getenv("GITHUB_REGISTRY_MODULE_IDENTIFIER")
if githubIdentifier == "" {
Expand Down
5 changes: 5 additions & 0 deletions test_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package tfe

type TestConfig struct {
TestsEnabled bool `jsonapi:"attr,tests-enabled"`
}

0 comments on commit bd95d23

Please sign in to comment.