diff --git a/export_test.go b/export_test.go index ac929ef..e856d3c 100644 --- a/export_test.go +++ b/export_test.go @@ -6,7 +6,18 @@ var ( LoadZipArchive = loadZipArchive MergeTags = mergeTags FillDefaultValues = fillDefaultValues + JSONStr = jsonStr + MarshalJSON = marshalJSON + NewFunctionFrom = newFunctionFrom ) type VersionsOutput = versionsOutput type VersionsOutputs = versionsOutputs + +func (app *App) CallerIdentity() *CallerIdentity { + return app.callerIdentity +} + +func (app *App) LoadFunction(f string) (*Function, error) { + return app.loadFunction(f) +} diff --git a/function_test.go b/function_test.go index 9ea6ca1..7206e07 100644 --- a/function_test.go +++ b/function_test.go @@ -1,25 +1,37 @@ -package lambroll +package lambroll_test import ( "context" - "os" "testing" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/lambda" "github.com/aws/aws-sdk-go-v2/service/lambda/types" + "github.com/aws/aws-sdk-go-v2/service/sts" + "github.com/fujiwara/lambroll" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +var ignore = cmpopts.IgnoreUnexported( + types.EphemeralStorage{}, + types.Environment{}, + types.FileSystemConfig{}, + types.LoggingConfig{}, + types.TracingConfig{}, + types.VpcConfig{}, + lambda.CreateFunctionOutput{}, ) func TestLoadFunction(t *testing.T) { - os.Setenv("FUNCTION_NAME", "test") - envfiles := []string{"test/env"} - path := "test/terraform.tfstate" - app, err := New(context.Background(), &Option{ - TFState: &path, + t.Setenv("FUNCTION_NAME", "test") + app, err := lambroll.New(context.Background(), &lambroll.Option{ + TFState: aws.String("test/terraform.tfstate"), PrefixedTFState: map[string]string{ "prefix1_": "test/terraform_1.tfstate", "prefix2_": "test/terraform_2.tfstate", }, - Envfile: envfiles, + Envfile: []string{"test/env"}, ExtStr: map[string]string{ "Description": "hello function", }, @@ -30,43 +42,69 @@ func TestLoadFunction(t *testing.T) { if err != nil { t.Error(err) } + app.CallerIdentity().Resolver = func(_ context.Context) (*sts.GetCallerIdentityOutput, error) { + return &sts.GetCallerIdentityOutput{ + Account: aws.String("123456789012"), + Arn: aws.String("arn:aws:iam::123456789012:user/test-user"), + UserId: aws.String("AIXXXXXXXXXXXXXXXXXX"), + }, nil + } + expected := lambroll.Function{ + Architectures: []types.Architecture{types.ArchitectureX8664}, + Description: aws.String("hello function"), + Environment: &types.Environment{ + Variables: map[string]string{ + "PREFIXED_TFSTATE_1": "arn:aws:iam::123456789012:role/test_lambda_role_1", + "PREFIXED_TFSTATE_2": "arn:aws:iam::123456789012:role/test_lambda_role_2", + "JSON": `{"foo":"bar"}`, + }, + }, + EphemeralStorage: &types.EphemeralStorage{ + Size: aws.Int32(1024), + }, + FileSystemConfigs: []types.FileSystemConfig{ + { + Arn: aws.String("arn:aws:elasticfilesystem:ap-northeast-1:123456789012:access-point/fsap-04fc0858274e7dd9a"), + LocalMountPath: aws.String("/mnt/lambda"), + }, + }, + FunctionName: aws.String("test"), + Handler: aws.String("index.js"), + LoggingConfig: &types.LoggingConfig{ + ApplicationLogLevel: "DEBUG", + LogGroup: aws.String("/aws/lambda/test/json"), + SystemLogLevel: "INFO", + LogFormat: types.LogFormatJson, + }, + MemorySize: aws.Int32(128), + Runtime: types.RuntimeNodejs16x, + Role: aws.String("arn:aws:iam::123456789012:role/test_lambda_role"), + Timeout: aws.Int32(5), + TracingConfig: &types.TracingConfig{ + Mode: types.TracingModePassThrough, + }, + VpcConfig: &types.VpcConfig{ + SubnetIds: []string{ + "subnet-08dc9a51660120991", + "subnet-023e96b860485e2ad", + "subnet-045cd24ab8e92a20d", + }, + SecurityGroupIds: []string{ + "sg-01a9b01eab0a3c154", + }, + }, + } + for _, f := range []string{"test/function.json", "test/function.jsonnet"} { - fn, err := app.loadFunction(f) + fn, err := app.LoadFunction(f) if err != nil { t.Error(err) } - if *fn.Role != "arn:aws:iam::123456789012:role/test_lambda_role" { - t.Errorf("unexpected role got %s", *fn.Role) - } - if *fn.FunctionName != "test" { - t.Errorf("unexpected function name got %s", *fn.FunctionName) - } - if *fn.FileSystemConfigs[0].Arn != "arn:aws:elasticfilesystem:ap-northeast-1:123456789012:access-point/fsap-04fc0858274e7dd9a" { - t.Errorf("unexpected fileSystemConfigs %v", *&fn.FileSystemConfigs) - } - if fn.Environment.Variables["JSON"] != `{"foo":"bar"}` { - t.Errorf("unexpected environment %v", fn.Environment.Variables) - } - if fn.Environment.Variables["PREFIXED_TFSTATE_1"] != "arn:aws:iam::123456789012:role/test_lambda_role_1" { - t.Errorf("unexpected environment %v", fn.Environment.Variables) - } - if fn.Environment.Variables["PREFIXED_TFSTATE_2"] != "arn:aws:iam::123456789012:role/test_lambda_role_2" { - t.Errorf("unexpected environment %v", fn.Environment.Variables) - } - if fn.VpcConfig.SecurityGroupIds[0] != "sg-01a9b01eab0a3c154" { - t.Errorf("unexpected SecurityGroupIds %v", fn.VpcConfig.SecurityGroupIds) + expectedJSON, _ := lambroll.MarshalJSON(expected) + fnJSON, _ := lambroll.MarshalJSON(fn) + if diff := cmp.Diff(string(expectedJSON), string(fnJSON), ignore); diff != "" { + t.Errorf("unexpected function got %s", diff) } - arch := fn.Architectures - if len(arch) != 1 || arch[0] != "x86_64" { - t.Errorf("unexpected Architectures %v", fn.Architectures) - } - if *fn.LoggingConfig.LogGroup != "/aws/lambda/test/json" { - t.Errorf("unexpected LoggingConfig %v", fn.LoggingConfig) - } - if *fn.EphemeralStorage.Size != 1024 { - t.Errorf("unexpected EphemeralStorage %v", fn.EphemeralStorage) - } - t.Log(fn) } } @@ -82,29 +120,21 @@ func TestNewFunction(t *testing.T) { tags := map[string]string{ "foo": "bar", } - fn := newFunctionFrom(conf, nil, tags) - if *fn.FunctionName != "hello" { - t.Errorf("unexpected function name got %s", *fn.FunctionName) - } - if *fn.MemorySize != 128 { - t.Errorf("unexpected memory size got %d", *fn.MemorySize) - } - if fn.Runtime != types.RuntimeNodejs18x { - t.Errorf("unexpected runtime got %s", fn.Runtime) - } - if *fn.Timeout != 3 { - t.Errorf("unexpected timeout got %d", *fn.Timeout) - } - if *fn.Handler != "index.handler" { - t.Errorf("unexpected handler got %s", *fn.Handler) - } - if *fn.Role != "arn:aws:iam::0123456789012:role/YOUR_LAMBDA_ROLE_NAME" { - t.Errorf("unexpected role got %s", *fn.Role) - } - if fn.Tags["foo"] != "bar" { - t.Errorf("unexpected tags got %v", fn.Tags) + fn := lambroll.NewFunctionFrom(conf, nil, tags) + + expected := lambroll.Function{ + FunctionName: aws.String("hello"), + MemorySize: aws.Int32(128), + Runtime: types.RuntimeNodejs18x, + Timeout: aws.Int32(3), + Handler: aws.String("index.handler"), + Role: aws.String("arn:aws:iam::0123456789012:role/YOUR_LAMBDA_ROLE_NAME"), + Tags: tags, } - if fn.SnapStart != nil { - t.Errorf("unexpected snap start got %v", fn.SnapStart) + + fnJSON, _ := lambroll.MarshalJSON(fn) + expectedJSON, _ := lambroll.MarshalJSON(expected) + if diff := cmp.Diff(string(expectedJSON), string(fnJSON), ignore); diff != "" { + t.Errorf("unexpected function got %s", diff) } } diff --git a/test/function.jsonnet b/test/function.jsonnet index 80a6dce..dc87cdb 100644 --- a/test/function.jsonnet +++ b/test/function.jsonnet @@ -1,6 +1,7 @@ local prefix1_tfstate = std.native('prefix1_tfstate'); local tfstate = std.native('tfstate'); local must_env = std.native('must_env'); +local caller = std.native('caller_identity')(); { Architectures: [ 'x86_64', @@ -19,7 +20,7 @@ local must_env = std.native('must_env'); FunctionName: must_env('FUNCTION_NAME'), FileSystemConfigs: [ { - Arn: 'arn:aws:elasticfilesystem:ap-northeast-1:123456789012:access-point/fsap-04fc0858274e7dd9a', + Arn: 'arn:aws:elasticfilesystem:ap-northeast-1:%s:access-point/fsap-04fc0858274e7dd9a' % caller.Account, LocalMountPath: '/mnt/lambda', }, ], @@ -32,7 +33,7 @@ local must_env = std.native('must_env'); }, MemorySize: std.extVar('MemorySize'), Role: tfstate('data.aws_iam_role.lambda.arn'), - Runtime: 'nodejs12.x', + Runtime: 'nodejs16.x', Timeout: 5, TracingConfig: { Mode: 'PassThrough',