Skip to content

Commit 1ff0a03

Browse files
committed
Allow larger logs from acceptance tests and implement experimental OIDC refresh
1 parent 7348f7d commit 1ff0a03

File tree

5 files changed

+76
-16
lines changed

5 files changed

+76
-16
lines changed

acceptance/ecosystem/report.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,16 @@ func (tr TestResult) Failed() bool {
2929
return !tr.Pass && !tr.Skip
3030
}
3131

32-
func (tr TestResult) Summary() string {
32+
func (tr TestResult) Summary(cap int) string {
33+
out, padding := tr.Output, 512
34+
diff := len(out) + padding - cap
35+
if diff > 0 {
36+
out = fmt.Sprintf("... (skipped %d bytes)\n%s", diff, out[diff:])
37+
}
3338
res := []string{}
3439
res = append(res, "<details>")
3540
res = append(res, fmt.Sprintf("<summary>%s</summary>", tr))
36-
res = append(res, fmt.Sprintf("\n```\n%s\n```\n", tr.Output))
41+
res = append(res, fmt.Sprintf("\n```\n%s\n```\n", out))
3742
res = append(res, "</details>")
3843
return strings.Join(res, "\n")
3944
}
@@ -148,13 +153,24 @@ func (r TestReport) String() string {
148153
return fmt.Sprintf("%s %s", emoji, strings.Join(parts, ", "))
149154
}
150155

156+
const CommentMaxSize = 65536
157+
151158
func (r TestReport) StepSummary() string {
152-
res := []string{r.String()}
159+
res, failures, maybeOutput, padding := []string{r.String()}, []TestResult{}, 0, 1024
153160
for _, v := range r {
154161
if !v.Failed() {
155162
continue
156163
}
157-
res = append(res, v.Summary())
164+
failures = append(failures, v)
165+
maybeOutput += len(v.Summary(CommentMaxSize))
166+
}
167+
summaryCap := CommentMaxSize - len(strings.Join(res, "\n")) - padding
168+
if maybeOutput > (CommentMaxSize - padding) {
169+
// if the output is too large, truncate the summaries up to a fraction of the total size
170+
summaryCap /= len(failures)
171+
}
172+
for _, v := range failures {
173+
res = append(res, v.Summary(summaryCap))
158174
}
159175
if r.Flaky() {
160176
res = append(res, "\nFlaky tests:\n")

acceptance/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func (a *acceptance) notifyIfNeeded(ctx context.Context, alert *notify.Notificat
148148
}
149149
err := a.CreateOrCommentOnIssue(ctx, github.NewIssue{
150150
Title: fmt.Sprintf("Test failure: `%s`", v.Name),
151-
Body: v.Summary(),
151+
Body: v.Summary(ecosystem.CommentMaxSize),
152152
Labels: []string{"bug"},
153153
})
154154
if err != nil {

acceptance/shim.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const version = 'v0.2.2';
1+
const version = 'v0.3.0';
22
const action = 'acceptance';
33

44
const { createWriteStream, chmodSync } = require('fs');

acceptance/testenv/githubOidc.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,38 @@ func NewWithGitHubOIDC(a *githubactions.Action, vaultURI string) *vaultEnv {
2323
}
2424
}
2525

26-
type ghOidcCreds struct {
27-
a *githubactions.Action
26+
type ghOidcProxy struct {
27+
ctx context.Context
28+
a *githubactions.Action
29+
resource string
2830
}
2931

30-
func (c *ghOidcCreds) oidcTokenSource(ctx context.Context, resource string) (oauth2.TokenSource, error) {
31-
// TODO: at the moment, ID token expires in 1 hour, so we need to rewrite the logic to refresh it
32-
clientAssertion, err := c.a.GetIDToken(ctx, "api://AzureADTokenExchange")
32+
func (c *ghOidcProxy) Token() (*oauth2.Token, error) {
33+
clientAssertion, err := c.a.GetIDToken(c.ctx, "api://AzureADTokenExchange")
3334
if err != nil {
3435
return nil, fmt.Errorf("id token: %w", err)
3536
}
3637
clientID := c.a.Getenv("ARM_CLIENT_ID")
3738
tenantID := c.a.Getenv("ARM_TENANT_ID")
38-
return (&clientcredentials.Config{
39+
creds := (&clientcredentials.Config{
3940
ClientID: clientID,
4041
TokenURL: fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/token", tenantID),
4142
EndpointParams: url.Values{
4243
"client_assertion_type": []string{"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"},
4344
"client_assertion": []string{clientAssertion},
44-
"resource": []string{resource},
45+
"resource": []string{c.resource},
4546
},
46-
}).TokenSource(ctx), nil
47+
}).TokenSource(c.ctx)
48+
refresher := oauth2.ReuseTokenSource(nil, creds)
49+
return refresher.Token()
50+
}
51+
52+
type ghOidcCreds struct {
53+
a *githubactions.Action
54+
}
55+
56+
func (c *ghOidcCreds) oidcTokenSource(ctx context.Context, resource string) (oauth2.TokenSource, error) {
57+
return &ghOidcProxy{ctx: ctx, a: c.a, resource: resource}, nil
4758
}
4859

4960
func (c *ghOidcCreds) Name() string {

acceptance/testenv/loaded.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package testenv
22

33
import (
44
"context"
5+
"encoding/base64"
56
"encoding/json"
67
"fmt"
78
"net/http"
@@ -150,15 +151,47 @@ func (l *loadedEnv) metadataServer(seed *config.Config) *httptest.Server {
150151
Message: "Wrong Authorization header",
151152
})
152153
}
154+
// try parse expiry date from JWT token
155+
exp, err := l.parseExpiryDate(ctx, accessToken)
156+
if err != nil {
157+
logger.Errorf(ctx, "parse expiry date: %s", err)
158+
exp = time.Now().Add(2 * time.Minute).Unix()
159+
}
153160
l.replyJson(ctx, w, 200, msiToken{
154161
TokenType: tokenType,
155162
AccessToken: accessToken,
156-
// TODO: get the real expiry of the token (if we can)
157-
ExpiresOn: json.Number(fmt.Sprint(time.Now().Add(2 * time.Minute).Unix())),
163+
ExpiresOn: json.Number(fmt.Sprint(exp)),
158164
})
159165
}))
160166
}
161167

168+
func (l *loadedEnv) parseExpiryDate(ctx context.Context, tokenString string) (int64, error) {
169+
parts := strings.Split(tokenString, ".")
170+
if len(parts) != 3 {
171+
return 0, fmt.Errorf("invalid token format")
172+
}
173+
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
174+
if err != nil {
175+
return 0, fmt.Errorf("payload: %v", err)
176+
}
177+
var claims map[string]interface{}
178+
err = json.Unmarshal(payload, &claims)
179+
if err != nil {
180+
return 0, fmt.Errorf("json: %v", err)
181+
}
182+
exp, ok := claims["exp"].(float64)
183+
if ok {
184+
logger.Debugf(ctx, "exp is float64: %d", exp)
185+
return int64(exp), nil
186+
}
187+
expInt, ok := claims["exp"].(int64)
188+
if ok {
189+
logger.Debugf(ctx, "exp is int64: %d", expInt)
190+
return expInt, nil
191+
}
192+
return 0, fmt.Errorf("not found")
193+
}
194+
162195
func (l *loadedEnv) replyJson(ctx context.Context, w http.ResponseWriter, status int, body any) {
163196
msg := "<token response>"
164197
apiErrBody, ok := body.(apierr.APIErrorBody)

0 commit comments

Comments
 (0)