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

Feat/test block generator #64

Merged
merged 4 commits into from
Apr 17, 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
50 changes: 50 additions & 0 deletions pkg/helper/provider_block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package helper

// Provider structur
type Provider struct {
provider string
organisation string
}

// New function type that accepts pointer to Provider
// (~= Signature of option functions)
type ProviderOption func(*Provider)

// Provider constructor:
// - desc: Build a new Provider and apply specifics ProviderOption functions
// - args: provider name, ProviderOption function
// - return: pointer to Provider
func NewProvider(providerName string) *Provider {
// default values
const (
defaultOrganisation = ""
)

p := &Provider{
provider: providerName,
organisation: defaultOrganisation,
}

return p
}

// Organisation name:
// - desc: chained function that set Provider.Organisation then return Provider
// - args: new organisation name
// - return: pointer to Provider
func (p *Provider) SetOrganisation(orgName string) *Provider {
p.organisation = orgName
return p
}

// Provider block
// - desc: chained function that stringify Provider into a terraform block
// - args: none
// - return: string
func (p *Provider) String() string {
s := `provider "` + p.provider + `" {
organisation = "` + p.organisation + `"
}
`
return s
}
23 changes: 23 additions & 0 deletions pkg/helper/provider_block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package helper

import "testing"

func TestProvider_String(t *testing.T) {
tests := []struct {
name string
fields *Provider
want string
}{
{name: "test1", fields: NewProvider("clevercloud").SetOrganisation("clevercloud"), want: `provider "clevercloud" {
organisation = "clevercloud"
}
`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.fields.String(); got != tt.want {
t.Errorf("Provider.String() = %v, want %v", got, tt.want)
}
})
}
}
127 changes: 127 additions & 0 deletions pkg/helper/ressource_block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package helper

import (
"reflect"
"sort"
"strconv"
"strings"

"go.clever-cloud.com/terraform-provider/pkg"
)

type Ressource struct {
ressourceType string
ressourceName string
keyValues map[string]any
blockValues map[string]any
}

// New function type that accepts pointer to Ressource
// (~= Signature of option functions)
type RessourceOption func(*Ressource)

// Ressource constructor:
// - desc: Build a new Ressource and apply specifics RessourceOption functions
// - args: Ressource type and ressource name, RessourceOption function
// - return: pointer to Ressource
func NewRessource(ressourceType, ressourceName string, opts ...RessourceOption) *Ressource {

var r Ressource
r.ressourceType = ressourceType
r.ressourceName = ressourceName
r.keyValues = map[string]any{}
r.blockValues = map[string]any{}

// RessourceOption functions
for _, opt := range opts {
opt(&r)
}

return &r
}

// unit keyValues setter:
// - desc: set/add only one key: value to keyvalues field of a Ressource then return the Ressource
// - args: key + value
// - return: pointer to Ressource
func (r *Ressource) SetOneValue(key string, value any) *Ressource {
r.keyValues[key] = value
return r
}

// keyValues setter:
// - desc: set/add key: value to keyValues field of a Ressource then return the Ressource
// - args: map of string key + value
// - return: RessourceOption functions
func SetKeyValues(newMap map[string]any) RessourceOption {
return func(r *Ressource) {
for key, value := range newMap {
r.keyValues[key] = value
}
}
}

// blockValues setter:
// - desc: set/add key: value to kblockValues field of a Ressource then return the Ressource
// - args: map of string key + value
// - return: RessourceOption functions
func SetBlockValues(blockName string, newMap map[string]any) RessourceOption {
return func(r *Ressource) {
r.blockValues[blockName] = newMap
}
}

// Ressource block
// - desc: chained function that stringify Ressource into a terraform block
// - args: none
// - return: string
func (r *Ressource) String() string {
s := `resource "` + r.ressourceType + `" "` + r.ressourceName + `" {
`

// create keyValues block
s = map_String(r.keyValues, s, ` `, ` =`)
// create blockValues block
s = map_String(r.blockValues, s, ` `, ``)

// close s
s += `}
`

return s
}

func map_String(m map[string]any, s, tab, separator string) string {
// sort keyValues keys
valuesKeys := make([]string, 0, len(m))
for k := range m {
valuesKeys = append(valuesKeys, k)
}
sort.Strings(valuesKeys)

// create keyValues block
s = pkg.Reduce(valuesKeys, s, func(acc, key string) string {
switch c_type := m[key].(type) {
case string:
var_tmp := m[key].(string)
return acc + tab + key + ` = "` + strings.ReplaceAll(var_tmp, "\"", "\\\"") + `"
`
case int:
return acc + tab + key + ` = ` + strconv.Itoa(m[key].(int)) + `
`
case bool:
return acc + tab + key + ` = ` + strconv.FormatBool(m[key].(bool)) + `
`
case map[string]any:
acc := acc + tab + key + separator + ` {
`
return map_String(m[key].(map[string]any), acc, ` `, separator) + tab + `}
`
default:
return acc + `// Type ` + reflect.TypeOf(c_type).String() + ` of key "` + key + `" not considered yet
`
}
})

return s
}
60 changes: 60 additions & 0 deletions pkg/helper/ressource_block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package helper

