Skip to content

Commit 3351774

Browse files
committed
feat(api): add tree commits documentation
Part of #86 Closes #811
1 parent 87e409d commit 3351774

File tree

3 files changed

+163
-12
lines changed

3 files changed

+163
-12
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from datetime import datetime
2+
from typing import List
3+
from pydantic import BaseModel, RootModel, Field
4+
5+
from kernelCI_app.typeModels.commonDetails import BuildStatusCount
6+
from kernelCI_app.typeModels.databases import (
7+
Checkout__GitCommitHash,
8+
Checkout__GitCommitName
9+
)
10+
11+
12+
class TreeCommitsTestStatusCount(BaseModel):
13+
fail_count: int = Field(alias="fail")
14+
error_count: int = Field(alias="error")
15+
miss_count: int = Field(alias="miss")
16+
pass_count: int = Field(alias="pass")
17+
done_count: int = Field(alias="done")
18+
skip_count: int = Field(alias="skip")
19+
null_count: int = Field(alias="null")
20+
21+
22+
class TreeCommitsQueryParameters(BaseModel):
23+
origin: str
24+
git_url: str
25+
git_branch: str
26+
start_time_stamp_in_seconds: str
27+
end_time_stamp_in_seconds: str
28+
# TODO: Add filters field in this model
29+
30+
31+
class TreeCommitsData(BaseModel):
32+
git_commit_hash: Checkout__GitCommitHash
33+
git_commit_name: Checkout__GitCommitName
34+
earliest_start_time: datetime
35+
builds: BuildStatusCount
36+
boots: TreeCommitsTestStatusCount
37+
tests: TreeCommitsTestStatusCount
38+
39+
40+
class TreeCommitsResponse(RootModel):
41+
root: List[TreeCommitsData]

backend/kernelCI_app/views/treeCommitsHistory.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from datetime import datetime, timezone
2-
from django.http import JsonResponse, HttpResponseBadRequest
32
from django.db import connection
43
from http import HTTPStatus
5-
from kernelCI_app.helpers.errorHandling import create_error_response
4+
from kernelCI_app.helpers.errorHandling import create_api_error_response
65
from kernelCI_app.helpers.filters import (
76
UNKNOWN_STRING,
87
FilterParams,
@@ -16,12 +15,17 @@
1615
env_misc_value_or_default,
1716
)
1817
from kernelCI_app.typeModels.databases import FAIL_STATUS
19-
from kernelCI_app.utils import getErrorResponseBody, is_boot
18+
from kernelCI_app.utils import is_boot
2019
from rest_framework.views import APIView
2120
from rest_framework.response import Response
22-
from rest_framework import status
21+
from drf_spectacular.utils import extend_schema
2322
from typing import Dict, List, Optional
2423
from kernelCI_app.helpers.treeDetails import create_checkouts_where_clauses
24+
from kernelCI_app.typeModels.treeCommits import (
25+
TreeCommitsQueryParameters,
26+
TreeCommitsResponse,
27+
)
28+
from pydantic import ValidationError
2529

2630

2731
# TODO Move this endpoint to a function so it doesn't
@@ -355,7 +359,12 @@ def _process_time_range(self, request) -> None:
355359
except Exception as ex:
356360
log_message(ex)
357361

358-
def get(self, request, commit_hash):
362+
@extend_schema(
363+
responses=TreeCommitsResponse,
364+
parameters=[TreeCommitsQueryParameters],
365+
methods=["GET"],
366+
)
367+
def get(self, request, commit_hash: Optional[str]) -> Response:
359368
origin_param = request.GET.get("origin")
360369
git_url_param = request.GET.get("git_url")
361370
git_branch_param = request.GET.get("git_branch")
@@ -367,9 +376,8 @@ def get(self, request, commit_hash):
367376
missing_params.append("origin")
368377

