Compare commits
43 commits
master
...
t0yv0/use-
Author | SHA1 | Date | |
---|---|---|---|
5d84f19c10 | |||
f87cce811b | |||
7ea1a887f7 | |||
a987213849 | |||
be53d8ffba | |||
ebc8f5e87b | |||
4d1f52ac9e | |||
793fadc2af | |||
e98d9ff7dd | |||
7644edc14e | |||
3b152acd86 | |||
f1906d20cf | |||
8b1b66aea2 | |||
65fc505f50 | |||
fa3d827a40 | |||
fe5c782a61 | |||
533c8fd102 | |||
809b6841f9 | |||
8587bf4049 | |||
30c91e2c5c | |||
baed6beddc | |||
60438a8cba | |||
af3eb07a8a | |||
f473cb5510 | |||
a408388ad7 | |||
8f54f616d5 | |||
38dcb00450 | |||
09a49fff40 | |||
a6a25f5715 | |||
cbb76c8aad | |||
b79939d7de | |||
761c5c52ca | |||
e1e288d1fe | |||
fed3e82dc8 | |||
bcf9c1f401 | |||
15ae1c0618 | |||
90b67ecc49 | |||
71fbbf43dc | |||
1f77c7509f | |||
cc26af2960 | |||
71f2330ae0 | |||
dedffe1011 | |||
f1b6920630 |
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -47,3 +47,6 @@ pulumi-python3-shim.cmd
|
|||
pulumi-python-shim.cmd
|
||||
pulumi-analyzer-policy.cmd
|
||||
pulumi-analyzer-policy-python.cmd
|
||||
|
||||
|
||||
__pycache__
|
|
@ -157,12 +157,12 @@ func initTestPackageSpec(t *testing.T) {
|
|||
{{% /example %}}
|
||||
{{% /examples %}}
|
||||
|
||||
## Import
|
||||
## Import
|
||||
|
||||
The import docs would be here
|
||||
|
||||
` + codeFence + `sh
|
||||
$ pulumi import prov:module/resource:Resource test test
|
||||
$ pulumi import prov:module/resource:Resource test test
|
||||
` + codeFence + `
|
||||
`,
|
||||
},
|
||||
|
@ -413,5 +413,8 @@ func generatePackage(tool string, pkg *schema.Package, extraFiles map[string][]b
|
|||
|
||||
func TestGeneratePackage(t *testing.T) {
|
||||
// TODO: do we have a compile step on templates?
|
||||
test.TestSDKCodegen(t, "docs", generatePackage, func(*testing.T, string) {})
|
||||
test.TestSDKCodegen(t, &test.SDKCodegenOptions{
|
||||
Language: "docs",
|
||||
GenPackage: generatePackage,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package dotnet
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -15,21 +13,30 @@ import (
|
|||
)
|
||||
|
||||
func TestGeneratePackage(t *testing.T) {
|
||||
test.TestSDKCodegen(t, "dotnet", GeneratePackage, typeCheckGeneratedPackage)
|
||||
test.TestSDKCodegen(t, &test.SDKCodegenOptions{
|
||||
Language: "dotnet",
|
||||
GenPackage: generatePackageWithVersion,
|
||||
Checks: map[string]test.CodegenCheck{
|
||||
"dotnet/compile": typeCheckGeneratedPackage,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// TODO replace this with GeneratePackage when https://github.com/pulumi/pulumi/pull/7938 lands.
|
||||
func generatePackageWithVersion(
|
||||
tool string,
|
||||
pkg *schema.Package,
|
||||
extraFiles map[string][]byte) (map[string][]byte, error) {
|
||||
if extraFiles == nil {
|
||||
extraFiles = make(map[string][]byte)
|
||||
}
|
||||
extraFiles["version.txt"] = []byte("0.0.0\n")
|
||||
return GeneratePackage(tool, pkg, extraFiles)
|
||||
}
|
||||
|
||||
func typeCheckGeneratedPackage(t *testing.T, pwd string) {
|
||||
var err error
|
||||
var dotnet string
|
||||
|
||||
// TODO remove when https://github.com/pulumi/pulumi/pull/7938 lands
|
||||
version := "0.0.0\n"
|
||||
err = os.WriteFile(filepath.Join(pwd, "version.txt"), []byte(version), 0600)
|
||||
if !os.IsExist(err) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
// endTODO
|
||||
|
||||
dotnet, err = executable.FindExecutable("dotnet")
|
||||
require.NoError(t, err)
|
||||
cmdOptions := integration.ProgramTestOptions{}
|
||||
|
|
|
@ -1,29 +1,23 @@
|
|||
package gen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant"
|
||||
tree "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant/tree/v1"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
|
||||
"github.com/pulumi/pulumi/pkg/v3/testing/integration"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/executable"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
)
|
||||
|
||||
func TestInputUsage(t *testing.T) {
|
||||
|
@ -66,53 +60,63 @@ func TestGoPackageName(t *testing.T) {
|
|||
|
||||
func TestGeneratePackage(t *testing.T) {
|
||||
generatePackage := func(tool string, pkg *schema.Package, files map[string][]byte) (map[string][]byte, error) {
|
||||
|
||||
for f := range files {
|
||||
t.Logf("Ignoring extraFile %s", f)
|
||||
}
|
||||
|
||||
return GeneratePackage(tool, pkg)
|
||||
}
|
||||
test.TestSDKCodegen(t, "go", generatePackage, typeCheckGeneratedPackage)
|
||||
test.TestSDKCodegen(t, &test.SDKCodegenOptions{
|
||||
Language: "go",
|
||||
GenPackage: generatePackage,
|
||||
Checks: map[string]test.CodegenCheck{
|
||||
"go/compile": typeCheckGeneratedPackage,
|
||||
"go/test": testGeneratedPackage,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func typeCheckGeneratedPackage(t *testing.T, pwd string) {
|
||||
var err error
|
||||
var ex string
|
||||
ex, err = executable.FindExecutable("go")
|
||||
require.NoError(t, err)
|
||||
|
||||
// go SDKs live in their own folder:
|
||||
// typecheck/go/$NAME/$FILES
|
||||
// where FILES contains all the project files (including go.mod)
|
||||
func inferModuleName(codeDir string) string {
|
||||
// For example for this path:
|
||||
//
|
||||
// This is not true when `package.language.go.rootPackageName` is set.
|
||||
dir, err := ioutil.ReadDir(pwd)
|
||||
require.NoError(t, err)
|
||||
root := pwd
|
||||
if len(dir) == 1 {
|
||||
require.True(t, dir[0].IsDir())
|
||||
root = filepath.Join(pwd, dir[0].Name())
|
||||
}
|
||||
t.Logf("*** Testing go in dir: %q ***", root)
|
||||
// codeDir = "../internal/test/testdata/external-resource-schema/go/"
|
||||
//
|
||||
// We will generate "$codeDir/go.mod" using
|
||||
// `external-resource-schema` as the module name so that it
|
||||
// can compile independently.
|
||||
return filepath.Base(filepath.Dir(codeDir))
|
||||
}
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmdOptions := integration.ProgramTestOptions{Stderr: &stderr, Stdout: &stdout}
|
||||
// We don't want to corrupt the global go.mod and go.sum with packages we
|
||||
// don't actually depend on. For this, we need to have each go package be
|
||||
// it's own module.
|
||||
err = integration.RunCommand(t, "mod init",
|
||||
[]string{ex, "mod", "init", "github.com/pulumi/test/internal"}, root, &cmdOptions)
|
||||
if err != nil {
|
||||
stdout := stdout.String()
|
||||
stderr := stderr.String()
|
||||
if len(stdout) > 0 {
|
||||
t.Logf("stdout: %s", stdout)
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
t.Logf("stderr: %s", stderr)
|
||||
}
|
||||
t.FailNow()
|
||||
func typeCheckGeneratedPackage(t *testing.T, codeDir string) {
|
||||
sdk, err := filepath.Abs(filepath.Join("..", "..", "..", "sdk"))
|
||||
require.NoError(t, err)
|
||||
|
||||
goExe, err := executable.FindExecutable("go")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Remove existing `go.mod` first otherise `go mod init` fails.
|
||||
goMod := filepath.Join(codeDir, "go.mod")
|
||||
alreadyHaveGoMod, err := test.PathExists(goMod)
|
||||
|
||||
require.NoError(t, err)
|
||||
if alreadyHaveGoMod {
|
||||
err := os.Remove(goMod)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err = integration.RunCommand(t, "get", []string{ex, "get"}, root, &cmdOptions)
|
||||
require.NoError(t, err)
|
||||
err = integration.RunCommand(t, "go build", []string{ex, "build"}, root, &cmdOptions)
|
||||
|
||||
test.RunCommand(t, "go_mod_init", codeDir, goExe, "mod", "init", inferModuleName(codeDir))
|
||||
replacement := fmt.Sprintf("github.com/pulumi/pulumi/sdk/v3=%s", sdk)
|
||||
test.RunCommand(t, "go_mod_edit", codeDir, goExe, "mod", "edit", "-replace", replacement)
|
||||
test.RunCommand(t, "go_mod_tidy", codeDir, goExe, "mod", "tidy")
|
||||
test.RunCommand(t, "go_build", codeDir, goExe, "build", "-v", "all")
|
||||
}
|
||||
|
||||
func testGeneratedPackage(t *testing.T, codeDir string) {
|
||||
goExe, err := executable.FindExecutable("go")
|
||||
require.NoError(t, err)
|
||||
|
||||
test.RunCommand(t, "go-test", codeDir, goExe, "test", fmt.Sprintf("%s/...", inferModuleName(codeDir)))
|
||||
}
|
||||
|
||||
func TestGenerateTypeNames(t *testing.T) {
|
||||
|
@ -135,177 +139,6 @@ func TestGenerateTypeNames(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
type mocks int
|
||||
|
||||
func (mocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
return args.Name + "_id", args.Inputs, nil
|
||||
}
|
||||
|
||||
func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
|
||||
return args.Args, nil
|
||||
}
|
||||
|
||||
func TestEnumUsage(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: &plant.ContainerArgs{
|
||||
Color: plant.ContainerColorRed,
|
||||
Material: pulumi.String("ceramic"),
|
||||
Size: plant.ContainerSizeFourInch,
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us,
|
||||
Type: tree.RubberTreeVarietyRuby,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Container.Brightness(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
brightness := all[4].(*plant.ContainerBrightness)
|
||||
typ := all[5].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "red", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSizeFourInch, "unexpected size on resource: %v", urn)
|
||||
assert.Nil(t, brightness)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyRuby, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(0))))
|
||||
})
|
||||
|
||||
t.Run("StringsForRelaxedEnum", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: plant.ContainerArgs{
|
||||
Color: pulumi.String("Magenta"),
|
||||
Material: pulumi.String("ceramic"),
|
||||
Size: plant.ContainerSize(22),
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us,
|
||||
Type: tree.RubberTreeVarietyRuby,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
typ := all[4].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSize(22), "unexpected size on resource: %v", urn)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyRuby, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(1))))
|
||||
})
|
||||
|
||||
t.Run("StringsForStrictEnum", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: plant.ContainerArgs{
|
||||
Color: pulumi.String("Magenta"),
|
||||
Material: pulumi.String("ceramic"),
|
||||
Size: plant.ContainerSize(22),
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us,
|
||||
Type: tree.RubberTreeVarietyBurgundy,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
typ := all[4].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSize(22), "unexpected size on resource: %v", urn)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyBurgundy, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(1))))
|
||||
})
|
||||
|
||||
t.Run("EnumOutputs", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: plant.ContainerArgs{
|
||||
Color: plant.ContainerColor("Magenta").ToContainerColorOutput().ToStringOutput(),
|
||||
Material: pulumi.String("ceramic").ToStringOutput(),
|
||||
Size: plant.ContainerSize(22).ToContainerSizeOutput(),
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us.ToFarmPtrOutput().ToStringPtrOutput(),
|
||||
Type: tree.RubberTreeVarietyBurgundy.ToRubberTreeVarietyOutput(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
typ := all[4].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSize(22), "unexpected size on resource: %v", urn)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyBurgundy, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(1))))
|
||||
})
|
||||
}
|
||||
|
||||
func TestGenerateOutputFuncs(t *testing.T) {
|
||||
testDir := filepath.Join("..", "internal", "test", "testdata", "output-funcs")
|
||||
|
||||
|
|
|
@ -17,10 +17,12 @@ package test
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -28,6 +30,8 @@ import (
|
|||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
|
||||
"github.com/pulumi/pulumi/pkg/v3/testing/integration"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/executable"
|
||||
)
|
||||
|
||||
// GenPkgSignature corresponds to the shape of the codegen GeneratePackage functions.
|
||||
|
@ -76,7 +80,11 @@ func LoadFiles(dir, lang string, files []string) (map[string][]byte, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func loadDirectory(fs map[string][]byte, root, path string) error {
|
||||
// Recursively loads files from a directory into the `fs` map. Ignores
|
||||
// entries that match `ignore(path)==true`, also skips descending into
|
||||
// directories that are ignored. This is useful for example to avoid
|
||||
// `node_modules`.
|
||||
func loadDirectory(fs map[string][]byte, root, path string, ignore func(path string) bool) error {
|
||||
entries, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -84,8 +92,12 @@ func loadDirectory(fs map[string][]byte, root, path string) error {
|
|||
|
||||
for _, e := range entries {
|
||||
entryPath := filepath.Join(path, e.Name())
|
||||
if e.IsDir() {
|
||||
if err = loadDirectory(fs, root, entryPath); err != nil {
|
||||
relativeEntryPath := entryPath[len(root)+1:]
|
||||
baseName := filepath.Base(relativeEntryPath)
|
||||
if ignore != nil && (ignore(relativeEntryPath) || ignore(baseName)) {
|
||||
// pass
|
||||
} else if e.IsDir() {
|
||||
if err = loadDirectory(fs, root, entryPath, ignore); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
@ -93,8 +105,7 @@ func loadDirectory(fs map[string][]byte, root, path string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := filepath.ToSlash(entryPath[len(root)+1:])
|
||||
|
||||
name := filepath.ToSlash(relativeEntryPath)
|
||||
fs[name] = contents
|
||||
}
|
||||
}
|
||||
|
@ -102,12 +113,92 @@ func loadDirectory(fs map[string][]byte, root, path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func PathExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Reads `.sdkcodegenignore` file if present to use as loadDirectory ignore func.
|
||||
func loadIgnoreMap(dir string) (func(path string) bool, error) {
|
||||
|
||||
load1 := func(dir string, ignoredPathSet map[string]bool) error {
|
||||
p := filepath.Join(dir, ".sdkcodegenignore")
|
||||
|
||||
gotIgnore, err := PathExists(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if gotIgnore {
|
||||
contents, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range strings.Split(string(contents), "\n") {
|
||||
s = strings.Trim(s, " \r\n\t")
|
||||
|
||||
if s != "" {
|
||||
ignoredPathSet[s] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
loadAll := func(dir string, ignoredPathSet map[string]bool) error {
|
||||
for {
|
||||
atTopOfRepo, err := PathExists(filepath.Join(dir, ".git"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = load1(dir, ignoredPathSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if atTopOfRepo || dir == "." {
|
||||
return nil
|
||||
}
|
||||
|
||||
dir = filepath.Dir(dir)
|
||||
}
|
||||
}
|
||||
|
||||
ignoredPathSet := make(map[string]bool)
|
||||
err := loadAll(dir, ignoredPathSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return func(path string) bool {
|
||||
path = strings.ReplaceAll(path, "\\", "/")
|
||||
_, ignoredPath := ignoredPathSet[path]
|
||||
return ignoredPath
|
||||
}, nil
|
||||
}
|
||||
|
||||
// LoadBaseline loads the contents of the given baseline directory.
|
||||
func LoadBaseline(dir, lang string) (map[string][]byte, error) {
|
||||
dir = filepath.Join(dir, lang)
|
||||
|
||||
fs := map[string][]byte{}
|
||||
if err := loadDirectory(fs, dir, dir); err != nil {
|
||||
|
||||
ignore, err := loadIgnoreMap(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := loadDirectory(fs, dir, dir, ignore); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fs, nil
|
||||
|
@ -117,14 +208,20 @@ func LoadBaseline(dir, lang string) (map[string][]byte, error) {
|
|||
func ValidateFileEquality(t *testing.T, actual, expected map[string][]byte) bool {
|
||||
ok := true
|
||||
for name, file := range expected {
|
||||
if !assert.Contains(t, actual, name) || !assert.Equal(t, string(file), string(actual[name]), name) {
|
||||
t.Logf("%s did not agree", name)
|
||||
_, inActual := actual[name]
|
||||
if inActual {
|
||||
if !assert.Equal(t, string(file), string(actual[name]), name) {
|
||||
t.Logf("%s did not agree", name)
|
||||
ok = false
|
||||
}
|
||||
} else {
|
||||
t.Logf("File %s was expected but is missing from the actual fileset", name)
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
for name := range actual {
|
||||
if _, has := expected[name]; !has {
|
||||
t.Logf("missing data for %s", name)
|
||||
if _, inExpected := expected[name]; !inExpected {
|
||||
t.Logf("File %s from the actual fileset was not expected", name)
|
||||
ok = false
|
||||
}
|
||||
}
|
||||
|
@ -142,38 +239,80 @@ func RewriteFilesWhenPulumiAccept(t *testing.T, dir, lang string, actual map[str
|
|||
baseline := filepath.Join(dir, lang)
|
||||
|
||||
// Remove the baseline directory's current contents.
|
||||
entries, err := os.ReadDir(baseline)
|
||||
_, err := os.ReadDir(baseline)
|
||||
switch {
|
||||
case err == nil:
|
||||
for _, e := range entries {
|
||||
err = os.RemoveAll(filepath.Join(baseline, e.Name()))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
err = os.RemoveAll(baseline)
|
||||
require.NoError(t, err)
|
||||
case os.IsNotExist(err):
|
||||
// OK
|
||||
default:
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
WriteTestFiles(t, dir, lang, actual)
|
||||
for file, bytes := range actual {
|
||||
relPath := filepath.FromSlash(file)
|
||||
path := filepath.Join(dir, lang, relPath)
|
||||
|
||||
err := writeFileEnsuringDir(path, bytes)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// WriteTestFiles writes out the files generated by GeneratePackage to a directory.
|
||||
func WriteTestFiles(t *testing.T, dir, lang string, files map[string][]byte) {
|
||||
var err error
|
||||
for file, bytes := range files {
|
||||
relPath := filepath.FromSlash(file)
|
||||
path := filepath.Join(dir, lang, relPath)
|
||||
// Useful for populating code-generated destination
|
||||
// `codeDir=$dir/$lang` with extra manually written files such as the
|
||||
// unit test files. These files are copied from `$dir/$lang-extras`
|
||||
// folder if present.
|
||||
func CopyExtraFiles(t *testing.T, dir, lang string) {
|
||||
codeDir := filepath.Join(dir, lang)
|
||||
extrasDir := filepath.Join(dir, fmt.Sprintf("%s-extras", lang))
|
||||
gotExtras, err := PathExists(extrasDir)
|
||||
|
||||
if err = os.MkdirAll(filepath.Dir(path), 0755); err != nil && !os.IsExist(err) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path, bytes, 0600)
|
||||
require.NoError(t, err)
|
||||
if !gotExtras {
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
require.NoError(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = filepath.Walk(extrasDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
relPath, err := filepath.Rel(extrasDir, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
destPath := filepath.Join(codeDir, relPath)
|
||||
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = writeFileEnsuringDir(destPath, bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.Logf("Copied %s to %s", path, destPath)
|
||||
return nil
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func writeFileEnsuringDir(path string, bytes []byte) error {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil && !os.IsExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(path, bytes, 0600)
|
||||
}
|
||||
|
||||
// CheckAllFilesGenerated ensures that the set of expected and actual files generated
|
||||
|
@ -238,3 +377,32 @@ func ValidateFileTransformer(
|
|||
|
||||
ValidateFileEquality(t, actual, expected)
|
||||
}
|
||||
|
||||
func RunCommand(t *testing.T, name string, cwd string, exec string, args ...string) {
|
||||
exec, err := executable.FindExecutable(exec)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
wd, err := filepath.Abs(cwd)
|
||||
require.NoError(t, err)
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmdOptions := integration.ProgramTestOptions{Stderr: &stderr, Stdout: &stdout, Verbose: true}
|
||||
err = integration.RunCommand(t,
|
||||
name,
|
||||
append([]string{exec}, args...),
|
||||
wd,
|
||||
&cmdOptions)
|
||||
require.NoError(t, err)
|
||||
if err != nil {
|
||||
stdout := stdout.String()
|
||||
stderr := stderr.String()
|
||||
if len(stdout) > 0 {
|
||||
t.Logf("stdout: %s", stdout)
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
t.Logf("stderr: %s", stderr)
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,40 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
||||
)
|
||||
|
||||
type ThenFunc func(t *testing.T, testDir string)
|
||||
// Defines an extra check logic that accepts the directory with the
|
||||
// generated code, typically `$TestDir/$test.Directory/$language`.
|
||||
type CodegenCheck func(t *testing.T, codedir string)
|
||||
|
||||
type sdkTest struct {
|
||||
Directory string
|
||||
Description string
|
||||
Directory string
|
||||
Description string
|
||||
|
||||
// Extra checks for this test. They keys of this map
|
||||
// are of the form "$language/$check" such as "go/compile".
|
||||
Checks map[string]CodegenCheck
|
||||
|
||||
// Skip checks, identified by "$language/$check".
|
||||
Skip codegen.StringSet
|
||||
|
||||
// Do not compile the generated code for the languages in this set.
|
||||
// This is a helper form of `Skip`.
|
||||
SkipCompileCheck codegen.StringSet
|
||||
Then map[string]ThenFunc
|
||||
}
|
||||
|
||||
const (
|
||||
python = "python"
|
||||
nodejs = "nodejs"
|
||||
dotnet = "dotnet"
|
||||
golang = "go"
|
||||
|
@ -32,10 +44,12 @@ var sdkTests = []sdkTest{
|
|||
{
|
||||
Directory: "input-collision",
|
||||
Description: "Schema with types that could potentially produce collisions (go).",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "dash-named-schema",
|
||||
Description: "Simple schema with a two part name (foo-bar)",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "external-resource-schema",
|
||||
|
@ -55,41 +69,37 @@ var sdkTests = []sdkTest{
|
|||
{
|
||||
Directory: "plain-schema-gh6957",
|
||||
Description: "Repro for #6957",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "resource-args-python",
|
||||
Description: "Resource args with same named resource and type",
|
||||
Then: map[string]ThenFunc{
|
||||
"go": func(t *testing.T, testDir string) {
|
||||
cmd := exec.Command("go", "test", "./...")
|
||||
cmd.Dir = filepath.Join(testDir, "go-program")
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
if !assert.NoError(t, err) {
|
||||
t.Logf("output: %v", string(out))
|
||||
}
|
||||
},
|
||||
},
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "simple-enum-schema",
|
||||
Description: "Simple schema with enum types",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "simple-plain-schema",
|
||||
Description: "Simple schema with plain properties",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "simple-plain-schema-with-root-package",
|
||||
Description: "Simple schema with root package set",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "simple-resource-schema",
|
||||
Description: "Simple schema with local resource properties",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "simple-resource-schema-custom-pypackage-name",
|
||||
Description: "Simple schema with local resource properties and custom Python package name",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "simple-methods-schema",
|
||||
|
@ -99,25 +109,44 @@ var sdkTests = []sdkTest{
|
|||
{
|
||||
Directory: "simple-yaml-schema",
|
||||
Description: "Simple schema encoded using YAML",
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "provider-config-schema",
|
||||
Description: "Simple provider config schema",
|
||||
SkipCompileCheck: codegen.NewStringSet(dotnet),
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "replace-on-change",
|
||||
Description: "Simple use of replaceOnChange in schema",
|
||||
SkipCompileCheck: codegen.NewStringSet(golang),
|
||||
Skip: codegen.NewStringSet("nodejs/test"),
|
||||
},
|
||||
{
|
||||
Directory: "resource-property-overlap",
|
||||
Description: "A resource with the same name as it's property",
|
||||
SkipCompileCheck: codegen.NewStringSet(dotnet, nodejs),
|
||||
},
|
||||
{
|
||||
Directory: "output-funcs",
|
||||
Description: "Test generation of $fn_Output helper forms",
|
||||
SkipCompileCheck: codegen.NewStringSet(dotnet, python, golang),
|
||||
},
|
||||
}
|
||||
|
||||
type checkPackageSignature = func(t *testing.T, pwd string)
|
||||
type SDKCodegenOptions struct {
|
||||
// Name of the programming language.
|
||||
Language string
|
||||
|
||||
// Language-aware code generator; such as `GeneratePackage`.
|
||||
// from `codgen/dotnet`.
|
||||
GenPackage GenPkgSignature
|
||||
|
||||
// Extra checks for all the tests. They keys of this map are
|
||||
// of the form "$language/$check" such as "go/compile".
|
||||
Checks map[string]CodegenCheck
|
||||
}
|
||||
|
||||
// TestSDKCodegen runs the complete set of SDK code generation tests against a particular language's code
|
||||
// generator. It also verifies that the generated code is structurally sound.
|
||||
|
@ -133,11 +162,13 @@ type checkPackageSignature = func(t *testing.T, pwd string)
|
|||
//
|
||||
// The schema is the only piece that must be manually authored. Once the schema has been written, the expected outputs
|
||||
// can be generated by running `PULUMI_ACCEPT=true go test ./..." from the `pkg/codegen` directory.
|
||||
func TestSDKCodegen(t *testing.T, language string, genPackage GenPkgSignature, checkPackage checkPackageSignature) {
|
||||
func TestSDKCodegen(t *testing.T, opts *SDKCodegenOptions) {
|
||||
testDir := filepath.Join("..", "internal", "test", "testdata")
|
||||
|
||||
for _, tt := range sdkTests {
|
||||
t.Run(tt.Description, func(t *testing.T) {
|
||||
t.Run(tt.Directory, func(t *testing.T) {
|
||||
t.Log(tt.Description)
|
||||
|
||||
dirPath := filepath.Join(testDir, filepath.FromSlash(tt.Directory))
|
||||
|
||||
schemaPath := filepath.Join(dirPath, "schema.json")
|
||||
|
@ -145,31 +176,74 @@ func TestSDKCodegen(t *testing.T, language string, genPackage GenPkgSignature, c
|
|||
schemaPath = filepath.Join(dirPath, "schema.yaml")
|
||||
}
|
||||
|
||||
files, err := GeneratePackageFilesFromSchema(schemaPath, genPackage)
|
||||
files, err := GeneratePackageFilesFromSchema(schemaPath, opts.GenPackage)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check output is valid code (will type-check). If code will not
|
||||
// type-check, we don't allow the user to run PULUMI_ACCEPT=true and
|
||||
// replace the test files.
|
||||
if !tt.SkipCompileCheck.Has(language) {
|
||||
typeCheckPath := filepath.Join(dirPath, "typecheck")
|
||||
langTypeCheckPath := filepath.Join(typeCheckPath, language)
|
||||
contract.IgnoreError(os.RemoveAll(langTypeCheckPath))
|
||||
WriteTestFiles(t, typeCheckPath, language, files)
|
||||
checkPackage(t, langTypeCheckPath)
|
||||
}
|
||||
|
||||
if !RewriteFilesWhenPulumiAccept(t, dirPath, language, files) {
|
||||
expectedFiles, err := LoadBaseline(dirPath, language)
|
||||
if !RewriteFilesWhenPulumiAccept(t, dirPath, opts.Language, files) {
|
||||
expectedFiles, err := LoadBaseline(dirPath, opts.Language)
|
||||
require.NoError(t, err)
|
||||
|
||||
if !ValidateFileEquality(t, files, expectedFiles) {
|
||||
return
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
if then, ok := tt.Then[language]; ok {
|
||||
then(t, dirPath)
|
||||
CopyExtraFiles(t, dirPath, opts.Language)
|
||||
|
||||
// Merge language-specific global and
|
||||
// test-specific checks, with test-specific
|
||||
// having precedence.
|
||||
allChecks := make(map[string]CodegenCheck)
|
||||
for k, v := range opts.Checks {
|
||||
allChecks[k] = v
|
||||
}
|
||||
for k, v := range tt.Checks {
|
||||
allChecks[k] = v
|
||||
}
|
||||
|
||||
// Define check filter.
|
||||
shouldSkipCheck := func(check string) bool {
|
||||
|
||||
// Only language-specific checks.
|
||||
if !strings.HasPrefix(check, opts.Language+"/") {
|
||||
return true
|
||||
}
|
||||
|
||||
// Obey SkipCompileCheck to skip compile and test targets.
|
||||
if tt.SkipCompileCheck != nil &&
|
||||
tt.SkipCompileCheck.Has(opts.Language) &&
|
||||
(check == fmt.Sprintf("%s/compile", opts.Language) ||
|
||||
check == fmt.Sprintf("%s/test", opts.Language)) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Obey Skip.
|
||||
if tt.Skip != nil && tt.Skip.Has(check) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Sort the checks in alphabetical order.
|
||||
var checkOrder []string
|
||||
for check := range allChecks {
|
||||
checkOrder = append(checkOrder, check)
|
||||
}
|
||||
sort.Strings(checkOrder)
|
||||
|
||||
codeDir := filepath.Join(dirPath, opts.Language)
|
||||
|
||||
// Perform the checks.
|
||||
for _, checkVar := range checkOrder {
|
||||
check := checkVar
|
||||
t.Run(check, func(t *testing.T) {
|
||||
if shouldSkipCheck(check) {
|
||||
t.Skip()
|
||||
}
|
||||
checkFun := allChecks[check]
|
||||
checkFun(t, codeDir)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
4
pkg/codegen/internal/test/testdata/.gitignore
vendored
Normal file
4
pkg/codegen/internal/test/testdata/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
package-lock.json
|
||||
go.sum
|
||||
go.mod
|
||||
tests
|
10
pkg/codegen/internal/test/testdata/.sdkcodegenignore
vendored
Normal file
10
pkg/codegen/internal/test/testdata/.sdkcodegenignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
__pycache__
|
||||
bin
|
||||
node_modules
|
||||
tests
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
obj
|
||||
command-output
|
||||
go.sum
|
||||
go.mod
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -6,8 +6,8 @@ package submodule1
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"dash-named-schema/foo"
|
||||
"github.com/blang/semver"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/dash-named-schema/go/foo"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/dash-named-schema/go/foo"
|
||||
"dash-named-schema/foo"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
)
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
}
|
||||
},
|
||||
"go": {
|
||||
"importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/dash-named-schema/go/foo"
|
||||
"importBasePath": "dash-named-schema/foo"
|
||||
},
|
||||
"nodejs": {
|
||||
"dependencies": {
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -28,3 +28,11 @@ export interface ArgFunctionArgs {
|
|||
export interface ArgFunctionResult {
|
||||
readonly age?: number;
|
||||
}
|
||||
|
||||
export function argFunctionOutput(args?: ArgFunctionOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<ArgFunctionResult> {
|
||||
return pulumi.output(args).apply(a => argFunction(a, opts))
|
||||
}
|
||||
|
||||
export interface ArgFunctionOutputArgs {
|
||||
name?: pulumi.Input<pulumiRandom.RandomPet>;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/pulumi/pulumi-foo-bar/sdk/v2/go/foo-bar"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
"nested-module-thirdparty/foo"
|
||||
)
|
||||
|
||||
type module struct {
|
||||
|
@ -32,7 +32,7 @@ func (m *module) Construct(ctx *pulumi.Context, name, typ, urn string) (r pulumi
|
|||
}
|
||||
|
||||
func init() {
|
||||
version, err := foo - bar.PkgVersion()
|
||||
version, err := foo.PkgVersion()
|
||||
if err != nil {
|
||||
fmt.Printf("failed to determine package version. defaulting to v1: %v\n", err)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
"packageReferences": {
|
||||
"Pulumi": "3.12"
|
||||
}
|
||||
},
|
||||
"go": {
|
||||
"importBasePath": "nested-module-thirdparty/foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/nested-module/go/foo"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
"nested-module/foo"
|
||||
)
|
||||
|
||||
type module struct {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
}
|
||||
},
|
||||
"go": {
|
||||
"importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/nested-module/go/foo"
|
||||
"importBasePath": "nested-module/foo"
|
||||
},
|
||||
"nodejs": {},
|
||||
"python": {}
|
||||
|
|
182
pkg/codegen/internal/test/testdata/output-funcs/nodejs-extras/tests/codegen.spec.ts
vendored
Normal file
182
pkg/codegen/internal/test/testdata/output-funcs/nodejs-extras/tests/codegen.spec.ts
vendored
Normal file
|
@ -0,0 +1,182 @@
|
|||
// Copyright 2016-2021, 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.
|
||||
|
||||
import 'mocha';
|
||||
import * as assert from 'assert';
|
||||
|
||||
import * as pulumi from '@pulumi/pulumi';
|
||||
|
||||
import { listStorageAccountKeysOutput, ListStorageAccountKeysResult } from '../listStorageAccountKeys';
|
||||
import { funcWithAllOptionalInputsOutput } from '../funcWithAllOptionalInputs';
|
||||
import { funcWithDefaultValueOutput } from '../funcWithDefaultValue';
|
||||
import { funcWithListParamOutput } from '../funcWithListParam';
|
||||
import { funcWithDictParamOutput } from '../funcWithDictParam';
|
||||
import * as giro from '../getIntegrationRuntimeObjectMetadatum';
|
||||
|
||||
pulumi.runtime.setMocks({
|
||||
newResource: function(_: pulumi.runtime.MockResourceArgs): {id: string, state: any} {
|
||||
throw new Error('newResource not implemented');
|
||||
},
|
||||
call: function(args: pulumi.runtime.MockCallArgs) {
|
||||
if (args.token == 'mypkg::listStorageAccountKeys') {
|
||||
return {
|
||||
'keys': [{
|
||||
'creationTime': 'my-creation-time',
|
||||
'keyName': 'my-key-name',
|
||||
'permissions': 'my-permissions',
|
||||
'value': JSON.stringify(args.inputs),
|
||||
}]
|
||||
};
|
||||
}
|
||||
if (args.token == 'mypkg::getIntegrationRuntimeObjectMetadatum') {
|
||||
return {nextLink: JSON.stringify(args.inputs)};
|
||||
}
|
||||
if (args.token == 'mypkg::funcWithAllOptionalInputs' ||
|
||||
args.token == 'mypkg::funcWithDefaultValue' ||
|
||||
args.token == 'mypkg::funcWithListParam' ||
|
||||
args.token == 'mypkg::funcWithDictParam')
|
||||
{
|
||||
return {r: JSON.stringify(args.inputs)};
|
||||
}
|
||||
throw new Error('call not implemented for ' + args.token);
|
||||
},
|
||||
});
|
||||
|
||||
function checkTable(done: any, transform: (res: any) => any, table: {given: pulumi.Output<any>, expect: any}[]) {
|
||||
checkOutput(done, pulumi.all(table.map(x => x.given)), res => {
|
||||
res.map((actual, i) => {
|
||||
assert.deepStrictEqual(transform(actual), table[i].expect);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('output-funcs', () => {
|
||||
it('funcWithAllOptionalInputsOutput', (done) => {
|
||||
checkTable(done, res => JSON.parse(res.r), [
|
||||
{given: funcWithAllOptionalInputsOutput({}),
|
||||
expect: {}},
|
||||
{given: funcWithAllOptionalInputsOutput({a: pulumi.output('my-a')}),
|
||||
expect: {'a': 'my-a'}},
|
||||
{given: funcWithAllOptionalInputsOutput({a: pulumi.output('my-a'),
|
||||
b: pulumi.output('my-b')}),
|
||||
expect: {'a': 'my-a', 'b': 'my-b'}}
|
||||
]);
|
||||
});
|
||||
|
||||
// TODO[pulumi/pulumi#7973] Node codegen does not respect default
|
||||
// values at the moment, otherwise 'b' parameter would receive the
|
||||
// default value from the schema.
|
||||
it('funcWithDefaultValueOutput', (done) => {
|
||||
checkTable(done, res => JSON.parse(res.r), [
|
||||
{given: funcWithDefaultValueOutput({'a': pulumi.output('my-a')}),
|
||||
expect: {'a': 'my-a'}},
|
||||
{given: funcWithDefaultValueOutput({'a': pulumi.output('my-a'),
|
||||
'b': pulumi.output('my-b')}),
|
||||
expect: {'a': 'my-a', 'b': 'my-b'}}
|
||||
]);
|
||||
});
|
||||
|
||||
it('funcWithListParamOutput', (done) => {
|
||||
const l = ['a', 'b', 'c'];
|
||||
checkTable(done, res => JSON.parse(res.r), [
|
||||
{given: funcWithListParamOutput({}),
|
||||
expect: {}},
|
||||
{given: funcWithListParamOutput({'a': pulumi.output(l)}),
|
||||
expect: {'a': l}},
|
||||
{given: funcWithListParamOutput({'a': pulumi.output(l),
|
||||
'b': pulumi.output('my-b')}),
|
||||
expect: {'a': l, 'b': 'my-b'}},
|
||||
]);
|
||||
});
|
||||
|
||||
it('funcWithDictParamOutput', (done) => {
|
||||
const d = {'key-a': 'value-a', 'key-b': 'value-b'};
|
||||
checkTable(done, res => JSON.parse(res.r), [
|
||||
{given: funcWithDictParamOutput({}),
|
||||
expect: {}},
|
||||
{given: funcWithDictParamOutput({'a': pulumi.output(d)}),
|
||||
expect: {'a': d}},
|
||||
{given: funcWithDictParamOutput({'a': pulumi.output(d),
|
||||
'b': pulumi.output('my-b')}),
|
||||
expect: {'a': d, 'b': 'my-b'}},
|
||||
]);
|
||||
});
|
||||
|
||||
it('listStorageAccountKeysOutput', (done) => {
|
||||
const output = listStorageAccountKeysOutput({
|
||||
accountName: pulumi.output('my-account-name'),
|
||||
resourceGroupName: pulumi.output('my-resource-group-name'),
|
||||
});
|
||||
checkOutput(done, output, (res: ListStorageAccountKeysResult) => {
|
||||
assert.equal(res.keys.length, 1);
|
||||
const k = res.keys[0];
|
||||
assert.equal(k.creationTime, 'my-creation-time');
|
||||
assert.equal(k.keyName, 'my-key-name');
|
||||
assert.equal(k.permissions, 'my-permissions');
|
||||
assert.deepStrictEqual(JSON.parse(k.value), {
|
||||
'accountName': 'my-account-name',
|
||||
'resourceGroupName': 'my-resource-group-name'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('listStorageAccountKeysOutput with optional arg set', (done) => {
|
||||
const output = listStorageAccountKeysOutput({
|
||||
accountName: pulumi.output('my-account-name'),
|
||||
resourceGroupName: pulumi.output('my-resource-group-name'),
|
||||
expand: pulumi.output('my-expand'),
|
||||
});
|
||||
checkOutput(done, output, (res: ListStorageAccountKeysResult) => {
|
||||
assert.equal(res.keys.length, 1);
|
||||
const k = res.keys[0];
|
||||
assert.equal(k.creationTime, 'my-creation-time');
|
||||
assert.equal(k.keyName, 'my-key-name');
|
||||
assert.equal(k.permissions, 'my-permissions');
|
||||
assert.deepStrictEqual(JSON.parse(k.value), {
|
||||
'accountName': 'my-account-name',
|
||||
'resourceGroupName': 'my-resource-group-name',
|
||||
'expand': 'my-expand'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('getIntegrationRuntimeObjectMetadatumOutput', (done) => {
|
||||
checkTable(
|
||||
done,
|
||||
(res: giro.GetIntegrationRuntimeObjectMetadatumResult) =>
|
||||
JSON.parse(res.nextLink || "{}"),
|
||||
[{given: giro.getIntegrationRuntimeObjectMetadatumOutput({
|
||||
factoryName: pulumi.output('my-factory-name'),
|
||||
integrationRuntimeName: pulumi.output('my-integration-runtime-name'),
|
||||
metadataPath: pulumi.output('my-metadata-path'),
|
||||
resourceGroupName: pulumi.output('my-resource-group-name')}),
|
||||
expect: {'factoryName': 'my-factory-name',
|
||||
'integrationRuntimeName': 'my-integration-runtime-name',
|
||||
'metadataPath': 'my-metadata-path',
|
||||
'resourceGroupName': 'my-resource-group-name'}}]
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function checkOutput<T>(done: any, output: pulumi.Output<T>, check: (value: T) => void) {
|
||||
output.apply(value => {
|
||||
try {
|
||||
check(value);
|
||||
done();
|
||||
} catch (error) {
|
||||
done(error);
|
||||
}
|
||||
});
|
||||
}
|
0
pkg/codegen/internal/test/testdata/output-funcs/nodejs/README.md
vendored
Normal file
0
pkg/codegen/internal/test/testdata/output-funcs/nodejs/README.md
vendored
Normal file
54
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithAllOptionalInputs.ts
vendored
Normal file
54
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithAllOptionalInputs.ts
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* Check codegen of functions with all optional inputs.
|
||||
*/
|
||||
export function funcWithAllOptionalInputs(args?: FuncWithAllOptionalInputsArgs, opts?: pulumi.InvokeOptions): Promise<FuncWithAllOptionalInputsResult> {
|
||||
args = args || {};
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::funcWithAllOptionalInputs", {
|
||||
"a": args.a,
|
||||
"b": args.b,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface FuncWithAllOptionalInputsArgs {
|
||||
/**
|
||||
* Property A
|
||||
*/
|
||||
a?: string;
|
||||
/**
|
||||
* Property B
|
||||
*/
|
||||
b?: string;
|
||||
}
|
||||
|
||||
export interface FuncWithAllOptionalInputsResult {
|
||||
readonly r: string;
|
||||
}
|
||||
|
||||
export function funcWithAllOptionalInputsOutput(args?: FuncWithAllOptionalInputsOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<FuncWithAllOptionalInputsResult> {
|
||||
return pulumi.output(args).apply(a => funcWithAllOptionalInputs(a, opts))
|
||||
}
|
||||
|
||||
export interface FuncWithAllOptionalInputsOutputArgs {
|
||||
/**
|
||||
* Property A
|
||||
*/
|
||||
a?: pulumi.Input<string>;
|
||||
/**
|
||||
* Property B
|
||||
*/
|
||||
b?: pulumi.Input<string>;
|
||||
}
|
27
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithConstInput.ts
vendored
Normal file
27
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithConstInput.ts
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* Codegen demo with const inputs
|
||||
*/
|
||||
export function funcWithConstInput(args?: FuncWithConstInputArgs, opts?: pulumi.InvokeOptions): Promise<void> {
|
||||
args = args || {};
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::funcWithConstInput", {
|
||||
"plainInput": args.plainInput,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface FuncWithConstInputArgs {
|
||||
plainInput?: "fixed";
|
||||
}
|
41
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithDefaultValue.ts
vendored
Normal file
41
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithDefaultValue.ts
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* Check codegen of functions with default values.
|
||||
*/
|
||||
export function funcWithDefaultValue(args: FuncWithDefaultValueArgs, opts?: pulumi.InvokeOptions): Promise<FuncWithDefaultValueResult> {
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::funcWithDefaultValue", {
|
||||
"a": args.a,
|
||||
"b": args.b,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface FuncWithDefaultValueArgs {
|
||||
a: string;
|
||||
b?: string;
|
||||
}
|
||||
|
||||
export interface FuncWithDefaultValueResult {
|
||||
readonly r: string;
|
||||
}
|
||||
|
||||
export function funcWithDefaultValueOutput(args: FuncWithDefaultValueOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<FuncWithDefaultValueResult> {
|
||||
return pulumi.output(args).apply(a => funcWithDefaultValue(a, opts))
|
||||
}
|
||||
|
||||
export interface FuncWithDefaultValueOutputArgs {
|
||||
a: pulumi.Input<string>;
|
||||
b?: pulumi.Input<string>;
|
||||
}
|
42
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithDictParam.ts
vendored
Normal file
42
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithDictParam.ts
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* Check codegen of functions with a Dict<str,str> parameter.
|
||||
*/
|
||||
export function funcWithDictParam(args?: FuncWithDictParamArgs, opts?: pulumi.InvokeOptions): Promise<FuncWithDictParamResult> {
|
||||
args = args || {};
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::funcWithDictParam", {
|
||||
"a": args.a,
|
||||
"b": args.b,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface FuncWithDictParamArgs {
|
||||
a?: {[key: string]: string};
|
||||
b?: string;
|
||||
}
|
||||
|
||||
export interface FuncWithDictParamResult {
|
||||
readonly r: string;
|
||||
}
|
||||
|
||||
export function funcWithDictParamOutput(args?: FuncWithDictParamOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<FuncWithDictParamResult> {
|
||||
return pulumi.output(args).apply(a => funcWithDictParam(a, opts))
|
||||
}
|
||||
|
||||
export interface FuncWithDictParamOutputArgs {
|
||||
a?: pulumi.Input<{[key: string]: pulumi.Input<string>}>;
|
||||
b?: pulumi.Input<string>;
|
||||
}
|
42
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithListParam.ts
vendored
Normal file
42
pkg/codegen/internal/test/testdata/output-funcs/nodejs/funcWithListParam.ts
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* Check codegen of functions with a List parameter.
|
||||
*/
|
||||
export function funcWithListParam(args?: FuncWithListParamArgs, opts?: pulumi.InvokeOptions): Promise<FuncWithListParamResult> {
|
||||
args = args || {};
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::funcWithListParam", {
|
||||
"a": args.a,
|
||||
"b": args.b,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface FuncWithListParamArgs {
|
||||
a?: string[];
|
||||
b?: string;
|
||||
}
|
||||
|
||||
export interface FuncWithListParamResult {
|
||||
readonly r: string;
|
||||
}
|
||||
|
||||
export function funcWithListParamOutput(args?: FuncWithListParamOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<FuncWithListParamResult> {
|
||||
return pulumi.output(args).apply(a => funcWithListParam(a, opts))
|
||||
}
|
||||
|
||||
export interface FuncWithListParamOutputArgs {
|
||||
a?: pulumi.Input<pulumi.Input<string>[]>;
|
||||
b?: pulumi.Input<string>;
|
||||
}
|
43
pkg/codegen/internal/test/testdata/output-funcs/nodejs/getClientConfig.ts
vendored
Normal file
43
pkg/codegen/internal/test/testdata/output-funcs/nodejs/getClientConfig.ts
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* Failing example taken from azure-native. Original doc: Use this function to access the current configuration of the native Azure provider.
|
||||
*/
|
||||
export function getClientConfig(opts?: pulumi.InvokeOptions): Promise<GetClientConfigResult> {
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::getClientConfig", {
|
||||
}, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration values returned by getClientConfig.
|
||||
*/
|
||||
export interface GetClientConfigResult {
|
||||
/**
|
||||
* Azure Client ID (Application Object ID).
|
||||
*/
|
||||
readonly clientId: string;
|
||||
/**
|
||||
* Azure Object ID of the current user or service principal.
|
||||
*/
|
||||
readonly objectId: string;
|
||||
/**
|
||||
* Azure Subscription ID
|
||||
*/
|
||||
readonly subscriptionId: string;
|
||||
/**
|
||||
* Azure Tenant ID
|
||||
*/
|
||||
readonly tenantId: string;
|
||||
}
|
82
pkg/codegen/internal/test/testdata/output-funcs/nodejs/getIntegrationRuntimeObjectMetadatum.ts
vendored
Normal file
82
pkg/codegen/internal/test/testdata/output-funcs/nodejs/getIntegrationRuntimeObjectMetadatum.ts
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* Another failing example. A list of SSIS object metadata.
|
||||
* API Version: 2018-06-01.
|
||||
*/
|
||||
export function getIntegrationRuntimeObjectMetadatum(args: GetIntegrationRuntimeObjectMetadatumArgs, opts?: pulumi.InvokeOptions): Promise<GetIntegrationRuntimeObjectMetadatumResult> {
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::getIntegrationRuntimeObjectMetadatum", {
|
||||
"factoryName": args.factoryName,
|
||||
"integrationRuntimeName": args.integrationRuntimeName,
|
||||
"metadataPath": args.metadataPath,
|
||||
"resourceGroupName": args.resourceGroupName,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface GetIntegrationRuntimeObjectMetadatumArgs {
|
||||
/**
|
||||
* The factory name.
|
||||
*/
|
||||
factoryName: string;
|
||||
/**
|
||||
* The integration runtime name.
|
||||
*/
|
||||
integrationRuntimeName: string;
|
||||
/**
|
||||
* Metadata path.
|
||||
*/
|
||||
metadataPath?: string;
|
||||
/**
|
||||
* The resource group name.
|
||||
*/
|
||||
resourceGroupName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of SSIS object metadata.
|
||||
*/
|
||||
export interface GetIntegrationRuntimeObjectMetadatumResult {
|
||||
/**
|
||||
* The link to the next page of results, if any remaining results exist.
|
||||
*/
|
||||
readonly nextLink?: string;
|
||||
/**
|
||||
* List of SSIS object metadata.
|
||||
*/
|
||||
readonly value?: outputs.SsisEnvironmentResponse | outputs.SsisFolderResponse | outputs.SsisPackageResponse | outputs.SsisProjectResponse[];
|
||||
}
|
||||
|
||||
export function getIntegrationRuntimeObjectMetadatumOutput(args: GetIntegrationRuntimeObjectMetadatumOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<GetIntegrationRuntimeObjectMetadatumResult> {
|
||||
return pulumi.output(args).apply(a => getIntegrationRuntimeObjectMetadatum(a, opts))
|
||||
}
|
||||
|
||||
export interface GetIntegrationRuntimeObjectMetadatumOutputArgs {
|
||||
/**
|
||||
* The factory name.
|
||||
*/
|
||||
factoryName: pulumi.Input<string>;
|
||||
/**
|
||||
* The integration runtime name.
|
||||
*/
|
||||
integrationRuntimeName: pulumi.Input<string>;
|
||||
/**
|
||||
* Metadata path.
|
||||
*/
|
||||
metadataPath?: pulumi.Input<string>;
|
||||
/**
|
||||
* The resource group name.
|
||||
*/
|
||||
resourceGroupName: pulumi.Input<string>;
|
||||
}
|
35
pkg/codegen/internal/test/testdata/output-funcs/nodejs/index.ts
vendored
Normal file
35
pkg/codegen/internal/test/testdata/output-funcs/nodejs/index.ts
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
// Export members:
|
||||
export * from "./funcWithAllOptionalInputs";
|
||||
export * from "./funcWithConstInput";
|
||||
export * from "./funcWithDefaultValue";
|
||||
export * from "./funcWithDictParam";
|
||||
export * from "./funcWithListParam";
|
||||
export * from "./getClientConfig";
|
||||
export * from "./getIntegrationRuntimeObjectMetadatum";
|
||||
export * from "./listStorageAccountKeys";
|
||||
export * from "./provider";
|
||||
|
||||
// Export sub-modules:
|
||||
import * as types from "./types";
|
||||
|
||||
export {
|
||||
types,
|
||||
};
|
||||
|
||||
import { Provider } from "./provider";
|
||||
|
||||
pulumi.runtime.registerResourcePackage("mypkg", {
|
||||
version: utilities.getVersion(),
|
||||
constructProvider: (name: string, type: string, urn: string): pulumi.ProviderResource => {
|
||||
if (type !== "pulumi:providers:mypkg") {
|
||||
throw new Error(`unknown provider type ${type}`);
|
||||
}
|
||||
return new Provider(name, <any>undefined, { urn });
|
||||
},
|
||||
});
|
69
pkg/codegen/internal/test/testdata/output-funcs/nodejs/listStorageAccountKeys.ts
vendored
Normal file
69
pkg/codegen/internal/test/testdata/output-funcs/nodejs/listStorageAccountKeys.ts
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
/**
|
||||
* The response from the ListKeys operation.
|
||||
* API Version: 2021-02-01.
|
||||
*/
|
||||
export function listStorageAccountKeys(args: ListStorageAccountKeysArgs, opts?: pulumi.InvokeOptions): Promise<ListStorageAccountKeysResult> {
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("mypkg::listStorageAccountKeys", {
|
||||
"accountName": args.accountName,
|
||||
"expand": args.expand,
|
||||
"resourceGroupName": args.resourceGroupName,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface ListStorageAccountKeysArgs {
|
||||
/**
|
||||
* The name of the storage account within the specified resource group. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
*/
|
||||
accountName: string;
|
||||
/**
|
||||
* Specifies type of the key to be listed. Possible value is kerb.
|
||||
*/
|
||||
expand?: string;
|
||||
/**
|
||||
* The name of the resource group within the user's subscription. The name is case insensitive.
|
||||
*/
|
||||
resourceGroupName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The response from the ListKeys operation.
|
||||
*/
|
||||
export interface ListStorageAccountKeysResult {
|
||||
/**
|
||||
* Gets the list of storage account keys and their properties for the specified storage account.
|
||||
*/
|
||||
readonly keys: outputs.StorageAccountKeyResponse[];
|
||||
}
|
||||
|
||||
export function listStorageAccountKeysOutput(args: ListStorageAccountKeysOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<ListStorageAccountKeysResult> {
|
||||
return pulumi.output(args).apply(a => listStorageAccountKeys(a, opts))
|
||||
}
|
||||
|
||||
export interface ListStorageAccountKeysOutputArgs {
|
||||
/**
|
||||
* The name of the storage account within the specified resource group. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
*/
|
||||
accountName: pulumi.Input<string>;
|
||||
/**
|
||||
* Specifies type of the key to be listed. Possible value is kerb.
|
||||
*/
|
||||
expand?: pulumi.Input<string>;
|
||||
/**
|
||||
* The name of the resource group within the user's subscription. The name is case insensitive.
|
||||
*/
|
||||
resourceGroupName: pulumi.Input<string>;
|
||||
}
|
19
pkg/codegen/internal/test/testdata/output-funcs/nodejs/package.json
vendored
Normal file
19
pkg/codegen/internal/test/testdata/output-funcs/nodejs/package.json
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "@pulumi/mypkg",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "mocha -r ts-node/register tests/**/*.spec.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pulumi/pulumi": "file:../../../../../../../sdk/nodejs/bin",
|
||||
"@types/mocha": "latest",
|
||||
"@types/node": "latest",
|
||||
"mocha": "latest",
|
||||
"ts-node": "latest",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"pulumi": {
|
||||
"resource": true
|
||||
}
|
||||
}
|
46
pkg/codegen/internal/test/testdata/output-funcs/nodejs/provider.ts
vendored
Normal file
46
pkg/codegen/internal/test/testdata/output-funcs/nodejs/provider.ts
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
export class Provider extends pulumi.ProviderResource {
|
||||
/** @internal */
|
||||
public static readonly __pulumiType = 'mypkg';
|
||||
|
||||
/**
|
||||
* Returns true if the given object is an instance of Provider. This is designed to work even
|
||||
* when multiple copies of the Pulumi SDK have been loaded into the same process.
|
||||
*/
|
||||
public static isInstance(obj: any): obj is Provider {
|
||||
if (obj === undefined || obj === null) {
|
||||
return false;
|
||||
}
|
||||
return obj['__pulumiType'] === Provider.__pulumiType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a Provider resource with the given unique name, arguments, and options.
|
||||
*
|
||||
* @param name The _unique_ name of the resource.
|
||||
* @param args The arguments to use to populate this resource's properties.
|
||||
* @param opts A bag of options that control this resource's behavior.
|
||||
*/
|
||||
constructor(name: string, args?: ProviderArgs, opts?: pulumi.ResourceOptions) {
|
||||
let inputs: pulumi.Inputs = {};
|
||||
opts = opts || {};
|
||||
{
|
||||
}
|
||||
if (!opts.version) {
|
||||
opts = pulumi.mergeOptions(opts, { version: utilities.getVersion()});
|
||||
}
|
||||
super(Provider.__pulumiType, name, inputs, opts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of arguments for constructing a Provider resource.
|
||||
*/
|
||||
export interface ProviderArgs {
|
||||
}
|
32
pkg/codegen/internal/test/testdata/output-funcs/nodejs/tsconfig.json
vendored
Normal file
32
pkg/codegen/internal/test/testdata/output-funcs/nodejs/tsconfig.json
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "bin",
|
||||
"target": "es2016",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"declaration": true,
|
||||
"sourceMap": true,
|
||||
"stripInternal": true,
|
||||
"experimentalDecorators": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true
|
||||
},
|
||||
"files": [
|
||||
"funcWithAllOptionalInputs.ts",
|
||||
"funcWithConstInput.ts",
|
||||
"funcWithDefaultValue.ts",
|
||||
"funcWithDictParam.ts",
|
||||
"funcWithListParam.ts",
|
||||
"getClientConfig.ts",
|
||||
"getIntegrationRuntimeObjectMetadatum.ts",
|
||||
"index.ts",
|
||||
"listStorageAccountKeys.ts",
|
||||
"provider.ts",
|
||||
"tests/codegen.spec.ts",
|
||||
"types/index.ts",
|
||||
"types/input.ts",
|
||||
"types/output.ts",
|
||||
"utilities.ts"
|
||||
]
|
||||
}
|
11
pkg/codegen/internal/test/testdata/output-funcs/nodejs/types/index.ts
vendored
Normal file
11
pkg/codegen/internal/test/testdata/output-funcs/nodejs/types/index.ts
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
// Export sub-modules:
|
||||
import * as input from "./input";
|
||||
import * as output from "./output";
|
||||
|
||||
export {
|
||||
input,
|
||||
output,
|
||||
};
|
6
pkg/codegen/internal/test/testdata/output-funcs/nodejs/types/input.ts
vendored
Normal file
6
pkg/codegen/internal/test/testdata/output-funcs/nodejs/types/input.ts
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "../types";
|
||||
|
270
pkg/codegen/internal/test/testdata/output-funcs/nodejs/types/output.ts
vendored
Normal file
270
pkg/codegen/internal/test/testdata/output-funcs/nodejs/types/output.ts
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "../types";
|
||||
|
||||
/**
|
||||
* Ssis environment reference.
|
||||
*/
|
||||
export interface SsisEnvironmentReferenceResponse {
|
||||
/**
|
||||
* Environment folder name.
|
||||
*/
|
||||
environmentFolderName?: string;
|
||||
/**
|
||||
* Environment name.
|
||||
*/
|
||||
environmentName?: string;
|
||||
/**
|
||||
* Environment reference id.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Reference type
|
||||
*/
|
||||
referenceType?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ssis environment.
|
||||
*/
|
||||
export interface SsisEnvironmentResponse {
|
||||
/**
|
||||
* Metadata description.
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* Folder id which contains environment.
|
||||
*/
|
||||
folderId?: number;
|
||||
/**
|
||||
* Metadata id.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Metadata name.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* The type of SSIS object metadata.
|
||||
* Expected value is 'Environment'.
|
||||
*/
|
||||
type: "Environment";
|
||||
/**
|
||||
* Variable in environment
|
||||
*/
|
||||
variables?: outputs.SsisVariableResponse[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ssis folder.
|
||||
*/
|
||||
export interface SsisFolderResponse {
|
||||
/**
|
||||
* Metadata description.
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* Metadata id.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Metadata name.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* The type of SSIS object metadata.
|
||||
* Expected value is 'Folder'.
|
||||
*/
|
||||
type: "Folder";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ssis Package.
|
||||
*/
|
||||
export interface SsisPackageResponse {
|
||||
/**
|
||||
* Metadata description.
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* Folder id which contains package.
|
||||
*/
|
||||
folderId?: number;
|
||||
/**
|
||||
* Metadata id.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Metadata name.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Parameters in package
|
||||
*/
|
||||
parameters?: outputs.SsisParameterResponse[];
|
||||
/**
|
||||
* Project id which contains package.
|
||||
*/
|
||||
projectId?: number;
|
||||
/**
|
||||
* Project version which contains package.
|
||||
*/
|
||||
projectVersion?: number;
|
||||
/**
|
||||
* The type of SSIS object metadata.
|
||||
* Expected value is 'Package'.
|
||||
*/
|
||||
type: "Package";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ssis parameter.
|
||||
*/
|
||||
export interface SsisParameterResponse {
|
||||
/**
|
||||
* Parameter type.
|
||||
*/
|
||||
dataType?: string;
|
||||
/**
|
||||
* Default value of parameter.
|
||||
*/
|
||||
defaultValue?: string;
|
||||
/**
|
||||
* Parameter description.
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* Design default value of parameter.
|
||||
*/
|
||||
designDefaultValue?: string;
|
||||
/**
|
||||
* Parameter id.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Parameter name.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Whether parameter is required.
|
||||
*/
|
||||
required?: boolean;
|
||||
/**
|
||||
* Whether parameter is sensitive.
|
||||
*/
|
||||
sensitive?: boolean;
|
||||
/**
|
||||
* Default sensitive value of parameter.
|
||||
*/
|
||||
sensitiveDefaultValue?: string;
|
||||
/**
|
||||
* Parameter value set.
|
||||
*/
|
||||
valueSet?: boolean;
|
||||
/**
|
||||
* Parameter value type.
|
||||
*/
|
||||
valueType?: string;
|
||||
/**
|
||||
* Parameter reference variable.
|
||||
*/
|
||||
variable?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ssis project.
|
||||
*/
|
||||
export interface SsisProjectResponse {
|
||||
/**
|
||||
* Metadata description.
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* Environment reference in project
|
||||
*/
|
||||
environmentRefs?: outputs.SsisEnvironmentReferenceResponse[];
|
||||
/**
|
||||
* Folder id which contains project.
|
||||
*/
|
||||
folderId?: number;
|
||||
/**
|
||||
* Metadata id.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Metadata name.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Parameters in project
|
||||
*/
|
||||
parameters?: outputs.SsisParameterResponse[];
|
||||
/**
|
||||
* The type of SSIS object metadata.
|
||||
* Expected value is 'Project'.
|
||||
*/
|
||||
type: "Project";
|
||||
/**
|
||||
* Project version.
|
||||
*/
|
||||
version?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ssis variable.
|
||||
*/
|
||||
export interface SsisVariableResponse {
|
||||
/**
|
||||
* Variable type.
|
||||
*/
|
||||
dataType?: string;
|
||||
/**
|
||||
* Variable description.
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* Variable id.
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* Variable name.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Whether variable is sensitive.
|
||||
*/
|
||||
sensitive?: boolean;
|
||||
/**
|
||||
* Variable sensitive value.
|
||||
*/
|
||||
sensitiveValue?: string;
|
||||
/**
|
||||
* Variable value.
|
||||
*/
|
||||
value?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* An access key for the storage account.
|
||||
*/
|
||||
export interface StorageAccountKeyResponse {
|
||||
/**
|
||||
* Creation time of the key, in round trip date format.
|
||||
*/
|
||||
creationTime: string;
|
||||
/**
|
||||
* Name of the key.
|
||||
*/
|
||||
keyName: string;
|
||||
/**
|
||||
* Permissions for the key -- read-only or full permissions.
|
||||
*/
|
||||
permissions: string;
|
||||
/**
|
||||
* Base 64-encoded value of the key.
|
||||
*/
|
||||
value: string;
|
||||
}
|
||||
|
49
pkg/codegen/internal/test/testdata/output-funcs/nodejs/utilities.ts
vendored
Normal file
49
pkg/codegen/internal/test/testdata/output-funcs/nodejs/utilities.ts
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
|
||||
export function getEnv(...vars: string[]): string | undefined {
|
||||
for (const v of vars) {
|
||||
const value = process.env[v];
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getEnvBoolean(...vars: string[]): boolean | undefined {
|
||||
const s = getEnv(...vars);
|
||||
if (s !== undefined) {
|
||||
// NOTE: these values are taken from https://golang.org/src/strconv/atob.go?s=351:391#L1, which is what
|
||||
// Terraform uses internally when parsing boolean values.
|
||||
if (["1", "t", "T", "true", "TRUE", "True"].find(v => v === s) !== undefined) {
|
||||
return true;
|
||||
}
|
||||
if (["0", "f", "F", "false", "FALSE", "False"].find(v => v === s) !== undefined) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getEnvNumber(...vars: string[]): number | undefined {
|
||||
const s = getEnv(...vars);
|
||||
if (s !== undefined) {
|
||||
const f = parseFloat(s);
|
||||
if (!isNaN(f)) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getVersion(): string {
|
||||
let version = require('./package.json').version;
|
||||
// Node allows for the version to be prefixed by a "v", while semver doesn't.
|
||||
// If there is a v, strip it off.
|
||||
if (version.indexOf('v') === 0) {
|
||||
version = version.slice(1);
|
||||
}
|
||||
return version;
|
||||
}
|
591
pkg/codegen/internal/test/testdata/output-funcs/schema.json
vendored
Normal file
591
pkg/codegen/internal/test/testdata/output-funcs/schema.json
vendored
Normal file
|
@ -0,0 +1,591 @@
|
|||
{
|
||||
"name": "mypkg",
|
||||
"version": "0.0.1",
|
||||
"functions": {
|
||||
"mypkg::funcWithAllOptionalInputs": {
|
||||
"description": "Check codegen of functions with all optional inputs.",
|
||||
"inputs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"a": {
|
||||
"type": "string",
|
||||
"description": "Property A"
|
||||
},
|
||||
"b": {
|
||||
"type": "string",
|
||||
"description": "Property B"
|
||||
}
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"properties": {
|
||||
"r": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"r"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mypkg::funcWithConstInput": {
|
||||
"description": "Codegen demo with const inputs",
|
||||
"inputs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"plainInput": {
|
||||
"type": "string",
|
||||
"const": "fixed"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mypkg::funcWithDefaultValue": {
|
||||
"description": "Check codegen of functions with default values.",
|
||||
"inputs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"a"
|
||||
],
|
||||
"properties": {
|
||||
"a": {
|
||||
"type": "string"
|
||||
},
|
||||
"b": {
|
||||
"type": "string",
|
||||
"default": "b-default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"properties": {
|
||||
"r": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"r"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mypkg::funcWithDictParam": {
|
||||
"description": "Check codegen of functions with a Dict<str,str> parameter.",
|
||||
"inputs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"a": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"b": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"properties": {
|
||||
"r": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"r"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mypkg::funcWithListParam": {
|
||||
"description": "Check codegen of functions with a List parameter.",
|
||||
"inputs": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"a": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"b": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"properties": {
|
||||
"r": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"r"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mypkg::getClientConfig": {
|
||||
"description": "Failing example taken from azure-native. Original doc: Use this function to access the current configuration of the native Azure provider.",
|
||||
"outputs": {
|
||||
"description": "Configuration values returned by getClientConfig.",
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": "string",
|
||||
"description": "Azure Client ID (Application Object ID)."
|
||||
},
|
||||
"objectId": {
|
||||
"type": "string",
|
||||
"description": "Azure Object ID of the current user or service principal."
|
||||
},
|
||||
"subscriptionId": {
|
||||
"type": "string",
|
||||
"description": "Azure Subscription ID"
|
||||
},
|
||||
"tenantId": {
|
||||
"type": "string",
|
||||
"description": "Azure Tenant ID"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientId",
|
||||
"objectId",
|
||||
"subscriptionId",
|
||||
"tenantId"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mypkg::getIntegrationRuntimeObjectMetadatum": {
|
||||
"description": "Another failing example. A list of SSIS object metadata.\nAPI Version: 2018-06-01.",
|
||||
"inputs": {
|
||||
"properties": {
|
||||
"factoryName": {
|
||||
"type": "string",
|
||||
"description": "The factory name."
|
||||
},
|
||||
"integrationRuntimeName": {
|
||||
"type": "string",
|
||||
"description": "The integration runtime name."
|
||||
},
|
||||
"metadataPath": {
|
||||
"type": "string",
|
||||
"description": "Metadata path."
|
||||
},
|
||||
"resourceGroupName": {
|
||||
"type": "string",
|
||||
"description": "The resource group name."
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"factoryName",
|
||||
"integrationRuntimeName",
|
||||
"resourceGroupName"
|
||||
]
|
||||
},
|
||||
"outputs": {
|
||||
"description": "A list of SSIS object metadata.",
|
||||
"properties": {
|
||||
"nextLink": {
|
||||
"type": "string",
|
||||
"description": "The link to the next page of results, if any remaining results exist."
|
||||
},
|
||||
"value": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisEnvironmentResponse"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisFolderResponse"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisPackageResponse"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisProjectResponse"
|
||||
}
|
||||
],
|
||||
"discriminator": {
|
||||
"propertyName": "type",
|
||||
"mapping": {
|
||||
"Environment": "#/types/mypkg::SsisEnvironmentResponse",
|
||||
"Folder": "#/types/mypkg::SsisFolderResponse",
|
||||
"Package": "#/types/mypkg::SsisPackageResponse",
|
||||
"Project": "#/types/mypkg::SsisProjectResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "List of SSIS object metadata."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"mypkg::listStorageAccountKeys": {
|
||||
"description": "The response from the ListKeys operation.\nAPI Version: 2021-02-01.",
|
||||
"inputs": {
|
||||
"properties": {
|
||||
"accountName": {
|
||||
"type": "string",
|
||||
"description": "The name of the storage account within the specified resource group. Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only."
|
||||
},
|
||||
"expand": {
|
||||
"type": "string",
|
||||
"description": "Specifies type of the key to be listed. Possible value is kerb."
|
||||
},
|
||||
"resourceGroupName": {
|
||||
"type": "string",
|
||||
"description": "The name of the resource group within the user's subscription. The name is case insensitive."
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"accountName",
|
||||
"resourceGroupName"
|
||||
]
|
||||
},
|
||||
"outputs": {
|
||||
"description": "The response from the ListKeys operation.",
|
||||
"properties": {
|
||||
"keys": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::StorageAccountKeyResponse"
|
||||
},
|
||||
"description": "Gets the list of storage account keys and their properties for the specified storage account."
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"keys"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"types": {
|
||||
"mypkg::SsisEnvironmentResponse": {
|
||||
"description": "Ssis environment.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Metadata description."
|
||||
},
|
||||
"folderId": {
|
||||
"type": "number",
|
||||
"description": "Folder id which contains environment."
|
||||
},
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Metadata id."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Metadata name."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The type of SSIS object metadata.\nExpected value is 'Environment'.",
|
||||
"const": "Environment"
|
||||
},
|
||||
"variables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisVariableResponse"
|
||||
},
|
||||
"description": "Variable in environment"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"mypkg::SsisFolderResponse": {
|
||||
"description": "Ssis folder.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Metadata description."
|
||||
},
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Metadata id."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Metadata name."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The type of SSIS object metadata.\nExpected value is 'Folder'.",
|
||||
"const": "Folder"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"mypkg::SsisPackageResponse": {
|
||||
"description": "Ssis Package.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Metadata description."
|
||||
},
|
||||
"folderId": {
|
||||
"type": "number",
|
||||
"description": "Folder id which contains package."
|
||||
},
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Metadata id."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Metadata name."
|
||||
},
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisParameterResponse"
|
||||
},
|
||||
"description": "Parameters in package"
|
||||
},
|
||||
"projectId": {
|
||||
"type": "number",
|
||||
"description": "Project id which contains package."
|
||||
},
|
||||
"projectVersion": {
|
||||
"type": "number",
|
||||
"description": "Project version which contains package."
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The type of SSIS object metadata.\nExpected value is 'Package'.",
|
||||
"const": "Package"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"mypkg::SsisProjectResponse": {
|
||||
"description": "Ssis project.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Metadata description."
|
||||
},
|
||||
"environmentRefs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisEnvironmentReferenceResponse"
|
||||
},
|
||||
"description": "Environment reference in project"
|
||||
},
|
||||
"folderId": {
|
||||
"type": "number",
|
||||
"description": "Folder id which contains project."
|
||||
},
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Metadata id."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Metadata name."
|
||||
},
|
||||
"parameters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/types/mypkg::SsisParameterResponse"
|
||||
},
|
||||
"description": "Parameters in project"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "The type of SSIS object metadata.\nExpected value is 'Project'.",
|
||||
"const": "Project"
|
||||
},
|
||||
"version": {
|
||||
"type": "number",
|
||||
"description": "Project version."
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"mypkg::SsisEnvironmentReferenceResponse": {
|
||||
"description": "Ssis environment reference.",
|
||||
"properties": {
|
||||
"environmentFolderName": {
|
||||
"type": "string",
|
||||
"description": "Environment folder name."
|
||||
},
|
||||
"environmentName": {
|
||||
"type": "string",
|
||||
"description": "Environment name."
|
||||
},
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Environment reference id."
|
||||
},
|
||||
"referenceType": {
|
||||
"type": "string",
|
||||
"description": "Reference type"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"mypkg::SsisParameterResponse": {
|
||||
"description": "Ssis parameter.",
|
||||
"properties": {
|
||||
"dataType": {
|
||||
"type": "string",
|
||||
"description": "Parameter type."
|
||||
},
|
||||
"defaultValue": {
|
||||
"type": "string",
|
||||
"description": "Default value of parameter."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Parameter description."
|
||||
},
|
||||
"designDefaultValue": {
|
||||
"type": "string",
|
||||
"description": "Design default value of parameter."
|
||||
},
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Parameter id."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Parameter name."
|
||||
},
|
||||
"required": {
|
||||
"type": "boolean",
|
||||
"description": "Whether parameter is required."
|
||||
},
|
||||
"sensitive": {
|
||||
"type": "boolean",
|
||||
"description": "Whether parameter is sensitive."
|
||||
},
|
||||
"sensitiveDefaultValue": {
|
||||
"type": "string",
|
||||
"description": "Default sensitive value of parameter."
|
||||
},
|
||||
"valueSet": {
|
||||
"type": "boolean",
|
||||
"description": "Parameter value set."
|
||||
},
|
||||
"valueType": {
|
||||
"type": "string",
|
||||
"description": "Parameter value type."
|
||||
},
|
||||
"variable": {
|
||||
"type": "string",
|
||||
"description": "Parameter reference variable."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"mypkg::SsisVariableResponse": {
|
||||
"description": "Ssis variable.",
|
||||
"properties": {
|
||||
"dataType": {
|
||||
"type": "string",
|
||||
"description": "Variable type."
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Variable description."
|
||||
},
|
||||
"id": {
|
||||
"type": "number",
|
||||
"description": "Variable id."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Variable name."
|
||||
},
|
||||
"sensitive": {
|
||||
"type": "boolean",
|
||||
"description": "Whether variable is sensitive."
|
||||
},
|
||||
"sensitiveValue": {
|
||||
"type": "string",
|
||||
"description": "Variable sensitive value."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Variable value."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"mypkg::StorageAccountKeyResponse": {
|
||||
"description": "An access key for the storage account.",
|
||||
"properties": {
|
||||
"creationTime": {
|
||||
"type": "string",
|
||||
"description": "Creation time of the key, in round trip date format."
|
||||
},
|
||||
"keyName": {
|
||||
"type": "string",
|
||||
"description": "Name of the key."
|
||||
},
|
||||
"permissions": {
|
||||
"type": "string",
|
||||
"description": "Permissions for the key -- read-only or full permissions."
|
||||
},
|
||||
"value": {
|
||||
"type": "string",
|
||||
"description": "Base 64-encoded value of the key."
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"creationTime",
|
||||
"keyName",
|
||||
"permissions",
|
||||
"value"
|
||||
]
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"nodejs": {
|
||||
"devDependencies": {
|
||||
"@types/mocha": "latest",
|
||||
"@types/node": "latest",
|
||||
"mocha": "latest",
|
||||
"ts-node": "latest",
|
||||
"@pulumi/pulumi": "file:../../../../../../../sdk/nodejs/bin"
|
||||
},
|
||||
"extraTypeScriptFiles": [
|
||||
"tests/codegen.spec.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "mocha -r ts-node/register tests/**/*.spec.ts"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package main
|
||||
package tests
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/resource-args-python/go/example"
|
||||
"resource-args-python/example"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
186
pkg/codegen/internal/test/testdata/simple-enum-schema/go-extras/tests/go_test.go
vendored
Normal file
186
pkg/codegen/internal/test/testdata/simple-enum-schema/go-extras/tests/go_test.go
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
|
||||
"simple-enum-schema/plant"
|
||||
tree "simple-enum-schema/plant/tree/v1"
|
||||
)
|
||||
|
||||
func TestEnumUsage(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: &plant.ContainerArgs{
|
||||
Color: plant.ContainerColorRed,
|
||||
Material: pulumi.String("ceramic"),
|
||||
Size: plant.ContainerSizeFourInch,
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us,
|
||||
Type: tree.RubberTreeVarietyRuby,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Container.Brightness(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
brightness := all[4].(*plant.ContainerBrightness)
|
||||
typ := all[5].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "red", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSizeFourInch, "unexpected size on resource: %v", urn)
|
||||
assert.Nil(t, brightness)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyRuby, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(0))))
|
||||
})
|
||||
|
||||
t.Run("StringsForRelaxedEnum", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: plant.ContainerArgs{
|
||||
Color: pulumi.String("Magenta"),
|
||||
Material: pulumi.String("ceramic"),
|
||||
Size: plant.ContainerSize(22),
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us,
|
||||
Type: tree.RubberTreeVarietyRuby,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
typ := all[4].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSize(22), "unexpected size on resource: %v", urn)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyRuby, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(1))))
|
||||
})
|
||||
|
||||
t.Run("StringsForStrictEnum", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: plant.ContainerArgs{
|
||||
Color: pulumi.String("Magenta"),
|
||||
Material: pulumi.String("ceramic"),
|
||||
Size: plant.ContainerSize(22),
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us,
|
||||
Type: tree.RubberTreeVarietyBurgundy,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
typ := all[4].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSize(22), "unexpected size on resource: %v", urn)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyBurgundy, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(1))))
|
||||
})
|
||||
|
||||
t.Run("EnumOutputs", func(t *testing.T) {
|
||||
require.NoError(t, pulumi.RunErr(func(ctx *pulumi.Context) error {
|
||||
rubberTree, err := tree.NewRubberTree(ctx, "blah", &tree.RubberTreeArgs{
|
||||
Container: plant.ContainerArgs{
|
||||
Color: plant.ContainerColor("Magenta").ToContainerColorOutput().ToStringOutput(),
|
||||
Material: pulumi.String("ceramic").ToStringOutput(),
|
||||
Size: plant.ContainerSize(22).ToContainerSizeOutput(),
|
||||
},
|
||||
Farm: tree.Farm_Plants_R_Us.ToFarmPtrOutput().ToStringPtrOutput(),
|
||||
Type: tree.RubberTreeVarietyBurgundy.ToRubberTreeVarietyOutput(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rubberTree)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
pulumi.All(
|
||||
rubberTree.URN(),
|
||||
rubberTree.Container.Material(),
|
||||
rubberTree.Container.Color(),
|
||||
rubberTree.Container.Size(),
|
||||
rubberTree.Type,
|
||||
).ApplyT(func(all []interface{}) error {
|
||||
urn := all[0].(pulumi.URN)
|
||||
material := all[1].(*string)
|
||||
color := all[2].(*string)
|
||||
size := all[3].(*plant.ContainerSize)
|
||||
typ := all[4].(tree.RubberTreeVariety)
|
||||
assert.Equal(t, *material, "ceramic", "unexpected material on resource: %v", urn)
|
||||
assert.Equal(t, *color, "Magenta", "unexpected color on resource: %v", urn)
|
||||
assert.Equal(t, *size, plant.ContainerSize(22), "unexpected size on resource: %v", urn)
|
||||
assert.Equal(t, typ, tree.RubberTreeVarietyBurgundy, "unexpected type on resource: %v", urn)
|
||||
wg.Done()
|
||||
return nil
|
||||
})
|
||||
wg.Wait()
|
||||
return nil
|
||||
}, pulumi.WithMocks("project", "stack", mocks(1))))
|
||||
})
|
||||
}
|
||||
|
||||
type mocks int
|
||||
|
||||
func (mocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) {
|
||||
return args.Name + "_id", args.Inputs, nil
|
||||
}
|
||||
|
||||
func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
|
||||
return args.Args, nil
|
||||
}
|
|
@ -7,8 +7,8 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
"simple-enum-schema/plant"
|
||||
)
|
||||
|
||||
type module struct {
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"reflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
"simple-enum-schema/plant"
|
||||
)
|
||||
|
||||
type RubberTree struct {
|
||||
|
|
|
@ -254,10 +254,7 @@
|
|||
}
|
||||
},
|
||||
"go": {
|
||||
"importBasePath": "github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant",
|
||||
"packageImportAliases": {
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test/testdata/simple-enum-schema/go/plant/tree/v1": "treev1"
|
||||
}
|
||||
"importBasePath": "simple-enum-schema/plant"
|
||||
},
|
||||
"nodejs": {
|
||||
"dependencies": {
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -28,3 +28,11 @@ export interface ArgFunctionArgs {
|
|||
export interface ArgFunctionResult {
|
||||
readonly result?: Resource;
|
||||
}
|
||||
|
||||
export function argFunctionOutput(args?: ArgFunctionOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<ArgFunctionResult> {
|
||||
return pulumi.output(args).apply(a => argFunction(a, opts))
|
||||
}
|
||||
|
||||
export interface ArgFunctionOutputArgs {
|
||||
arg1?: pulumi.Input<Resource>;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -28,3 +28,11 @@ export interface ArgFunctionArgs {
|
|||
export interface ArgFunctionResult {
|
||||
readonly result?: Resource;
|
||||
}
|
||||
|
||||
export function argFunctionOutput(args?: ArgFunctionOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<ArgFunctionResult> {
|
||||
return pulumi.output(args).apply(a => argFunction(a, opts))
|
||||
}
|
||||
|
||||
export interface ArgFunctionOutputArgs {
|
||||
arg1?: pulumi.Input<Resource>;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.1
|
||||
0.0.0
|
||||
|
|
|
@ -28,3 +28,11 @@ export interface ArgFunctionArgs {
|
|||
export interface ArgFunctionResult {
|
||||
readonly result?: Resource;
|
||||
}
|
||||
|
||||
export function argFunctionOutput(args?: ArgFunctionOutputArgs, opts?: pulumi.InvokeOptions): pulumi.Output<ArgFunctionResult> {
|
||||
return pulumi.output(args).apply(a => argFunction(a, opts))
|
||||
}
|
||||
|
||||
export interface ArgFunctionOutputArgs {
|
||||
arg1?: pulumi.Input<Resource>;
|
||||
}
|
||||
|
|
|
@ -870,28 +870,16 @@ func (mod *modContext) genFunction(w io.Writer, fun *schema.Function) {
|
|||
|
||||
// Now, emit the function signature.
|
||||
var argsig string
|
||||
argsOptional := true
|
||||
argsOptional := functionArgsOptional(fun)
|
||||
if fun.Inputs != nil {
|
||||
for _, p := range fun.Inputs.Properties {
|
||||
if p.IsRequired() {
|
||||
argsOptional = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
optFlag := ""
|
||||
if argsOptional {
|
||||
optFlag = "?"
|
||||
}
|
||||
argsig = fmt.Sprintf("args%s: %sArgs, ", optFlag, title(name))
|
||||
}
|
||||
var retty string
|
||||
if fun.Outputs == nil {
|
||||
retty = "void"
|
||||
} else {
|
||||
retty = title(name) + "Result"
|
||||
}
|
||||
fmt.Fprintf(w, "export function %s(%sopts?: pulumi.InvokeOptions): Promise<%s> {\n", name, argsig, retty)
|
||||
fmt.Fprintf(w, "export function %s(%sopts?: pulumi.InvokeOptions): Promise<%s> {\n",
|
||||
name, argsig, functionReturnType(fun))
|
||||
if fun.DeprecationMessage != "" && mod.compatibility != kubernetes20 {
|
||||
fmt.Fprintf(w, " pulumi.log.warn(\"%s is deprecated: %s\")\n", name, fun.DeprecationMessage)
|
||||
}
|
||||
|
@ -930,6 +918,67 @@ func (mod *modContext) genFunction(w io.Writer, fun *schema.Function) {
|
|||
fmt.Fprintf(w, "\n")
|
||||
mod.genPlainType(w, title(name)+"Result", fun.Outputs.Comment, fun.Outputs.Properties, false, true, 0)
|
||||
}
|
||||
|
||||
mod.genFunctionOutputVersion(w, fun)
|
||||
}
|
||||
|
||||
func functionArgsOptional(fun *schema.Function) bool {
|
||||
argsOptional := true
|
||||
if fun.Inputs != nil {
|
||||
for _, p := range fun.Inputs.Properties {
|
||||
if p.IsRequired() {
|
||||
argsOptional = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return argsOptional
|
||||
}
|
||||
|
||||
func functionReturnType(fun *schema.Function) string {
|
||||
name := tokenToFunctionName(fun.Token)
|
||||
var retty string
|
||||
if fun.Outputs == nil {
|
||||
retty = "void"
|
||||
} else {
|
||||
retty = title(name) + "Result"
|
||||
}
|
||||
return retty
|
||||
}
|
||||
|
||||
// Generates `function ${fn}Output(..)` version lifted to work on
|
||||
// `Input`-warpped arguments and producing an `Output`-wrapped result.
|
||||
func (mod *modContext) genFunctionOutputVersion(w io.Writer, fun *schema.Function) {
|
||||
if !fun.NeedsOutputVersion() {
|
||||
return
|
||||
}
|
||||
|
||||
originalName := tokenToFunctionName(fun.Token)
|
||||
fnOutput := fmt.Sprintf("%sOutput", originalName)
|
||||
argTypeName := fmt.Sprintf("%sArgs", title(fnOutput))
|
||||
|
||||
var argsig string
|
||||
argsOptional := functionArgsOptional(fun)
|
||||
optFlag := ""
|
||||
if argsOptional {
|
||||
optFlag = "?"
|
||||
}
|
||||
argsig = fmt.Sprintf("args%s: %s, ", optFlag, argTypeName)
|
||||
|
||||
fmt.Fprintf(w, `
|
||||
export function %s(%sopts?: pulumi.InvokeOptions): pulumi.Output<%s> {
|
||||
return pulumi.output(args).apply(a => %s(a, opts))
|
||||
}
|
||||
`, fnOutput, argsig, functionReturnType(fun), originalName)
|
||||
fmt.Fprintf(w, "\n")
|
||||
|
||||
mod.genPlainType(w,
|
||||
argTypeName,
|
||||
fun.Inputs.Comment,
|
||||
fun.Inputs.InputShape.Properties,
|
||||
true, /* input */
|
||||
false, /* readonly */
|
||||
0 /* level */)
|
||||
}
|
||||
|
||||
func visitObjectTypes(properties []*schema.Property, visitor func(*schema.ObjectType)) {
|
||||
|
@ -1796,22 +1845,30 @@ func genNPMPackageMetadata(pkg *schema.Package, info NodePackageInfo) string {
|
|||
packageVersion = pkg.Version.String()
|
||||
}
|
||||
|
||||
// Ideally, this `scripts` section would include an install
|
||||
// script that installs the provider, however, doing so causes
|
||||
// problems when we try to restore package dependencies, since
|
||||
// we must do an install for that. So we have another process
|
||||
// that adds the install script when generating the
|
||||
// package.json that we actually publish.
|
||||
scripts := map[string]string{
|
||||
"build": "tsc",
|
||||
}
|
||||
|
||||
for k, v := range info.Scripts {
|
||||
scripts[k] = v
|
||||
}
|
||||
|
||||
// Create info that will get serialized into an NPM package.json.
|
||||
npminfo := npmPackage{
|
||||
Name: packageName,
|
||||
Version: packageVersion,
|
||||
Description: info.PackageDescription,
|
||||
Keywords: pkg.Keywords,
|
||||
Homepage: pkg.Homepage,
|
||||
Repository: pkg.Repository,
|
||||
License: pkg.License,
|
||||
// Ideally, this `scripts` section would include an install script that installs the provider, however, doing
|
||||
// so causes problems when we try to restore package dependencies, since we must do an install for that. So
|
||||
// we have another process that adds the install script when generating the package.json that we actually
|
||||
// publish.
|
||||
Scripts: map[string]string{
|
||||
"build": "tsc",
|
||||
},
|
||||
Name: packageName,
|
||||
Version: packageVersion,
|
||||
Description: info.PackageDescription,
|
||||
Keywords: pkg.Keywords,
|
||||
Homepage: pkg.Homepage,
|
||||
Repository: pkg.Repository,
|
||||
License: pkg.License,
|
||||
Scripts: scripts,
|
||||
DevDependencies: devDependencies,
|
||||
Pulumi: npmPulumiManifest{
|
||||
Resource: true,
|
||||
|
@ -1890,6 +1947,8 @@ func genTypeScriptProjectFile(info NodePackageInfo, files fs) string {
|
|||
tsFiles = append(tsFiles, f)
|
||||
}
|
||||
}
|
||||
|
||||
tsFiles = append(tsFiles, info.ExtraTypeScriptFiles...)
|
||||
sort.Strings(tsFiles)
|
||||
|
||||
for i, file := range tsFiles {
|
||||
|
@ -2113,7 +2172,6 @@ func GeneratePackage(tool string, pkg *schema.Package, extraFiles map[string][]b
|
|||
}
|
||||
}
|
||||
|
||||
// Finally emit the package metadata (NPM, TypeScript, and so on).
|
||||
genPackageMetadata(pkg, info, files)
|
||||
return files, nil
|
||||
}
|
||||
|
|
|
@ -2,61 +2,32 @@
|
|||
package nodejs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/internal/test"
|
||||
"github.com/pulumi/pulumi/pkg/v3/codegen/schema"
|
||||
"github.com/pulumi/pulumi/pkg/v3/testing/integration"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/executable"
|
||||
)
|
||||
|
||||
func TestGeneratePackage(t *testing.T) {
|
||||
test.TestSDKCodegen(t, "nodejs", GeneratePackage, typeCheckGeneratedPackage)
|
||||
test.TestSDKCodegen(t, &test.SDKCodegenOptions{
|
||||
Language: "nodejs",
|
||||
GenPackage: GeneratePackage,
|
||||
Checks: map[string]test.CodegenCheck{
|
||||
"nodejs/compile": typeCheckGeneratedPackage,
|
||||
"nodejs/test": testGeneratedPackage,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func typeCheckGeneratedPackage(t *testing.T, pwd string) {
|
||||
var err error
|
||||
var npm string
|
||||
npm, err = executable.FindExecutable("npm")
|
||||
require.NoError(t, err)
|
||||
test.RunCommand(t, "npm_install", pwd, "npm", "install")
|
||||
test.RunCommand(t, "npm_build", pwd, "npm", "run", "build")
|
||||
}
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmdOptions := integration.ProgramTestOptions{
|
||||
Verbose: true,
|
||||
Stderr: &stderr,
|
||||
Stdout: &stdout,
|
||||
}
|
||||
|
||||
// TODO remove when https://github.com/pulumi/pulumi/pull/7938 lands
|
||||
file := filepath.Join(pwd, "package.json")
|
||||
oldFile, err := ioutil.ReadFile(file)
|
||||
require.NoError(t, err)
|
||||
newFile := strings.ReplaceAll(string(oldFile), "${VERSION}", "0.0.1")
|
||||
err = ioutil.WriteFile(file, []byte(newFile), 0600)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = integration.RunCommand(t, "npm install", []string{npm, "i"}, pwd, &cmdOptions)
|
||||
require.NoError(t, err)
|
||||
err = integration.RunCommand(t, "typecheck ts",
|
||||
[]string{filepath.Join(".", "node_modules", ".bin", "tsc"), "--noEmit"}, pwd, &cmdOptions)
|
||||
if err != nil {
|
||||
stderr := stderr.String()
|
||||
if len(stderr) > 0 {
|
||||
t.Logf("stderr: %s", stderr)
|
||||
}
|
||||
stdout := stdout.String()
|
||||
if len(stdout) > 0 {
|
||||
t.Logf("stdout: %s", stdout)
|
||||
}
|
||||
|
||||
}
|
||||
require.NoError(t, err)
|
||||
func testGeneratedPackage(t *testing.T, pwd string) {
|
||||
test.RunCommand(t, "npm_test", pwd, "npm", "run", "test")
|
||||
}
|
||||
|
||||
func TestGenerateTypeNames(t *testing.T) {
|
||||
|
|
|
@ -58,6 +58,16 @@ type NodePackageInfo struct {
|
|||
PluginName string `json:"pluginName,omitempty"`
|
||||
// The version of the plugin, which might be different from the version of the package..
|
||||
PluginVersion string `json:"pluginVersion,omitempty"`
|
||||
// Additional files to include in TypeScript compilation.
|
||||
// These paths are added to the `files` section of the
|
||||
// generated `tsconfig.json`. A typical use case for this is
|
||||
// compiling hand-authored unit test files that check the
|
||||
// generated code.
|
||||
ExtraTypeScriptFiles []string `json:"extraTypeScriptFiles,omitempty"`
|
||||
// NPM script definitions. These define the `scripts` property
|
||||
// of the generated `package.json`. See also:
|
||||
// https://docs.npmjs.com/cli/v7/using-npm/scripts
|
||||
Scripts map[string]string `json:"scripts,omitempty"`
|
||||
}
|
||||
|
||||
// NodeObjectInfo contains NodeJS-specific information for an object.
|
||||
|
|
|
@ -59,21 +59,27 @@ func TestRelPathToRelImport(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGeneratePackage(t *testing.T) {
|
||||
test.TestSDKCodegen(t, "python", GeneratePackage, typeCheckGeneratedPackage)
|
||||
test.TestSDKCodegen(t, &test.SDKCodegenOptions{
|
||||
Language: "python",
|
||||
GenPackage: GeneratePackage,
|
||||
Checks: map[string]test.CodegenCheck{
|
||||
"python/py_compile": pyCompileCheck,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// We can't type check a python program. We just check for syntax errors.
|
||||
func typeCheckGeneratedPackage(t *testing.T, pwd string) {
|
||||
// Checks generated code for syntax errors with `python -m compile`.
|
||||
func pyCompileCheck(t *testing.T, codeDir string) {
|
||||
ex, _, err := python.CommandPath()
|
||||
require.NoError(t, err)
|
||||
cmdOptions := integration.ProgramTestOptions{}
|
||||
err = filepath.Walk(pwd, func(path string, info filesystem.FileInfo, err error) error {
|
||||
err = filepath.Walk(codeDir, func(path string, info filesystem.FileInfo, err error) error {
|
||||
require.NoError(t, err) // an error in the walk
|
||||
if info.Mode().IsRegular() && strings.HasSuffix(info.Name(), ".py") {
|
||||
path, err = filepath.Abs(path)
|
||||
require.NoError(t, err)
|
||||
err = integration.RunCommand(t, "python syntax check",
|
||||
[]string{ex, "-m", "py_compile", path}, pwd, &cmdOptions)
|
||||
[]string{ex, "-m", "py_compile", path}, codeDir, &cmdOptions)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -83,9 +83,15 @@ func RunCommand(t *testing.T, name string, args []string, wd string, opts *Progr
|
|||
t.Logf("Invoke '%v' failed: %s\n", command, cmdutil.DetailedError(runerr))
|
||||
|
||||
if !opts.Verbose {
|
||||
stderr := opts.Stderr
|
||||
|
||||
if stderr == nil {
|
||||
stderr = os.Stderr
|
||||
}
|
||||
|
||||
// Make sure we write the output in case of a failure to stderr so
|
||||
// tests can assert the shape of the error message.
|
||||
_, _ = fmt.Fprintf(opts.Stderr, "%s\n", string(runout))
|
||||
_, _ = fmt.Fprintf(stderr, "%s\n", string(runout))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue