Skip to content

Commit

Permalink
Add tests for partial initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
iwahbe committed Apr 5, 2024
1 parent be6aef4 commit f5b8dbc
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 14 deletions.
8 changes: 4 additions & 4 deletions tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ replace github.com/pulumi/pulumi-go-provider/integration => ../integration

require (
github.com/blang/semver v3.5.1+incompatible
github.com/pulumi/providertest v0.0.11
github.com/pulumi/pulumi-go-provider v0.0.0-00010101000000-000000000000
github.com/pulumi/pulumi-go-provider/integration v0.0.0-00010101000000-000000000000
github.com/pulumi/pulumi-terraform-bridge/testing v0.0.1
github.com/pulumi/pulumi/pkg/v3 v3.95.0
github.com/pulumi/pulumi/sdk/v3 v3.95.0
github.com/stretchr/testify v1.8.4
Expand Down Expand Up @@ -88,13 +88,13 @@ require (
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/zclconf/go-cty v1.13.2 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.15.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 // indirect
Expand Down
16 changes: 8 additions & 8 deletions tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435
github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE=
github.com/pulumi/esc v0.6.1-0.20231111193429-44b746a5b3b5 h1:1DJMji9F7XPea46bSuhy4/85n8J4/Mfz8PWLZtjKKiI=
github.com/pulumi/esc v0.6.1-0.20231111193429-44b746a5b3b5/go.mod h1:Y6W21yUukvxS2NnS5ae1beMSPhMvj0xNAYcDqDHVj/g=
github.com/pulumi/pulumi-terraform-bridge/testing v0.0.1 h1:SCg1gjfY9N4yn8U8peIUYATifjoDABkyR7H9lmefsfc=
github.com/pulumi/pulumi-terraform-bridge/testing v0.0.1/go.mod h1:7OeUPH8rpt5ipyj9EFcnXpuzQ8SHL0dyqdfa8nOacdk=
github.com/pulumi/providertest v0.0.11 h1:mg8MQ7Cq7+9XlHIkBD+aCqQO4mwAJEISngZgVdnQUe8=
github.com/pulumi/providertest v0.0.11/go.mod h1:HsxjVsytcMIuNj19w1lT2W0QXY0oReXl1+h6eD2JXP8=
github.com/pulumi/pulumi/pkg/v3 v3.95.0 h1:FBA0EmjRaqUgzleFMpLSAQUojXH2PyIVERzAm53p63U=
github.com/pulumi/pulumi/pkg/v3 v3.95.0/go.mod h1:4mjOPC8lb49ihR/HbGmid0y9GFlpfP9Orumr0wFOGno=
github.com/pulumi/pulumi/sdk/v3 v3.95.0 h1:SBpFZYdbVF8DtmiEosut2BRVRjLxPpcQf5bOkyPWosQ=
Expand Down Expand Up @@ -206,8 +206,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
Expand Down Expand Up @@ -259,15 +259,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
2 changes: 1 addition & 1 deletion tests/grpc/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package grpc
import (
"testing"

replay "github.com/pulumi/pulumi-terraform-bridge/testing/x"
replay "github.com/pulumi/providertest/replay"
"github.com/stretchr/testify/require"

p "github.com/pulumi/pulumi-go-provider"
Expand Down
2 changes: 1 addition & 1 deletion tests/grpc/grpc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023, Pulumi Corporation.
// Copyright 2023-2024, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
81 changes: 81 additions & 0 deletions tests/grpc/partial/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package partial

import (
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"

p "github.com/pulumi/pulumi-go-provider"
"github.com/pulumi/pulumi-go-provider/infer"
)

func Provider() p.Provider {
return infer.Provider(infer.Options{
Resources: []infer.InferredResource{infer.Resource[*Partial, Args, State]()},
ModuleMap: map[tokens.ModuleName]tokens.ModuleName{
"partial": "index",
},
})
}

var (
_ infer.CustomResource[Args, State] = (*Partial)(nil)
_ infer.CustomUpdate[Args, State] = (*Partial)(nil)
_ infer.CustomRead[Args, State] = (*Partial)(nil)
)

type Partial struct{}
type Args struct {
S string `pulumi:"s"`
}
type State struct {
Args

Out string `pulumi:"out"`
}

func (*Partial) Create(ctx p.Context, name string, input Args, preview bool) (string, State, error) {
if preview {
return "", State{}, nil
}
contract.Assertf(input.S == "for-create", `expected input.S to be "for-create"`)
return "id", State{
Args: Args{S: "+for-create"},
Out: "partial-create",
}, infer.ResourceInitFailedError{
Reasons: []string{"create: failed to fully init"},
}
}

func (*Partial) Update(ctx p.Context, id string, olds State, news Args, preview bool) (State, error) {
if preview {
return State{}, nil
}
contract.Assertf(news.S == "for-update", `expected news.S to be "for-update"`)
contract.Assertf(olds.S == "+for-create", `expected olds.Out to be "partial-create"`)
contract.Assertf(olds.Out == "partial-init", `expected olds.Out to be "partial-create"`)

return State{
Args: Args{
S: "from-update",
},
Out: "partial-update",
}, infer.ResourceInitFailedError{
Reasons: []string{"update: failed to continue init"},
}
}

func (*Partial) Read(ctx p.Context, id string, inputs Args, state State) (
canonicalID string, normalizedInputs Args, normalizedState State, err error) {
contract.Assertf(inputs.S == "for-read", `expected inputs.S to be "for-read"`)
contract.Assertf(state.S == "from-update", `expected olds.Out to be "partial-create"`)
contract.Assertf(state.Out == "state-for-read", `expected state.Out to be "state-for-read"`)

return "from-read-id", Args{
S: "from-read-input",
}, State{
Args: Args{"s-state-from-read"},
Out: "out-state-from-read",
}, infer.ResourceInitFailedError{
Reasons: []string{"read: failed to finish read"},
}
}
145 changes: 145 additions & 0 deletions tests/grpc/partial_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright 2024, 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 grpc

import (
"context"
"testing"

"github.com/pulumi/pulumi/sdk/v3/go/common/util/rpcutil/rpcerror"
pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/structpb"

p "github.com/pulumi/pulumi-go-provider"
"github.com/pulumi/pulumi-go-provider/tests/grpc/partial"
)

// partial_test.go asserts on the errors returned by the gRPC server generated by
// [p.Provider] and [infer.Provider]. It can't use replay, since that doesn't expose
// errors with enough fidelity to assert against.

// must makes f infallible by requiring that it does not return an error.
func must[I, T any](t *testing.T, f func(I) (T, error), i I) T {
v, err := f(i)
require.NoError(t, err)
return v
}

func TestPartialCreate(t *testing.T) {
t.Parallel()
s, err := p.RawServer("partial", "1.0.0", partial.Provider())(nil)
require.NoError(t, err)

_, err = s.Create(context.Background(), &pulumirpc.CreateRequest{
Urn: "urn:pulumi:dev::dev::partial:index:Partial::t1",
Properties: must(t, structpb.NewStruct, map[string]any{
"s": "for-create",
}),
})

rpcError, ok := rpcerror.FromError(err)
if assert.True(t, ok) {
for _, d := range rpcError.Details() {
initFailed, ok := d.(*pulumirpc.ErrorResourceInitFailed)
if !ok {
continue
}
assert.Equal(t, (&pulumirpc.ErrorResourceInitFailed{
Id: "id",
Properties: must(t, structpb.NewStruct, map[string]any{
"s": "+for-create",
"out": "partial-create",
}),
Reasons: []string{"create: failed to fully init"},
}).String(), initFailed.String())
}
}
}

func TestPartialUpdate(t *testing.T) {
t.Parallel()
s, err := p.RawServer("partial", "1.0.0", partial.Provider())(nil)
require.NoError(t, err)

_, err = s.Update(context.Background(), &pulumirpc.UpdateRequest{
Id: "update-id",
Urn: "urn:pulumi:dev::dev::partial:index:Partial::t1",
News: must(t, structpb.NewStruct, map[string]any{
"s": "for-update",
}),
Olds: must(t, structpb.NewStruct, map[string]any{
"s": "+for-create",
"out": "partial-init",
}),
})

rpcError, ok := rpcerror.FromError(err)
if assert.True(t, ok) {
for _, d := range rpcError.Details() {
initFailed, ok := d.(*pulumirpc.ErrorResourceInitFailed)
if !ok {
continue
}
assert.Equal(t, (&pulumirpc.ErrorResourceInitFailed{
Id: "update-id",
Properties: must(t, structpb.NewStruct, map[string]any{
"s": "from-update",
"out": "partial-update",
}),
Reasons: []string{"update: failed to continue init"},
}).String(), initFailed.String())
}
}
}
func TestPartialRead(t *testing.T) {
t.Parallel()
s, err := p.RawServer("partial", "1.0.0", partial.Provider())(nil)
require.NoError(t, err)

_, err = s.Read(context.Background(), &pulumirpc.ReadRequest{
Id: "read-id",
Urn: "urn:pulumi:dev::dev::partial:index:Partial::t1",
Inputs: must(t, structpb.NewStruct, map[string]any{
"s": "for-read",
}),
Properties: must(t, structpb.NewStruct, map[string]any{
"s": "from-update",
"out": "state-for-read",
}),
})

rpcError, ok := rpcerror.FromError(err)
if assert.True(t, ok) {
for _, d := range rpcError.Details() {
initFailed, ok := d.(*pulumirpc.ErrorResourceInitFailed)
if !ok {
continue
}
assert.Equal(t, (&pulumirpc.ErrorResourceInitFailed{
Id: "from-read-id",
Inputs: must(t, structpb.NewStruct, map[string]any{
"s": "from-read-input",
}),
Properties: must(t, structpb.NewStruct, map[string]any{
"s": "s-state-from-read",
"out": "out-state-from-read",
}),
Reasons: []string{"read: failed to finish read"},
}).String(), initFailed.String())
}
}
}

0 comments on commit f5b8dbc

Please sign in to comment.