Skip to content

Commit b15c590

Browse files
committed
temp
1 parent 3fa2702 commit b15c590

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_test")
2+
3+
package(default_visibility = ["//enterprise:__subpackages__"])
4+
5+
go_test(
6+
name = "usage_test",
7+
srcs = ["usage_test.go"],
8+
deps = [
9+
"//enterprise/server/testutil/buildbuddy_enterprise",
10+
"//proto:api_key_go_proto",
11+
"//proto:capability_go_proto",
12+
"//proto:context_go_proto",
13+
"//proto:group_go_proto",
14+
"//proto:usage_go_proto",
15+
"//server/tables",
16+
"@com_github_stretchr_testify//assert",
17+
"@com_github_stretchr_testify//require",
18+
"@org_golang_google_protobuf//encoding/protojson",
19+
],
20+
)
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package usage_test
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
"testing"
9+
"time"
10+
11+
"github.com/buildbuddy-io/buildbuddy/enterprise/server/testutil/buildbuddy_enterprise"
12+
"github.com/buildbuddy-io/buildbuddy/server/tables"
13+
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/require"
15+
"google.golang.org/protobuf/encoding/protojson"
16+
17+
akpb "github.com/buildbuddy-io/buildbuddy/proto/api_key"
18+
cappb "github.com/buildbuddy-io/buildbuddy/proto/capability"
19+
ctxpb "github.com/buildbuddy-io/buildbuddy/proto/context"
20+
grpb "github.com/buildbuddy-io/buildbuddy/proto/group"
21+
usagepb "github.com/buildbuddy-io/buildbuddy/proto/usage"
22+
)
23+
24+
func TestGetUsage_ParentAdminFetchesChildGroupUsage(t *testing.T) {
25+
// Start enterprise app
26+
app := buildbuddy_enterprise.Run(
27+
t,
28+
"--app.usage_tracking_enabled=true",
29+
"--app.region=test", // Required for usage tracking
30+
"--auth.api_key_group_cache_ttl=0", // Don't cache API key -> group mappings for this test
31+
)
32+
wc := buildbuddy_enterprise.LoginAsDefaultSelfAuthUser(t, app)
33+
34+
// Treat the logged-in user's selected group as the parent org; mark it as parent and
35+
// set SAML metadata so that authdb recognizes child orgs sharing the same IdP.
36+
parentGroupID := wc.RequestContext.GetGroupId()
37+
parent := &tables.Group{}
38+
require.NoError(t, app.DB().Where("group_id = ?", parentGroupID).Take(parent).Error)
39+
parent.IsParent = true
40+
parent.SamlIdpMetadataUrl = "https://idp.example.test/metadata"
41+
parent.URLIdentifier = "parent-org"
42+
require.NoError(t, app.DB().Save(parent).Error)
43+
44+
// Create an ORG_ADMIN API key for the parent org using cookie-authenticated Web RPC.
45+
createKeyReq := &akpb.CreateApiKeyRequest{
46+
RequestContext: &ctxpb.RequestContext{GroupId: parentGroupID},
47+
Label: "admin-1",
48+
Capability: []cappb.Capability{cappb.Capability_ORG_ADMIN},
49+
}
50+
createKeyRsp := &akpb.CreateApiKeyResponse{}
51+
require.NoError(t, wc.RPC("CreateApiKey", createKeyReq, createKeyRsp))
52+
adminAPIKey := createKeyRsp.GetApiKey().GetValue()
53+
require.NotEmpty(t, adminAPIKey)
54+
55+
// Create a child group (same SAML as parent) using the API.
56+
// Do NOT add the user as a member: authenticate with the parent ORG_ADMIN API key.
57+
createChildGrpReq, err := http.NewRequest(
58+
http.MethodPost,
59+
app.HTTPURL()+"/rpc/BuildBuddyService/CreateGroup",
60+
bytes.NewBufferString(`{"name":"child-org","urlIdentifier":"child-org"}`),
61+
)
62+
require.NoError(t, err)
63+
createChildGrpReq.Header.Set("Content-Type", "application/json")
64+
createChildGrpReq.Header.Set("x-buildbuddy-api-key", adminAPIKey)
65+
createChildGrpResp, err := http.DefaultClient.Do(createChildGrpReq)
66+
require.NoError(t, err)
67+
defer createChildGrpResp.Body.Close()
68+
createResBytes, err := io.ReadAll(createChildGrpResp.Body)
69+
require.NoError(t, err)
70+
require.Equal(t, http.StatusOK, createChildGrpResp.StatusCode)
71+
childGrpRsp := &grpb.CreateGroupResponse{}
72+
require.NoError(t, protojson.Unmarshal(createResBytes, childGrpRsp))
73+
childGroupID := childGrpRsp.GetId()
74+
require.NotEmpty(t, childGroupID)
75+
child := &tables.Group{}
76+
require.NoError(t, app.DB().Where("group_id = ?", childGroupID).Take(child).Error)
77+
78+
// Seed a usage row for the child group.
79+
now := time.Now().UTC()
80+
monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, time.UTC)
81+
seeded := &tables.Usage{
82+
GroupID: childGroupID,
83+
PeriodStartUsec: monthStart.UnixMicro(),
84+
Region: "test",
85+
FinalBeforeUsec: monthStart.Add(30 * 24 * time.Hour).UnixMicro(),
86+
UsageCounts: tables.UsageCounts{
87+
Invocations: 3,
88+
CASCacheHits: 1,
89+
ActionCacheHits: 2,
90+
TotalDownloadSizeBytes: 2048,
91+
LinuxExecutionDurationUsec: 111,
92+
TotalUploadSizeBytes: 4096,
93+
TotalCachedActionExecUsec: 222,
94+
CPUNanos: 333,
95+
},
96+
UsageLabels: tables.UsageLabels{Origin: "internal", Client: "bazel", Server: "app"},
97+
}
98+
db := app.DB()
99+
require.NoError(t, db.Create(seeded).Error)
100+
101+
// Make the HTTP protolet request using the parent admin API key and requesting the child group.
102+
// Use JSON body for documentation clarity.
103+
httpReq, err := http.NewRequest(
104+
http.MethodPost,
105+
app.HTTPURL()+"/rpc/BuildBuddyService/GetUsage",
106+
bytes.NewBufferString(fmt.Sprintf(`{"requestContext":{"groupId":"%s"}}`, childGroupID)),
107+
)
108+
require.NoError(t, err)
109+
httpReq.Header.Set("Content-Type", "application/json")
110+
httpReq.Header.Set("x-buildbuddy-api-key", adminAPIKey)
111+
httpRes, err := http.DefaultClient.Do(httpReq)
112+
require.NoError(t, err)
113+
defer httpRes.Body.Close()
114+
resBytes, err := io.ReadAll(httpRes.Body)
115+
require.NoError(t, err)
116+
require.Equal(t, http.StatusOK, httpRes.StatusCode)
117+
rsp := &usagepb.GetUsageResponse{}
118+
require.NoError(t, protojson.Unmarshal(resBytes, rsp))
119+
120+
require.NotNil(t, rsp.GetUsage())
121+
assert.EqualValues(t, 3, rsp.GetUsage().GetInvocations())
122+
assert.EqualValues(t, 2, rsp.GetUsage().GetActionCacheHits())
123+
assert.EqualValues(t, 1, rsp.GetUsage().GetCasCacheHits())
124+
assert.EqualValues(t, 2048, rsp.GetUsage().GetTotalDownloadSizeBytes())
125+
assert.EqualValues(t, 4096, rsp.GetUsage().GetTotalUploadSizeBytes())
126+
assert.EqualValues(t, 111, rsp.GetUsage().GetLinuxExecutionDurationUsec())
127+
assert.EqualValues(t, 222, rsp.GetUsage().GetTotalCachedActionExecUsec())
128+
assert.EqualValues(t, 333, rsp.GetUsage().GetCloudCpuNanos())
129+
require.Len(t, rsp.GetDailyUsage(), 1)
130+
assert.EqualValues(t, 3, rsp.GetDailyUsage()[0].GetInvocations())
131+
}

0 commit comments

Comments
 (0)