Skip to content

Commit bc8e716

Browse files
committed
feat: add instrumentation in e2e for GH API calls
- Introduced a mechanism to collect GitHub API call metrics from controller logs during E2E tests. - Added logic to parse structured log entries for API calls at the end of each test run. - Stored the collected data, including operation, duration, and status code, in a structured JSON report. - Updated the CI workflow to archive the generated reports for analysis and monitoring. Signed-off-by: Chmouel Boudjnah <[email protected]>
1 parent 8346f33 commit bc8e716

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

test/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ this repo should differ from the one which is configured as part of `TEST_GITHUB
5858
- `TEST_BITBUCKET_SERVER_API_URL` - URL where your Bitbucket Data Center instance is running.
5959
- `TEST_BITBUCKET_SERVER_WEBHOOK_SECRET` - Webhook secret
6060

61+
- `PAC_API_INSTRUMENTATION_DIR` - Optional. When set, E2E tests write per-test JSON reports of GitHub API calls parsed from controller logs to this directory. Useful for analyzing API usage and rate limits. Example: `export PAC_API_INSTRUMENTATION_DIR=/tmp/api-instrumentation`.
62+
6163
You don't need to configure all of those if you restrict running your e2e tests to a subset.
6264

6365
## Running
@@ -155,6 +157,57 @@ The `hack/gh-workflow-ci.sh` script contains several functions that assist in th
155157

156158
The script filters tests by category using pattern matching on test function names.
157159

160+
> [!NOTE]
161+
> For details on how API call metrics are generated and archived as artifacts, see [API Instrumentation (optional)](#api-instrumentation-optional).
162+
163+
### API Instrumentation (optional)
164+
165+
To help debug and analyze GitHub API usage during E2E runs, tests can emit
166+
structured JSON reports of API calls when the environment variable
167+
`PAC_API_INSTRUMENTATION_DIR` is set.
168+
169+
> [!NOTE]
170+
> Currently supported only for GitHub (both GitHub App and GitHub webhook flows). Support for other providers is planned.
171+
172+
- Set `PAC_API_INSTRUMENTATION_DIR` to a writable path before running tests,
173+
for example:
174+
- `export PAC_API_INSTRUMENTATION_DIR=/tmp/api-instrumentation`
175+
- Each test produces a file named like `YYYY-MM-DDTHH-MM-SS_<test_name>.json` containing summary fields and an array of API calls (operation, duration_ms, url_path, status_code, rate_limit_remaining, provider, repo).
176+
- In CI, this variable defaults to `/tmp/api-instrumentation` and `hack/gh-workflow-ci.sh collect_logs` copies the directory into the uploaded artifacts.
177+
178+
Log source details:
179+
180+
- Parses controller pod logs from the `pac-controller` container.
181+
- Uses label selector `app.kubernetes.io/name=controller` (or `ghe-controller` when testing against GHE).
182+
- Considers only log lines after the last occurrence of `github-app: initialized OAuth2 client`.
183+
- Matches lines containing `GitHub API call completed` and extracts the embedded JSON payload.
184+
185+
Sample output:
186+
187+
```json
188+
{
189+
"test_name": "TestGithubAppSimple",
190+
"timestamp": "2025-08-05T16:12:20Z",
191+
"controller": "controller",
192+
"pr_number": 123,
193+
"sha": "abcdef1",
194+
"target_namespace": "pac-e2e-ns-xyz12",
195+
"total_calls": 2,
196+
"oauth2_marker_line": 42,
197+
"github_api_calls": [
198+
{
199+
"operation": "get_commit",
200+
"duration_ms": 156,
201+
"url_path": "/api/v3/repos/org/repo/git/commits/62a0...",
202+
"rate_limit_remaining": "",
203+
"status_code": 200,
204+
"provider": "github",
205+
"repo": "org/repo"
206+
}
207+
]
208+
}
209+
```
210+
158211
### Test Execution Flow
159212

160213
1. **Setup**:
@@ -176,6 +229,7 @@ The script filters tests by category using pattern matching on test function nam
176229
- Collect logs regardless of test outcome
177230
- Detect any panic in the controller logs
178231
- Upload artifacts to GitHub Actions
232+
- If `PAC_API_INSTRUMENTATION_DIR` is set, include API instrumentation reports (see [API Instrumentation (optional)](#api-instrumentation-optional))
179233

180234
### Debugging CI
181235

test/pkg/github/instrumentation.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ type TestResult struct {
3939
OAuth2MarkerLine int `json:"oauth2_marker_line"`
4040
}
4141

42+
// collectGitHubAPICalls collects GitHub API calls from the controller logs.
43+
// It retrieves logs from the controller pod, searches for the last OAuth2 initialization marker,
44+
// the Oauth2 marker shows even if the controller is not using github app, so
45+
// we can use it to find the start of the API calls.
46+
// TODO(chmouel): Fix Oauth2 marker to be more specific to GitHub App usage and
47+
// not github webhook. use another marker for github webhook.
48+
// TODO(chmouel): Add support for Gitlab.
49+
// TODO(chmouel): Add support for Bitbucket.
50+
// TODO(chmouel): Add support for Gitea.
4251
func (g *PRTest) collectGitHubAPICalls(ctx context.Context, _ *testing.T) {
4352
numLines := int64(100)
4453
controllerName := "controller"

0 commit comments

Comments
 (0)