2017-01-19 05:47:56 +01:00
|
|
|
package local
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2021-02-16 13:19:15 +01:00
|
|
|
"strings"
|
2017-01-19 05:47:56 +01:00
|
|
|
"testing"
|
|
|
|
|
2021-05-17 21:00:50 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
2021-05-17 17:42:17 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/backend"
|
2021-05-17 21:07:38 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/command/arguments"
|
|
|
|
"github.com/hashicorp/terraform/internal/command/clistate"
|
|
|
|
"github.com/hashicorp/terraform/internal/command/views"
|
2021-05-17 21:17:09 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/configs/configschema"
|
2019-01-09 03:39:14 +01:00
|
|
|
"github.com/hashicorp/terraform/internal/initwd"
|
2021-05-17 19:40:40 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/providers"
|
2021-05-17 21:43:35 +02:00
|
|
|
"github.com/hashicorp/terraform/internal/states"
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
"github.com/hashicorp/terraform/internal/terminal"
|
2017-01-19 05:47:56 +01:00
|
|
|
"github.com/hashicorp/terraform/terraform"
|
2020-04-01 21:07:05 +02:00
|
|
|
|
2018-05-23 04:57:04 +02:00
|
|
|
"github.com/zclconf/go-cty/cty"
|
2017-01-19 05:47:56 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestLocal_refresh(t *testing.T) {
|
2018-03-28 16:54:08 +02:00
|
|
|
b, cleanup := TestLocal(t)
|
|
|
|
defer cleanup()
|
|
|
|
|
2018-05-23 04:57:04 +02:00
|
|
|
p := TestLocalProvider(t, b, "test", refreshFixtureSchema())
|
2020-04-01 21:07:05 +02:00
|
|
|
testStateFile(t, b.StatePath, testRefreshState())
|
2017-01-19 05:47:56 +01:00
|
|
|
|
2018-10-04 00:50:04 +02:00
|
|
|
p.ReadResourceFn = nil
|
2021-01-12 22:13:10 +01:00
|
|
|
p.ReadResourceResponse = &providers.ReadResourceResponse{NewState: cty.ObjectVal(map[string]cty.Value{
|
2018-10-04 00:50:04 +02:00
|
|
|
"id": cty.StringVal("yes"),
|
|
|
|
})}
|
2017-01-19 05:47:56 +01:00
|
|
|
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
op, configCleanup, done := testOperationRefresh(t, "./testdata/refresh")
|
2018-03-21 02:43:02 +01:00
|
|
|
defer configCleanup()
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
defer done(t)
|
2017-01-19 05:47:56 +01:00
|
|
|
|
|
|
|
run, err := b.Operation(context.Background(), op)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("bad: %s", err)
|
|
|
|
}
|
|
|
|
<-run.Done()
|
|
|
|
|
2018-09-28 23:04:57 +02:00
|
|
|
if !p.ReadResourceCalled {
|
|
|
|
t.Fatal("ReadResource should be called")
|
2017-01-19 05:47:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
checkState(t, b.StateOutPath, `
|
|
|
|
test_instance.foo:
|
|
|
|
ID = yes
|
2020-04-01 21:07:05 +02:00
|
|
|
provider = provider["registry.terraform.io/hashicorp/test"]
|
2017-01-19 05:47:56 +01:00
|
|
|
`)
|
2017-02-22 22:08:03 +01:00
|
|
|
|
2020-08-11 17:23:42 +02:00
|
|
|
// the backend should be unlocked after a run
|
|
|
|
assertBackendStateUnlocked(t, b)
|
2017-02-22 22:08:03 +01:00
|
|
|
}
|
|
|
|
|
2017-01-19 05:47:56 +01:00
|
|
|
func TestLocal_refreshInput(t *testing.T) {
|
2018-03-28 16:54:08 +02:00
|
|
|
b, cleanup := TestLocal(t)
|
|
|
|
defer cleanup()
|
2017-01-19 05:47:56 +01:00
|
|
|
|
2020-09-21 21:58:06 +02:00
|
|
|
schema := &terraform.ProviderSchema{
|
2018-05-23 04:57:04 +02:00
|
|
|
Provider: &configschema.Block{
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
"value": {Type: cty.String, Optional: true},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
|
|
"test_instance": {
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
2020-09-21 21:58:06 +02:00
|
|
|
"id": {Type: cty.String, Computed: true},
|
2018-05-23 04:57:04 +02:00
|
|
|
"foo": {Type: cty.String, Optional: true},
|
2020-09-21 21:58:06 +02:00
|
|
|
"ami": {Type: cty.String, Optional: true},
|
2018-05-23 04:57:04 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2020-09-21 21:58:06 +02:00
|
|
|
|
|
|
|
p := TestLocalProvider(t, b, "test", schema)
|
|
|
|
testStateFile(t, b.StatePath, testRefreshState())
|
|
|
|
|
2018-10-04 00:50:04 +02:00
|
|
|
p.ReadResourceFn = nil
|
2021-01-12 22:13:10 +01:00
|
|
|
p.ReadResourceResponse = &providers.ReadResourceResponse{NewState: cty.ObjectVal(map[string]cty.Value{
|
2018-10-04 00:50:04 +02:00
|
|
|
"id": cty.StringVal("yes"),
|
|
|
|
})}
|
2021-02-18 16:13:43 +01:00
|
|
|
p.ConfigureProviderFn = func(req providers.ConfigureProviderRequest) (resp providers.ConfigureProviderResponse) {
|
2020-10-08 19:52:04 +02:00
|
|
|
val := req.Config.GetAttr("value")
|
|
|
|
if val.IsNull() || val.AsString() != "bar" {
|
|
|
|
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("incorrect value %#v", val))
|
2017-01-19 05:47:56 +01:00
|
|
|
}
|
|
|
|
|
2020-10-08 19:52:04 +02:00
|
|
|
return
|
2017-01-19 05:47:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Enable input asking since it is normally disabled by default
|
|
|
|
b.OpInput = true
|
|
|
|
b.ContextOpts.UIInput = &terraform.MockUIInput{InputReturnString: "bar"}
|
|
|
|
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
op, configCleanup, done := testOperationRefresh(t, "./testdata/refresh-var-unset")
|
2018-03-21 02:43:02 +01:00
|
|
|
defer configCleanup()
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
defer done(t)
|
2017-01-19 05:47:56 +01:00
|
|
|
op.UIIn = b.ContextOpts.UIInput
|
|
|
|
|
|
|
|
run, err := b.Operation(context.Background(), op)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("bad: %s", err)
|
|
|
|
}
|
|
|
|
<-run.Done()
|
|
|
|
|
2018-09-28 23:04:57 +02:00
|
|
|
if !p.ReadResourceCalled {
|
|
|
|
t.Fatal("ReadResource should be called")
|
2017-01-19 05:47:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
checkState(t, b.StateOutPath, `
|
|
|
|
test_instance.foo:
|
|
|
|
ID = yes
|
2020-04-01 21:07:05 +02:00
|
|
|
provider = provider["registry.terraform.io/hashicorp/test"]
|
2017-01-19 05:47:56 +01:00
|
|
|
`)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLocal_refreshValidate(t *testing.T) {
|
2018-03-28 16:54:08 +02:00
|
|
|
b, cleanup := TestLocal(t)
|
|
|
|
defer cleanup()
|
2018-05-23 04:57:04 +02:00
|
|
|
p := TestLocalProvider(t, b, "test", refreshFixtureSchema())
|
2020-04-01 21:07:05 +02:00
|
|
|
testStateFile(t, b.StatePath, testRefreshState())
|
2018-10-04 00:50:04 +02:00
|
|
|
p.ReadResourceFn = nil
|
2021-01-12 22:13:10 +01:00
|
|
|
p.ReadResourceResponse = &providers.ReadResourceResponse{NewState: cty.ObjectVal(map[string]cty.Value{
|
2018-10-04 00:50:04 +02:00
|
|
|
"id": cty.StringVal("yes"),
|
|
|
|
})}
|
2017-01-19 05:47:56 +01:00
|
|
|
|
|
|
|
// Enable validation
|
|
|
|
b.OpValidation = true
|
|
|
|
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
op, configCleanup, done := testOperationRefresh(t, "./testdata/refresh")
|
2018-03-21 02:43:02 +01:00
|
|
|
defer configCleanup()
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
defer done(t)
|
2017-01-19 05:47:56 +01:00
|
|
|
|
|
|
|
run, err := b.Operation(context.Background(), op)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("bad: %s", err)
|
|
|
|
}
|
|
|
|
<-run.Done()
|
|
|
|
|
|
|
|
checkState(t, b.StateOutPath, `
|
|
|
|
test_instance.foo:
|
2020-12-06 19:02:26 +01:00
|
|
|
ID = yes
|
|
|
|
provider = provider["registry.terraform.io/hashicorp/test"]
|
|
|
|
`)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLocal_refreshValidateProviderConfigured(t *testing.T) {
|
|
|
|
b, cleanup := TestLocal(t)
|
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
schema := &terraform.ProviderSchema{
|
|
|
|
Provider: &configschema.Block{
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
"value": {Type: cty.String, Optional: true},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
|
|
"test_instance": {
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
"id": {Type: cty.String, Computed: true},
|
|
|
|
"ami": {Type: cty.String, Optional: true},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
p := TestLocalProvider(t, b, "test", schema)
|
|
|
|
testStateFile(t, b.StatePath, testRefreshState())
|
|
|
|
p.ReadResourceFn = nil
|
2021-01-12 22:13:10 +01:00
|
|
|
p.ReadResourceResponse = &providers.ReadResourceResponse{NewState: cty.ObjectVal(map[string]cty.Value{
|
2020-12-06 19:02:26 +01:00
|
|
|
"id": cty.StringVal("yes"),
|
|
|
|
})}
|
|
|
|
|
|
|
|
// Enable validation
|
|
|
|
b.OpValidation = true
|
|
|
|
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
op, configCleanup, done := testOperationRefresh(t, "./testdata/refresh-provider-config")
|
2020-12-06 19:02:26 +01:00
|
|
|
defer configCleanup()
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
defer done(t)
|
2020-12-06 19:02:26 +01:00
|
|
|
|
|
|
|
run, err := b.Operation(context.Background(), op)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("bad: %s", err)
|
|
|
|
}
|
|
|
|
<-run.Done()
|
|
|
|
|
2021-02-18 16:13:43 +01:00
|
|
|
if !p.ValidateProviderConfigCalled {
|
|
|
|
t.Fatal("Validate provider config should be called")
|
2020-12-06 19:02:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
checkState(t, b.StateOutPath, `
|
|
|
|
test_instance.foo:
|
2017-01-19 05:47:56 +01:00
|
|
|
ID = yes
|
2020-04-01 21:07:05 +02:00
|
|
|
provider = provider["registry.terraform.io/hashicorp/test"]
|
2017-01-19 05:47:56 +01:00
|
|
|
`)
|
|
|
|
}
|
|
|
|
|
2020-08-11 17:23:42 +02:00
|
|
|
// This test validates the state lacking behavior when the inner call to
|
|
|
|
// Context() fails
|
|
|
|
func TestLocal_refresh_context_error(t *testing.T) {
|
|
|
|
b, cleanup := TestLocal(t)
|
|
|
|
defer cleanup()
|
|
|
|
testStateFile(t, b.StatePath, testRefreshState())
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
op, configCleanup, done := testOperationRefresh(t, "./testdata/apply")
|
2020-08-11 17:23:42 +02:00
|
|
|
defer configCleanup()
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
defer done(t)
|
2020-08-11 17:23:42 +02:00
|
|
|
|
|
|
|
// we coerce a failure in Context() by omitting the provider schema
|
|
|
|
|
|
|
|
run, err := b.Operation(context.Background(), op)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("bad: %s", err)
|
|
|
|
}
|
|
|
|
<-run.Done()
|
|
|
|
if run.Result == backend.OperationSuccess {
|
|
|
|
t.Fatal("operation succeeded; want failure")
|
|
|
|
}
|
|
|
|
assertBackendStateUnlocked(t, b)
|
|
|
|
}
|
|
|
|
|
2021-02-16 13:19:15 +01:00
|
|
|
func TestLocal_refreshEmptyState(t *testing.T) {
|
|
|
|
b, cleanup := TestLocal(t)
|
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
p := TestLocalProvider(t, b, "test", refreshFixtureSchema())
|
|
|
|
testStateFile(t, b.StatePath, states.NewState())
|
|
|
|
|
|
|
|
p.ReadResourceFn = nil
|
|
|
|
p.ReadResourceResponse = &providers.ReadResourceResponse{NewState: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
"id": cty.StringVal("yes"),
|
|
|
|
})}
|
|
|
|
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
op, configCleanup, done := testOperationRefresh(t, "./testdata/refresh")
|
2021-02-16 13:19:15 +01:00
|
|
|
defer configCleanup()
|
|
|
|
|
|
|
|
run, err := b.Operation(context.Background(), op)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("bad: %s", err)
|
|
|
|
}
|
|
|
|
<-run.Done()
|
|
|
|
|
2021-02-25 16:02:23 +01:00
|
|
|
output := done(t)
|
|
|
|
|
|
|
|
if stderr := output.Stderr(); stderr != "" {
|
|
|
|
t.Fatalf("expected only warning diags, got errors: %s", stderr)
|
2021-02-16 13:19:15 +01:00
|
|
|
}
|
2021-02-25 16:02:23 +01:00
|
|
|
if got, want := output.Stdout(), "Warning: Empty or non-existent state"; !strings.Contains(got, want) {
|
2021-02-16 13:19:15 +01:00
|
|
|
t.Errorf("wrong diags\n got: %s\nwant: %s", got, want)
|
|
|
|
}
|
|
|
|
|
|
|
|
// the backend should be unlocked after a run
|
|
|
|
assertBackendStateUnlocked(t, b)
|
|
|
|
}
|
|
|
|
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
func testOperationRefresh(t *testing.T, configDir string) (*backend.Operation, func(), func(*testing.T) *terminal.TestOutput) {
|
2018-03-21 02:43:02 +01:00
|
|
|
t.Helper()
|
|
|
|
|
2019-01-09 03:39:14 +01:00
|
|
|
_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir)
|
2018-03-21 02:43:02 +01:00
|
|
|
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
streams, done := terminal.StreamsForTesting(t)
|
|
|
|
view := views.NewOperation(arguments.ViewHuman, false, views.NewView(streams))
|
|
|
|
|
2017-01-19 05:47:56 +01:00
|
|
|
return &backend.Operation{
|
2021-02-25 16:02:23 +01:00
|
|
|
Type: backend.OperationTypeRefresh,
|
|
|
|
ConfigDir: configDir,
|
|
|
|
ConfigLoader: configLoader,
|
|
|
|
StateLocker: clistate.NewNoopLocker(),
|
|
|
|
View: view,
|
backend/local: Replace CLI with view instance
This commit extracts the remaining UI logic from the local backend,
and removes access to the direct CLI output. This is replaced with an
instance of a `views.Operation` interface, which codifies the current
requirements for the local backend to interact with the user.
The exception to this at present is interactivity: approving a plan
still depends on the `UIIn` field for the backend. This is out of scope
for this commit and can be revisited separately, at which time the
`UIOut` field can also be removed.
Changes in support of this:
- Some instances of direct error output have been replaced with
diagnostics, most notably in the emergency state backup handler. This
requires reformatting the error messages to allow the diagnostic
renderer to line-wrap them;
- The "in-automation" logic has moved out of the backend and into the
view implementation;
- The plan, apply, refresh, and import commands instantiate a view and
set it on the `backend.Operation` struct, as these are the only code
paths which call the `local.Operation()` method that requires it;
- The show command requires the plan rendering code which is now in the
views package, so there is a stub implementation of a `views.Show`
interface there.
Other refactoring work in support of migrating these commands to the
common views code structure will come in follow-up PRs, at which point
we will be able to remove the UI instances from the unit tests for those
commands.
2021-02-17 19:01:30 +01:00
|
|
|
}, configCleanup, done
|
2017-01-19 05:47:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// testRefreshState is just a common state that we use for testing refresh.
|
2020-04-01 21:07:05 +02:00
|
|
|
func testRefreshState() *states.State {
|
|
|
|
state := states.NewState()
|
|
|
|
root := state.EnsureModule(addrs.RootModuleInstance)
|
|
|
|
root.SetResourceInstanceCurrent(
|
|
|
|
mustResourceInstanceAddr("test_instance.foo").Resource,
|
|
|
|
&states.ResourceInstanceObjectSrc{
|
|
|
|
Status: states.ObjectReady,
|
|
|
|
AttrsJSON: []byte(`{"id":"bar"}`),
|
2017-01-19 05:47:56 +01:00
|
|
|
},
|
2020-04-01 21:07:05 +02:00
|
|
|
mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`),
|
|
|
|
)
|
|
|
|
return state
|
2017-01-19 05:47:56 +01:00
|
|
|
}
|
2018-05-23 04:57:04 +02:00
|
|
|
|
|
|
|
// refreshFixtureSchema returns a schema suitable for processing the
|
2019-06-30 09:38:36 +02:00
|
|
|
// configuration in testdata/refresh . This schema should be
|
2018-05-23 04:57:04 +02:00
|
|
|
// assigned to a mock provider named "test".
|
|
|
|
func refreshFixtureSchema() *terraform.ProviderSchema {
|
|
|
|
return &terraform.ProviderSchema{
|
|
|
|
ResourceTypes: map[string]*configschema.Block{
|
|
|
|
"test_instance": {
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
"ami": {Type: cty.String, Optional: true},
|
2018-10-04 00:50:04 +02:00
|
|
|
"id": {Type: cty.String, Computed: true},
|
2018-05-23 04:57:04 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|