bench/handler_bench_test.go

package bench_test

import (
	"context"
	"testing"

	awslambda "github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-lambda-go/lambdacontext"

	adapter "mercemay.top/src/lambdalog/adapters/lambda"
)

type benchLogger struct{}

func (benchLogger) Info(string, ...adapter.Field)          {}
func (benchLogger) Error(string, ...adapter.Field)         {}
func (benchLogger) With(...adapter.Field) adapter.Logger    { return benchLogger{} }

func BenchmarkHandler_Invoke(b *testing.B) {
	h := adapter.Handler(benchLogger{}, awslambda.HandlerFunc(func(ctx context.Context, p []byte) ([]byte, error) {
		return p, nil
	}))
	ctx := lambdacontext.NewContext(context.Background(), &lambdacontext.LambdaContext{AwsRequestID: "bench"})
	payload := []byte(`{"n":1}`)
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = h.Invoke(ctx, payload)
	}
}

func BenchmarkHandlerFunc_JSON(b *testing.B) {
	type in struct{ A int }
	type out struct{ B int }
	h := adapter.HandlerFunc(benchLogger{}, func(ctx context.Context, v in) (out, error) {
		return out{B: v.A * 2}, nil
	})
	payload := []byte(`{"A":3}`)
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_, _ = h.Invoke(context.Background(), payload)
	}
}

func BenchmarkHandler_ColdCtx(b *testing.B) {
	h := adapter.Handler(benchLogger{}, awslambda.HandlerFunc(func(ctx context.Context, p []byte) ([]byte, error) {
		return p, nil
	}))
	payload := []byte(`{"n":1}`)
	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		// Fresh context each loop simulates the first invocation after a
		// cold start where no logger is attached yet.
		_, _ = h.Invoke(context.Background(), payload)
	}
}

func BenchmarkHandler_Parallel(b *testing.B) {
	h := adapter.Handler(benchLogger{}, awslambda.HandlerFunc(func(ctx context.Context, p []byte) ([]byte, error) {
		return p, nil
	}))
	ctx := lambdacontext.NewContext(context.Background(), &lambdacontext.LambdaContext{AwsRequestID: "bench"})
	payload := []byte(`{"n":1}`)
	b.ReportAllocs()
	b.ResetTimer()
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			_, _ = h.Invoke(ctx, payload)
		}
	})
}