369378
if missing_params:
370-
return Response(
371-
{"error": f"Missing parameters: {', '.join(missing_params)}"},
372-
status=status.HTTP_400_BAD_REQUEST,
379+
return create_api_error_response(
380+
error_message=f"Missing parameters: {', '.join(missing_params)}",
373381
)
374382

375383
if None not in (start_timestamp, end_timestamp):
@@ -379,7 +387,7 @@ def get(self, request, commit_hash):
379387
self.filterParams = FilterParams(request)
380388
self.setup_filters()
381389
except InvalidComparisonOP as e:
382-
return HttpResponseBadRequest(getErrorResponseBody(str(e)))
390+
return create_api_error_response(error_message=str(e))
383391

384392
self.field_values = {
385393
"commit_hash": commit_hash,
@@ -478,7 +486,7 @@ def get(self, request, commit_hash):
478486
rows = cursor.fetchall()
479487

480488
if not rows:
481-
return create_error_response(
489+
return create_api_error_response(
482490
error_message="History of tree commits not found",
483491
status_code=HTTPStatus.OK,
484492
)
@@ -519,4 +527,9 @@ def get(self, request, commit_hash):
519527
}
520528
)
521529

522-
return JsonResponse(results, safe=False)
530+
try:
531+
valid_response = TreeCommitsResponse(results)
532+
except ValidationError as e:
533+
return Response(data=e.json(), status=HTTPStatus.INTERNAL_SERVER_ERROR)
534+
535+
return Response(valid_response.model_dump(by_alias=True))

backend/schema.yml

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,36 @@ paths:
582582
schema:
583583
type: string
584584
required: true
585+
- in: query
586+
name: end_time_stamp_in_seconds
587+
schema:
588+
title: End Time Stamp In Seconds
589+
type: string
590+
required: true
591+
- in: query
592+
name: git_branch
593+
schema:
594+
title: Git Branch
595+
type: string
596+
required: true
597+
- in: query
598+
name: git_url
599+
schema:
600+
title: Git Url
601+
type: string
602+
required: true
603+
- in: query
604+
name: origin
605+
schema:
606+
title: Origin
607+
type: string
608+
required: true
609+
- in: query
610+
name: start_time_stamp_in_seconds
611+
schema:
612+
title: Start Time Stamp In Seconds
613+
type: string
614+
required: true
585615
tags:
586616
- tree
587617
security:
@@ -590,7 +620,11 @@ paths:
590620
- {}
591621
responses:
592622
'200':
593-
description: No response body
623+
content:
624+
application/json:
625+
schema:
626+
$ref: '#/components/schemas/TreeCommitsResponse'
627+
description: ''
594628
/api/tree/{commit_hash}/summary:
595629
get:
596630
operationId: tree_summary_retrieve
@@ -2092,6 +2126,69 @@ components:
20922126
- is_selected
20932127
title: Tree
20942128
type: object
2129+
TreeCommitsData:
2130+
properties:
2131+
git_commit_hash:
2132+
$ref: '#/components/schemas/Checkout__GitCommitHash'
2133+
git_commit_name:
2134+
$ref: '#/components/schemas/Checkout__GitCommitName'
2135+
earliest_start_time:
2136+
format: date-time
2137+
title: Earliest Start Time
2138+
type: string
2139+
builds:
2140+
$ref: '#/components/schemas/BuildStatusCount'
2141+
boots:
2142+
$ref: '#/components/schemas/TreeCommitsTestStatusCount'
2143+
tests:
2144+
$ref: '#/components/schemas/TreeCommitsTestStatusCount'
2145+
required:
2146+
- git_commit_hash
2147+
- git_commit_name
2148+
- earliest_start_time
2149+
- builds
2150+
- boots
2151+
- tests
2152+
title: TreeCommitsData
2153+
type: object
2154+
TreeCommitsResponse:
2155+
items:
2156+
$ref: '#/components/schemas/TreeCommitsData'
2157+
title: TreeCommitsResponse
2158+
type: array
2159+
TreeCommitsTestStatusCount:
2160+
properties:
2161+
fail:
2162+
title: Fail
2163+
type: integer
2164+
error:
2165+
title: Error
2166+
type: integer
2167+
miss:
2168+
title: Miss
2169+
type: integer
2170+
pass:
2171+
title: Pass
2172+
type: integer
2173+
done:
2174+
title: Done
2175+
type: integer
2176+
skip:
2177+
title: Skip
2178+
type: integer
2179+
'null':
2180+
title: 'Null'
2181+
type: integer
2182+
required:
2183+
- fail
2184+
- error
2185+
- miss
2186+
- pass
2187+
- done
2188+
- skip
2189+
- 'null'
2190+
title: TreeCommitsTestStatusCount
2191+
type: object
20952192
TreeCommon:
20962193
properties:
20972194
hardware:

0 commit comments

Comments
 (0)