Propagate secretness correctly in Python apply
(#4273)
* Propagate secretness correctly in Python `apply` * Improve `apply` test coverage * Update CHANGELOG.md
This commit is contained in:
parent
9c82975478
commit
dd104a00a7
|
@ -5,6 +5,9 @@ CHANGELOG
|
|||
- Fix handling of `nil` values in Outputs in Go.
|
||||
[#4268](https://github.com/pulumi/pulumi/pull/4268)
|
||||
|
||||
- Fix secretness propagation in Python `apply`.
|
||||
[#4273](https://github.com/pulumi/pulumi/pull/4273)
|
||||
|
||||
## 1.14.0 (2020-04-01)
|
||||
- Fix error related to side-by-side versions of `@pulumi/pulumi`.
|
||||
[#4235](https://github.com/pulumi/pulumi/pull/4235)
|
||||
|
|
|
@ -26,6 +26,39 @@ namespace Pulumi.Tests.Core
|
|||
Assert.Equal(1, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyCanRunOnKnownAwaitableValue()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyCanRunOnKnownKnownOutputValue()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyCanRunOnKnownUnknownOutputValue()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesUnknownDefaultOnUnknown()
|
||||
=> RunInPreview(async () =>
|
||||
|
@ -37,6 +70,39 @@ namespace Pulumi.Tests.Core
|
|||
Assert.Equal(0, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesUnknownDefaultOnUnknownAwaitable()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesUnknownDefaultOnUnknownKnownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesUnknownDefaultOnUnknownUnknownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnown()
|
||||
=> RunInPreview(async () =>
|
||||
|
@ -49,6 +115,42 @@ namespace Pulumi.Tests.Core
|
|||
Assert.Equal(1, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnownAwaitable()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true, isSecret: true);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnownKnownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnownUnknownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknown()
|
||||
=> RunInPreview(async () =>
|
||||
|
@ -60,6 +162,90 @@ namespace Pulumi.Tests.Core
|
|||
Assert.True(data.IsSecret);
|
||||
Assert.Equal(0, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknownAwaitable()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false, isSecret: true);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknownKnownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknownUnknownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPropagatesSecretOnKnownKnownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPropagatesSecretOnKnownUnknownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyDoesNotPropagateSecretOnUnknownKnownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.False(data.IsSecret);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyDoesNotPropagateSecretOnUnknownUnknownOutput()
|
||||
=> RunInPreview(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.False(data.IsSecret);
|
||||
Assert.Null(data.Value);
|
||||
});
|
||||
}
|
||||
|
||||
public class NormalTests
|
||||
|
@ -75,6 +261,39 @@ namespace Pulumi.Tests.Core
|
|||
Assert.Equal(1, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyCanRunOnKnownAwaitableValue()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyCanRunOnKnownKnownOutputValue()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyCanRunOnKnownUnknownOutputValue()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesKnownOnUnknown()
|
||||
=> RunInNormal(async () =>
|
||||
|
@ -86,6 +305,39 @@ namespace Pulumi.Tests.Core
|
|||
Assert.Equal(1, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesKnownOnUnknownAwaitable()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesKnownOnUnknownKnownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyProducesUnknownOnUnknownUnknownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnown()
|
||||
=> RunInNormal(async () =>
|
||||
|
@ -98,6 +350,42 @@ namespace Pulumi.Tests.Core
|
|||
Assert.Equal(1, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnownAwaitable()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true, isSecret: true);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnownKnownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnKnownUnknownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknown()
|
||||
=> RunInNormal(async () =>
|
||||
|
@ -109,6 +397,90 @@ namespace Pulumi.Tests.Core
|
|||
Assert.True(data.IsSecret);
|
||||
Assert.Equal(1, data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknownAwaitable()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false, isSecret: true);
|
||||
var o2 = o1.Apply(a => Task.FromResult("inner"));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknownKnownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPreservesSecretOnUnknownUnknownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false, isSecret: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPropagatesSecretOnKnownKnownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.True(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPropagatesSecretOnKnownUnknownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: true);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPropagatesSecretOnUnknownKnownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: true, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
|
||||
[Fact]
|
||||
public Task ApplyPropagatesSecretOnUnknownUnknownOutput()
|
||||
=> RunInNormal(async () =>
|
||||
{
|
||||
var o1 = CreateOutput(0, isKnown: false);
|
||||
var o2 = o1.Apply(a => CreateOutput("inner", isKnown: false, isSecret: true));
|
||||
var data = await o2.DataTask.ConfigureAwait(false);
|
||||
Assert.False(data.IsKnown);
|
||||
Assert.True(data.IsSecret);
|
||||
Assert.Equal("inner", data.Value);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { Output, all, concat, interpolate, output, unknown } from "../output";
|
|||
import { Resource } from "../resource";
|
||||
import * as runtime from "../runtime";
|
||||
import { asyncTest } from "./util";
|
||||
import { promiseResult } from "../utils";
|
||||
|
||||
interface Widget {
|
||||
type: string; // metric | text
|
||||
|
@ -137,6 +138,437 @@ describe("output", () => {
|
|||
assert.equal(value, "inner");
|
||||
}));
|
||||
|
||||
describe("apply", () => {
|
||||
function createOutput<T>(val: T, isKnown: boolean, isSecret: boolean = false): Output<T> {
|
||||
return new Output(new Set(), Promise.resolve(val), Promise.resolve(isKnown), Promise.resolve(isSecret),
|
||||
Promise.resolve(new Set()));
|
||||
}
|
||||
|
||||
it("can run on known value during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), 1);
|
||||
}));
|
||||
|
||||
it("can run on known awaitable value during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("can run on known known output value during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("can run on known unknown output value during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("produces unknown default on unknown during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("produces unknown default on unknown awaitable during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("produces unknown default on unknown known output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("produces unknown default on unknown unknown output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("preserves secret on known during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), 1);
|
||||
}));
|
||||
|
||||
it("preserves secret on known awaitable during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on known known output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on known unknown output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown awaitable during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown known output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown unknown output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("propagates secret on known known output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", true, true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("propagates secret on known unknown output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", false, true));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("does not propagate secret on unknown known output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", true, true));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, false);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("does not propagate secret on unknown unknown output during preview", asyncTest(async () => {
|
||||
runtime._setIsDryRun(true);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", false, true));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, false);
|
||||
assert.equal(await r.promise(), undefined);
|
||||
}));
|
||||
|
||||
it("can run on known value", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), 1);
|
||||
}));
|
||||
|
||||
it("can run on known awaitable value", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("can run on known known output value", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("can run on unknown known output value", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("produces known on unknown", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), 1);
|
||||
}));
|
||||
|
||||
it("produces known on unknown awaitable", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("produces known on unknown known output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("produces unknown on unknown unknown output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on known", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), 1);
|
||||
}));
|
||||
|
||||
it("preserves secret on known awaitable", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on known known output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on known known output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true, true);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => v + 1);
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), 1);
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown awaitable", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => Promise.resolve("inner"));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown known output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => createOutput("inner", true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("preserves secret on unknown known output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false, true);
|
||||
const r = out.apply(v => createOutput("inner", false));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("propagates secret on known known output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", true, true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("propagates secret on known unknown output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, true);
|
||||
const r = out.apply(v => createOutput("inner", false, true));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("propagates secret on unknown known output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", true, true));
|
||||
|
||||
assert.equal(await r.isKnown, true);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
|
||||
it("propagates secret on unknown uknown output", asyncTest(async () => {
|
||||
runtime._setIsDryRun(false);
|
||||
|
||||
const out = createOutput(0, false);
|
||||
const r = out.apply(v => createOutput("inner", false, true));
|
||||
|
||||
assert.equal(await r.isKnown, false);
|
||||
assert.equal(await r.isSecret, true);
|
||||
assert.equal(await r.promise(), "inner");
|
||||
}));
|
||||
});
|
||||
|
||||
describe("isKnown", () => {
|
||||
function or<T>(output1: Output<T>, output2: Output<T>): Output<T> {
|
||||
const val1 = output1.promise();
|
||||
|
|
|
@ -64,7 +64,7 @@ class Output(Generic[T]):
|
|||
|
||||
_is_secret: Awaitable[bool]
|
||||
"""
|
||||
Where or not this 'Output' should be treated as containing secret data. Secret outputs are tagged when
|
||||
Whether or not this 'Output' should be treated as containing secret data. Secret outputs are tagged when
|
||||
flowing across the RPC interface to the resource monitor, such that when they are persisted to disk in
|
||||
our state file, they are encrypted instead of being in plaintext.
|
||||
"""
|
||||
|
@ -155,16 +155,16 @@ class Output(Generic[T]):
|
|||
value = await self._future
|
||||
|
||||
if runtime.is_dry_run():
|
||||
# During previews only perform the apply if the engine was able togive us an actual value for this
|
||||
# During previews only perform the apply if the engine was able to give us an actual value for this
|
||||
# Output or if the caller is able to tolerate unknown values.
|
||||
apply_during_preview = is_known or run_with_unknowns
|
||||
|
||||
if not apply_during_preview:
|
||||
# We didn't actually run the function, our new Output is definitely
|
||||
# **not** known and **not** secret
|
||||
# **not** known.
|
||||
result_resources.set_result(resources)
|
||||
result_is_known.set_result(False)
|
||||
result_is_secret.set_result(False)
|
||||
result_is_secret.set_result(is_secret)
|
||||
return cast(U, None)
|
||||
|
||||
# If we are running with unknown values and the value is explicitly unknown but does not actually
|
||||
|
@ -187,16 +187,16 @@ class Output(Generic[T]):
|
|||
|
||||
# 2. transformed is an Awaitable[U]
|
||||
if isawaitable(transformed):
|
||||
# Since transformed is not an Output, it is both known and not a secret.
|
||||
# Since transformed is not an Output, it is known.
|
||||
result_resources.set_result(resources)
|
||||
result_is_known.set_result(True)
|
||||
result_is_secret.set_result(False)
|
||||
result_is_secret.set_result(is_secret)
|
||||
return await cast(Awaitable[U], transformed)
|
||||
|
||||
# 3. transformed is U. It is trivially known.
|
||||
result_resources.set_result(resources)
|
||||
result_is_known.set_result(True)
|
||||
result_is_secret.set_result(False)
|
||||
result_is_secret.set_result(is_secret)
|
||||
return cast(U, transformed)
|
||||
finally:
|
||||
# Always resolve the future if it hasn't been done already.
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# limitations under the License.
|
||||
import asyncio
|
||||
import unittest
|
||||
from typing import Any, Optional
|
||||
|
||||
from google.protobuf import struct_pb2
|
||||
from pulumi.resource import CustomResource
|
||||
|
@ -291,13 +292,484 @@ class NextSerializationTests(unittest.TestCase):
|
|||
out = Output(set(), fut, known_fut)
|
||||
self.assertFalse(await out.is_known())
|
||||
|
||||
def create_output(self, val: Any, is_known: bool, is_secret: Optional[bool] = None):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result(val)
|
||||
known_fut = asyncio.Future()
|
||||
known_fut.set_result(is_known)
|
||||
if is_secret is not None:
|
||||
is_secret_fut = asyncio.Future()
|
||||
is_secret_fut.set_result(True)
|
||||
return Output(set(), fut, known_fut, is_secret_fut)
|
||||
return Output(set(), fut, known_fut)
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_value_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), 1)
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_awaitable_value_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_known_output_value_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_unknown_output_value_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_unknown_default_on_unknown_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_unknown_default_on_unknown_awaitable_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_unknown_default_on_unknown_known_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_unknown_default_on_unknown_unknown_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), 1)
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known_awaitable_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known_known_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known_unknown_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown_awaitable_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown_known_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown_unknown_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_propagates_secret_on_known_known_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True, is_secret=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_propagates_secret_on_known_unknown_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False, is_secret=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_does_not_propagate_secret_on_unknown_known_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True, is_secret=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertFalse(await r.is_secret())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_does_not_propagate_secret_on_unknown_unknown_output_during_preview(self):
|
||||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=false, is_secret=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertFalse(await r.is_secret())
|
||||
self.assertEqual(await r.future(), None)
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_value(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), 1)
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_awaitable_value(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_known_output_value(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_can_run_on_known_unknown_output_value(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_known_on_unknown(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), 1)
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_known_on_unknown_awaitable(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_known_on_unknown_known_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_produces_unknown_on_unknown_unknown_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), 1)
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known_awaitable(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known_known_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_known_unknown_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
r = out.apply(lambda v: v + 1)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), 1)
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown_awaitable(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
|
||||
def apply(v):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("inner")
|
||||
return fut
|
||||
r = out.apply(apply)
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown_known_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_preserves_secret_on_unknown_unknown_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False, is_secret=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_propagates_secret_on_known_known_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True, is_secret=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_propagates_secret_on_known_unknown_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=True)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False, is_secret=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_propagates_secret_on_unknown_known_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=True, is_secret=True))
|
||||
|
||||
self.assertTrue(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_propagates_secret_on_unknown_unknown_output(self):
|
||||
settings.SETTINGS.dry_run = False
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False, is_secret=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertTrue(await r.is_secret())
|
||||
self.assertEqual(await r.future(), "inner")
|
||||
|
||||
@async_test
|
||||
async def test_apply_unknown_output(self):
|
||||
fut = asyncio.Future()
|
||||
fut.set_result("foo")
|
||||
known_fut = asyncio.Future()
|
||||
known_fut.set_result(True)
|
||||
out = Output(set(), fut, known_fut)
|
||||
out = self.create_output("foo", is_known=True)
|
||||
|
||||
r1 = out.apply(lambda v: UNKNOWN)
|
||||
r2 = out.apply(lambda v: [v, UNKNOWN])
|
||||
|
|
Loading…
Reference in a new issue