blob: 8a362ef3d5855833b70f367fe07eaeb58d6b481e [file] [log] [blame]
Oleksii Petrenko99539bd2020-07-31 20:00:06 +03001import datetime
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +03002import json
3import os
4
stavrovska28772bc2024-05-22 09:33:50 +02005from django.shortcuts import HttpResponse, redirect, render
Anna Arhipova22ea6bf2024-02-20 15:25:30 +01006from django_celery_beat.models import CrontabSchedule, PeriodicTasks
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +03007
stavrovska28772bc2024-05-22 09:33:50 +02008from . import forms, models
9from .celery_tasks import test_rail_api
10from .celery_tasks.tasks import (
11 get_test_passability_in_suite,
12 process_run,
13 update_plot_data,
14)
15from .utils import get_dict_diff, short_names_for_dict
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030016
17
18def index(request):
Oleksii Petrenko68268172020-09-28 16:58:13 +030019 runs = models.TestRailTestRun.objects.all()
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030020 return render(request, "control/index.html", {"runs": runs})
21
22
23def redirect_to_index(request):
24 return redirect("index")
25
26
27def single_run(request, run_id):
Oleksii Petrenko68268172020-09-28 16:58:13 +030028 run = models.TestRailTestRun.objects.get(pk=run_id)
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030029 if request.method == "POST":
30 form = forms.TestRunForm(request.POST, instance=run)
31 if form.is_valid():
32 form.save()
33 return redirect("single_run", run_id)
34 else:
35 form = forms.TestRunForm(instance=run)
36
stavrovska28772bc2024-05-22 09:33:50 +020037 return render(
38 request,
39 "control/update_run.html",
40 {"form": form, "run_id": run_id, "checked_tests": run.checked_tests},
41 )
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030042
43
44def create_run(request):
45 if request.method == "POST":
46 form = forms.TestRunForm(request.POST)
47 if form.is_valid():
48 obj = form.save()
49 return redirect("single_run", obj.id)
50 else:
51 form = forms.TestRunForm()
52
stavrovska28772bc2024-05-22 09:33:50 +020053 form.fields["created_after"].initial = (
54 datetime.date.today() + datetime.timedelta(days=-3 * 30)
55 )
Anna Arhipova62760612023-11-28 23:20:38 +010056 form.fields["created_before"].initial = datetime.date.today()
Anna Arhipova175d4712023-11-06 11:19:44 +010057 return render(request, "control/update_run.html", {"form": form})
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030058
59
60def list_reports(request):
Oleksii Petrenko68268172020-09-28 16:58:13 +030061 reports = models.TestRailReport.objects.order_by("-created_at").all()
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030062 return render(request, "control/reports.html", {"reports": reports})
63
64
65def single_report(request, report_id):
Oleksii Petrenko68268172020-09-28 16:58:13 +030066 report = models.TestRailReport.objects.get(pk=report_id)
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030067 data = report.path.read().decode("utf-8")
stavrovska28772bc2024-05-22 09:33:50 +020068 if (
69 request.method == "POST"
70 and request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest"
71 ):
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030072 return HttpResponse(
73 json.dumps({"data": data, "finished": report.finished}),
stavrovska28772bc2024-05-22 09:33:50 +020074 content_type="application/json",
75 )
Anna Arhipova175d4712023-11-06 11:19:44 +010076
stavrovska28772bc2024-05-22 09:33:50 +020077 return render(
78 request,
79 "control/report.html",
80 {"report_id": report.id, "report": data, "finished": report.finished},
81 )
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030082
83
Anna Arhipova6ecdd342023-11-21 13:43:37 +010084def delete_report(request, report_id):
stavrovska28772bc2024-05-22 09:33:50 +020085 report: models.TestRailReport = models.TestRailReport.objects.get(
86 pk=report_id
87 )
Anna Arhipova6ecdd342023-11-21 13:43:37 +010088 try:
89 os.remove(report.path.path)
90 except FileNotFoundError:
91 pass
92 report.delete()
93 return redirect("list_reports")
94
95
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030096def submit_run(request, run_id):
Oleksii Petrenko68268172020-09-28 16:58:13 +030097 run = models.TestRailTestRun.objects.get(pk=run_id)
Anna Arhipovae9258f32023-11-04 12:31:19 +010098 is_testplan = test_rail_api.is_testplan(run.run_id)
Anna Arhipovae9258f32023-11-04 12:31:19 +010099 if is_testplan:
100 testrail_run = test_rail_api.get_plan_by_id(run.run_id)
101 else:
102 testrail_run = test_rail_api.get_run_by_id(run.run_id)
Sofiia Andriichenko4b440da2023-02-10 12:29:46 +0100103 if not run.run_name:
Anna Arhipovaf1ea3ee2024-01-24 13:29:09 +0100104 if is_testplan:
105 _name = f"Plan {testrail_run['name']}"
106 else:
107 parent_plan_id = testrail_run["plan_id"]
stavrovska28772bc2024-05-22 09:33:50 +0200108 parent_plan_name = test_rail_api.get_plan_by_id(parent_plan_id)[
109 "name"
110 ]
Anna Arhipovaf1ea3ee2024-01-24 13:29:09 +0100111 _name = f"Run {testrail_run['name']} from {parent_plan_name}"
112 run.run_name = _name
113 run.save()
114
Sofiia Andriichenko4b440da2023-02-10 12:29:46 +0100115 report_name = "{}-run_id-{}-date-{}".format(
Anna Arhipovaf1ea3ee2024-01-24 13:29:09 +0100116 run.run_name,
117 run.run_id,
stavrovska28772bc2024-05-22 09:33:50 +0200118 datetime.datetime.isoformat(datetime.datetime.now()),
119 )
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300120 path = os.path.join(models.fs.location, report_name)
121 with open(path, "w"):
122 pass
123
stavrovska28772bc2024-05-22 09:33:50 +0200124 report = models.TestRailReport(report_name=report_name, path=path)
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300125 report.save()
Anna Arhipovae9258f32023-11-04 12:31:19 +0100126 process_run.delay(run_id, report.id, path, is_testplan)
Oleksii Petrenko12508832020-07-10 18:13:53 +0300127 return redirect("single_report", report.id)
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300128
129
Anna Arhipova52cdec92023-10-05 23:05:48 +0200130def delete_run(request, run_id):
131 run = models.TestRailTestRun.objects.get(pk=run_id)
132 run.delete()
133 return redirect("index")
134
135
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300136def show_help(request):
137 return render(request, "control/help.html")
Oleksii Petrenko68268172020-09-28 16:58:13 +0300138
139
140def update_jenkins_plot(request):
141 try:
142 models.ActionLog.objects.get(name="update_plot_started")
143 return HttpResponse("Update in progress", status=403)
144 except models.ActionLog.DoesNotExist:
145 pass
146 update = models.ActionLog(
stavrovska28772bc2024-05-22 09:33:50 +0200147 name="update_plot_started", date=datetime.datetime.now()
148 )
Oleksii Petrenko68268172020-09-28 16:58:13 +0300149 update.save()
150 update_plot_data.delay()
151 return HttpResponse("Started Update", status=200)
152
153
154def jenkins_plot(request):
155 try:
156 update_date = models.ActionLog.objects.get(
stavrovska28772bc2024-05-22 09:33:50 +0200157 name="update_jenkins_plot"
158 ).date
Oleksii Petrenko68268172020-09-28 16:58:13 +0300159 except models.ActionLog.DoesNotExist:
160 update_date = None
161 try:
162 models.ActionLog.objects.get(name="update_plot_started")
163 update_started = True
164 except models.ActionLog.DoesNotExist:
165 update_started = False
166
167 job_names_path = os.path.join(models.fs.location, "job_names.txt")
168 job_names = []
169 if os.path.exists(job_names_path):
170 try:
171 with open(job_names_path, "r") as f:
172 job_names = json.load(f)
stavrovska28772bc2024-05-22 09:33:50 +0200173 except Exception:
Oleksii Petrenko68268172020-09-28 16:58:13 +0300174 pass
175
176 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200177 request,
178 "control/jenkins_plot.html",
179 {
180 "update_date": update_date,
181 "update_started": update_started,
182 "job_names": enumerate(job_names, 1),
183 },
184 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100185
186
187def submit_suites(request):
188 form = forms.DiffPassRatesForm(request.POST)
189 if not form.is_valid():
190 print(f"{form.errors=}")
191 return
192 report1 = models.SuitePassRate(suite_id=request.POST["first-suite_id"])
193 report1.save()
194 report2 = models.SuitePassRate(suite_id=request.POST["second-suite_id"])
195 report2.save()
196
197 diff_model = models.DiffOfSuitesPassRates(
198 report1=report1,
199 report2=report2,
200 limit=form.cleaned_data["limit"],
stavrovska28772bc2024-05-22 09:33:50 +0200201 test_keyword=form.cleaned_data["test_keyword"],
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100202 )
203 diff_model.save()
204 get_test_passability_in_suite.delay(diff_model.id, report1.id)
205 get_test_passability_in_suite.delay(diff_model.id, report2.id)
206
207 return redirect("report_comparing_suites", diff_model.id)
208
209
210def compare_suites(request):
211 if request.method == "POST":
212 return submit_suites(request)
213
214 diff_form = forms.DiffPassRatesForm()
stavrovska28772bc2024-05-22 09:33:50 +0200215 report1_form = forms.SuitePassRateForm(prefix="first")
216 report2_form = forms.SuitePassRateForm(prefix="second")
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100217
218 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200219 request,
220 "control/compare_suites.html",
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100221 {
stavrovska28772bc2024-05-22 09:33:50 +0200222 "diff_form": diff_form,
223 "report1_form": report1_form,
224 "report2_form": report2_form,
225 "finished": None,
226 },
227 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100228
229
230def list_of_comparing_reports(request):
231 list_of_reports = models.DiffOfSuitesPassRates.objects.all()
232 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200233 request,
234 "control/list_comparing_suites.html",
235 {"reports": list_of_reports},
236 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100237
238
239def report_comparing_suites(request, report_id):
240 report = models.DiffOfSuitesPassRates.objects.get(pk=report_id)
stavrovska28772bc2024-05-22 09:33:50 +0200241 passrate1 = short_names_for_dict(
242 json.loads(report.report1.passrate_by_tests)
243 )
244 passrate2 = short_names_for_dict(
245 json.loads(report.report2.passrate_by_tests)
246 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100247
stavrovska28772bc2024-05-22 09:33:50 +0200248 diff_table = get_dict_diff(
249 dict1=passrate1, dict2=passrate2, compare_by_key="rate"
250 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100251 diff_form = forms.DiffPassRatesForm(instance=report)
stavrovska28772bc2024-05-22 09:33:50 +0200252 report1_form = forms.SuitePassRateForm(
253 instance=report.report1, prefix="first"
254 )
255 report2_form = forms.SuitePassRateForm(
256 instance=report.report2, prefix="second"
257 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100258
259 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200260 request,
261 "control/compare_suites.html",
262 {
263 "diff_form": diff_form,
264 "report1_form": report1_form,
265 "report2_form": report2_form,
266 "report1": report.report1,
267 "report2": report.report2,
268 "is_finished": report.report1.finished and report.report2.finished,
269 "diff_table": diff_table,
270 },
271 )
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100272
273
274def schedulers(request):
275
276 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200277 request,
278 "control/schedulers.html",
279 {"schedulers": models.CronPeriodicTask.objects.all()},
280 )
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100281
282
283def scheduler(request, pk=None):
284 if request.method == "POST":
285 return save_scheduler(request)
286
287 if pk:
288 task_pk = models.CronPeriodicTask.objects.get(pk=pk)
289 form = forms.PeriodicTaskForm(instance=task_pk)
290 else:
291 form = forms.PeriodicTaskForm()
292
293 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200294 request,
295 "control/scheduler.html",
296 {"form": form, "pk": pk, "TASKS": models.TASKS},
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100297 )
298
299
300def save_scheduler(request, pk=None):
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100301 print(f"{request.POST=}")
stavrovska28772bc2024-05-22 09:33:50 +0200302 minute, hour, day_of_month, month_of_year, day_of_week = request.POST.get(
303 "cron", "* * * * *"
304 ).split(" ")
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100305 if pk is None:
306 sch = CrontabSchedule.objects.create(
307 minute=minute,
308 hour=hour,
309 day_of_month=day_of_month,
310 month_of_year=month_of_year,
stavrovska28772bc2024-05-22 09:33:50 +0200311 day_of_week=day_of_week,
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100312 )
313 task = models.CronPeriodicTask.objects.create(
314 crontab=sch,
315 cron=request.POST.get("cron"),
316 name=request.POST.get("name"),
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100317 task_name=request.POST.get("task_name"),
stavrovska28772bc2024-05-22 09:33:50 +0200318 enabled=request.POST.get("enabled") == "on",
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100319 testplan_id_arg=request.POST.get("testplan_id_arg"),
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100320 )
321 else:
322 task = models.CronPeriodicTask.objects.get(pk=pk)
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100323
324 task.task = request.POST.get("task_name")
325 task.args = json.dumps((request.POST.get("testplan_id_arg"),))
326
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100327 form = forms.PeriodicTaskForm(request.POST, instance=task)
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100328
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100329 CrontabSchedule.objects.filter(id=task.crontab.id).update(
330 minute=minute,
331 hour=hour,
332 day_of_month=day_of_month,
333 month_of_year=month_of_year,
stavrovska28772bc2024-05-22 09:33:50 +0200334 day_of_week=day_of_week,
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100335 )
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100336 if not form.is_valid():
337 print(f"{form.errors=}")
338 return
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100339 form.save()
340 PeriodicTasks.update_changed()
341 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200342 request,
343 "control/scheduler.html",
344 {"form": form, "pk": task.id, "TASKS": models.TASKS},
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100345 )
346
347
348def delete_scheduler(request, pk):
349 task = models.CronPeriodicTask.objects.get(pk=pk)
350 task.delete()
351 return redirect("schedulers")