Refactor Mock newResource and call to accept property bag rather than individual args (#6672)
This commit is contained in:
parent
fef3157b18
commit
e955a6b06a
|
@ -19,13 +19,12 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pulumi/pulumi/pkg/v3/backend"
|
||||
"github.com/pulumi/pulumi/pkg/v3/backend/display"
|
||||
"github.com/pulumi/pulumi/pkg/v3/resource/stack"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/apitype"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/config"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/backend/display"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func newStackChangeSecretsProviderCmd() *cobra.Command {
|
||||
|
|
|
@ -18,10 +18,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/result"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pulumi/pulumi/pkg/v3/backend/display"
|
||||
"github.com/pulumi/pulumi/pkg/v3/resource/deploy"
|
||||
|
@ -31,6 +27,8 @@ import (
|
|||
"github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/result"
|
||||
"github.com/spf13/cobra"
|
||||
survey "gopkg.in/AlecAivazis/survey.v1"
|
||||
surveycore "gopkg.in/AlecAivazis/survey.v1/core"
|
||||
|
|
|
@ -143,18 +143,12 @@ func TestGeneratePackage(t *testing.T) {
|
|||
|
||||
type mocks int
|
||||
|
||||
func (mocks) NewResource(
|
||||
typeToken string,
|
||||
name string,
|
||||
inputs resource.PropertyMap,
|
||||
provider string,
|
||||
id string,
|
||||
) (string, resource.PropertyMap, error) {
|
||||
return name + "_id", inputs, nil
|
||||
func (mocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
return args.Name + "_id", args.Inputs, nil
|
||||
}
|
||||
|
||||
func (mocks) Call(token string, args resource.PropertyMap, provider string) (resource.PropertyMap, error) {
|
||||
return args, nil
|
||||
func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
|
||||
return args.Args, nil
|
||||
}
|
||||
|
||||
func TestEnumUsage(t *testing.T) {
|
||||
|
|
|
@ -22,14 +22,13 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/hcl2"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/hcl2/model"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/hcl2/model/format"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/hcl2/syntax"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
|
|
@ -12,23 +12,23 @@ namespace Pulumi.Tests.Mocks
|
|||
{
|
||||
class MyMocks : IMocks
|
||||
{
|
||||
public Task<object> CallAsync(string token, ImmutableDictionary<string, object> args, string? provider)
|
||||
public Task<object> CallAsync(MockCallArgs args)
|
||||
{
|
||||
return Task.FromResult<object>(args);
|
||||
}
|
||||
|
||||
public Task<(string? id, object state)> NewResourceAsync(string type, string name, ImmutableDictionary<string, object> inputs, string? provider, string? id)
|
||||
public Task<(string? id, object state)> NewResourceAsync(MockResourceArgs args)
|
||||
{
|
||||
switch (type)
|
||||
switch (args.Type)
|
||||
{
|
||||
case "aws:ec2/instance:Instance":
|
||||
return Task.FromResult<(string?, object)>(("i-1234567890abcdef0", new Dictionary<string, object> {
|
||||
{ "publicIp", "203.0.113.12" },
|
||||
}));
|
||||
case "pkg:index:MyCustom":
|
||||
return Task.FromResult<(string?, object)>((name + "_id", inputs));
|
||||
return Task.FromResult<(string?, object)>((args.Name + "_id", args.Inputs));
|
||||
default:
|
||||
throw new Exception($"Unknown resource {type}");
|
||||
throw new Exception($"Unknown resource {args.Type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,14 +66,14 @@ namespace Pulumi.Tests.Serialization
|
|||
this.isPreview = isPreview;
|
||||
}
|
||||
|
||||
public Task<object> CallAsync(string token, ImmutableDictionary<string, object> args, string? provider)
|
||||
public Task<object> CallAsync(MockCallArgs args)
|
||||
{
|
||||
throw new Exception($"Unknown function {token}");
|
||||
throw new Exception($"Unknown function {args.Token}");
|
||||
}
|
||||
|
||||
public Task<(string? id, object state)> NewResourceAsync(string type, string name, ImmutableDictionary<string, object> inputs, string? provider, string? id)
|
||||
public Task<(string? id, object state)> NewResourceAsync(MockResourceArgs args)
|
||||
{
|
||||
switch (type)
|
||||
switch (args.Type)
|
||||
{
|
||||
case "test:index:resource":
|
||||
case "test:missing:resource":
|
||||
|
@ -82,7 +82,7 @@ namespace Pulumi.Tests.Serialization
|
|||
case "test:missing:component":
|
||||
return Task.FromResult<(string?, object)>((null, new Dictionary<string, object> {}));
|
||||
default:
|
||||
throw new Exception($"Unknown resource {type}");
|
||||
throw new Exception($"Unknown resource {args.Type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,9 +204,29 @@ Pulumi.StackReferenceArgs.Name.set -> void
|
|||
Pulumi.StackReferenceArgs.StackReferenceArgs() -> void
|
||||
Pulumi.StringAsset
|
||||
Pulumi.StringAsset.StringAsset(string text) -> void
|
||||
Pulumi.Testing.MockResourceArgs
|
||||
Pulumi.Testing.MockResourceArgs.MockResourceArgs() -> void
|
||||
Pulumi.Testing.MockResourceArgs.Type.get -> string
|
||||
Pulumi.Testing.MockResourceArgs.Type.set -> void
|
||||
Pulumi.Testing.MockResourceArgs.Name.get -> string
|
||||
Pulumi.Testing.MockResourceArgs.Name.set -> void
|
||||
Pulumi.Testing.MockResourceArgs.Provider.get -> string
|
||||
Pulumi.Testing.MockResourceArgs.Provider.set -> void
|
||||
Pulumi.Testing.MockResourceArgs.Id.get -> string
|
||||
Pulumi.Testing.MockResourceArgs.Id.set -> void
|
||||
Pulumi.Testing.MockResourceArgs.Inputs.get -> System.Collections.Immutable.ImmutableDictionary<string, object>
|
||||
Pulumi.Testing.MockResourceArgs.Inputs.set -> void
|
||||
Pulumi.Testing.MockCallArgs
|
||||
Pulumi.Testing.MockCallArgs.MockCallArgs() -> void
|
||||
Pulumi.Testing.MockCallArgs.Token.get -> string
|
||||
Pulumi.Testing.MockCallArgs.Token.set -> void
|
||||
Pulumi.Testing.MockCallArgs.Provider.get -> string
|
||||
Pulumi.Testing.MockCallArgs.Provider.set -> void
|
||||
Pulumi.Testing.MockCallArgs.Args.get -> System.Collections.Immutable.ImmutableDictionary<string, object>
|
||||
Pulumi.Testing.MockCallArgs.Args.set -> void
|
||||
Pulumi.Testing.IMocks
|
||||
Pulumi.Testing.IMocks.CallAsync(string token, System.Collections.Immutable.ImmutableDictionary<string, object> args, string provider) -> System.Threading.Tasks.Task<object>
|
||||
Pulumi.Testing.IMocks.NewResourceAsync(string type, string name, System.Collections.Immutable.ImmutableDictionary<string, object> inputs, string provider, string id) -> System.Threading.Tasks.Task<(string id, object state)>
|
||||
Pulumi.Testing.IMocks.CallAsync(Pulumi.Testing.MockCallArgs args) -> System.Threading.Tasks.Task<object>
|
||||
Pulumi.Testing.IMocks.NewResourceAsync(Pulumi.Testing.MockResourceArgs args) -> System.Threading.Tasks.Task<(string id, object state)>
|
||||
Pulumi.Testing.TestOptions
|
||||
Pulumi.Testing.TestOptions.TestOptions() -> void
|
||||
Pulumi.Testing.TestOptions.ProjectName.get -> string
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2016-2020, Pulumi Corporation
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -13,24 +14,69 @@ namespace Pulumi.Testing
|
|||
/// <summary>
|
||||
/// Invoked when a new resource is created by the program.
|
||||
/// </summary>
|
||||
/// <param name="type">Resource type name.</param>
|
||||
/// <param name="name">Resource name.</param>
|
||||
/// <param name="inputs">Dictionary of resource input properties.</param>
|
||||
/// <param name="provider">Provider.</param>
|
||||
/// <param name="id">Resource identifier.</param>
|
||||
/// <param name="args">MockResourceArgs</param>
|
||||
/// <returns>A tuple of a resource identifier and resource state. State can be either a POCO
|
||||
/// or a dictionary bag. The returned ID may be null for component resources.</returns>
|
||||
Task<(string? id, object state)> NewResourceAsync(string type, string name,
|
||||
ImmutableDictionary<string, object> inputs, string? provider, string? id);
|
||||
Task<(string? id, object state)> NewResourceAsync(MockResourceArgs args);
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the program needs to call a provider to load data (e.g., to retrieve an existing
|
||||
/// resource).
|
||||
/// </summary>
|
||||
/// <param name="token">Function token.</param>
|
||||
/// <param name="args">Dictionary of input arguments.</param>
|
||||
/// <param name="provider">Provider.</param>
|
||||
/// <param name="args">MockCallArgs</param>
|
||||
/// <returns>Invocation result, can be either a POCO or a dictionary bag.</returns>
|
||||
Task<object> CallAsync(string token, ImmutableDictionary<string, object> args, string? provider);
|
||||
Task<object> CallAsync(MockCallArgs args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MockResourceArgs for use in NewResourceAsync
|
||||
/// </summary>
|
||||
public class MockResourceArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Resource type name.
|
||||
/// </summary>
|
||||
public string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Resource Name.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of resource input properties.
|
||||
/// </summary>
|
||||
public ImmutableDictionary<string, object> Inputs { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Provider.
|
||||
/// </summary>
|
||||
public string? Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Resource identifier.
|
||||
/// </summary>
|
||||
public string? Id { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MockCallArgs for use in CallAsync
|
||||
/// </summary>
|
||||
public class MockCallArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Resource identifier.
|
||||
/// </summary>
|
||||
public string? Token { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of input arguments.
|
||||
/// </summary>
|
||||
public ImmutableDictionary<string, object> Args { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Provider.
|
||||
/// </summary>
|
||||
public string? Provider { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,16 +47,27 @@ namespace Pulumi.Testing
|
|||
}
|
||||
return new InvokeResponse { Return = await SerializeAsync(registeredResource).ConfigureAwait(false) };
|
||||
}
|
||||
|
||||
var result = await _mocks.CallAsync(request.Tok, args, request.Provider)
|
||||
|
||||
var result = await _mocks.CallAsync(new MockCallArgs
|
||||
{
|
||||
Token = request.Tok,
|
||||
Args = args,
|
||||
Provider = request.Provider,
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
return new InvokeResponse { Return = await SerializeAsync(result).ConfigureAwait(false) };
|
||||
}
|
||||
|
||||
public async Task<ReadResourceResponse> ReadResourceAsync(Resource resource, ReadResourceRequest request)
|
||||
{
|
||||
var (id, state) = await _mocks.NewResourceAsync(request.Type, request.Name,
|
||||
ToDictionary(request.Properties), request.Provider, request.Id).ConfigureAwait(false);
|
||||
var (id, state) = await _mocks.NewResourceAsync(new MockResourceArgs
|
||||
{
|
||||
Type = request.Type,
|
||||
Name = request.Name,
|
||||
Inputs = ToDictionary(request.Properties),
|
||||
Provider = request.Provider,
|
||||
Id = request.Id,
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var urn = NewUrn(request.Parent, request.Type, request.Name);
|
||||
var serializedState = await SerializeToDictionary(state).ConfigureAwait(false);
|
||||
|
@ -101,8 +112,14 @@ namespace Pulumi.Testing
|
|||
};
|
||||
}
|
||||
|
||||
var (id, state) = await _mocks.NewResourceAsync(request.Type, request.Name, ToDictionary(request.Object),
|
||||
request.Provider, request.ImportId).ConfigureAwait(false);
|
||||
var (id, state) = await _mocks.NewResourceAsync(new MockResourceArgs
|
||||
{
|
||||
Type = request.Type,
|
||||
Name = request.Name,
|
||||
Inputs = ToDictionary(request.Object),
|
||||
Provider = request.Provider,
|
||||
Id = request.ImportId,
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var urn = NewUrn(request.Parent, request.Type, request.Name);
|
||||
var serializedState = await SerializeToDictionary(state).ConfigureAwait(false);
|
||||
|
|
|
@ -219,8 +219,6 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzr
|
|||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/pulumi/pulumi/sdk/v2 v2.22.0 h1:O42/vaUiXIyDgIcChQ6RvFEshCGzuVJy53uJr9QZI8o=
|
||||
github.com/pulumi/pulumi/sdk/v2 v2.22.0/go.mod h1:fCFhRV6NmidWetmgDPA76efL+s0JqLlS54JJIwfOt+o=
|
||||
github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014 h1:WUlOHsRhzO08oUCEjZhWS0VHssiIjCNio89VlAvD9ao=
|
||||
github.com/pulumi/pulumi/sdk/v3 v3.0.0-20210322210933-10a6a2caf014/go.mod h1:GBHyQ7awNQSRmiKp/p8kIKrGrMOZeA/k2czoM/GOqds=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng=
|
||||
|
|
|
@ -16,9 +16,8 @@ import (
|
|||
)
|
||||
|
||||
type MockResourceMonitor interface {
|
||||
Call(token string, args resource.PropertyMap, provider string) (resource.PropertyMap, error)
|
||||
NewResource(typeToken, name string, inputs resource.PropertyMap,
|
||||
provider, id string) (string, resource.PropertyMap, error)
|
||||
Call(args MockCallArgs) (resource.PropertyMap, error)
|
||||
NewResource(args MockResourceArgs) (string, resource.PropertyMap, error)
|
||||
}
|
||||
|
||||
func WithMocks(project, stack string, mocks MockResourceMonitor) RunOption {
|
||||
|
@ -27,6 +26,33 @@ func WithMocks(project, stack string, mocks MockResourceMonitor) RunOption {
|
|||
}
|
||||
}
|
||||
|
||||
// MockResourceArgs is used to construct call Mock
|
||||
type MockCallArgs struct {
|
||||
// Token indicates which function is being called. This token is of the form "package:module:function".
|
||||
Token string
|
||||
// Args are the arguments provided to the function call.
|
||||
Args resource.PropertyMap
|
||||
// Provider is the identifier of the provider instance being used to make the call.
|
||||
Provider string
|
||||
}
|
||||
|
||||
// MockResourceArgs is a used to construct a newResource Mock
|
||||
type MockResourceArgs struct {
|
||||
// TypeToken is the token that indicates which resource type is being constructed. This token
|
||||
// is of the form "package:module:type".
|
||||
TypeToken string
|
||||
// Name is the logical name of the resource instance.
|
||||
Name string
|
||||
// Inputs are the inputs for the resource.
|
||||
Inputs resource.PropertyMap
|
||||
// Provider is the identifier of the provider instance being used to manage this resource.
|
||||
Provider string
|
||||
// ID is the physical identifier of an existing resource to read or import.
|
||||
ID string
|
||||
// Custom specifies whether or not the resource is Custom (i.e. managed by a resource provider).
|
||||
Custom bool
|
||||
}
|
||||
|
||||
type mockMonitor struct {
|
||||
project string
|
||||
stack string
|
||||
|
@ -81,8 +107,11 @@ func (m *mockMonitor) Invoke(ctx context.Context, in *pulumirpc.InvokeRequest,
|
|||
Return: result,
|
||||
}, nil
|
||||
}
|
||||
|
||||
resultV, err := m.mocks.Call(in.GetTok(), args, in.GetProvider())
|
||||
resultV, err := m.mocks.Call(MockCallArgs{
|
||||
Token: in.GetTok(),
|
||||
Args: args,
|
||||
Provider: in.GetProvider(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -117,7 +146,14 @@ func (m *mockMonitor) ReadResource(ctx context.Context, in *pulumirpc.ReadResour
|
|||
return nil, err
|
||||
}
|
||||
|
||||
id, state, err := m.mocks.NewResource(in.GetType(), in.GetName(), stateIn, in.GetProvider(), in.GetId())
|
||||
id, state, err := m.mocks.NewResource(MockResourceArgs{
|
||||
TypeToken: in.GetType(),
|
||||
Name: in.GetName(),
|
||||
Inputs: stateIn,
|
||||
Provider: in.GetProvider(),
|
||||
ID: in.GetId(),
|
||||
Custom: false,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -161,7 +197,14 @@ func (m *mockMonitor) RegisterResource(ctx context.Context, in *pulumirpc.Regist
|
|||
return nil, err
|
||||
}
|
||||
|
||||
id, state, err := m.mocks.NewResource(in.GetType(), in.GetName(), inputs, in.GetProvider(), in.GetImportId())
|
||||
id, state, err := m.mocks.NewResource(MockResourceArgs{
|
||||
TypeToken: in.GetType(),
|
||||
Name: in.GetName(),
|
||||
Inputs: inputs,
|
||||
Provider: in.GetProvider(),
|
||||
ID: in.GetImportId(),
|
||||
Custom: in.GetCustom(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -12,25 +12,23 @@ import (
|
|||
)
|
||||
|
||||
type testMonitor struct {
|
||||
CallF func(tok string, args resource.PropertyMap, provider string) (resource.PropertyMap, error)
|
||||
NewResourceF func(typeToken, name string, inputs resource.PropertyMap,
|
||||
provider, id string) (string, resource.PropertyMap, error)
|
||||
CallF func(args MockCallArgs) (resource.PropertyMap, error)
|
||||
NewResourceF func(args MockResourceArgs) (string, resource.PropertyMap, error)
|
||||
}
|
||||
|
||||
func (m *testMonitor) Call(tok string, args resource.PropertyMap, provider string) (resource.PropertyMap, error) {
|
||||
func (m *testMonitor) Call(args MockCallArgs) (resource.PropertyMap, error) {
|
||||
if m.CallF == nil {
|
||||
return resource.PropertyMap{}, nil
|
||||
}
|
||||
return m.CallF(tok, args, provider)
|
||||
return m.CallF(args)
|
||||
}
|
||||
|
||||
func (m *testMonitor) NewResource(typeToken, name string, inputs resource.PropertyMap,
|
||||
provider, id string) (string, resource.PropertyMap, error) {
|
||||
func (m *testMonitor) NewResource(args MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
|
||||
if m.NewResourceF == nil {
|
||||
return name, resource.PropertyMap{}, nil
|
||||
return args.Name, resource.PropertyMap{}, nil
|
||||
}
|
||||
return m.NewResourceF(typeToken, name, inputs, provider, id)
|
||||
return m.NewResourceF(args)
|
||||
}
|
||||
|
||||
type testResource2 struct {
|
||||
|
@ -75,19 +73,18 @@ type invokeResult struct {
|
|||
|
||||
func TestRegisterResource(t *testing.T) {
|
||||
mocks := &testMonitor{
|
||||
NewResourceF: func(typeToken, name string, inputs resource.PropertyMap,
|
||||
provider, id string) (string, resource.PropertyMap, error) {
|
||||
NewResourceF: func(args MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
|
||||
assert.Equal(t, "test:resource:type", typeToken)
|
||||
assert.Equal(t, "resA", name)
|
||||
assert.True(t, inputs.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
assert.Equal(t, "test:resource:type", args.TypeToken)
|
||||
assert.Equal(t, "resA", args.Name)
|
||||
assert.True(t, args.Inputs.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
"foo": "oof",
|
||||
"bar": "rab",
|
||||
"baz": "zab",
|
||||
"bang": "gnab",
|
||||
})))
|
||||
assert.Equal(t, "", provider)
|
||||
assert.Equal(t, "", id)
|
||||
assert.Equal(t, "", args.Provider)
|
||||
assert.Equal(t, "", args.ID)
|
||||
|
||||
return "someID", resource.PropertyMap{"foo": resource.NewStringProperty("qux")}, nil
|
||||
},
|
||||
|
@ -163,18 +160,17 @@ func TestRegisterResource(t *testing.T) {
|
|||
|
||||
func TestReadResource(t *testing.T) {
|
||||
mocks := &testMonitor{
|
||||
NewResourceF: func(typeToken, name string, state resource.PropertyMap,
|
||||
provider, id string) (string, resource.PropertyMap, error) {
|
||||
NewResourceF: func(args MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
|
||||
assert.Equal(t, "test:resource:type", typeToken)
|
||||
assert.Equal(t, "resA", name)
|
||||
assert.True(t, state.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
assert.Equal(t, "test:resource:type", args.TypeToken)
|
||||
assert.Equal(t, "resA", args.Name)
|
||||
assert.True(t, args.Inputs.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
"foo": "oof",
|
||||
})))
|
||||
assert.Equal(t, "", provider)
|
||||
assert.Equal(t, "someID", id)
|
||||
assert.Equal(t, "", args.Provider)
|
||||
assert.Equal(t, "someID", args.ID)
|
||||
|
||||
return id, resource.PropertyMap{"foo": resource.NewStringProperty("qux")}, nil
|
||||
return args.ID, resource.PropertyMap{"foo": resource.NewStringProperty("qux")}, nil
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -228,9 +224,9 @@ func TestReadResource(t *testing.T) {
|
|||
|
||||
func TestInvoke(t *testing.T) {
|
||||
mocks := &testMonitor{
|
||||
CallF: func(token string, args resource.PropertyMap, provider string) (resource.PropertyMap, error) {
|
||||
assert.Equal(t, "test:index:func", token)
|
||||
assert.True(t, args.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
CallF: func(args MockCallArgs) (resource.PropertyMap, error) {
|
||||
assert.Equal(t, "test:index:func", args.Token)
|
||||
assert.True(t, args.Args.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
"bang": "gnab",
|
||||
"bar": "rab",
|
||||
})))
|
||||
|
@ -357,16 +353,15 @@ func TestRegisterResourceWithResourceReferences(t *testing.T) {
|
|||
RegisterResourceModule("pkg", "index", module(0))
|
||||
|
||||
mocks := &testMonitor{
|
||||
NewResourceF: func(typeToken, name string, inputs resource.PropertyMap,
|
||||
provider, id string) (string, resource.PropertyMap, error) {
|
||||
NewResourceF: func(args MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
|
||||
switch typeToken {
|
||||
switch args.TypeToken {
|
||||
case "pkg:index:Instance":
|
||||
return "i-1234567890abcdef0", resource.PropertyMap{}, nil
|
||||
case "pkg:index:MyCustom":
|
||||
return name + "_id", inputs, nil
|
||||
return args.Name + "_id", args.Inputs, nil
|
||||
default:
|
||||
return "", nil, errors.Errorf("unknown resource %s", typeToken)
|
||||
return "", nil, errors.Errorf("unknown resource %s", args.TypeToken)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -17,16 +17,15 @@ func TestStackReference(t *testing.T) {
|
|||
},
|
||||
}
|
||||
mocks := &testMonitor{
|
||||
NewResourceF: func(typeToken, name string, inputs resource.PropertyMap,
|
||||
provider, id string) (string, resource.PropertyMap, error) {
|
||||
assert.Equal(t, "pulumi:pulumi:StackReference", typeToken)
|
||||
assert.Equal(t, resName, name)
|
||||
assert.True(t, inputs.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
NewResourceF: func(args MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
assert.Equal(t, "pulumi:pulumi:StackReference", args.TypeToken)
|
||||
assert.Equal(t, resName, args.Name)
|
||||
assert.True(t, args.Inputs.DeepEquals(resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
"name": "stack",
|
||||
})))
|
||||
assert.Equal(t, "", provider)
|
||||
assert.Equal(t, inputs["name"].StringValue(), id)
|
||||
return inputs["name"].StringValue(), resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
assert.Equal(t, "", args.Provider)
|
||||
assert.Equal(t, args.Inputs["name"].StringValue(), args.ID)
|
||||
return args.Inputs["name"].StringValue(), resource.NewPropertyMapFromMap(map[string]interface{}{
|
||||
"name": "stack",
|
||||
"outputs": outputs,
|
||||
}), nil
|
||||
|
|
|
@ -21,7 +21,7 @@ export {
|
|||
|
||||
export { CodePathOptions, computeCodePaths } from "./closure/codePaths";
|
||||
export { leakedPromises } from "./debuggable";
|
||||
export { Mocks, setMocks } from "./mocks";
|
||||
export { Mocks, setMocks, MockResourceArgs, MockCallArgs } from "./mocks";
|
||||
|
||||
export * from "./config";
|
||||
export * from "./invoke";
|
||||
|
|
|
@ -19,6 +19,61 @@ const provproto = require("../proto/provider_pb.js");
|
|||
const resproto = require("../proto/resource_pb.js");
|
||||
const structproto = require("google-protobuf/google/protobuf/struct_pb.js");
|
||||
|
||||
/**
|
||||
* MockResourceArgs is a used to construct a newResource Mock
|
||||
*/
|
||||
export interface MockResourceArgs {
|
||||
/**
|
||||
* The token that indicates which resource type is being constructed. This token is of the form "package:module:type".
|
||||
*/
|
||||
type: string;
|
||||
|
||||
/**
|
||||
* The logical name of the resource instance.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* The inputs for the resource.
|
||||
*/
|
||||
inputs: any;
|
||||
|
||||
/**
|
||||
* If provided, the identifier of the provider instance being used to manage this resource.
|
||||
*/
|
||||
provider?: string;
|
||||
|
||||
/**
|
||||
* Specifies whether or not the resource is Custom (i.e. managed by a resource provider).
|
||||
*/
|
||||
custom?: boolean;
|
||||
|
||||
/**
|
||||
* If provided, the physical identifier of an existing resource to read or import.
|
||||
*/
|
||||
id?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* MockResourceArgs is used to construct call Mock
|
||||
*/
|
||||
export interface MockCallArgs {
|
||||
/**
|
||||
* The token that indicates which function is being called. This token is of the form "package:module:function".
|
||||
*/
|
||||
token: string;
|
||||
|
||||
/**
|
||||
* The arguments provided to the function call.
|
||||
*/
|
||||
inputs: any;
|
||||
|
||||
/**
|
||||
* If provided, the identifier of the provider instance being used to make the call.
|
||||
*/
|
||||
provider?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks is an abstract class that allows subclasses to replace operations normally implemented by the Pulumi engine with
|
||||
* their own implementations. This can be used during testing to ensure that calls to provider functions and resource constructors
|
||||
|
@ -28,24 +83,17 @@ export interface Mocks {
|
|||
/**
|
||||
* Mocks provider-implemented function calls (e.g. aws.get_availability_zones).
|
||||
*
|
||||
* @param token: The token that indicates which function is being called. This token is of the form "package:module:function".
|
||||
* @param args: The arguments provided to the function call.
|
||||
* @param provider: If provided, the identifier of the provider instance being used to make the call.
|
||||
* @param args: MockCallArgs
|
||||
*/
|
||||
call(token: string, args: any, provider?: string): Record<string, any>;
|
||||
call(args: MockCallArgs): Record<string, any>;
|
||||
|
||||
/**
|
||||
* Mocks resource construction calls. This function should return the physical identifier and the output properties
|
||||
* for the resource being constructed.
|
||||
*
|
||||
* @param type: The token that indicates which resource type is being constructed. This token is of the form "package:module:type".
|
||||
* @param name: The logical name of the resource instance.
|
||||
* @param inputs: The inputs for the resource.
|
||||
* @param provider: If provided, the identifier of the provider instance being used to manage this resource.
|
||||
* @param id: If provided, the physical identifier of an existing resource to read or import.
|
||||
* @param custom: Specifies whether or not the resource is Custom (i.e. managed by a resource provider). This is always set, but marked optional for backwards compatibility.
|
||||
|
||||
* @param args: MockResourceArgs
|
||||
*/
|
||||
newResource(type: string, name: string, inputs: any, provider?: string, id?: string, custom?: boolean): { id: string | undefined, state: Record<string, any> };
|
||||
newResource(args: MockResourceArgs): { id: string | undefined, state: Record<string, any> };
|
||||
}
|
||||
|
||||
export class MockMonitor {
|
||||
|
@ -79,7 +127,11 @@ export class MockMonitor {
|
|||
return;
|
||||
}
|
||||
|
||||
const result = this.mocks.call(tok, inputs, req.getProvider());
|
||||
const result = this.mocks.call({
|
||||
token: tok,
|
||||
inputs: inputs,
|
||||
provider: req.getProvider(),
|
||||
});
|
||||
const response = new provproto.InvokeResponse();
|
||||
response.setReturn(structproto.Struct.fromJavaScript(await serializeProperties("", result)));
|
||||
callback(null, response);
|
||||
|
@ -90,13 +142,14 @@ export class MockMonitor {
|
|||
|
||||
public async readResource(req: any, callback: (err: any, innterResponse: any) => void) {
|
||||
try {
|
||||
const result = this.mocks.newResource(
|
||||
req.getType(),
|
||||
req.getName(),
|
||||
deserializeProperties(req.getProperties()),
|
||||
req.getProvider(),
|
||||
req.getId(),
|
||||
req.getCustom());
|
||||
const result = this.mocks.newResource({
|
||||
type: req.getType(),
|
||||
name: req.getName(),
|
||||
inputs: deserializeProperties(req.getProperties()),
|
||||
provider: req.getProvider(),
|
||||
custom: req.getCustom(),
|
||||
id: req.getId(),
|
||||
});
|
||||
|
||||
const urn = this.newUrn(req.getParent(), req.getType(), req.getName());
|
||||
const serializedState = await serializeProperties("", result.state);
|
||||
|
@ -114,13 +167,14 @@ export class MockMonitor {
|
|||
|
||||
public async registerResource(req: any, callback: (err: any, innerResponse: any) => void) {
|
||||
try {
|
||||
const result = this.mocks.newResource(
|
||||
req.getType(),
|
||||
req.getName(),
|
||||
deserializeProperties(req.getObject()),
|
||||
req.getProvider(),
|
||||
req.getImportid(),
|
||||
req.getCustom());
|
||||
const result = this.mocks.newResource({
|
||||
type: req.getType(),
|
||||
name: req.getName(),
|
||||
inputs: deserializeProperties(req.getObject()),
|
||||
provider: req.getProvider(),
|
||||
custom: req.getCustom(),
|
||||
id: req.getImportid(),
|
||||
});
|
||||
|
||||
const urn = this.newUrn(req.getParent(), req.getType(), req.getName());
|
||||
const serializedState = await serializeProperties("", result.state);
|
||||
|
|
|
@ -52,12 +52,12 @@ class TestResourceModule implements runtime.ResourceModule {
|
|||
}
|
||||
|
||||
class TestMocks implements runtime.Mocks {
|
||||
call(token: string, args: any, provider?: string): Record<string, any> {
|
||||
throw new Error(`unknown function ${token}`);
|
||||
call(args: runtime.MockCallArgs): Record<string, any> {
|
||||
throw new Error(`unknown function ${args.token}`);
|
||||
}
|
||||
|
||||
newResource(type: string, name: string, inputs: any, provider?: string, id?: string): { id: string | undefined, state: Record<string, any> } {
|
||||
switch (type) {
|
||||
newResource(args: runtime.MockResourceArgs): { id: string | undefined, state: Record<string, any> } {
|
||||
switch (args.type) {
|
||||
case "test:index:component":
|
||||
return {id: undefined, state: {}};
|
||||
case "test:index:custom":
|
||||
|
@ -69,7 +69,7 @@ class TestMocks implements runtime.Mocks {
|
|||
case "error":
|
||||
throw new Error("this is an intentional error");
|
||||
default:
|
||||
throw new Error(`unknown resource type ${type}`);
|
||||
throw new Error(`unknown resource type ${args.type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,20 +15,21 @@
|
|||
import * as assert from "assert";
|
||||
import * as pulumi from "../index";
|
||||
import { CustomResourceOptions } from "../resource";
|
||||
import { MockCallArgs, MockResourceArgs } from "../runtime";
|
||||
|
||||
pulumi.runtime.setMocks({
|
||||
call: (token: string, args: any, provider?: string) => {
|
||||
switch (token) {
|
||||
call: (args: MockCallArgs) => {
|
||||
switch (args.token) {
|
||||
case "test:index:MyFunction":
|
||||
return { out_value: 59 };
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
},
|
||||
newResource: (type: string, name: string, inputs: any, provider?: string, id?: string, custom?: boolean): {id: string, state: any} => {
|
||||
switch (type) {
|
||||
newResource: (args: MockResourceArgs): {id: string, state: any} => {
|
||||
switch (args.type) {
|
||||
case "aws:ec2/instance:Instance":
|
||||
assert.strictEqual(custom, true);
|
||||
assert.strictEqual(args.custom, true);
|
||||
const state = {
|
||||
arn: "arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0",
|
||||
instanceState: "running",
|
||||
|
@ -37,12 +38,12 @@ pulumi.runtime.setMocks({
|
|||
publicDns: "ec2-203-0-113-12.compute-1.amazonaws.com",
|
||||
publicIP: "203.0.113.12",
|
||||
};
|
||||
return { id: "i-1234567890abcdef0", state: { ...inputs, ...state } };
|
||||
return { id: "i-1234567890abcdef0", state: { ...args.inputs, ...state } };
|
||||
case "pkg:index:MyCustom":
|
||||
assert.strictEqual(custom, true);
|
||||
return { id: name + "_id", state: inputs };
|
||||
assert.strictEqual(args.custom, true);
|
||||
return { id: args.name + "_id", state: args.inputs };
|
||||
default:
|
||||
assert.strictEqual(custom, false);
|
||||
assert.strictEqual(args.custom, false);
|
||||
return { id: "", state: {} };
|
||||
}
|
||||
},
|
||||
|
|
|
@ -28,6 +28,8 @@ from .mocks import (
|
|||
Mocks,
|
||||
set_mocks,
|
||||
test,
|
||||
MockResourceArgs,
|
||||
MockCallArgs,
|
||||
)
|
||||
|
||||
from .settings import (
|
||||
|
@ -70,6 +72,8 @@ __all__ = [
|
|||
"Mocks",
|
||||
"set_mocks",
|
||||
"test",
|
||||
"MockCallArgs",
|
||||
"MockResourceArgs",
|
||||
|
||||
# settings
|
||||
"Settings",
|
||||
|
|
|
@ -38,6 +38,52 @@ def test(fn):
|
|||
return wrapper
|
||||
|
||||
|
||||
class MockResourceArgs:
|
||||
"""
|
||||
MockResourceArgs is used to construct a newResource Mock
|
||||
"""
|
||||
typ: str
|
||||
name: str
|
||||
inputs: dict
|
||||
provider: str
|
||||
resource_id: str
|
||||
custom: bool
|
||||
|
||||
def __init__(self, typ: str, name: str, inputs: dict, provider: str, resource_id: str, custom: bool) -> None:
|
||||
"""
|
||||
:param str typ: The token that indicates which resource type is being constructed. This token is of the form "package:module:type".
|
||||
:param str name: The logical name of the resource instance.
|
||||
:param dict inputs: The inputs for the resource.
|
||||
:param str provider: The identifier of the provider instance being used to manage this resource.
|
||||
:param str resource_id: The physical identifier of an existing resource to read or import.
|
||||
:param bool custom: Specifies whether or not the resource is Custom (i.e. managed by a resource provider).
|
||||
"""
|
||||
self.typ = typ
|
||||
self.name = name
|
||||
self.inputs = inputs
|
||||
self.provider = provider
|
||||
self.resource_id = resource_id
|
||||
self.custom = custom
|
||||
|
||||
class MockCallArgs:
|
||||
"""
|
||||
MockCallArgs is used to construct a call Mock
|
||||
"""
|
||||
token: str
|
||||
args: dict
|
||||
provider: str
|
||||
|
||||
def __init__(self, token: str, args: dict, provider: str) -> None:
|
||||
"""
|
||||
:param str token: The token that indicates which function is being called. This token is of the form "package:module:function".
|
||||
:param dict args: The arguments provided to the function call.
|
||||
:param str provider: The identifier of the provider instance being used to make the call
|
||||
"""
|
||||
self.token = token
|
||||
self.args = args
|
||||
self.provider = provider
|
||||
|
||||
|
||||
class Mocks(ABC):
|
||||
"""
|
||||
Mocks is an abstract class that allows subclasses to replace operations normally implemented by the Pulumi engine with
|
||||
|
@ -45,27 +91,21 @@ class Mocks(ABC):
|
|||
return predictable values.
|
||||
"""
|
||||
@abstractmethod
|
||||
def call(self, token: str, args: dict, provider: Optional[str]) -> Tuple[dict, Optional[List[Tuple[str,str]]]]:
|
||||
def call(self, args: MockCallArgs) -> Tuple[dict, Optional[List[Tuple[str,str]]]]:
|
||||
"""
|
||||
call mocks provider-implemented function calls (e.g. aws.get_availability_zones).
|
||||
|
||||
:param str token: The token that indicates which function is being called. This token is of the form "package:module:function".
|
||||
:param dict args: The arguments provided to the function call.
|
||||
:param Optional[str] provider: If provided, the identifier of the provider instance being used to make the call.
|
||||
:param MockCallArgs args.
|
||||
"""
|
||||
return {}, None
|
||||
|
||||
@abstractmethod
|
||||
def new_resource(self, type_: str, name: str, inputs: dict, provider: Optional[str], id_: Optional[str]) -> Tuple[Optional[str], dict]:
|
||||
def new_resource(self, args: MockResourceArgs) -> Tuple[Optional[str], dict]:
|
||||
"""
|
||||
new_resource mocks resource construction calls. This function should return the physical identifier and the output properties
|
||||
for the resource being constructed.
|
||||
|
||||
:param str type_: The token that indicates which resource type is being constructed. This token is of the form "package:module:type".
|
||||
:param str name: The logical name of the resource instance.
|
||||
:param dict inputs: The inputs for the resource.
|
||||
:param Optional[str] provider: If provided, the identifier of the provider instance being used to manage this resource.
|
||||
:param Optional[str] id_: If provided, the physical identifier of an existing resource to read or import.
|
||||
:param MockResourceArgs args.
|
||||
"""
|
||||
return "", {}
|
||||
|
||||
|
@ -105,7 +145,8 @@ class MockMonitor:
|
|||
fields = {"failures": None, "return": ret_proto}
|
||||
return provider_pb2.InvokeResponse(**fields)
|
||||
|
||||
tup = self.mocks.call(request.tok, args, request.provider)
|
||||
call_args = MockCallArgs(token=request.tok, args=args, provider=request.provider)
|
||||
tup = self.mocks.call(call_args)
|
||||
if isinstance(tup, dict):
|
||||
(ret, failures) = (tup, None)
|
||||
else:
|
||||
|
@ -122,7 +163,13 @@ class MockMonitor:
|
|||
|
||||
state = rpc.deserialize_properties(request.properties)
|
||||
|
||||
id_, state = self.mocks.new_resource(request.type, request.name, state, request.provider, request.id)
|
||||
resource_args = MockResourceArgs(typ=request.type,
|
||||
name=request.name,
|
||||
inputs=state,
|
||||
provider=request.provider,
|
||||
resource_id=request.id,
|
||||
custom=request.custom or False)
|
||||
id_, state = self.mocks.new_resource(resource_args)
|
||||
|
||||
props_proto = _sync_await(rpc.serialize_properties(state, {}))
|
||||
|
||||
|
@ -143,7 +190,13 @@ class MockMonitor:
|
|||
|
||||
inputs = rpc.deserialize_properties(request.object)
|
||||
|
||||
id_, state = self.mocks.new_resource(request.type, request.name, inputs, request.provider, request.importId)
|
||||
resource_args = MockResourceArgs(typ=request.type,
|
||||
name=request.name,
|
||||
inputs=inputs,
|
||||
provider=request.provider,
|
||||
resource_id=request.importId,
|
||||
custom=request.custom or False)
|
||||
id_, state = self.mocks.new_resource(resource_args)
|
||||
|
||||
obj_proto = _sync_await(rpc.serialize_properties(state, {}))
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ from typing import Any, Dict, List, Mapping, Optional, Sequence, cast
|
|||
|
||||
from google.protobuf import struct_pb2
|
||||
from pulumi.resource import ComponentResource, CustomResource, ResourceOptions
|
||||
from pulumi.runtime import Mocks, ResourceModule, rpc, rpc_manager, known_types, set_mocks, settings
|
||||
from pulumi.runtime import Mocks, MockCallArgs, MockResourceArgs, ResourceModule, rpc, rpc_manager, known_types, set_mocks, settings
|
||||
from pulumi import Input, Output, UNKNOWN, input_type
|
||||
from pulumi.asset import (
|
||||
FileAsset,
|
||||
|
@ -66,16 +66,16 @@ class MyResourceModule(ResourceModule):
|
|||
|
||||
|
||||
class MyMocks(Mocks):
|
||||
def call(self, token, args, provider):
|
||||
raise Exception(f"unknown function {token}")
|
||||
def call(self, args: MockCallArgs):
|
||||
raise Exception(f"unknown function {args.token}")
|
||||
|
||||
def new_resource(self, typ, name, inputs, provider, id):
|
||||
if typ == "test:index:resource":
|
||||
def new_resource(self, args: MockResourceArgs):
|
||||
if args.typ == "test:index:resource":
|
||||
return [None if settings.is_dry_run() else "id", {}]
|
||||
elif typ == "test:index:component":
|
||||
elif args.typ == "test:index:component":
|
||||
return [None, {}]
|
||||
else:
|
||||
raise Exception(f"unknown resource type {typ}")
|
||||
raise Exception(f"unknown resource type {args.typ}")
|
||||
|
||||
|
||||
@pulumi.output_type
|
||||
|
|
|
@ -27,26 +27,26 @@ class GrpcError(grpc.RpcError):
|
|||
return self._details
|
||||
|
||||
class MyMocks(pulumi.runtime.Mocks):
|
||||
def call(self, token, args, provider):
|
||||
if token == 'test:index:MyFunction':
|
||||
def call(self, args: pulumi.runtime.MockCallArgs):
|
||||
if args.token == 'test:index:MyFunction':
|
||||
return {
|
||||
'out_value': 59,
|
||||
}
|
||||
elif token == 'test:index:FailFunction':
|
||||
elif args.token == 'test:index:FailFunction':
|
||||
return ({}, [('none', 'this function fails!')])
|
||||
elif token == 'test:index:ThrowFunction':
|
||||
elif args.token == 'test:index:ThrowFunction':
|
||||
raise GrpcError(42, 'this function throws!')
|
||||
else:
|
||||
return {}
|
||||
|
||||
def new_resource(self, type_, name, inputs, provider, id_):
|
||||
if type_ == 'aws:ec2/securityGroup:SecurityGroup':
|
||||
def new_resource(self, args: pulumi.runtime.MockResourceArgs):
|
||||
if args.typ == 'aws:ec2/securityGroup:SecurityGroup':
|
||||
state = {
|
||||
'arn': 'arn:aws:ec2:us-west-2:123456789012:security-group/sg-12345678',
|
||||
'name': inputs['name'] if 'name' in inputs else name + '-sg',
|
||||
'name': args.inputs['name'] if 'name' in args.inputs else args.name + '-sg',
|
||||
}
|
||||
return ['sg-12345678', dict(inputs, **state)]
|
||||
elif type_ == 'aws:ec2/instance:Instance':
|
||||
return ['sg-12345678', dict(args.inputs, **state)]
|
||||
elif args.typ == 'aws:ec2/instance:Instance':
|
||||
state = {
|
||||
'arn': 'arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0',
|
||||
'instanceState': 'running',
|
||||
|
@ -55,9 +55,9 @@ class MyMocks(pulumi.runtime.Mocks):
|
|||
'public_dns': 'ec2-203-0-113-12.compute-1.amazonaws.com',
|
||||
'public_ip': '203.0.113.12',
|
||||
}
|
||||
return ['i-1234567890abcdef0', dict(inputs, **state)]
|
||||
elif type_ == 'pkg:index:MyCustom':
|
||||
return [name + '_id', inputs]
|
||||
return ['i-1234567890abcdef0', dict(args.inputs, **state)]
|
||||
elif args.typ == 'pkg:index:MyCustom':
|
||||
return [args.name + '_id', args.inputs]
|
||||
else:
|
||||
return ['', {}]
|
||||
|
||||
|
|
|
@ -3,34 +3,37 @@
|
|||
import pulumi
|
||||
from pulumi_example import Foo, FooArgs, Provider
|
||||
|
||||
|
||||
class MyMocks(pulumi.runtime.Mocks):
|
||||
resources = {}
|
||||
def call(self, token, args, provider):
|
||||
|
||||
def call(self, args: pulumi.runtime.MockCallArgs):
|
||||
return {}
|
||||
def new_resource(self, type_, name, inputs, provider, id_):
|
||||
self.resources[name] = inputs
|
||||
if name == "f1":
|
||||
assert inputs == {"first": 1, "second": "second", "third": "third"}
|
||||
elif name == "f2":
|
||||
assert inputs == {"args": "args", "first": 2, "second": "s", "third": "t"}
|
||||
elif name == "f3":
|
||||
assert len(inputs) == 0
|
||||
assert provider.endswith("f3provider_id")
|
||||
elif name == "f4":
|
||||
assert inputs == {"args": "hi"}
|
||||
elif name == "f5":
|
||||
assert inputs == {"first": 100, "second": "200", "third": "300"}
|
||||
assert provider.endswith("f5provider_id")
|
||||
elif name == "a1":
|
||||
assert inputs == {"first": 10, "second": "asecond", "third": "athird"}
|
||||
elif name == "a2":
|
||||
assert inputs == {"first": 42, "second": "2nd", "third": "3rd"}
|
||||
elif name == "a3":
|
||||
assert inputs == {"args": "someargs", "first": 50, "second": "2", "third": "3"}
|
||||
elif name == "a4":
|
||||
assert inputs == {"first": 11, "second": "12", "third": "13"}
|
||||
assert provider.endswith("a4provider_id")
|
||||
return [name + '_id', inputs]
|
||||
|
||||
def new_resource(self, args: pulumi.runtime.MockResourceArgs):
|
||||
if args.name == "f1":
|
||||
assert args.inputs == {"first": 1, "second": "second", "third": "third"}
|
||||
elif args.name == "f2":
|
||||
assert args.inputs == {"args": "args", "first": 2, "second": "s", "third": "t"}
|
||||
elif args.name == "f3":
|
||||
assert len(args.inputs) == 0
|
||||
assert args.provider.endswith("f3provider_id")
|
||||
elif args.name == "f4":
|
||||
assert args.inputs == {"args": "hi"}
|
||||
elif args.name == "f5":
|
||||
assert args.inputs == {"first": 100, "second": "200", "third": "300"}
|
||||
assert args.provider.endswith("f5provider_id")
|
||||
elif args.name == "a1":
|
||||
assert args.inputs == {"first": 10, "second": "asecond", "third": "athird"}
|
||||
elif args.name == "a2":
|
||||
assert args.inputs == {"first": 42, "second": "2nd", "third": "3rd"}
|
||||
elif args.name == "a3":
|
||||
assert args.inputs == {"args": "someargs", "first": 50, "second": "2", "third": "3"}
|
||||
elif args.name == "a4":
|
||||
assert args.inputs == {"first": 11, "second": "12", "third": "13"}
|
||||
assert args.provider.endswith("a4provider_id")
|
||||
return [args.name + '_id', args.inputs]
|
||||
|
||||
|
||||
pulumi.runtime.set_mocks(MyMocks())
|
||||
|
||||
|
|
|
@ -502,35 +502,35 @@ class NewBehaviorDict(pulumi.CustomResource):
|
|||
|
||||
|
||||
class MyMocks(pulumi.runtime.Mocks):
|
||||
def call(self, token, args, provider):
|
||||
def call(self, args: pulumi.runtime.MockCallArgs):
|
||||
return {}
|
||||
def new_resource(self, type_, name, inputs, provider, id_):
|
||||
if name == "o1":
|
||||
assert inputs == {"serviceName": "hello"}
|
||||
elif name == "o2":
|
||||
assert inputs == {"serviceName": "hi", "nestedValue": {"fooBar": "foo bar", "someValue": 42}}
|
||||
elif name == "o3":
|
||||
assert inputs == {"serviceName": "bye", "nestedValue": {"fooBar": "bar foo", "someValue": 24}}
|
||||
elif name == "o4":
|
||||
def new_resource(self, args: pulumi.runtime.MockResourceArgs):
|
||||
if args.name == "o1":
|
||||
assert args.inputs == {"serviceName": "hello"}
|
||||
elif args.name == "o2":
|
||||
assert args.inputs == {"serviceName": "hi", "nestedValue": {"fooBar": "foo bar", "someValue": 42}}
|
||||
elif args.name == "o3":
|
||||
assert args.inputs == {"serviceName": "bye", "nestedValue": {"fooBar": "bar foo", "someValue": 24}}
|
||||
elif args.name == "o4":
|
||||
# The "service_name" key in the user-defined tags dict is translated to "serviceName"
|
||||
# due to it being in the case tables.
|
||||
assert inputs == {"serviceName": "sn", "tags": {"serviceName": "my-service"}}
|
||||
elif name == "o5":
|
||||
assert inputs == {"serviceName": "o5sn", "listOfNestedValues": [{"fooBar": "f", "someValue": 1}]}
|
||||
elif name == "o6":
|
||||
assert inputs == {"serviceName": "o6sn", "listOfNestedValues": [{"fooBar": "b", "someValue": 2}]}
|
||||
elif name == "n1":
|
||||
assert inputs == {"serviceName": "hi new", "nestedValue": {"fooBar": "noo nar", "someValue": 100}}
|
||||
elif name == "n2":
|
||||
assert inputs == {"serviceName": "hello new", "nestedValue": {"fooBar": "2", "someValue": 3}}
|
||||
elif name == "n3":
|
||||
assert args.inputs == {"serviceName": "sn", "tags": {"serviceName": "my-service"}}
|
||||
elif args.name == "o5":
|
||||
assert args.inputs == {"serviceName": "o5sn", "listOfNestedValues": [{"fooBar": "f", "someValue": 1}]}
|
||||
elif args.name == "o6":
|
||||
assert args.inputs == {"serviceName": "o6sn", "listOfNestedValues": [{"fooBar": "b", "someValue": 2}]}
|
||||
elif args.name == "n1":
|
||||
assert args.inputs == {"serviceName": "hi new", "nestedValue": {"fooBar": "noo nar", "someValue": 100}}
|
||||
elif args.name == "n2":
|
||||
assert args.inputs == {"serviceName": "hello new", "nestedValue": {"fooBar": "2", "someValue": 3}}
|
||||
elif args.name == "n3":
|
||||
# service_name correctly isn't translated, because the tags dict is a user-defined dict.
|
||||
assert inputs == {"serviceName": "sn", "tags": {"service_name": "a-service"}}
|
||||
elif name == "n4":
|
||||
assert inputs == {"serviceName": "a", "items": {"foo": "bar"}, "keys": ["foo"], "values": ["bar"], "get": "bar"}
|
||||
elif name == "d1":
|
||||
assert inputs == {"serviceName": "b", "items": {"hello": "world"}, "keys": ["hello"], "values": ["world"], "get": "world"}
|
||||
return [name + '_id', {**inputs, "somethingElse": "hehe"}]
|
||||
assert args.inputs == {"serviceName": "sn", "tags": {"service_name": "a-service"}}
|
||||
elif args.name == "n4":
|
||||
assert args.inputs == {"serviceName": "a", "items": {"foo": "bar"}, "keys": ["foo"], "values": ["bar"], "get": "bar"}
|
||||
elif args.name == "d1":
|
||||
assert args.inputs == {"serviceName": "b", "items": {"hello": "world"}, "keys": ["hello"], "values": ["world"], "get": "world"}
|
||||
return [args.name + '_id', {**args.inputs, "somethingElse": "hehe"}]
|
||||
|
||||
pulumi.runtime.set_mocks(MyMocks())
|
||||
|
||||
|
|
Loading…
Reference in a new issue