Skip to content

Commit 55d6274

Browse files
committed
Update (base update)
[ghstack-poisoned]
1 parent 23fae37 commit 55d6274

6 files changed

Lines changed: 209 additions & 297 deletions

File tree

aws/lambda/gha-log-uploader/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@ separate function.
4141

4242
It is reached through `lambda:InvokeFunction` rather than its public function URL
4343
(`AuthType: NONE`), so the path from here to classification never crosses a
44-
public endpoint. `log_classifier` builds on `lambda_http` with only the
45-
`apigw_http` feature, so `classifier_payload()` reproduces an API Gateway HTTP API
46-
v2.0 request. Verified against the deployed function: a payload with no `job_id`
47-
returns its 400 "no job id provided" branch, and a non-numeric one fails inside
48-
its `parse::<usize>()`, which together show both the envelope and the query
49-
string are read from a direct invoke.
44+
public endpoint. A function URL would not work anyway: those only support the
45+
`RequestResponse` invocation type, so calling one means waiting for
46+
classification to finish.
47+
48+
The payload is just `{"job_id": ..., "repo": "..."}`. `log_classifier` accepts
49+
that shape alongside the API Gateway request its function URL callers send — see
50+
`parse_request` in `../log-classifier/src/main.rs`, whose
51+
`parses_a_direct_invoke_payload` test pins this contract from the other side.
5052

5153
A failed handoff is logged and reported as `classified: false`, not raised.
5254
Raising would make Lambda retry the whole function, re-downloading a

aws/lambda/gha-log-uploader/lambda_function.py

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -135,56 +135,21 @@ def log_object_path(full_name, job_id):
135135
return f"log/{full_name}/{job_id}"
136136

137137

138-
def classifier_payload(full_name, job_id):
139-
"""An API Gateway HTTP API v2.0 request, which is what lambda_http parses.
140-
141-
log_classifier is built on lambda_http with only the `apigw_http` feature, so
142-
it expects this envelope even on a direct invoke. Verified against the
143-
deployed function: a payload with no `job_id` returns its 400 "no job id
144-
provided" branch, and a non-numeric one fails in its `parse::<usize>()`,
145-
which together show both the envelope and the query string are read.
146-
"""
147-
return {
148-
"version": "2.0",
149-
"routeKey": "$default",
150-
"rawPath": "/",
151-
"rawQueryString": f"job_id={job_id}&repo={full_name}",
152-
"headers": {},
153-
"queryStringParameters": {"job_id": str(job_id), "repo": full_name},
154-
"requestContext": {
155-
"accountId": "308535385114",
156-
"apiId": "gha-log-uploader",
157-
"domainName": "lambda-invoke",
158-
"domainPrefix": "lambda-invoke",
159-
"http": {
160-
"method": "GET",
161-
"path": "/",
162-
"protocol": "HTTP/1.1",
163-
"sourceIp": "127.0.0.1",
164-
"userAgent": "gha-log-uploader",
165-
},
166-
"requestId": f"gha-log-uploader-{job_id}",
167-
"routeKey": "$default",
168-
"stage": "$default",
169-
"time": "01/Jan/1970:00:00:00 +0000",
170-
"timeEpoch": 0,
171-
},
172-
"isBase64Encoded": False,
173-
}
174-
175-
176138
def classify_log(full_name, job_id):
177139
"""Kick off classification for a log we just stored. Returns True on handoff.
178140
179141
Asynchronous, and reached through `lambda:InvokeFunction` rather than
180142
log_classifier's public function URL, so the path from here to classification
181-
never crosses a public endpoint.
143+
never crosses a public endpoint. A function URL would not do: it only supports
144+
the RequestResponse invocation type, so using one means waiting for
145+
classification to finish -- which is exactly the mistake that gave
146+
github-status-test its multi-hundred-second tails.
182147
"""
183148
try:
184149
lambda_client.invoke(
185150
FunctionName=LOG_CLASSIFIER_FUNCTION,
186151
InvocationType="Event",
187-
Payload=json.dumps(classifier_payload(full_name, job_id)).encode(),
152+
Payload=json.dumps({"job_id": job_id, "repo": full_name}).encode(),
188153
)
189154
return True
190155
except Exception as err:

aws/lambda/gha-log-uploader/test_lambda_function.py

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import lambda_function
66
from lambda_function import (
7-
classifier_payload,
87
classify_log,
98
download_log,
109
installation_token,
@@ -56,23 +55,6 @@ def test_rejects_a_non_object_payload(self):
5655
parse_event(["pytorch/pytorch", 123])
5756

5857

59-
class TestClassifierPayload(unittest.TestCase):
60-
def test_is_a_v2_request_the_classifier_can_parse(self):
61-
payload = classifier_payload("pytorch/executorch", 999)
62-
# log_classifier builds on lambda_http with only the apigw_http feature,
63-
# so version 2.0 and requestContext.http are what make it deserialize.
64-
self.assertEqual(payload["version"], "2.0")
65-
self.assertIn("http", payload["requestContext"])
66-
self.assertEqual(
67-
payload["queryStringParameters"],
68-
{"job_id": "999", "repo": "pytorch/executorch"},
69-
)
70-
self.assertEqual(payload["rawQueryString"], "job_id=999&repo=pytorch/executorch")
71-
72-
def test_is_json_serializable(self):
73-
json.dumps(classifier_payload("pytorch/pytorch", 1))
74-
75-
7658
class TestClassifyLog(unittest.TestCase):
7759
def test_invokes_the_classifier_asynchronously(self):
7860
with patch.object(lambda_function, "lambda_client") as client:
@@ -83,9 +65,11 @@ def test_invokes_the_classifier_asynchronously(self):
8365
# Event, not RequestResponse: waiting on classification is exactly the
8466
# mistake that gave github-status-test its multi-hundred-second tails.
8567
self.assertEqual(kwargs["InvocationType"], "Event")
68+
# The plain shape log_classifier's parse_request accepts. Its
69+
# parses_a_direct_invoke_payload test pins the other side of this.
8670
self.assertEqual(
87-
json.loads(kwargs["Payload"])["queryStringParameters"],
88-
{"job_id": "123", "repo": "pytorch/pytorch"},
71+
json.loads(kwargs["Payload"]),
72+
{"job_id": 123, "repo": "pytorch/pytorch"},
8973
)
9074

9175
def test_a_failed_invoke_is_reported_not_raised(self):

0 commit comments

Comments
 (0)