1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
#!/usr/bin/env python3
# Copyright © 2025 Collabora Ltd.
# Authors:
# Sergi Blanch Torne <sergi.blanch.torne@collabora.com>
#
# SPDX-License-Identifier: MIT
from dataclasses import dataclass
from datetime import timedelta
from unittest import TestCase
from typing import Iterable
from marge_queue import MargeMergeRequest, MargeQueue, get_merge_queue
DATA = {
37564: {
# sample of a Merge Request rejected by marge and later reassigned to marge
"updated_at": "2025-09-25T10:59:27.144Z",
"title": "etnaviv: Fix util_blitter_save_so_targets(..) call",
"notes": [
# Those notes must be listed in reverse order
# because the list is requested sort="desc"
{
"body": "assigned to @marge-bot and unassigned @austriancoder",
"created_at": "2025-09-25T11:44:01.672Z",
},
{
"body": "added 1 commit",
"created_at": "2025-09-25T10:43:43.490Z",
},
{
"body": "This branch couldn't be merged:",
"created_at": "2025-09-25T10:42:27.817Z",
},
{
"body": "assigned to @austriancoder and unassigned @marge-bot",
"created_at": "2025-09-25T10:42:15.404Z",
},
{
"body": "added 3 commits",
"created_at": "2025-09-25T10:38:57.332Z",
},
{
"body": "assigned to @marge-bot",
"created_at": "2025-09-25T10:38:03.993Z",
},
],
},
37560: {
# sample of a Merge Request assigned to marge between the two
# assignments of the previous sample. This is meant to show that
# this goes first in the queue, and it doesn't confuses the sequence.
"updated_at": "2025-09-25T11:38:08.420Z",
"title": "tu: limit query pool types logged into RMV",
"notes": [
{
"body": "assigned to @marge-bot",
"created_at": "2025-09-25T10:47:40.040Z",
},
{
"body": "added 1 commit",
"created_at": "2025-09-25T10:46:42.113Z",
},
{
"body": "mentioned in issue #13970",
"created_at": "2025-09-25T10:45:35.566Z",
},
{
"body": "Rb",
"created_at": "2025-09-25T08:25:51.527Z",
},
],
},
}
@dataclass
class ProjectMergeRequestNote:
body: str
created_at: str
@dataclass
class ProjectMergeRequestNoteManager:
"""
Mock the gitlab.v4.objects.ProjectMergeRequestNoteManager
"""
iid: int
def list(self, *args, **kwargs) -> Iterable:
for note in DATA[self.iid]["notes"]:
yield ProjectMergeRequestNote(**note)
@dataclass
class ProjectMergeRequest:
"""
Mock the gitlab.v4.objects.ProjectMergeRequest
"""
iid: int
@property
def updated_at(self) -> str:
return DATA[self.iid]["updated_at"]
@property
def web_url(self) -> str:
return f"https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/{self.iid}"
@property
def title(self) -> str:
return DATA[self.iid]["title"]
@property
def notes(self) -> ProjectMergeRequestNoteManager:
return ProjectMergeRequestNoteManager(self.iid)
@dataclass
class ProjectMergeRequestManager:
"""
Mock the gitlab.v4.objects.ProjectMergeRequestManager
"""
def list(self, *args, **kwargs) -> Iterable:
for mr in DATA.keys():
yield ProjectMergeRequest(mr)
@dataclass
class Project:
"""
Mock the gitlab.v4.objects.Project
"""
@property
def mergerequests(self) -> ProjectMergeRequestManager:
return ProjectMergeRequestManager()
class MargeMergeTestCase(TestCase):
def test_queue(self) -> None:
queue = MargeQueue()
for mr_id in DATA.keys():
gl_mr_mock_obj = ProjectMergeRequest(mr_id)
marge_mr = MargeMergeRequest(gl_mr_mock_obj)
# for each element in the data sample, test the MargeMergeRequest construction
self.assertEqual(marge_mr.title, gl_mr_mock_obj.title)
self.assertEqual(marge_mr.web_url, gl_mr_mock_obj.web_url)
self.assertIsInstance(marge_mr.time_enqueued, timedelta)
queue.append(marge_mr)
self.assertEqual(queue.n_merge_requests_enqueued, 2)
def test_get_merge_queue(self) -> None:
project = Project()
queue = get_merge_queue(project)
self.assertEqual(queue.n_merge_requests_enqueued, 2)
self.assertEqual(len(queue.sorted_queue), 2)
# They are in reverse order because of the reassignment to marge
self.assertEqual(queue.sorted_queue[0].id, list(DATA.keys())[1])
self.assertEqual(queue.sorted_queue[1].id, list(DATA.keys())[0])
self.assertEqual(len(queue.undetermined), 0)
for marge_mr in queue.sorted_queue:
mr_id = marge_mr.id
self.assertEqual(marge_mr.title, DATA[mr_id]["title"])
self.assertEqual(
marge_mr.web_url,
f"https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/{mr_id}"
)
self.assertIsInstance(marge_mr.time_enqueued, timedelta)
|