blob: 350f9da7890b12159dfbd2ea388a752b972ed94e [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):
Anna Arhipovaa843b462024-07-06 17:37:00 +020066 report: models.TestRailReport = models.TestRailReport.objects.get(
67 pk=report_id
68 )
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030069 data = report.path.read().decode("utf-8")
stavrovska28772bc2024-05-22 09:33:50 +020070 if (
71 request.method == "POST"
72 and request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest"
73 ):
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030074 return HttpResponse(
75 json.dumps({"data": data, "finished": report.finished}),
stavrovska28772bc2024-05-22 09:33:50 +020076 content_type="application/json",
77 )
Anna Arhipova175d4712023-11-06 11:19:44 +010078
Anna Arhipovaa843b462024-07-06 17:37:00 +020079 test_results = [
80 models.TestResult.objects.filter(result_id=test_id)[0]
81 for test_id in report.test_results
82 ]
stavrovska28772bc2024-05-22 09:33:50 +020083 return render(
84 request,
85 "control/report.html",
Anna Arhipovaa843b462024-07-06 17:37:00 +020086 {"report_obj": report, "report": data, "test_results": test_results},
stavrovska28772bc2024-05-22 09:33:50 +020087 )
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +030088
89
Anna Arhipovaa843b462024-07-06 17:37:00 +020090def update_test_result(request, report_id, result_id, action_needed):
91 result = models.TestResult.objects.get(result_id=result_id)
92 result.action_needed = bool(action_needed)
93 result.save()
94 print(result.__dict__)
95 return redirect("single_report", report_id)
96
97
Anna Arhipova6ecdd342023-11-21 13:43:37 +010098def delete_report(request, report_id):
stavrovska28772bc2024-05-22 09:33:50 +020099 report: models.TestRailReport = models.TestRailReport.objects.get(
100 pk=report_id
101 )
Anna Arhipova6ecdd342023-11-21 13:43:37 +0100102 try:
103 os.remove(report.path.path)
104 except FileNotFoundError:
105 pass
106 report.delete()
107 return redirect("list_reports")
108
109
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300110def submit_run(request, run_id):
Oleksii Petrenko68268172020-09-28 16:58:13 +0300111 run = models.TestRailTestRun.objects.get(pk=run_id)
Anna Arhipovae9258f32023-11-04 12:31:19 +0100112 is_testplan = test_rail_api.is_testplan(run.run_id)
Anna Arhipovae9258f32023-11-04 12:31:19 +0100113 if is_testplan:
114 testrail_run = test_rail_api.get_plan_by_id(run.run_id)
115 else:
116 testrail_run = test_rail_api.get_run_by_id(run.run_id)
Sofiia Andriichenko4b440da2023-02-10 12:29:46 +0100117 if not run.run_name:
Anna Arhipovaf1ea3ee2024-01-24 13:29:09 +0100118 if is_testplan:
119 _name = f"Plan {testrail_run['name']}"
120 else:
121 parent_plan_id = testrail_run["plan_id"]
stavrovska28772bc2024-05-22 09:33:50 +0200122 parent_plan_name = test_rail_api.get_plan_by_id(parent_plan_id)[
123 "name"
124 ]
Anna Arhipovaf1ea3ee2024-01-24 13:29:09 +0100125 _name = f"Run {testrail_run['name']} from {parent_plan_name}"
126 run.run_name = _name
127 run.save()
128
Sofiia Andriichenko4b440da2023-02-10 12:29:46 +0100129 report_name = "{}-run_id-{}-date-{}".format(
Anna Arhipovaf1ea3ee2024-01-24 13:29:09 +0100130 run.run_name,
131 run.run_id,
stavrovska28772bc2024-05-22 09:33:50 +0200132 datetime.datetime.isoformat(datetime.datetime.now()),
133 )
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300134 path = os.path.join(models.fs.location, report_name)
135 with open(path, "w"):
136 pass
137
stavrovska28772bc2024-05-22 09:33:50 +0200138 report = models.TestRailReport(report_name=report_name, path=path)
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300139 report.save()
Anna Arhipovae9258f32023-11-04 12:31:19 +0100140 process_run.delay(run_id, report.id, path, is_testplan)
Oleksii Petrenko12508832020-07-10 18:13:53 +0300141 return redirect("single_report", report.id)
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300142
143
Anna Arhipova52cdec92023-10-05 23:05:48 +0200144def delete_run(request, run_id):
145 run = models.TestRailTestRun.objects.get(pk=run_id)
146 run.delete()
147 return redirect("index")
148
149
Oleksii Petrenko24f1f8f2020-06-26 18:09:43 +0300150def show_help(request):
151 return render(request, "control/help.html")
Oleksii Petrenko68268172020-09-28 16:58:13 +0300152
153
154def update_jenkins_plot(request):
155 try:
156 models.ActionLog.objects.get(name="update_plot_started")
157 return HttpResponse("Update in progress", status=403)
158 except models.ActionLog.DoesNotExist:
159 pass
160 update = models.ActionLog(
stavrovska28772bc2024-05-22 09:33:50 +0200161 name="update_plot_started", date=datetime.datetime.now()
162 )
Oleksii Petrenko68268172020-09-28 16:58:13 +0300163 update.save()
164 update_plot_data.delay()
165 return HttpResponse("Started Update", status=200)
166
167
168def jenkins_plot(request):
169 try:
170 update_date = models.ActionLog.objects.get(
stavrovska28772bc2024-05-22 09:33:50 +0200171 name="update_jenkins_plot"
172 ).date
Oleksii Petrenko68268172020-09-28 16:58:13 +0300173 except models.ActionLog.DoesNotExist:
174 update_date = None
175 try:
176 models.ActionLog.objects.get(name="update_plot_started")
177 update_started = True
178 except models.ActionLog.DoesNotExist:
179 update_started = False
180
181 job_names_path = os.path.join(models.fs.location, "job_names.txt")
182 job_names = []
183 if os.path.exists(job_names_path):
184 try:
185 with open(job_names_path, "r") as f:
186 job_names = json.load(f)
stavrovska28772bc2024-05-22 09:33:50 +0200187 except Exception:
Oleksii Petrenko68268172020-09-28 16:58:13 +0300188 pass
189
190 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200191 request,
192 "control/jenkins_plot.html",
193 {
194 "update_date": update_date,
195 "update_started": update_started,
196 "job_names": enumerate(job_names, 1),
197 },
198 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100199
200
201def submit_suites(request):
202 form = forms.DiffPassRatesForm(request.POST)
203 if not form.is_valid():
204 print(f"{form.errors=}")
205 return
206 report1 = models.SuitePassRate(suite_id=request.POST["first-suite_id"])
207 report1.save()
208 report2 = models.SuitePassRate(suite_id=request.POST["second-suite_id"])
209 report2.save()
210
211 diff_model = models.DiffOfSuitesPassRates(
212 report1=report1,
213 report2=report2,
214 limit=form.cleaned_data["limit"],
stavrovska28772bc2024-05-22 09:33:50 +0200215 test_keyword=form.cleaned_data["test_keyword"],
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100216 )
217 diff_model.save()
218 get_test_passability_in_suite.delay(diff_model.id, report1.id)
219 get_test_passability_in_suite.delay(diff_model.id, report2.id)
220
221 return redirect("report_comparing_suites", diff_model.id)
222
223
224def compare_suites(request):
225 if request.method == "POST":
226 return submit_suites(request)
227
228 diff_form = forms.DiffPassRatesForm()
stavrovska28772bc2024-05-22 09:33:50 +0200229 report1_form = forms.SuitePassRateForm(prefix="first")
230 report2_form = forms.SuitePassRateForm(prefix="second")
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100231
232 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200233 request,
234 "control/compare_suites.html",
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100235 {
stavrovska28772bc2024-05-22 09:33:50 +0200236 "diff_form": diff_form,
237 "report1_form": report1_form,
238 "report2_form": report2_form,
239 "finished": None,
240 },
241 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100242
243
244def list_of_comparing_reports(request):
245 list_of_reports = models.DiffOfSuitesPassRates.objects.all()
246 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200247 request,
248 "control/list_comparing_suites.html",
249 {"reports": list_of_reports},
250 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100251
252
253def report_comparing_suites(request, report_id):
254 report = models.DiffOfSuitesPassRates.objects.get(pk=report_id)
stavrovska28772bc2024-05-22 09:33:50 +0200255 passrate1 = short_names_for_dict(
256 json.loads(report.report1.passrate_by_tests)
257 )
258 passrate2 = short_names_for_dict(
259 json.loads(report.report2.passrate_by_tests)
260 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100261
stavrovska28772bc2024-05-22 09:33:50 +0200262 diff_table = get_dict_diff(
263 dict1=passrate1, dict2=passrate2, compare_by_key="rate"
264 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100265 diff_form = forms.DiffPassRatesForm(instance=report)
stavrovska28772bc2024-05-22 09:33:50 +0200266 report1_form = forms.SuitePassRateForm(
267 instance=report.report1, prefix="first"
268 )
269 report2_form = forms.SuitePassRateForm(
270 instance=report.report2, prefix="second"
271 )
Anna Arhipova7cdcc852023-11-15 18:20:45 +0100272
273 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200274 request,
275 "control/compare_suites.html",
276 {
277 "diff_form": diff_form,
278 "report1_form": report1_form,
279 "report2_form": report2_form,
280 "report1": report.report1,
281 "report2": report.report2,
282 "is_finished": report.report1.finished and report.report2.finished,
283 "diff_table": diff_table,
284 },
285 )
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100286
287
288def schedulers(request):
289
290 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200291 request,
292 "control/schedulers.html",
293 {"schedulers": models.CronPeriodicTask.objects.all()},
294 )
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100295
296
297def scheduler(request, pk=None):
298 if request.method == "POST":
299 return save_scheduler(request)
300
301 if pk:
302 task_pk = models.CronPeriodicTask.objects.get(pk=pk)
303 form = forms.PeriodicTaskForm(instance=task_pk)
304 else:
305 form = forms.PeriodicTaskForm()
306
307 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200308 request,
309 "control/scheduler.html",
310 {"form": form, "pk": pk, "TASKS": models.TASKS},
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100311 )
312
313
314def save_scheduler(request, pk=None):
stavrovska28772bc2024-05-22 09:33:50 +0200315 minute, hour, day_of_month, month_of_year, day_of_week = request.POST.get(
316 "cron", "* * * * *"
317 ).split(" ")
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100318 if pk is None:
319 sch = CrontabSchedule.objects.create(
320 minute=minute,
321 hour=hour,
322 day_of_month=day_of_month,
323 month_of_year=month_of_year,
stavrovska28772bc2024-05-22 09:33:50 +0200324 day_of_week=day_of_week,
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100325 )
326 task = models.CronPeriodicTask.objects.create(
327 crontab=sch,
328 cron=request.POST.get("cron"),
329 name=request.POST.get("name"),
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100330 task_name=request.POST.get("task_name"),
stavrovska28772bc2024-05-22 09:33:50 +0200331 enabled=request.POST.get("enabled") == "on",
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100332 testplan_id_arg=request.POST.get("testplan_id_arg"),
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100333 )
334 else:
335 task = models.CronPeriodicTask.objects.get(pk=pk)
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100336
337 task.task = request.POST.get("task_name")
338 task.args = json.dumps((request.POST.get("testplan_id_arg"),))
339
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100340 form = forms.PeriodicTaskForm(request.POST, instance=task)
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100341
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100342 CrontabSchedule.objects.filter(id=task.crontab.id).update(
343 minute=minute,
344 hour=hour,
345 day_of_month=day_of_month,
346 month_of_year=month_of_year,
stavrovska28772bc2024-05-22 09:33:50 +0200347 day_of_week=day_of_week,
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100348 )
Anna Arhipovad2d4d9b2024-03-18 20:57:44 +0100349 if not form.is_valid():
350 print(f"{form.errors=}")
351 return
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100352 form.save()
353 PeriodicTasks.update_changed()
354 return render(
stavrovska28772bc2024-05-22 09:33:50 +0200355 request,
356 "control/scheduler.html",
357 {"form": form, "pk": task.id, "TASKS": models.TASKS},
Anna Arhipova22ea6bf2024-02-20 15:25:30 +0100358 )
359
360
361def delete_scheduler(request, pk):
362 task = models.CronPeriodicTask.objects.get(pk=pk)
363 task.delete()
364 return redirect("schedulers")