У меня есть функция, которая принимает входные данные ресурса AWS OpenIdConnectProvider Pulumi и создает роль IAM с прикрепленной AssumeRolePolicy, которая содержит информацию от этого поставщика OIDC.
Проблема: я пытаюсь написать тест для этой функции и имитировать провайдера OIDC, который будет использоваться в качестве входных данных для вызова функции. У меня возникли проблемы с пониманием того, как правильно издеваться над этим, чтобы выходные данные теста показывали то, что я ожидаю, в настоящее время кажется, что имитированные данные не появляются, как я ожидал.
Кажется, я неправильно использую мокап, но я ушел от примера здесь
Дополнительные документы здесь
package myPkg
import (
"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/iam"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func CreateMyCustomRole(ctx *pulumi.Context, name string, oidcProvider *iam.OpenIdConnectProvider, opts ...pulumi.ResourceOption) (*iam.Role, error) {
role := &iam.Role{}
componentURN := fmt.Sprintf("%s-custom-role", name)
err := ctx.RegisterComponentResource("pkg:aws:MyCustomRole", componentURN, role, opts...)
if err != nil {
return nil, err
}
url := oidc.Url.ApplyT(func(s string) string {
return fmt.Sprint(strings.ReplaceAll(s, "https://", ""), ":sub")
}).(pulumi.StringOutput)
assumeRolePolicy := pulumi.Sprintf(`{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Federated": "%s" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"%s": [
"system:serviceaccount:kube-system:*",
"system:serviceaccount:kube-system:cluster-autoscaler"
]
}
}
}]
}`, oidcProvider.Arn, url)
roleURN := fmt.Sprintf("%s-custom-role", name)
role, err = iam.NewRole(ctx, roleURN, &iam.RoleArgs{
Name: pulumi.String(roleURN),
Description: pulumi.String("Create Custom Role"),
AssumeRolePolicy: assumeRolePolicy,
Tags: pulumi.ToStringMap(map[string]string{"project": "test"}),
})
if err != nil {
return nil, err
}
return role, nil
}
package myPkg
import (
"sync"
"testing"
"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/iam"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/stretchr/testify/assert"
)
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) {
outputs := map[string]interface{}{}
if args.Token == "aws:iam/getOpenidConnectProvider:getOpenidConnectProvider" {
outputs["arn"] = "arn:aws:iam::123:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/abc"
outputs["id"] = "abc"
outputs["url"] = "https://someurl"
}
return resource.NewPropertyMapFromMap(outputs), nil
}
func TestCreateMyCustomRole(t *testing.T) {
err := pulumi.RunErr(func(ctx *pulumi.Context) error {
// Gets the mocked OIDC provider to use as input for the CreateDefaultAutoscalerRole
oidc, err := iam.GetOpenIdConnectProvider(ctx, "get-test-oidc-provider", pulumi.ID("abc"), &iam.OpenIdConnectProviderState{})
assert.NoError(t, err)
infra, err := CreateMyCustomRole(ctx, "role1", oidc})
assert.NoError(t, err)
var wg sync.WaitGroup
wg.Add(1)
// check 1: Assume Role Policy is formatted correctly
pulumi.All(infra.URN(), infra.AssumeRolePolicy).ApplyT(func(all []interface{}) error {
urn := all[0].(pulumi.URN)
assumeRolePolicy := all[1].(string)
assert.Equal(t, `{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::123:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/abc" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"someurl:sub": [
"system:serviceaccount:kube-system:*",
"system:serviceaccount:kube-system:cluster-autoscaler"
]
}
}
}]
}`, assumeRolePolicy)
wg.Done()
return nil
})
wg.Wait()
return nil
}, pulumi.WithMocks("project", "stack", mocks(0)))
assert.NoError(t, err)
}
Output
Diff:
--- Expected
+++ Actual
@@ -4,3 +4,3 @@
"Effect": "Allow",
- "Principal": { "Federated": "arn:aws:iam::123:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/abc" },
+ "Principal": { "Federated": "" },
"Action": "sts:AssumeRoleWithWebIdentity",
@@ -8,3 +8,3 @@
"StringEquals": {
- "someurl:sub": [
+ ":sub": [
"system:serviceaccount:kube-system:*",
Test: TestCreateMyCustomRole
Если вы хотите имитировать ресурсы Pulumi в модульных тестах Go, вы можете использовать пакет «mock», предоставляемый Pulumi SDK. Вот общие шаги, которые вы можете выполнить:
Создайте новый файл Go для своего теста и импортируйте необходимые пакеты, включая пакеты «testing» и «github.com/pulumi/pulumi/sdk/v3/go/pulumi/mock».
Определите структуру, реализующую интерфейс Pulumi Resource. Эта структура будет действовать как макет для фактического ресурса. Вы можете установить для полей структуры значения, которые хотите использовать в своем тесте.
type mockResource struct {
pulumi.ResourceState
Field1 string
Field2 int
}
Создайте новый экземпляр mockResource struct
и задайте для его полей значения, которые вы хотите использовать в своем тесте.
mock := &mockResource{
Field1: "test",
Field2: 123,
}
Используйте функцию mock.NewResourceMock
, чтобы создать нового фиктивного поставщика ресурсов. Этот провайдер вернет экземпляр mockResource
при вызове.
provider := mock.NewResourceMock(t, "test", "aws:ec2/instance:Instance", mock)
Создайте новый экземпляр ресурса, который вы хотите протестировать, и передайте фиктивному провайдеру.
instance := &ec2.Instance{}
err := instance.Create(ctx, "test", ec2.InstanceArgs{
// set args here
}, pulumi.Provider(provider))
Напишите свой тестовый код, чтобы убедиться, что ресурс ведет себя так, как ожидалось.
// assert that the resource was created successfully
assert.Nil(t, err)
// assert that the resource has the expected values
assert.Equal(t, mock.Field1, instance.Field1)
assert.Equal(t, mock.Field2, instance.Field2)
Вот и все! Следуя этим шагам, вы можете легко имитировать ресурсы Pulumi в модульных тестах Go с помощью Pulumi SDK.
❯ go get -u github.com/pulumi/pulumi/sdk/v3/go/pulumi/mock go: module github.com/pulumi/pulumi/sdk/v3@upgrade found (v3.64.0), but does not contain package github.com/pulumi/pulumi/sdk/v3/go/pulumi/mock
Отмечен как бесполезный, поскольку этот ответ, похоже, не использует ничего, описанного в pulumi SDK или справочниках по API. pulumi.com/docs/reference/pkg/nodejs/pulumi/pulumi/runtime/… pkg.go.dev/github.com/pulumi/pulumi/sdk/v3/go/pulumi Есть ли у вас в наличии информация об источнике документации ваша ссылка или полностью рабочий пример кода?
Оказывается, я использовал NewResource
неправильно.
Когда GetOpenIdConnectProvider
вызывается в тестовой функции, она переходит к чтению ресурса и созданию нового вывода ресурса, который запускает вызов mocks.NewResource.
Исправление заключалось в том, чтобы вместо этого определить оператор if для типа ресурса, возвращаемого GetOpenIdConnectProvider openIdConnectProvider
, в вызове функции NewResource с имитацией выходных данных.
func (mocks) NewResource(args pulumi.MockResourceArgs) (string, resource.PropertyMap, error) {
pulumi.Printf(args.TypeToken)
outputs := args.Inputs.Mappable()
if args.TypeToken == "aws:iam/openIdConnectProvider:OpenIdConnectProvider" {
outputs["arn"] = "arn:aws:iam::123:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/abc"
outputs["id"] = "abc"
outputs["url"] = "https://someurl"
}
return args.Name + "_id", resource.NewPropertyMapFromMap(outputs), nil
}
func (mocks) Call(args pulumi.MockCallArgs) (resource.PropertyMap, error) {
outputs := map[string]interface{}{}
return resource.NewPropertyMapFromMap(outputs), nil
}
В приведенном ниже фрагменте кода я изменил assert
, чтобы он не мог показать, как теперь выглядит разница с изменениями, внесенными в NewResource выше
Diff:
--- Expected
+++ Actual
@@ -8,3 +8,3 @@
"StringEquals": {
- "b:sub": [
+ "someurl:sub": [
"system:serviceaccount:kube-system:*",
github.com/pulumi/pulumi/sdk/v3/go/pulumi/mock
не является импортируемым пакетом