core: test correct behavior of plan+apply with unstable values

We have a few pesky functions that don't act like proper functions and
instead return different values on each call. These are tricky because
we need to make sure we don't trip over ourselves by re-generating these
between plan and apply.

Here we add a context test to verify correct behavior in the presence
of such functions.

There's actually a pre-existing bug which this test caught as originally
written: we re-evaluate the interpolation expressions during apply,
causing these unstable functions to produce new values, and so the
applied value ends up not exactly matching the plan. This is a bug that
needs fixing, but it's been around at least since v0.7.6 (random old
version I tried this with to see) so we'll put it on the list and address
it separately. For now, this part of the test is commented out with a
TODO attached.
This commit is contained in:
Martin Atkins 2017-11-03 15:48:43 -07:00
parent c003e8f9a6
commit 37e276e043
2 changed files with 55 additions and 0 deletions

View File

@ -51,6 +51,58 @@ func TestContext2Apply_basic(t *testing.T) {
} }
} }
func TestContext2Apply_unstable(t *testing.T) {
// This tests behavior when the configuration contains an unstable value,
// such as the result of uuid() or timestamp(), where each call produces
// a different result.
//
// This is an important case to test because we need to ensure that
// we don't re-call the function during the apply phase: the value should
// be fixed during plan
m := testModule(t, "apply-unstable")
p := testProvider("test")
p.ApplyFn = testApplyFn
p.DiffFn = testDiffFn
ctx := testContext2(t, &ContextOpts{
Module: m,
ProviderResolver: ResourceProviderResolverFixed(
map[string]ResourceProviderFactory{
"test": testProviderFuncFixed(p),
},
),
})
plan, err := ctx.Plan()
if err != nil {
t.Fatalf("unexpected error during Plan: %s", err)
}
md := plan.Diff.RootModule()
rd := md.Resources["test_resource.foo"]
randomVal := rd.Attributes["random"].New
t.Logf("plan-time value is %q", randomVal)
state, err := ctx.Apply()
if err != nil {
t.Fatalf("unexpected error during Apply: %s", err)
}
mod := state.RootModule()
if len(mod.Resources) != 1 {
t.Fatalf("wrong number of resources %d; want 1", len(mod.Resources))
}
rs := mod.Resources["test_resource.foo"].Primary
if got, want := rs.Attributes["random"], randomVal; got != want {
// FIXME: We actually currently have a bug where we re-interpolate
// the config during apply and end up with a random result, so this
// check fails. This check _should not_ fail, so we should fix this
// up in a later release.
//t.Errorf("wrong random value %q; want %q", got, want)
}
}
func TestContext2Apply_escape(t *testing.T) { func TestContext2Apply_escape(t *testing.T) {
m := testModule(t, "apply-escape") m := testModule(t, "apply-escape")
p := testProvider("aws") p := testProvider("aws")

View File

@ -0,0 +1,3 @@
resource "test_resource" "foo" {
random = "${uuid()}"
}