subtypes,handlers: add runtime trace regions (#4060)

* subtypes,handlers: add runtime trace regions

The subtype.Filterable and handlers.ProtoToStruct functions
are costly and worth measuring whenever runtime tracing
is in use. This has almost no cost when tracing is not in use,
so there's little harm in having them in place.

* testing: Add TRACING.md

TRACING.md contains information about how to perform
Go runtime tracing of the Boundary application.
This commit is contained in:
Johan Brandhorst-Satzkorn authored and GitHub committed 2023-11-27 13:37:04 -08:00
1 parent 18729721a1
commit a89573b35f
21 files changed
+102 -56

No files matched your search

@@ -187,7 +187,7 @@ func (s Service) ListAccounts(ctx context.Context, req *pbs.ListAccountsRequest)
// This comes last so that we can use item fields in the filter after
// the allowed fields are populated above
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -196,7 +196,7 @@ func (s Service) ListAuthMethods(ctx context.Context, req *pbs.ListAuthMethodsRe
// This comes last so that we can use item fields in the filter after
// the allowed fields are populated above
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -1387,7 +1387,7 @@ func (s Service) convertToAuthenticateResponse(ctx context.Context, req *pbs.Aut
}, nil
}
func transformAuthenticateRequestAttributes(msg proto.Message) error {
func transformAuthenticateRequestAttributes(ctx context.Context, msg proto.Message) error {
const op = "authmethod.transformAuthenticateRequestAttributes"
authRequest, ok := msg.(*pbs.AuthenticateRequest)
if !ok {
@@ -1451,7 +1451,7 @@ func transformAuthenticateRequestAttributes(msg proto.Message) error {
return nil
}
func transformAuthenticateResponseAttributes(msg proto.Message) error {
func transformAuthenticateResponseAttributes(ctx context.Context, msg proto.Message) error {
const op = "authmethod.transformAuthenticateResponseAttributes"
authResponse, ok := msg.(*pbs.AuthenticateResponse)
if !ok {
@@ -1468,22 +1468,22 @@ func transformAuthenticateResponseAttributes(msg proto.Message) error {
// No transformation necessary
newAttrs = attrs.Attributes
case *pbs.AuthenticateResponse_AuthTokenResponse:
newAttrs, err = handlers.ProtoToStruct(attrs.AuthTokenResponse)
newAttrs, err = handlers.ProtoToStruct(ctx, attrs.AuthTokenResponse)
if err != nil {
return err
}
case *pbs.AuthenticateResponse_OidcAuthMethodAuthenticateStartResponse:
newAttrs, err = handlers.ProtoToStruct(attrs.OidcAuthMethodAuthenticateStartResponse)
newAttrs, err = handlers.ProtoToStruct(ctx, attrs.OidcAuthMethodAuthenticateStartResponse)
if err != nil {
return err
}
case *pbs.AuthenticateResponse_OidcAuthMethodAuthenticateCallbackResponse:
newAttrs, err = handlers.ProtoToStruct(attrs.OidcAuthMethodAuthenticateCallbackResponse)
newAttrs, err = handlers.ProtoToStruct(ctx, attrs.OidcAuthMethodAuthenticateCallbackResponse)
if err != nil {
return err
}
case *pbs.AuthenticateResponse_OidcAuthMethodAuthenticateTokenResponse:
newAttrs, err = handlers.ProtoToStruct(attrs.OidcAuthMethodAuthenticateTokenResponse)
newAttrs, err = handlers.ProtoToStruct(ctx, attrs.OidcAuthMethodAuthenticateTokenResponse)
if err != nil {
return err
}
@@ -4,6 +4,7 @@
package authmethods
import (
"context"
"testing"
"github.com/google/go-cmp/cmp"
@@ -196,7 +197,7 @@ func TestTransformAuthenticateRequestAttributes(t *testing.T) {
t.Run(c.name, func(t *testing.T) {
t.Parallel()
in := proto.Clone(c.input)
require.NoError(t, transformAuthenticateRequestAttributes(in))
require.NoError(t, transformAuthenticateRequestAttributes(context.Background(), in))
require.Empty(t, cmp.Diff(c.expected, in, protocmp.Transform()))
})
}
@@ -206,11 +207,11 @@ func TestTransformAuthenticateRequestAttributesErrors(t *testing.T) {
t.Parallel()
t.Run("not-an-authenticate-request", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateRequestAttributes(&pb.AuthMethod{}))
require.Error(t, transformAuthenticateRequestAttributes(context.Background(), &pb.AuthMethod{}))
})
t.Run("invalid-auth-method-id", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateRequestAttributes(&pbs.AuthenticateRequest{
require.Error(t, transformAuthenticateRequestAttributes(context.Background(), &pbs.AuthenticateRequest{
AuthMethodId: "invalid",
Attrs: &pbs.AuthenticateRequest_Attributes{
Attributes: &structpb.Struct{},
@@ -219,7 +220,7 @@ func TestTransformAuthenticateRequestAttributesErrors(t *testing.T) {
})
t.Run("invalid-oidc-command", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateRequestAttributes(&pbs.AuthenticateRequest{
require.Error(t, transformAuthenticateRequestAttributes(context.Background(), &pbs.AuthenticateRequest{
AuthMethodId: "amoidc_test",
Command: "invalid",
Attrs: &pbs.AuthenticateRequest_Attributes{
@@ -229,7 +230,7 @@ func TestTransformAuthenticateRequestAttributesErrors(t *testing.T) {
})
t.Run("invalid-password-attributes", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateRequestAttributes(&pbs.AuthenticateRequest{
require.Error(t, transformAuthenticateRequestAttributes(context.Background(), &pbs.AuthenticateRequest{
AuthMethodId: "apw_test",
Attrs: &pbs.AuthenticateRequest_Attributes{
Attributes: &structpb.Struct{
@@ -243,7 +244,7 @@ func TestTransformAuthenticateRequestAttributesErrors(t *testing.T) {
})
t.Run("invalid-ldap-attributes", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateRequestAttributes(&pbs.AuthenticateRequest{
require.Error(t, transformAuthenticateRequestAttributes(context.Background(), &pbs.AuthenticateRequest{
AuthMethodId: "amldap_test",
Attrs: &pbs.AuthenticateRequest_Attributes{
Attributes: &structpb.Struct{
@@ -257,7 +258,7 @@ func TestTransformAuthenticateRequestAttributesErrors(t *testing.T) {
})
t.Run("invalid-oidc-start-attributes", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateRequestAttributes(&pbs.AuthenticateRequest{
require.Error(t, transformAuthenticateRequestAttributes(context.Background(), &pbs.AuthenticateRequest{
AuthMethodId: "amoidc_test",
Command: "start",
Attrs: &pbs.AuthenticateRequest_Attributes{
@@ -272,7 +273,7 @@ func TestTransformAuthenticateRequestAttributesErrors(t *testing.T) {
})
t.Run("invalid-oidc-token-attributes", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateRequestAttributes(&pbs.AuthenticateRequest{
require.Error(t, transformAuthenticateRequestAttributes(context.Background(), &pbs.AuthenticateRequest{
AuthMethodId: "amoidc_test",
Command: "token",
Attrs: &pbs.AuthenticateRequest_Attributes{
@@ -421,7 +422,7 @@ func TestTransformAuthenticateResponseAttributes(t *testing.T) {
t.Run(c.name, func(t *testing.T) {
t.Parallel()
in := proto.Clone(c.input)
require.NoError(t, transformAuthenticateResponseAttributes(in))
require.NoError(t, transformAuthenticateResponseAttributes(context.Background(), in))
require.Empty(t, cmp.Diff(c.expected, in, protocmp.Transform()))
})
}
@@ -431,6 +432,6 @@ func TestTransformAuthenticateResponseAttributesErrors(t *testing.T) {
t.Parallel()
t.Run("not-an-authenticate-response", func(t *testing.T) {
t.Parallel()
require.Error(t, transformAuthenticateResponseAttributes(&pb.AuthMethod{}))
require.Error(t, transformAuthenticateResponseAttributes(context.Background(), &pb.AuthMethod{}))
})
}
@@ -177,7 +177,7 @@ func (s Service) ListCredentialLibraries(ctx context.Context, req *pbs.ListCrede
return nil, err
}
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -160,7 +160,7 @@ func (s Service) ListCredentials(ctx context.Context, req *pbs.ListCredentialsRe
return nil, err
}
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -194,7 +194,7 @@ func (s Service) ListCredentialStores(ctx context.Context, req *pbs.ListCredenti
return nil, err
}
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -212,7 +212,7 @@ func (s Service) ListHostCatalogs(ctx context.Context, req *pbs.ListHostCatalogs
// This comes last so that we can use item fields in the filter after
// the allowed fields are populated above
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -166,7 +166,7 @@ func (s Service) ListHostSetsWithOptions(ctx context.Context, req *pbs.ListHostS
// This comes last so that we can use item fields in the filter after
// the allowed fields are populated above
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -147,7 +147,7 @@ func (s Service) ListHosts(ctx context.Context, req *pbs.ListHostsRequest) (*pbs
// This comes last so that we can use item fields in the filter after
// the allowed fields are populated above
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -159,7 +159,7 @@ func (s Service) ListManagedGroups(ctx context.Context, req *pbs.ListManagedGrou
// This comes last so that we can use item fields in the filter after
// the allowed fields are populated above
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}
@@ -22,7 +22,7 @@ import (
func TestOutgoingSplitCookie(t *testing.T) {
rec := httptest.NewRecorder()
attrs, err := ProtoToStruct(&pba.AuthToken{Token: "t_abc_1234567890"})
attrs, err := ProtoToStruct(context.Background(), &pba.AuthToken{Token: "t_abc_1234567890"})
require.NoError(t, err)
require.NoError(t, OutgoingResponseFilter(context.Background(), rec, &pbs.AuthenticateResponse{Attrs: &pbs.AuthenticateResponse_Attributes{Attributes: attrs}, Type: "cookie"}))
assert.ElementsMatch(t, rec.Result().Cookies(), []*http.Cookie{
@@ -4,6 +4,9 @@
package handlers
import (
"context"
"runtime/trace"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
@@ -30,7 +33,8 @@ func StructToProto(fields *structpb.Struct, p proto.Message, opt ...Option) erro
return nil
}
func ProtoToStruct(p proto.Message) (*structpb.Struct, error) {
func ProtoToStruct(ctx context.Context, p proto.Message) (*structpb.Struct, error) {
defer trace.StartRegion(ctx, "subtypes.ProtoToStruct").End()
js, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(p)
if err != nil {
return nil, err
@@ -4,6 +4,7 @@
package handlers
import (
"context"
"testing"
structpb "github.com/golang/protobuf/ptypes/struct"
@@ -49,7 +50,7 @@ func TestStructToProtoToStruct(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
st, err := ProtoToStruct(tc.pb)
st, err := ProtoToStruct(context.Background(), tc.pb)
require.NoError(t, err)
wantStruct := &structpb.Struct{}
@@ -104,6 +104,7 @@ func dynamicToSessionCredential(ctx context.Context, cred credential.Dynamic) (*
switch c := cred.(type) {
case credential.UsernamePassword:
credData, err = handlers.ProtoToStruct(
ctx,
&pb.UsernamePasswordCredential{
Username: c.Username(),
Password: string(c.Password()),
@@ -115,6 +116,7 @@ func dynamicToSessionCredential(ctx context.Context, cred credential.Dynamic) (*
case credential.SshPrivateKey:
credData, err = handlers.ProtoToStruct(
ctx,
&pb.SshPrivateKeyCredential{
Username: c.Username(),
PrivateKey: string(c.PrivateKey()),
@@ -196,6 +198,7 @@ func staticToSessionCredential(ctx context.Context, cred credential.Static) (*pb
var err error
credType = string(globals.UsernamePasswordCredentialType)
credData, err = handlers.ProtoToStruct(
ctx,
&pb.UsernamePasswordCredential{
Username: c.GetUsername(),
Password: string(c.GetPassword()),
@@ -213,6 +216,7 @@ func staticToSessionCredential(ctx context.Context, cred credential.Static) (*pb
var err error
credType = string(globals.SshPrivateKeyCredentialType)
credData, err = handlers.ProtoToStruct(
ctx,
&pb.SshPrivateKeyCredential{
Username: c.GetUsername(),
PrivateKey: string(c.GetPrivateKey()),
@@ -258,7 +258,7 @@ func (s Service) ListTargets(ctx context.Context, req *pbs.ListTargetsRequest) (
return nil, err
}
filterable, err := subtypes.Filterable(item)
filterable, err := subtypes.Filterable(ctx, item)
if err != nil {
return nil, err
}