Skip to content

Commit

Permalink
[PTFE-168] ✨ Get job cost & unit testing (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
gaspardmoindrot authored May 15, 2023
1 parent 2f52045 commit caa4b4d
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 8 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ jobs:
uses: trunk-io/trunk-action@v1
tests:
runs-on: ubuntu-latest
strategy:
matrix:
test: [unit, api]
steps:
- uses: actions/checkout@v3
- name: install poetry
Expand All @@ -23,9 +26,9 @@ jobs:
- name: Install dependencies
run: poetry install
- name: Run tests
run: poetry run pytest --cov=. --cov-report=xml
run: poetry run pytest tests/${{ matrix.test }} --cov=. --cov-report=xml
- name: Upload test coverage
uses: codecov/codecov-action@v3
with:
flags: api
flags: ${{ matrix.test }}
if: always()
5 changes: 4 additions & 1 deletion gh_actions_exporter/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@ class ConfigFile(BaseSettings):
class Settings(BaseSettings):
job_relabelling: Optional[List[Relabel]] = []
job_costs: Optional[Dict[str, float]] = {
"ubuntu-latest": 0.008,
"ubuntu-22.04": 0.008,
"ubuntu-20.04": 0.008,
"medium": 0.008,
"large": 0.016,
"xlarge": 0.032,
"2xlarge": 0.064,
"3xlarge": 0.128,
}
default_cost: Optional[float] = 0.008
default_cost: Optional[float] = 0

check_runs_enabled: bool = False
github_app_id: Optional[int]
Expand Down
18 changes: 18 additions & 0 deletions gh_actions_exporter/cost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from githubkit.webhooks import WorkflowJob

from gh_actions_exporter.config import Settings


class Cost(object):
def __init__(self, settings: Settings):
self.settings: Settings = settings

def get_job_cost(self, workflow_job: WorkflowJob, flavor_label: str) -> float:
cost_per_min: float = self.settings.job_costs.get(
flavor_label, self.settings.default_cost
)
duration: int = int(workflow_job.completed_at.timestamp()) - int(
workflow_job.started_at.timestamp()
)

return duration / 60 * cost_per_min
10 changes: 5 additions & 5 deletions gh_actions_exporter/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from prometheus_client import Counter, Histogram

from gh_actions_exporter.config import Relabel, RelabelType, Settings
from gh_actions_exporter.cost import Cost
from gh_actions_exporter.types import WebHook, WorkflowJob


class Metrics(object):
def __init__(self, settings: Settings):
self.settings = settings
self.cost = Cost(settings)
self.workflow_labelnames = [
"repository",
"workflow_name",
Expand Down Expand Up @@ -232,8 +234,6 @@ def flavor_type(self, webhook: WebHook) -> str or None:
def handle_job_cost(self, webhook: WebHook, settings: Settings):
labels = self.job_labels(webhook, settings)
flavor = self.flavor_type(webhook)
cost_per_min = settings.job_costs.get(flavor, settings.default_cost)
if webhook.workflow_job.conclusion and cost_per_min:
duration = self._get_job_duration(webhook)
# Cost of runner is duration / 60 * cost_per_min
self.job_cost.labels(**labels).inc(duration / 60 * cost_per_min)
if webhook.workflow_job.conclusion:
cost = self.cost.get_job_cost(webhook.workflow_job, flavor)
self.job_cost.labels(**labels).inc(cost)
40 changes: 40 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from datetime import datetime, timedelta

import pytest
from githubkit.webhooks import WorkflowJob

from gh_actions_exporter.config import Settings


@pytest.fixture
def workflow_job():
return WorkflowJob(
id=123,
run_id=456789,
run_attempt=1,
run_url="https://github.com/user/repo/actions/runs/123",
head_sha="a1b2c3d4e5f6g7h8i9j0",
node_id="MDg6Q29tbWl0MTIzNDU2Nzg5OnNhbXBsZQ==",
name="Job 1",
check_run_url="https://api.github.com/repos/user/repo/check-runs/123",
html_url="https://github.com/user/repo/actions/runs/123",
url="https://api.github.com/repos/user/repo/actions/jobs/123",
status="queued",
steps=[],
conclusion=None,
labels=["label1", "label2"],
runner_id=None,
runner_name=None,
runner_group_id=None,
runner_group_name=None,
started_at=datetime(2021, 1, 1, 0, 0),
completed_at=datetime(2021, 1, 1, 0, 0) + timedelta(minutes=10),
workflow_name=None,
head_branch=None,
created_at=datetime.now(),
)


@pytest.fixture
def settings():
return Settings()
9 changes: 9 additions & 0 deletions tests/unit/test_cost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from gh_actions_exporter.cost import Cost


def test_get_job_cost(workflow_job, settings):
assert Cost(settings).get_job_cost(workflow_job, "large") == 0.16


def test_job_cost_unknown_label(workflow_job, settings):
assert Cost(settings).get_job_cost(workflow_job, "xxx") == 0

0 comments on commit caa4b4d

Please sign in to comment.