Skip to content

Commit ade2dc9

Browse files
committed
Add support for running examples across multiple TF versions
Also add test to do this for a simple VCN test
1 parent eb9d6e6 commit ade2dc9

File tree

1 file changed

+79
-6
lines changed

1 file changed

+79
-6
lines changed

provider/examples_test.go

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package provider
44

55
import (
66
"fmt"
7+
"io/ioutil"
78
"log"
89
"os"
910
"os/exec"
@@ -13,8 +14,13 @@ import (
1314
)
1415

1516
const examplesTestStateFile = "test_examples.tfstate"
17+
const defaultTerraformBinary = "terraform"
18+
const vcnExamplePath = "../docs/examples/networking/vcn"
19+
const localBinPath = "/usr/local/bin"
20+
const tfPluginDir = "~/.terraform.d/plugins"
1621

1722
var examplesTestAllowedEnvironmentVariables = []string{
23+
"HOME",
1824
"PATH",
1925
"TF_VAR_user_ocid",
2026
"TF_VAR_tenancy_ocid",
@@ -36,6 +42,12 @@ func TestExamplesApply(t *testing.T) {
3642
RunExamples(t, false)
3743
}
3844

45+
func TestTerraformVersions(t *testing.T) {
46+
if RunConfigOnAllTerraformVersions(t, vcnExamplePath, false) {
47+
log.Printf("Successfully ran all Terraform version tests")
48+
}
49+
}
50+
3951
func RunExamples(t *testing.T, planOnly bool) {
4052
rootPath := "../docs/examples"
4153
log.Printf("Testing examples under %v", rootPath)
@@ -47,12 +59,30 @@ func RunExamples(t *testing.T, planOnly bool) {
4759
}
4860

4961
for _, dir := range pathList {
50-
if RunConfig(t, dir, planOnly) {
62+
if RunConfig(t, dir, planOnly, defaultTerraformBinary) {
5163
log.Printf("Success")
5264
}
5365
}
5466
}
5567

68+
func GetTerraformBinaries(binPath string) ([]string, error) {
69+
results := []string{}
70+
71+
entries, err := ioutil.ReadDir(binPath)
72+
if err != nil {
73+
return results, err
74+
}
75+
76+
for _, entry := range entries {
77+
// Include any binaries that start with "terraform" prefix
78+
if name := entry.Name(); !entry.IsDir() && strings.HasPrefix(name, defaultTerraformBinary) {
79+
results = append(results, name)
80+
}
81+
}
82+
83+
return results, nil
84+
}
85+
5686
func GetConfigPaths(t *testing.T, rootPath string) (pathList []string, err error) {
5787
dirSet := make(map[string]struct{})
5888

@@ -81,25 +111,60 @@ func GetConfigPaths(t *testing.T, rootPath string) (pathList []string, err error
81111
return pathList, err
82112
}
83113

84-
func RunConfig(t *testing.T, path string, planOnly bool) bool {
114+
func RunConfigOnAllTerraformVersions(t *testing.T, path string, planOnly bool) bool {
115+
terraformBinaries, err := GetTerraformBinaries(localBinPath)
116+
if err != nil {
117+
t.Errorf("Error retrieving terraform binaries: %v", err)
118+
return false
119+
}
120+
121+
if len(terraformBinaries) == 0 {
122+
t.Errorf("Did not find any terraform binaries")
123+
return false
124+
}
125+
126+
result := true
127+
for _, tfBin := range terraformBinaries {
128+
log.Printf("=== Terraform Version ('%s'), Config Path ('%s') ===\n", tfBin, path)
129+
if !runCommandWithOutputOptions(t, path, fmt.Sprintf("%s version", tfBin), true) {
130+
log.Printf("Unable to run version command. Skipping test for %s.\n", tfBin)
131+
result = false
132+
continue
133+
}
134+
135+
if !RunConfig(t, path, planOnly, tfBin) {
136+
log.Printf("Failed to run test on version '%s'\n", tfBin)
137+
result = false
138+
}
139+
}
140+
141+
return result
142+
}
143+
144+
func RunConfig(t *testing.T, path string, planOnly bool, terraformBinary string) bool {
85145
// Fail if a state file already exists, since that indicates that a previous run did not
86146
// properly clean up.
87147
if _, err := os.Stat(filepath.Join(path, examplesTestStateFile)); err == nil {
88148
t.Errorf("State file '%v' already exists at %v.", examplesTestStateFile, path)
89149
return false
90150
}
91151

92-
if !RunCommand(t, path, "terraform init") {
152+
terraformCommand := terraformBinary
153+
if terraformCommand == "" {
154+
terraformCommand = defaultTerraformBinary
155+
}
156+
157+
if !RunCommand(t, path, fmt.Sprintf("%s init -plugin-dir %s", terraformCommand, tfPluginDir)) {
93158
return false
94159
}
95160

96161
if planOnly {
97-
return RunCommand(t, path, fmt.Sprintf("terraform plan -state=%v", examplesTestStateFile))
162+
return RunCommand(t, path, fmt.Sprintf("%s plan -state=%v", terraformCommand, examplesTestStateFile))
98163
} else {
99-
result := RunCommand(t, path, fmt.Sprintf("terraform apply -auto-approve -state=%v", examplesTestStateFile))
164+
result := RunCommand(t, path, fmt.Sprintf("%s apply -auto-approve -state=%v", terraformCommand, examplesTestStateFile))
100165

101166
// Regardless of the result, attempt to destroy.
102-
if RunCommand(t, path, fmt.Sprintf("terraform destroy -force -state=%v", examplesTestStateFile)) {
167+
if RunCommand(t, path, fmt.Sprintf("%s destroy -force -state=%v", terraformCommand, examplesTestStateFile)) {
103168
// Only remove the state file if destroy was successful. Otherwise, leave it in place so that further
104169
// cleanup can be done manually.
105170
result = RunCommand(t, path, fmt.Sprintf("rm %v*", examplesTestStateFile)) && result
@@ -112,6 +177,10 @@ func RunConfig(t *testing.T, path string, planOnly bool) bool {
112177
}
113178

114179
func RunCommand(t *testing.T, path, command string) bool {
180+
return runCommandWithOutputOptions(t, path, command, false)
181+
}
182+
183+
func runCommandWithOutputOptions(t *testing.T, path, command string, displayOutputOnSuccess bool) bool {
115184
log.Printf("Running command '%v' at %v", command, path)
116185

117186
env := make([]string, len(examplesTestAllowedEnvironmentVariables))
@@ -130,5 +199,9 @@ func RunCommand(t *testing.T, path, command string) bool {
130199
return false
131200
}
132201

202+
if displayOutputOnSuccess {
203+
log.Printf("Output: %s", output)
204+
}
205+
133206
return true
134207
}

0 commit comments

Comments
 (0)