terraform/command/show_test.go

228 lines
5.6 KiB
Go

package command
import (
"path/filepath"
"testing"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs/configschema"
"github.com/hashicorp/terraform/plans"
"github.com/hashicorp/terraform/providers"
"github.com/hashicorp/terraform/states"
"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/cli"
"github.com/zclconf/go-cty/cty"
)
func TestShow(t *testing.T) {
ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"bad",
"bad",
}
if code := c.Run(args); code != 1 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}
}
func TestShow_JSONStateNotImplemented(t *testing.T) {
// Create the default state
statePath := testStateFile(t, testState())
defer testChdir(t, filepath.Dir(statePath))()
ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
"-json",
statePath,
}
if code := c.Run(args); code != 1 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}
}
func TestShow_noArgs(t *testing.T) {
// Create the default state
statePath := testStateFile(t, testState())
defer testChdir(t, filepath.Dir(statePath))()
ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}
}
func TestShow_noArgsNoState(t *testing.T) {
// Create the default state
statePath := testStateFile(t, testState())
defer testChdir(t, filepath.Dir(statePath))()
ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.OutputWriter.String())
}
}
func TestShow_plan(t *testing.T) {
planPath := testPlanFileNoop(t)
ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
planPath,
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
}
func TestShow_plan_json(t *testing.T) {
planPath := showFixturePlanFile(t)
ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(showFixtureProvider()),
Ui: ui,
},
}
args := []string{
"-json",
planPath,
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
}
func TestShow_state(t *testing.T) {
originalState := testState()
statePath := testStateFile(t, originalState)
ui := new(cli.MockUi)
c := &ShowCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(testProvider()),
Ui: ui,
},
}
args := []string{
statePath,
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
}
}
// showFixtureSchema returns a schema suitable for processing the configuration
// in test-fixtures/show. This schema should be assigned to a mock provider
// named "test".
func showFixtureSchema() *terraform.ProviderSchema {
return &terraform.ProviderSchema{
ResourceTypes: map[string]*configschema.Block{
"test_instance": {
Attributes: map[string]*configschema.Attribute{
"id": {Type: cty.String, Optional: true, Computed: true},
"ami": {Type: cty.String, Optional: true},
},
},
},
}
}
// showFixtureProvider returns a mock provider that is configured for basic
// operation with the configuration in test-fixtures/show. This mock has
// GetSchemaReturn, PlanResourceChangeFn, and ApplyResourceChangeFn populated,
// with the plan/apply steps just passing through the data determined by
// Terraform Core.
func showFixtureProvider() *terraform.MockProvider {
p := testProvider()
p.GetSchemaReturn = showFixtureSchema()
p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) providers.PlanResourceChangeResponse {
return providers.PlanResourceChangeResponse{
PlannedState: req.ProposedNewState,
}
}
p.ApplyResourceChangeFn = func(req providers.ApplyResourceChangeRequest) providers.ApplyResourceChangeResponse {
return providers.ApplyResourceChangeResponse{
NewState: cty.UnknownAsNull(req.PlannedState),
}
}
return p
}
// showFixturePlanFile creates a plan file at a temporary location containing a
// single change to create the test_instance.foo that is included in the "show"
// test fixture, returning the location of that plan file.
func showFixturePlanFile(t *testing.T) string {
_, snap := testModuleWithSnapshot(t, "show")
plannedVal := cty.ObjectVal(map[string]cty.Value{
"id": cty.UnknownVal(cty.String),
"ami": cty.StringVal("bar"),
})
priorValRaw, err := plans.NewDynamicValue(cty.NullVal(plannedVal.Type()), plannedVal.Type())
if err != nil {
t.Fatal(err)
}
plannedValRaw, err := plans.NewDynamicValue(plannedVal, plannedVal.Type())
if err != nil {
t.Fatal(err)
}
plan := testPlan(t)
plan.Changes.SyncWrapper().AppendResourceInstanceChange(&plans.ResourceInstanceChangeSrc{
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_instance",
Name: "foo",
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
ProviderAddr: addrs.ProviderConfig{Type: "test"}.Absolute(addrs.RootModuleInstance),
ChangeSrc: plans.ChangeSrc{
Action: plans.Create,
Before: priorValRaw,
After: plannedValRaw,
},
})
return testPlanFile(
t,
snap,
states.NewState(),
plan,
)
}