diff --git a/build/fixtures/test_trunk_next.yaml b/build/fixtures/test_trunk_next.yaml index d0b733f..9384e89 100644 --- a/build/fixtures/test_trunk_next.yaml +++ b/build/fixtures/test_trunk_next.yaml @@ -8,3 +8,45 @@ release: trunk-next start_date: '2024-10-14T10:28:01.000Z' uuid: 53f9e166-4271-4581-ae3d-b3c1bb0bb081 +- model: repoapi.jenkinsbuildinfo + pk: 1 + fields: + buildnumber: 38542 + date: '2024-10-14 19:31:21' + gerrit_change: '' + gerrit_eventtype: '' + gerrit_patchset: none_might-be-direct-push + git_commit_msg: '' + job_url: 'https://jenkins.mgm.sipwise.com/job/release-copy-debs-yml/' + jobname: release-copy-debs-yml + param_branch: '' + param_distribution: '' + param_ppa: '' + param_release: release-trunk-trixie + param_release_uuid: 53f9e166-4271-4581-ae3d-b3c1bb0bb081 + param_tag: '' + projectname: release-copy-debs-yml + repo_name: '' + result: SUCCESS, + tag: d9e505a5-e942-4687-9b0e-07f43a77a9aa +- model: repoapi.jenkinsbuildinfo + pk: 2 + fields: + buildnumber: 4056 + date: '2024-10-14 19:33:17' + gerrit_change: '' + gerrit_eventtype: '' + gerrit_patchset: none_might-be-direct-push + git_commit_msg: 2eb90b3 Release new version 13.1.0.0+0~mr13.1.0.0 + job_url: 'https://jenkins.mgm.sipwise.com/job/ngcpcfg-repos/' + jobname: ngcpcfg-repos + param_branch: trixie/master + param_distribution: trixie + param_ppa: $ppa + param_release: trunk + param_release_uuid: 53f9e166-4271-4581-ae3d-b3c1bb0bb081 + param_tag: none + projectname: ngcpcfg + repo_name: '' + result: SUCCESS + tag: 7737120e-f512-4793-9c45-47eb4a4f4891 diff --git a/build/test/test_next.py b/build/test/test_next.py index 2d4cb7e..3c5ab25 100644 --- a/build/test/test_next.py +++ b/build/test/test_next.py @@ -12,10 +12,15 @@ # # You should have received a copy of the GNU General Public License along # with this program. If not, see <http://www.gnu.org/licenses/>. +import pprint +import sys from unittest.mock import patch from django.test import override_settings from django.test import SimpleTestCase +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APITestCase from build.conf import settings from build.exceptions import PreviousBuildNotDone @@ -25,6 +30,7 @@ from build.utils import get_simple_release from build.utils import guess_trunk_filename from repoapi.models import JenkinsBuildInfo from repoapi.test.base import BaseTest +from repoapi.utils import get_build_release FIXTURES_PATH = settings.BASE_DIR.joinpath("build", "fixtures") @@ -177,3 +183,98 @@ class BuildReleaseCreate(BaseTest): self.assertEqual(cfg.config_file, "trunk-next.yml") self.assertEqual(cfg.debian_release, "bookworm") self.assertEqual(cfg.release, "trunk-next") + + +@override_settings( + BUILD_REPOS_SCRIPTS_CONFIG_DIR=FIXTURES_PATH.joinpath("config.next") +) +@patch("repoapi.utils.dlfile") +@patch("build.tasks.trigger_build") +class TestViews(BaseTest, APITestCase): + fixtures = ["test_trunk_next"] + release = "trunk" + release_uuid = "53f9e166-4271-4581-ae3d-b3c1bb0bb081" + + def test_release_ok(self, tb, dl): + qs = BuildRelease.objects.filter(uuid=self.release_uuid) + self.assertEqual(qs.count(), 1) + + def test_project_list(self, tb, dl): + url_base = reverse("project-list", args=["trunk-next"]) + url = f"{url_base}?release_uuid={self.release_uuid}" + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + pprint.pp(response.data, stream=sys.stderr) + # ngcpcfg build + self.assertEqual(len(response.data), 1) + info = response.data[0] + self.assertRegex(info["url"], r"http://testserver/release/trunk-next/") + self.assertNotIn(info["projectname"], settings.BUILD_RELEASE_JOBS) + + def test_project_fulllist(self, tb, dl): + url_base = reverse( + "project-fulllist", + args=["trunk-next"], + ) + url = f"{url_base}?release_uuid={self.release_uuid}" + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + pprint.pp(response.data, stream=sys.stderr) + # ngcpcfg build + self.assertEqual(len(response.data), 1) + info = response.data["ngcpcfg"]["7737120e-f512-4793-9c45-47eb4a4f4891"] + self.assertTrue(info["latest"]) + + def test_uuidinfo_list(self, tb, dl): + url_base = reverse( + "uuidinfo-list", + args=[ + "trunk-next", + "ngcpcfg", + "7737120e-f512-4793-9c45-47eb4a4f4891", + ], + ) + url = f"{url_base}?release_uuid={self.release_uuid}" + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + pprint.pp(response.data, stream=sys.stderr) + # ngcpcfg build + self.assertEqual(len(response.data), 1) + + def test_latestuuid_list(self, tb, dl): + url_base = reverse( + "latestuuid-list", + args=["trunk-next", "ngcpcfg"], + ) + url = f"{url_base}?release_uuid={self.release_uuid}" + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + pprint.pp(response.data, stream=sys.stderr) + self.assertEqual( + response.data["tag"], "7737120e-f512-4793-9c45-47eb4a4f4891" + ) + + def test_projectuuid_list(self, tb, dl): + url_base = reverse( + "projectuuid-list", + args=["trunk-next", "ngcpcfg"], + ) + url = f"{url_base}?release_uuid={self.release_uuid}" + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + pprint.pp(response.data, stream=sys.stderr) + info = response.data[0] + self.assertRegex(info["url"], r"http://testserver/release/trunk-next/") + self.assertEqual(info["tag"], "7737120e-f512-4793-9c45-47eb4a4f4891") + self.assertTrue(info["latest"]) + + +@override_settings( + BUILD_REPOS_SCRIPTS_CONFIG_DIR=FIXTURES_PATH.joinpath("config.next") +) +class UtilsRelease(BaseTest): + fixtures = ["test_trunk_next"] + release_uuid = "53f9e166-4271-4581-ae3d-b3c1bb0bb081" + + def test_get_build_release(self): + self.assertEqual(get_build_release(self.release_uuid), "trunk") diff --git a/repoapi/test/test_utils.py b/repoapi/test/test_utils.py index 791b990..9bac10d 100644 --- a/repoapi/test/test_utils.py +++ b/repoapi/test/test_utils.py @@ -85,3 +85,13 @@ class UtilsTestCase(BaseTest): utils.cleanup_build(build_path, dst_path) dst_path.mkdir.assert_not_called() sh.move.assert_called_once_with(build_path, dst_path) + + +class UtilsRelease(BaseTest): + fixtures = ["test_models"] + + def test_get_build_release(self): + release_uuid = "dbe569f7-eab6-4532-a6d1-d31fb559648b" + self.assertEqual( + utils.get_build_release(release_uuid), "release-mr8.1" + ) diff --git a/repoapi/urls.py b/repoapi/urls.py index 4468ec4..00c452a 100644 --- a/repoapi/urls.py +++ b/repoapi/urls.py @@ -75,7 +75,7 @@ api_patterns = [ name="projectuuid-list", ), re_path( - r"^release/(?P<release>[^/]+)" "/(?P<project>[^/]+)/(?P<uuid>[^/]+)/$", + r"^release/(?P<release>[^/]+)/(?P<project>[^/]+)/(?P<uuid>[^/]+)/$", views.UUIDInfoList.as_view(), name="uuidinfo-list", ), diff --git a/repoapi/utils.py b/repoapi/utils.py index 8f1115e..9548473 100644 --- a/repoapi/utils.py +++ b/repoapi/utils.py @@ -19,6 +19,8 @@ from pathlib import Path import requests import structlog +from django.apps import apps +from django.shortcuts import get_object_or_404 from requests.auth import HTTPBasicAuth from .conf import settings @@ -183,6 +185,12 @@ def get_next_release(branch): return None +def get_build_release(release_uuid): + BuildRelease = apps.get_model("build", "BuildRelease") + br = get_object_or_404(BuildRelease, uuid=release_uuid) + return br.build_release + + def is_download_artifacts(jobname): if jobname in settings.JBI_ARTIFACT_JOBS: return True diff --git a/repoapi/views.py b/repoapi/views.py index 9d3a193..780177c 100644 --- a/repoapi/views.py +++ b/repoapi/views.py @@ -1,4 +1,4 @@ -# Copyright (C) 2020-2022 The Sipwise Team - http://sipwise.com +# Copyright (C) 2020-2024 The Sipwise Team - http://sipwise.com # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,7 @@ from rest_framework.views import APIView from . import serializers from .models import JenkinsBuildInfo as jbi +from .utils import get_build_release @api_view(("GET",)) @@ -77,7 +78,10 @@ class ProjectList(APIView): params = {"flat": False} if "release_uuid" in self.request.query_params: params["release_uuid"] = self.request.query_params["release_uuid"] - projects = jbi.objects.release_projects(release, **params) + release_build = get_build_release(params["release_uuid"]) + else: + release_build = release + projects = jbi.objects.release_projects(release_build, **params) if projects is None: return Response({}, status=status.HTTP_404_NOT_FOUND) for project in projects: @@ -94,7 +98,10 @@ class ProjectFullList(APIView): params = {} if "release_uuid" in self.request.query_params: params["release_uuid"] = self.request.query_params["release_uuid"] - projects = jbi.objects.release_projects_full(release, **params) + release_build = get_build_release(params["release_uuid"]) + else: + release_build = release + projects = jbi.objects.release_projects_full(release_build, **params) return Response(projects) @@ -103,9 +110,14 @@ class ProjectUUIDList(APIView): params = {"flat": False} if "release_uuid" in self.request.query_params: params["release_uuid"] = self.request.query_params["release_uuid"] - uuids = jbi.objects.release_project_uuids(release, project, **params) + release_build = get_build_release(params["release_uuid"]) + else: + release_build = release + uuids = jbi.objects.release_project_uuids( + release_build, project, **params + ) params.pop("flat") - latest = jbi.objects.latest_uuid(release, project, **params) + latest = jbi.objects.latest_uuid(release_build, project, **params) for uuid in uuids: uuid["url"] = reverse( "uuidinfo-list", @@ -118,9 +130,14 @@ class ProjectUUIDList(APIView): class UUIDInfoList(APIView): def get(self, request, release, project, uuid, format=None): + if "release_uuid" in self.request.query_params: + release_uuid = self.request.query_params["release_uuid"] + release_build = get_build_release(release_uuid) + else: + release_build = release res = list() jbis = serializers.JenkinsBuildInfoSerializer - jobs = jbi.objects.jobs_by_uuid(release, project, uuid) + jobs = jbi.objects.jobs_by_uuid(release_build, project, uuid) for job in jobs: serializer = jbis(job, context={"request": request}) res.append(serializer.data) @@ -132,5 +149,8 @@ class LatestUUID(APIView): params = {} if "release_uuid" in self.request.query_params: params["release_uuid"] = self.request.query_params["release_uuid"] - res = jbi.objects.latest_uuid(release, project, **params) + release_build = get_build_release(params["release_uuid"]) + else: + release_build = release + res = jbi.objects.latest_uuid(release_build, project, **params) return Response(res)