// Copyright 2016-2023, Pulumi Corporation. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package lifecycletest import ( "context" "testing" "github.com/blang/semver" "github.com/pulumi/pulumi/pkg/v3/resource/deploy" "github.com/pulumi/pulumi/pkg/v3/resource/deploy/deploytest" "github.com/pulumi/pulumi/pkg/v3/resource/deploy/providers" "github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin" "github.com/pulumi/pulumi/sdk/v3/go/common/testing/diagtest" "github.com/pulumi/pulumi/sdk/v3/go/common/workspace" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestRunQuery_nocreate(t *testing.T) { t.Parallel() loaders := []*deploytest.ProviderLoader{ deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) { return &deploytest.Provider{ ReadF: func(_ context.Context, req plugin.ReadRequest) (plugin.ReadResponse, error) { return plugin.ReadResponse{ ReadResult: plugin.ReadResult{ Outputs: resource.PropertyMap{}, }, Status: resource.StatusOK, }, nil }, }, nil }), } programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error { _, err := monitor.RegisterResource(providers.MakeProviderType("pkgA"), "provA", true) assert.ErrorContains(t, err, "Query mode does not support creating, updating, or deleting resources") _, err = monitor.RegisterResource("pkgA:m:typA", "resA", true, deploytest.ResourceOptions{}) assert.ErrorContains(t, err, "Query mode does not support creating, updating, or deleting resources") _, _, err = monitor.ReadResource("pkgA:m:typA", "resA", "read-id", "", nil, "", "", "", "") assert.ErrorContains(t, err, "Query mode does not support reading resources") return nil }) plugCtx, err := plugin.NewContext( diagtest.LogSink(t), diagtest.LogSink(t), deploytest.NewPluginHostF(nil, nil, programF, loaders...)(), nil, "", nil, false, nil) assert.NoError(t, err) src, err := deploy.NewQuerySource(context.Background(), plugCtx, &deploytest.BackendClient{}, &deploy.EvalRunInfo{ ProjectRoot: "/", Pwd: "/", Program: ".", Proj: &workspace.Project{ Name: "query-program", }, }, nil, nil) assert.NoError(t, err) assert.NoError(t, src.Wait()) } func TestRunQuery_call_invoke(t *testing.T) { t.Parallel() loaders := []*deploytest.ProviderLoader{ deploytest.NewProviderLoader("pkgA", semver.MustParse("1.0.0"), func() (plugin.Provider, error) { return &deploytest.Provider{ InvokeF: func(_ context.Context, req plugin.InvokeRequest) (plugin.InvokeResponse, error) { name := req.Args["name"] ret := "unexpected" if name.IsString() { ret = "Hello, " + name.StringValue() + "!" } return plugin.InvokeResponse{ Properties: resource.NewPropertyMapFromMap(map[string]interface{}{ "message": ret, }), }, nil }, CallF: func( _ context.Context, req plugin.CallRequest, _ *deploytest.ResourceMonitor, ) (plugin.CallResponse, error) { ret := "unexpected" if req.Args["name"].IsString() { ret = "Hello, " + req.Args["name"].StringValue() + "!" } return plugin.CallResponse{ Return: resource.NewPropertyMapFromMap(map[string]interface{}{ "message": ret, }), }, nil }, }, nil }), } programF := deploytest.NewLanguageRuntimeF(func(_ plugin.RunInfo, monitor *deploytest.ResourceMonitor) error { outs, _, _, err := monitor.Call("pkgA:m:typA/methodA", resource.PropertyMap{ "name": resource.NewStringProperty("bar"), }, nil, "", "", "") assert.NoError(t, err) assert.Equal(t, (resource.PropertyMap{ "message": resource.NewStringProperty("Hello, bar!"), }), outs, "outs was %v", outs) outs, _, err = monitor.Invoke("pkgA:m:invokeA", resource.PropertyMap{ "name": resource.NewStringProperty("bar"), }, "", "", "") assert.NoError(t, err) assert.Equal(t, (resource.PropertyMap{ "message": resource.NewStringProperty("Hello, bar!"), }), outs, "outs was %v", outs) return nil }) plugCtx, err := plugin.NewContext( diagtest.LogSink(t), diagtest.LogSink(t), deploytest.NewPluginHostF(nil, nil, programF, loaders...)(), nil, "", nil, false, nil) require.NoError(t, err) src, err := deploy.NewQuerySource(context.Background(), plugCtx, &deploytest.BackendClient{}, &deploy.EvalRunInfo{ ProjectRoot: "/", Pwd: "/", Program: ".", Proj: &workspace.Project{ Name: "query-program", }, }, nil, nil) assert.NoError(t, err) assert.NoError(t, src.Wait()) }