import "testing"

func TestRessource_String(t *testing.T) {
tests := []struct {
name string
fields *Ressource
want string
}{
{name: "test1",
fields: NewRessource("clevercloud", "test1"),
want: `resource "clevercloud" "test1" {
}
`},
{
name: "test2",
fields: NewRessource("clevercloud_python", "test2").
SetOneValue("biggest_flavor", "XXL").
SetOneValue("test", 3),
want: `resource "clevercloud_python" "test2" {
biggest_flavor = "XXL"
test = 3
}
`},
{name: "test3",
fields: NewRessource(
"clevercloud_python",
"test3",
SetKeyValues(map[string]any{
"region": "ici",
"teststring": "smt",
"min_instance_count": 0,
"testint": 12,
"map": map[string]any{"test_string": "string", "test_int": 42}}),
SetBlockValues("testblock", map[string]any{"test_string": "string", "test_int": 42})),
want: `resource "clevercloud_python" "test3" {
map = {
test_int = 42
test_string = "string"
}
min_instance_count = 0
region = "ici"
testint = 12
teststring = "smt"
testblock {
test_int = 42
test_string = "string"
}
}
`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.fields.String(); got != tt.want {
t.Errorf("Ressource.String() = %v, want %v", got, tt.want)
}
})
}
}
3 changes: 0 additions & 3 deletions pkg/resources/python/provider_test_block.tf

This file was deleted.

45 changes: 34 additions & 11 deletions pkg/resources/python/resource_python_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,12 @@ import (
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"go.clever-cloud.com/terraform-provider/pkg"
"go.clever-cloud.com/terraform-provider/pkg/helper"
"go.clever-cloud.com/terraform-provider/pkg/provider/impl"
"go.clever-cloud.com/terraform-provider/pkg/tmp"
"go.clever-cloud.dev/client"
)

//go:embed resource_python_test_block.tf
var pythonBlock string

//go:embed resource_python_test_block2.tf
var pythonBlock2 string

//go:embed provider_test_block.tf
TheCrabe marked this conversation as resolved.
Show resolved Hide resolved
var providerBlock string

var protoV6Provider = map[string]func() (tfprotov6.ProviderServer, error){
"clevercloud": providerserver.NewProtocol6WithError(impl.New("test")()),
}
Expand Down Expand Up @@ -68,7 +60,28 @@ func TestAccPython_basic(t *testing.T) {
},
Steps: []resource.TestStep{{
ResourceName: rName,
Config: fmt.Sprintf(providerBlock, org) + fmt.Sprintf(pythonBlock, rName, rName),
Config: helper.NewProvider("clevercloud").
SetOrganisation(org).String() + helper.NewRessource(
"clevercloud_python",
rName,
helper.SetKeyValues(map[string]any{
"name": rName,
"region": "par",
"min_instance_count": 1,
"max_instance_count": 2,
"smallest_flavor": "XS",
"biggest_flavor": "M",
"redirect_https": true,
"sticky_sessions": true,
"app_folder": "./app",
"python_version": "2.7",
"pip_requirements": "requirements.txt",
"environment": map[string]any{
"MY_KEY": "myval",
},
}),
helper.SetBlockValues("hooks", map[string]any{"post_build": "echo \"build is OK!\""}),
).String(),
Check: resource.ComposeAggregateTestCheckFunc(
// Test the state for provider's populated values
resource.TestMatchResourceAttr(fullName, "id", regexp.MustCompile(`^app_.*$`)),
Expand Down Expand Up @@ -148,7 +161,17 @@ func TestAccPython_basic(t *testing.T) {
),
}, {
ResourceName: rName2,
Config: fmt.Sprintf(providerBlock, org) + fmt.Sprintf(pythonBlock2, rName2, rName2),
Config: helper.NewProvider("clevercloud").SetOrganisation(org).String() + helper.NewRessource("clevercloud_python",
rName2,
helper.SetKeyValues(map[string]any{
"name": "%s",
"region": "par",
"min_instance_count": 1,
"max_instance_count": 2,
"smallest_flavor": "XS",
"biggest_flavor": "M",
}),
helper.SetBlockValues("deployment", map[string]any{"repository": "https://github.com/CleverCloud/flask-example.git"})).String(),
Check: func(state *terraform.State) error {
id := state.RootModule().Resources[fullName2].Primary.ID

Expand Down
20 changes: 0 additions & 20 deletions pkg/resources/python/resource_python_test_block.tf

This file was deleted.

11 changes: 0 additions & 11 deletions pkg/resources/python/resource_python_test_block2.tf

This file was deleted.

Loading