provider/test: a test provider
Here we also introduce a `test` provider meant as an aid to exposing via automated tests issues involving interactions between `helper/schema` and Terraform core. This has been helpful so far in diagnosing `ignore_changes` problems, and I imagine it will be helpful in other contexts as well. We'll have to be careful to prevent the `test` provider from becoming a dumping ground for poorly specified tests that have a clear home elsewhere. But for bug exposure I think it's useful to have.
This commit is contained in:
parent
3bb990311d
commit
c3e27b3e0a
|
@ -0,0 +1,19 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Provider() terraform.ResourceProvider {
|
||||||
|
return &schema.Provider{
|
||||||
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
"test_resource": testResource(),
|
||||||
|
},
|
||||||
|
ConfigureFunc: providerConfigure,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testAccProviders map[string]terraform.ResourceProvider
|
||||||
|
var testAccProvider *schema.Provider
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
testAccProvider = Provider().(*schema.Provider)
|
||||||
|
testAccProviders = map[string]terraform.ResourceProvider{
|
||||||
|
"test": testAccProvider,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testResource() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: testResourceCreate,
|
||||||
|
Read: testResourceRead,
|
||||||
|
Update: testResourceUpdate,
|
||||||
|
Delete: testResourceDelete,
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"required": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"optional": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"optional_force_new": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
d.SetId("testId")
|
||||||
|
|
||||||
|
// Required must make it through to Create
|
||||||
|
if _, ok := d.GetOk("required"); !ok {
|
||||||
|
return fmt.Errorf("Missing attribute 'required', but it's required!")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testResourceDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResource_basic(t *testing.T) {
|
||||||
|
resource.UnitTest(t, resource.TestCase{
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckResourceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: strings.TrimSpace(`
|
||||||
|
resource "test_resource" "foo" {
|
||||||
|
required = "yep"
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
Check: func(s *terraform.State) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckResourceDestroy(s *terraform.State) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -19,6 +19,10 @@ import (
|
||||||
|
|
||||||
const TestEnvVar = "TF_ACC"
|
const TestEnvVar = "TF_ACC"
|
||||||
|
|
||||||
|
// UnitTestOverride is a value that when set in TestEnvVar indicates that this
|
||||||
|
// is a unit test borrowing the acceptance testing framework.
|
||||||
|
const UnitTestOverride = "UnitTestOverride"
|
||||||
|
|
||||||
// TestCheckFunc is the callback type used with acceptance tests to check
|
// TestCheckFunc is the callback type used with acceptance tests to check
|
||||||
// the state of a resource. The state passed in is the latest state known,
|
// the state of a resource. The state passed in is the latest state known,
|
||||||
// or in the case of being after a destroy, it is the last known state when
|
// or in the case of being after a destroy, it is the last known state when
|
||||||
|
@ -108,6 +112,8 @@ func Test(t TestT, c TestCase) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isUnitTest := (os.Getenv(TestEnvVar) == UnitTestOverride)
|
||||||
|
|
||||||
logWriter, err := logging.LogOutput()
|
logWriter, err := logging.LogOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(fmt.Errorf("error setting up logging: %s", err))
|
t.Error(fmt.Errorf("error setting up logging: %s", err))
|
||||||
|
@ -115,7 +121,7 @@ func Test(t TestT, c TestCase) {
|
||||||
log.SetOutput(logWriter)
|
log.SetOutput(logWriter)
|
||||||
|
|
||||||
// We require verbose mode so that the user knows what is going on.
|
// We require verbose mode so that the user knows what is going on.
|
||||||
if !testTesting && !testing.Verbose() {
|
if !testTesting && !testing.Verbose() && !isUnitTest {
|
||||||
t.Fatal("Acceptance tests must be run with the -v flag on tests")
|
t.Fatal("Acceptance tests must be run with the -v flag on tests")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -173,6 +179,22 @@ func Test(t TestT, c TestCase) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnitTest is a helper to force the acceptance testing harness to run in the
|
||||||
|
// normal unit test suite. This should only be used for resource that don't
|
||||||
|
// have any external dependencies.
|
||||||
|
func UnitTest(t TestT, c TestCase) {
|
||||||
|
oldEnv := os.Getenv(TestEnvVar)
|
||||||
|
if err := os.Setenv(TestEnvVar, UnitTestOverride); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := os.Setenv(TestEnvVar, oldEnv); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
Test(t, c)
|
||||||
|
}
|
||||||
|
|
||||||
func testStep(
|
func testStep(
|
||||||
opts terraform.ContextOpts,
|
opts terraform.ContextOpts,
|
||||||
state *terraform.State,
|
state *terraform.State,
|
||||||
|
|
Loading…
Reference in New Issue