squad 1.73__py3-none-any.whl → 1.75__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of squad might be problematic. Click here for more details.

squad/frontend/tests.py CHANGED
@@ -1,11 +1,12 @@
1
1
  import json
2
2
 
3
- from django.db.models import Prefetch
3
+ from collections import defaultdict
4
+
4
5
  from django.shortcuts import render, get_object_or_404
5
6
  from django.http import Http404
6
7
 
7
8
  from squad.http import auth
8
- from squad.core.models import Test, Suite, TestRun
9
+ from squad.core.models import Test, Suite, SuiteMetadata, Environment
9
10
  from squad.core.history import TestHistory
10
11
  from squad.core.queries import test_confidence
11
12
  from squad.frontend.views import get_build
@@ -46,23 +47,39 @@ class TestResultTable(list):
46
47
 
47
48
  def __init__(self):
48
49
  self.environments = None
50
+ self.filters = {
51
+ 'environment': None,
52
+ 'suite': None,
53
+ }
49
54
  self.paginator = self
50
55
  self.paginator.num_pages = 0
51
56
  self.number = 0
52
57
  self.all_tests = []
53
58
 
54
- def __get_all_tests__(self, build, search):
59
+ def __get_all_tests__(self, build, search, env=None, suite=None):
55
60
 
56
61
  queryset = Test.objects.filter(build=build)
57
62
  if search:
58
63
  queryset = queryset.filter(metadata__name__icontains=search)
59
64
 
60
- self.all_tests = queryset.only('result', 'has_known_issues', 'suite_id', 'metadata_id').order_by()
65
+ if env:
66
+ environment = Environment.objects.filter(project=build.project, slug=env)
67
+ if environment.exists():
68
+ self.filters['environment'] = environment.first()
69
+ queryset = queryset.filter(environment=self.filters['environment'])
70
+
71
+ if suite:
72
+ suite_ = Suite.objects.filter(project=build.project, slug=suite)
73
+ if suite_.exists():
74
+ self.filters['suite'] = suite_.first()
75
+ queryset = queryset.filter(suite=self.filters['suite'])
76
+
77
+ self.all_tests = queryset.only('result', 'has_known_issues', 'metadata_id').order_by()
61
78
 
62
79
  # count how many unique tests are represented in the given build, and sets
63
80
  # pagination data
64
81
  def __count_pages__(self, per_page):
65
- distinct_tests = set([(test.suite_id, test.metadata_id) for test in self.all_tests])
82
+ distinct_tests = set([test.metadata_id for test in self.all_tests])
66
83
  count = len(distinct_tests)
67
84
  self.num_pages = count // per_page
68
85
  if count % per_page > 0:
@@ -79,50 +96,48 @@ class TestResultTable(list):
79
96
  """
80
97
  offset = (page - 1) * per_page
81
98
 
82
- stats = {}
99
+ stats = defaultdict(lambda: {'pass': 0, 'fail': 0, 'xfail': 0, 'skip': 0})
83
100
  for test in self.all_tests:
84
- key = (test.suite_id, test.metadata_id)
85
- if key not in stats:
86
- stats[key] = {'pass': 0, 'fail': 0, 'xfail': 0, 'skip': 0, 'ids': []}
87
- stats[key][test.status] += 1
88
- stats[key]['ids'].append(test.id)
101
+ stats[test.metadata_id][test.status] += 1
89
102
 
90
103
  def keyfunc(item):
91
- name = item[0]
104
+ metadata_id = item[0]
92
105
  statuses = item[1]
93
- return tuple((-statuses[k] for k in ['fail', 'xfail', 'skip', 'pass'])) + (name,)
106
+ return tuple((-statuses[k] for k in ['fail', 'xfail', 'skip', 'pass'])) + (metadata_id,)
94
107
 
95
108
  ordered = sorted(stats.items(), key=keyfunc)
96
109
  tests_in_page = ordered[offset:offset + per_page]
97
-
98
- tests_ids = []
99
- for test in tests_in_page:
100
- tests_ids += test[1]['ids']
101
-
102
- return tests_ids
110
+ metadata_ids = [t[0] for t in tests_in_page]
111
+ return metadata_ids
103
112
 
104
113
  @classmethod
105
- def get(cls, build, page, search, per_page=50):
114
+ def get(cls, build, page, search, per_page=50, env=None, suite=None):
106
115
  table = cls()
107
- table.__get_all_tests__(build, search)
116
+ table.__get_all_tests__(build, search, env=env, suite=suite)
108
117
  table.number = page
109
118
  table.__count_pages__(per_page)
110
119
 
111
- table.environments = set([t.environment for t in build.test_runs.prefetch_related('environment').all()])
120
+ if table.filters['environment']:
121
+ table.environments = {table.filters['environment']}
122
+ else:
123
+ table.environments = set([t.environment for t in build.test_runs.prefetch_related('environment').all()])
124
+
125
+ queryset = build.tests
126
+ if table.filters['environment']:
127
+ queryset = queryset.filter(environment=table.filters['environment'])
112
128
 
113
- tests = Test.objects.filter(
114
- id__in=table.__get_page_filter__(page, per_page)
129
+ if table.filters['suite']:
130
+ queryset = queryset.filter(suite=table.filters['suite'])
131
+
132
+ tests = queryset.filter(
133
+ metadata_id__in=table.__get_page_filter__(page, per_page),
115
134
  ).prefetch_related(
116
- Prefetch('test_run', queryset=TestRun.objects.only('environment')),
117
135
  'suite__metadata',
118
136
  'metadata',
119
137
  )
120
138
 
121
- memo = {}
139
+ memo = defaultdict(lambda: defaultdict(list))
122
140
  for test in tests:
123
- memo.setdefault(test.full_name, {})
124
- if test.environment_id not in memo[test.full_name]:
125
- memo[test.full_name][test.environment_id] = []
126
141
  memo[test.full_name][test.environment_id].append(test)
127
142
 
128
143
  # handle duplicates
@@ -149,7 +164,7 @@ class TestResultTable(list):
149
164
  memo[full_name][env_id].append(info)
150
165
 
151
166
  if 'test_metadata' not in memo[full_name].keys():
152
- memo[full_name]['test_metadata'] = (test.test_run, test.suite, test.name)
167
+ memo[full_name]['test_metadata'] = (test.test_run_id, test.suite, test.name)
153
168
 
154
169
  for test_full_name, results in memo.items():
155
170
  test_result = TestResult(test_full_name)
@@ -173,13 +188,15 @@ def tests(request, group_slug, project_slug, build_version):
173
188
  except ValueError:
174
189
  page = 1
175
190
 
191
+ env = request.GET.get('environment')
192
+ suite = request.GET.get('suite')
176
193
  search = request.GET.get('search', '')
177
194
 
178
195
  context = {
179
196
  "project": project,
180
197
  "build": build,
181
198
  "search": search,
182
- "results": TestResultTable.get(build, page, search),
199
+ "results": TestResultTable.get(build, page, search, env=env, suite=suite),
183
200
  }
184
201
 
185
202
  return render(request, 'squad/tests.jinja2', context)
@@ -191,12 +208,12 @@ def legacy_test_history(request, group_slug, project_slug, full_test_name):
191
208
 
192
209
 
193
210
  @auth
194
- def test_history(request, group_slug, project_slug, build_version=None, testrun=None, suite_slug=None, test_name=None):
211
+ def test_history(request, group_slug, project_slug, build_version=None, testrun_id=None, suite_slug=None, test_name=None):
195
212
  project = request.project
196
213
  context = {"project": project}
197
- if build_version and testrun and suite_slug:
214
+ if build_version and testrun_id and suite_slug:
198
215
  build = get_build(project, build_version)
199
- test_run = get_object_or_404(build.test_runs, pk=testrun)
216
+ test_run = get_object_or_404(build.test_runs, pk=testrun_id)
200
217
  suite_slug = suite_slug.replace('$', '/')
201
218
  suite = get_object_or_404(project.suites, slug=suite_slug)
202
219
  status = get_object_or_404(test_run.status, suite=suite)
@@ -204,6 +221,7 @@ def test_history(request, group_slug, project_slug, build_version=None, testrun=
204
221
  context.update({"build": build, "status": status, "test": test_name})
205
222
  else:
206
223
  full_test_name = test_name.replace('$', '/')
224
+
207
225
  try:
208
226
  page = int(request.GET.get('page', '1'))
209
227
  except ValueError:
@@ -216,5 +234,5 @@ def test_history(request, group_slug, project_slug, build_version=None, testrun=
216
234
  history = TestHistory(project, full_test_name, top=top, page=page)
217
235
  context.update({"history": history})
218
236
  return render(request, 'squad/test_history.jinja2', context)
219
- except Suite.DoesNotExist:
220
- raise Http404("No such suite for test: %s")
237
+ except (Suite.DoesNotExist, SuiteMetadata.DoesNotExist) as e:
238
+ raise Http404(f"Test not found: {e}")
squad/frontend/urls.py CHANGED
@@ -7,7 +7,6 @@ from django.shortcuts import redirect
7
7
  from . import views
8
8
  from . import badges
9
9
  from . import comparison
10
- from . import failures
11
10
  from . import metrics
12
11
  from . import tests
13
12
  from . import ci
@@ -45,7 +44,6 @@ urlpatterns = [
45
44
  url(r'^(%s)/(%s)/build/([^/]+)/api/$' % group_and_project, views.build_api, name='build_api'),
46
45
  url(r'^(%s)/(%s)/build/([^/]+)/badge$' % group_and_project, badges.build_badge, name='build_badge'),
47
46
  url(r'^(%s)/(%s)/build/([^/]+)/tests/$' % group_and_project, tests.tests, name='tests'),
48
- url(r'^(%s)/(%s)/build/([^/]+)/failures/$' % group_and_project, failures.failures, name='failures'),
49
47
  url(r'^(%s)/(%s)/build/([^/]+)/metrics/$' % group_and_project, metrics.build_metrics, name='build_metrics'),
50
48
  url(r'^(%s)/(%s)/build/([^/]+)/testjobs/$' % group_and_project, ci.testjobs, name='testjobs'),
51
49
  url(r'^(%s)/(%s)/build/([^/]+)/metadata/$' % group_and_project, views.build_metadata, name='build_metadata'),
squad/frontend/views.py CHANGED
@@ -6,6 +6,9 @@ from django.core.paginator import Paginator, EmptyPage
6
6
  from django.contrib.auth.decorators import login_required
7
7
  from django.http import HttpResponse, Http404
8
8
  from django.shortcuts import render, get_object_or_404, redirect, reverse
9
+ from django.utils import timezone
10
+
11
+ from dateutil.relativedelta import relativedelta
9
12
 
10
13
  from squad.ci.models import TestJob
11
14
  from squad.core.models import Group, Metric, ProjectStatus, Status, MetricThreshold, KnownIssue, Test
@@ -83,24 +86,30 @@ def home(request):
83
86
  return render(request, 'squad/index.jinja2', context)
84
87
 
85
88
 
86
- def group_home(request, group_slug):
87
- group = get_object_or_404(Group, slug=group_slug)
88
-
89
- projects_queryset = group.projects.accessible_to(request.user)
89
+ def get_project_list(group, user, order_by, display_all_projects):
90
+ projects_queryset = group.projects.accessible_to(user)
90
91
  projects_queryset = projects_queryset.annotate(latest_build_id=Max('builds__id'))
91
92
 
92
- if request.user.is_authenticated:
93
- projects_queryset = projects_queryset.prefetch_related(Prefetch('subscriptions', queryset=Subscription.objects.filter(user=request.user), to_attr='user_subscriptions'))
93
+ if user.is_authenticated:
94
+ projects_queryset = projects_queryset.prefetch_related(Prefetch('subscriptions', queryset=Subscription.objects.filter(user=user), to_attr='user_subscriptions'))
94
95
 
95
- order_by = request.GET.get('order', 'last_updated')
96
96
  if group.get_setting('SORT_PROJECTS_BY_NAME'):
97
97
  order_by = 'by_name'
98
98
 
99
99
  elif order_by == 'last_updated':
100
100
  projects_queryset = projects_queryset.order_by('-datetime')
101
101
 
102
- display_all_projects = request.GET.get('all_projects') is not None
103
102
  num_projects = group.get_setting('DEFAULT_PROJECT_COUNT')
103
+
104
+ show_projects_active_n_days_ago = group.get_setting('SHOW_PROJECTS_ACTIVE_N_DAYS_AGO')
105
+ if show_projects_active_n_days_ago:
106
+ earilest_timestamp = timezone.now() - relativedelta(days=show_projects_active_n_days_ago)
107
+ latest_project_count = projects_queryset.filter(datetime__gte=earilest_timestamp).count()
108
+ if latest_project_count > 0:
109
+ projects_queryset = projects_queryset.filter(datetime__gte=earilest_timestamp)
110
+ # Ignore DEFAULT_PROJECT_COUNT if we are using age of project
111
+ num_projects = None
112
+
104
113
  if display_all_projects or num_projects is None:
105
114
  display_all_projects = True
106
115
  projects = projects_queryset.all()
@@ -108,6 +117,16 @@ def group_home(request, group_slug):
108
117
  display_all_projects = projects_queryset.count() <= num_projects
109
118
  projects = projects_queryset.all()[:num_projects]
110
119
 
120
+ return projects
121
+
122
+
123
+ def group_home(request, group_slug):
124
+ group = get_object_or_404(Group, slug=group_slug)
125
+
126
+ order_by = request.GET.get('order', 'last_updated')
127
+ display_all_projects = request.GET.get('all_projects') is not None
128
+ projects = get_project_list(group, request.user, order_by, display_all_projects)
129
+
111
130
  has_archived_projects = False
112
131
  latest_build_ids = {}
113
132
  projects_count = 0
@@ -157,7 +176,7 @@ def project_home(request, group_slug, project_slug):
157
176
  builds = [b for b in __get_builds_with_status__(project, 11)]
158
177
  last_build = len(builds) and builds[0] or None
159
178
 
160
- metadata = last_build and sorted(last_build.important_metadata.items()) or ()
179
+ metadata = last_build and last_build.important_metadata.items() or ()
161
180
  context = {
162
181
  'project': project,
163
182
  'builds': builds,
@@ -379,7 +398,7 @@ def build(request, group_slug, project_slug, version):
379
398
  'build': build,
380
399
  'test_results': test_results,
381
400
  'results_layout': results_layout,
382
- 'metadata': sorted(build.important_metadata.items()),
401
+ 'metadata': build.important_metadata.items(),
383
402
  'has_extra_metadata': build.has_extra_metadata,
384
403
  'failures_only': failures_only,
385
404
  'testjobs_progress': testjobs_progress,
@@ -455,13 +474,13 @@ def __test_run_suite_context__(request, group_slug, project_slug, build_version,
455
474
 
456
475
 
457
476
  @auth
458
- def test_run_suite_tests(request, group_slug, project_slug, build_version, testrun, suite_slug):
477
+ def test_run_suite_tests(request, group_slug, project_slug, build_version, testrun_id, suite_slug):
459
478
  context = __test_run_suite_context__(
460
479
  request,
461
480
  group_slug,
462
481
  project_slug,
463
482
  build_version,
464
- testrun,
483
+ testrun_id,
465
484
  suite_slug
466
485
  )
467
486
 
@@ -479,13 +498,13 @@ def test_run_suite_tests(request, group_slug, project_slug, build_version, testr
479
498
 
480
499
 
481
500
  @auth
482
- def test_run_suite_test_details(request, group_slug, project_slug, build_version, testrun, suite_slug, test_name):
501
+ def test_run_suite_test_details(request, group_slug, project_slug, build_version, testrun_id, suite_slug, test_name):
483
502
  context = __test_run_suite_context__(
484
503
  request,
485
504
  group_slug,
486
505
  project_slug,
487
506
  build_version,
488
- testrun,
507
+ testrun_id,
489
508
  suite_slug
490
509
  )
491
510
  test_name = test_name.replace("$", "/")
@@ -523,13 +542,13 @@ def test_run_suite_test_details(request, group_slug, project_slug, build_version
523
542
 
524
543
 
525
544
  @auth
526
- def test_run_suite_metrics(request, group_slug, project_slug, build_version, testrun, suite_slug):
545
+ def test_run_suite_metrics(request, group_slug, project_slug, build_version, testrun_id, suite_slug):
527
546
  context = __test_run_suite_context__(
528
547
  request,
529
548
  group_slug,
530
549
  project_slug,
531
550
  build_version,
532
- testrun,
551
+ testrun_id,
533
552
  suite_slug
534
553
  )
535
554
  all_metrics = context['status'].metrics.prefetch_related(
squad/settings.py CHANGED
@@ -81,6 +81,14 @@ except ImportError:
81
81
  pass
82
82
 
83
83
 
84
+ django_allauth_middleware = None
85
+ try:
86
+ import allauth.account.middleware # noqa: F401
87
+ django_allauth_middleware = 'allauth.account.middleware.AccountMiddleware'
88
+ except ImportError:
89
+ pass
90
+
91
+
84
92
  __apps__ = [
85
93
  'django.contrib.admin',
86
94
  'django.contrib.auth',
@@ -146,6 +154,7 @@ __middlewares__ = [
146
154
  'django.contrib.messages.middleware.MessageMiddleware',
147
155
  'django.middleware.clickjacking.XFrameOptionsMiddleware',
148
156
  django_toolbar_middleware, # OPTIONAL
157
+ django_allauth_middleware,
149
158
  ]
150
159
 
151
160
  MIDDLEWARE = [middleware for middleware in __middlewares__ if middleware]
squad/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.73'
1
+ __version__ = '1.75'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: squad
3
- Version: 1.73
3
+ Version: 1.75
4
4
  Summary: Software Quality Dashboard
5
5
  Home-page: https://github.com/Linaro/squad
6
6
  Author: Antonio Terceiro
@@ -7,17 +7,17 @@ squad/http.py,sha256=KuIKtpf3yOvf5fwc0T2MR0ul1l4AKxq3b0CLdk6KBhM,3667
7
7
  squad/jinja2.py,sha256=OKX-lzNz6qtTZL56HWv4UBMPuBl4WQXv0qFJztGp9zs,2541
8
8
  squad/mail.py,sha256=xH5wuIpD7u1fTN9vNOcbzByojleaffsKwp-9i3BeOD0,390
9
9
  squad/manage.py,sha256=Z-LXT67p0R-IzwJ9fLIAacEZmU0VUjqDOSg7j2ZSxJ4,1437
10
- squad/settings.py,sha256=8IuKnLnrgaTcotaLA-LIbDFVgmAiPqzMQfl5h3F0-58,14097
10
+ squad/settings.py,sha256=6pEhWkjPgdRS4H2u3BKkPQJGs7oFy8Nbgk3KfhMR7hk,14328
11
11
  squad/socialaccount.py,sha256=vySqPwQ3qVVpahuJ-Snln8K--yzRL3bw4Nx27AsB39A,789
12
12
  squad/urls.py,sha256=JiEfVW8YlzLPE52c2aHzdn5kVVKK4o22w8h5KOA6QhQ,2776
13
- squad/version.py,sha256=sHskipjTMgFJdgmMxqr6ik42QdKNmzMsDIUsY8847_Y,21
13
+ squad/version.py,sha256=OC6GKMpskxHfSEgiJ0ItR5gLS6QXMDmVsSkmSs2egUw,21
14
14
  squad/wsgi.py,sha256=SF8T0cQ0OPVyuYjO5YXBIQzvSXQHV0M2BTmd4gP1rPs,387
15
15
  squad/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  squad/api/apps.py,sha256=Trk72p-iV1uGn0o5mdJn5HARUoHGbfgO49jwXvpkmdQ,141
17
17
  squad/api/ci.py,sha256=g9ZodQW3A1scNci3K3EGprxSyW3rL9xn-qBYxd-_8ns,6462
18
18
  squad/api/data.py,sha256=obKDV0-neEvj5lPF9VED2gy_hpfhGtLJABYvSY38ing,2379
19
19
  squad/api/filters.py,sha256=Zvp8DCJmiNquFWqvfVseEAAMYYPiT95RUjqKdzcqSnw,6917
20
- squad/api/rest.py,sha256=xtlQicNBrrHfGlHDyAslddomEQnGoRKYMZYXa6ij7Iw,75733
20
+ squad/api/rest.py,sha256=EfpWljAvkkDwurRNoR1H6hRtYjpIS0B4kzXsQgS4UW8,75932
21
21
  squad/api/urls.py,sha256=rmsdaL1uOCVSZ5x1redup9RliICmijaBjRK5ObsTkG8,1343
22
22
  squad/api/utils.py,sha256=Sa8QFId3_oSqD2UOoY3Kuh54LLDLPNMq2sub5ktd6Fs,1160
23
23
  squad/api/views.py,sha256=yGLUp6RtNI5vuae6cOStMuUpSia46LcEVam3eMXmEqY,3885
@@ -25,14 +25,14 @@ squad/ci/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  squad/ci/admin.py,sha256=7yB-6F0cvt0NVvzGOTlZCyGPV_YHarmbKJZTTzataT4,2255
26
26
  squad/ci/apps.py,sha256=6OVnzTdJkxdqEJnKWYE9dZgUcc29_T1LrDw41cK4EQk,139
27
27
  squad/ci/exceptions.py,sha256=a1sccygniTYDSQi7FRn_6doapddFFiMf55AwGUh5Y80,227
28
- squad/ci/models.py,sha256=RoXJY4Xgu3-YA4FtcK-kem8HR8paqOb5648NByAlzDo,12325
28
+ squad/ci/models.py,sha256=R8kdrbkcplABeTZPSWADL2dOQsWbSfgfOh5jZltKK-8,13265
29
29
  squad/ci/tasks.py,sha256=yrtxfPuYEqqGCDYRwLz2XyIp9a7LJ-K6Zm3VS1ymdZk,2728
30
30
  squad/ci/utils.py,sha256=38zHpw8xkZDSFlkG-2BwSK6AkcddK9OkN9LXuQ3SHR0,97
31
31
  squad/ci/backend/__init__.py,sha256=yhpotXT9F4IdAOXvGQ3-17eOHAFwoaqf9SnMX17ab30,534
32
32
  squad/ci/backend/fake.py,sha256=zzOXGesDCW9xiMQvXGD_jqCQF32yEd7hPM8DgfZxUok,2159
33
33
  squad/ci/backend/lava.py,sha256=5KEXFwKGjzXPPe7_rzMGF7YShYCLwmooTc8tQUpGBSM,33076
34
34
  squad/ci/backend/null.py,sha256=vP77Xj7roruehSjX8fJs7xK2aWxgaUA2id3P8nHNrEY,4949
35
- squad/ci/backend/tuxsuite.py,sha256=_mEE46-J2pGKZtq2sECe97EkjmeaSyiyoTr0q8mJ-ys,14090
35
+ squad/ci/backend/tuxsuite.py,sha256=yAdLBOC3uLL2-wYxCsd8Rnk6lzTQLHcl2UOUjjJHYBg,16606
36
36
  squad/ci/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  squad/ci/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
38
  squad/ci/management/commands/create_tuxsuite_boot_tests.py,sha256=JvjNusebLX71eyz9d-kaeCyekYSpzc1eXoeIqWK9ygo,4045
@@ -76,14 +76,14 @@ squad/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  squad/core/admin.py,sha256=tFyRu_rhHN-ABJkEApaT4YtRYa4qxNe-8jou2H3Q0P4,7897
77
77
  squad/core/apps.py,sha256=Bl-4Yg0joKjygdifQG0ROIz4m5bHiPqytQ3G82uyzWc,143
78
78
  squad/core/callback.py,sha256=QhMf3ILkR2HAnqv1B2OW1pQEhrrIp4xRA9HhD6ywe1A,3066
79
- squad/core/comparison.py,sha256=pxEaOi7QCfZFudq1W6y0orWj86BqFJmRBdxJ8J2dcRc,23788
79
+ squad/core/comparison.py,sha256=LR3-Unv0CTmakFCDzF_h8fm2peTJzkv79mQWNau1iwI,24429
80
80
  squad/core/data.py,sha256=2zw56v7iYRTUc7wlhuUNgwIIMmK2w84hi-amR9J7EPU,2236
81
- squad/core/failures.py,sha256=CkLFGiKz1_BKWVRTkP-poQqsCePIqgVSIw6GKZjZ1eM,943
82
- squad/core/history.py,sha256=bCPqlpWnucTz78L4txRLfP51u5-4syYllZb1T_NwxUs,3112
83
- squad/core/models.py,sha256=ppfURnWBPYVEjc494mRE935Pb_Q2a_1PRZquY7YCFGs,60353
81
+ squad/core/failures.py,sha256=X6lJVghM2fOrd-RfuHeLlezW2pt7owDZ8eX-Kn_Qrt0,918
82
+ squad/core/history.py,sha256=APIgJ1fXAGyxoNgxVMn02kJzXhLR1x2SG4UyCcTyUEQ,3467
83
+ squad/core/models.py,sha256=E3E78ftWCYEqBz3ePyNf1wM5lfYRotjqdchfyWMZpRs,60346
84
84
  squad/core/notification.py,sha256=rOpO6F63w7_5l9gQgWBBEk-MFBjp7x_hVzoVIVyDze0,10030
85
85
  squad/core/plugins.py,sha256=PzgKrRvnwoe4ynLh0aRGAsL0CngHSu8dose37CO5ESg,5992
86
- squad/core/queries.py,sha256=pXTG5SVKNYkKXGOm_glUfyGym1dzDpA52dQ8gcUMorY,7680
86
+ squad/core/queries.py,sha256=78fhIJZWXIlDryewYAt96beK1VJad66Ufu8cg3dHh4w,7698
87
87
  squad/core/statistics.py,sha256=xyTHuhdBjcJ4AozZESjTzSD3dBmmCDgLpbg5XpeyO_M,1056
88
88
  squad/core/utils.py,sha256=L6c-suSBbNFBVEZF7GF8DcjD5lmXZLy7QO0T_2j9LCk,4893
89
89
  squad/core/locale/django.pot,sha256=XycSJyEaEpozGBS9zu7QTNQbffZC0D9eSJ-AwXaVZx4,2282
@@ -294,20 +294,19 @@ squad/frontend/apps.py,sha256=lKMd_HrIna5OZrfeWXndcGoIDR2KFmBFnMoGHtCGE4E,151
294
294
  squad/frontend/badges.py,sha256=rEgjkJQKZQT1mL9j9s47okTQO-J55eU8mDNHShijovY,5878
295
295
  squad/frontend/build_settings.py,sha256=_Hqw5npczuU01Zi6FGAiSbrtMMzK9eAXv-cX5U5btto,909
296
296
  squad/frontend/ci.py,sha256=lfglUArCj5iYRLZgC6mDgEN_k-dDqfCezXW3j2Fn_Uc,2244
297
- squad/frontend/comparison.py,sha256=iGmi5obsV5AALiuCgIvMWG3l6ZxsdO-npTS1EY9L10M,4547
297
+ squad/frontend/comparison.py,sha256=tZQOcXOOTU787VbZ2ueuXpWGUjiFSeq-O7fepSM0g-I,4547
298
298
  squad/frontend/extract.py,sha256=p88JGuBvaC4AMDkJi7lqzbj5ZGh6h2LSlV7tcXbmxDc,8491
299
- squad/frontend/failures.py,sha256=L71acQR_cDzu1Tqu9FtKWS0ABeOcQd-YBMsu63x9hUw,1945
300
299
  squad/frontend/forms.py,sha256=StPdrHsFsEoBKEOF6bBampLXbVXrZcEDkbuI4II1dCA,753
301
300
  squad/frontend/group_settings.py,sha256=mV0kJEfRo41AEbOZMxWXY1MpYNqSgWVqac0dUdwkGyk,6232
302
301
  squad/frontend/metrics.py,sha256=nGrfFHLG6g_DUYVJCIDlFLvLWhMrqJxX1Z0cckPBJlg,1149
303
302
  squad/frontend/project_settings.py,sha256=TtWz8h8Goeb3pccLy9jLUibeHqyqkdK8phL7_Vh_d0I,5045
304
303
  squad/frontend/queries.py,sha256=NxQF2woAf9A4Wk_ozHzZXOGmr2as-j7hqfvmsfJ-ojc,967
305
304
  squad/frontend/setup.py,sha256=NF9VunY1HJGB2HsHJss-go7EGmqr__JASddxiBCvmeQ,169
306
- squad/frontend/tests.py,sha256=-x7y454ha9l49UUrQkK1xrRbkBhPBMQYzb8lPKplVbQ,7877
307
- squad/frontend/urls.py,sha256=2DX52mnyKeMQljmi-iqrYLRLjodDJ50HxvxH9ba-99A,5010
305
+ squad/frontend/tests.py,sha256=q64Z6DyS6TiJTCzF6SXw4wZfvXR8c0A4t-f0ib1jJ0w,8713
306
+ squad/frontend/urls.py,sha256=biWauxwXR5j9kOfrSUqkv1Iqz-elB2aNViS9_UFoLzQ,4882
308
307
  squad/frontend/user_settings.py,sha256=IBogLusn-WNQiXqc_cF23s_tAWZ6wYVL6bbCfah_Aco,4189
309
308
  squad/frontend/utils.py,sha256=DeH58CJUI1dovpQrj3a-DcxNzM0cxsnBDOF0mrC4Qws,1364
310
- squad/frontend/views.py,sha256=u4A0OfNrT9_J5K-XUyS_Lb_K9uhi2p5aihtFJ1bSxf8,25677
309
+ squad/frontend/views.py,sha256=wK7ZPD-qjdhNTaBNJAZAwYmRTmIaHdjRxLiD6Oe9k1w,26477
311
310
  squad/frontend/locale/django.pot,sha256=ENSJCBcxS2gWg5byPCMxU8gvTNR6qtJdsSi9emUUOvY,30178
312
311
  squad/frontend/locale/pl/LC_MESSAGES/django.po,sha256=yKoZEDP72mn_5WSNDP8zh5Pl3Z5Z9OGuoDG159NPvEI,36297
313
312
  squad/frontend/locale/pt/LC_MESSAGES/django.po,sha256=8srHMXuXV0ZuUM284LEwTb5sXWEMzlCmul1lKXsDZc8,36375
@@ -357,7 +356,7 @@ squad/frontend/templates/squad/_pagination.jinja2,sha256=bA5h-LtVjaz3HhdU2m3nsQG
357
356
  squad/frontend/templates/squad/_permissions.jinja2,sha256=cZy_2JJTy3ePSxZVArnt-_PfRlp5vCTrXtvMFL1b5xA,895
358
357
  squad/frontend/templates/squad/_project_list.jinja2,sha256=NLIEkUxA-na4UE05V27xVNZWPd3ER7SgN1Iisphhtuw,3988
359
358
  squad/frontend/templates/squad/_regressions_and_fixes.jinja2,sha256=il0FYsrvzjbKoPp0EH0rYdQNdPBqTFPo6KnwMhV9hrs,1263
360
- squad/frontend/templates/squad/_results_table.jinja2,sha256=u9-ja_DLGBo0_RfYQvQ3uqLlQ6r1xNHi39X3I48ww7k,2751
359
+ squad/frontend/templates/squad/_results_table.jinja2,sha256=riSxp2L_2c_8WRp6SR3lGl_SY_KwjO-TWmosZnQ-gVs,2644
361
360
  squad/frontend/templates/squad/_results_transitions_filter.jinja2,sha256=6h9PI9OCM6CeGVfGOkMc0kelZ0maQRQVnk2UOKw22H0,1680
362
361
  squad/frontend/templates/squad/_subscribe.jinja2,sha256=WawVotX1CgxEg8EoPNYzZvJi0k6jfhOIN-p1rGR7pWg,920
363
362
  squad/frontend/templates/squad/_test_results_envbox.jinja2,sha256=vmMh3AtJppRgNQfkfGC11mXqBskJNODzxShflInIzR0,5157
@@ -369,7 +368,7 @@ squad/frontend/templates/squad/_test_run_test.jinja2,sha256=S3ZgmbJGsN4I7dQimvSr
369
368
  squad/frontend/templates/squad/_unfinished_build.jinja2,sha256=U1dWITSX2LLxKquBee0jU8d76ssh6dFc4sxxFX921Cw,164
370
369
  squad/frontend/templates/squad/_user_menu.jinja2,sha256=7pIdeUEInR9FejvxIqtcxbrIpbLt460uokcVspNRogI,1256
371
370
  squad/frontend/templates/squad/base.jinja2,sha256=tY7Emy9BSDHirxm4QN2jDSQbkfD1nCsrHEcEzOefw88,4335
372
- squad/frontend/templates/squad/build-nav.jinja2,sha256=sjSYg8482HZ6prOYBIrUvKj2jmzOBwbBRC0PudED2Es,9006
371
+ squad/frontend/templates/squad/build-nav.jinja2,sha256=w4j2eevYQSkNe1YEIdo6nKHbHnLub_1iRWrTYNzwZi0,8800
373
372
  squad/frontend/templates/squad/build.jinja2,sha256=RJe6cDQpQVqO3IMdS-61wWiq4p5y1TTyr3FU0lk3kzo,6190
374
373
  squad/frontend/templates/squad/build_callbacks.jinja2,sha256=eNN455gEodq3EmAQ4LplmlXcKCCmSoKA88UScubqjX8,2493
375
374
  squad/frontend/templates/squad/build_metadata.jinja2,sha256=1yiNjM9OANusiVKg1M10bdxG_tGfvAU9nD-5cf5sdUM,312
@@ -379,7 +378,6 @@ squad/frontend/templates/squad/builds.jinja2,sha256=fgncIoQ4S5A0SBh4WKGey80PxDhu
379
378
  squad/frontend/templates/squad/compare.jinja2,sha256=-jlpzpSHqNp-A-GDlsqyGEPgmGMyGNKtubUCaIUX3FI,3879
380
379
  squad/frontend/templates/squad/compare_builds.jinja2,sha256=5fYnzM9LAJ5fMYv1fpjXYpEOsGidO4ItVXHGSNBoD0Q,3830
381
380
  squad/frontend/templates/squad/compare_projects.jinja2,sha256=UYr2PCzrHxCcjW63lULKjgKG6T1rSPr1Hzbd1rNM5Uk,3246
382
- squad/frontend/templates/squad/failures.jinja2,sha256=SWJpC1EO-GCdHu2Zy2djI9IJhDBBvEc-7W_HV6WhQQs,2951
383
381
  squad/frontend/templates/squad/group-nav.jinja2,sha256=5cA9FZRSrlcGjdMT_NpmrHZEEjyUiM8rUha7pJgCKFs,969
384
382
  squad/frontend/templates/squad/group.jinja2,sha256=APntfdkRqdgA2sGgx2xvVU1guVZbJNi0wqHw45rYyds,336
385
383
  squad/frontend/templates/squad/index.jinja2,sha256=jtVWPDRr4l0CPWvmV60NGoNinCCr7eHXy6xiSQy-yYA,1901
@@ -388,7 +386,7 @@ squad/frontend/templates/squad/login.jinja2,sha256=NPp20MpmgoGxWOschCUxcZMJKdnkV
388
386
  squad/frontend/templates/squad/metrics.jinja2,sha256=CH6Dw539PwlA5TI8rRWgQyQ7nbVMjI3eJO2fUOVoYbE,3158
389
387
  squad/frontend/templates/squad/project-nav.jinja2,sha256=AHN7r5TMvJ-NwEo_u3vlJg34J1njsuII32SgQuTfiwA,1526
390
388
  squad/frontend/templates/squad/project.jinja2,sha256=dQp1yyB2cZ6cmMT7bY8vl9v8-u-qd6elarEDAhnh7FU,618
391
- squad/frontend/templates/squad/test_history.jinja2,sha256=dM5h5M1OwZXeQ_kpl1Z1GsqhxqD6-tTz6O7gibct8bE,5721
389
+ squad/frontend/templates/squad/test_history.jinja2,sha256=mGAIKtR8dsn8QDmxgYLuCw8_keq_tsKOU0U05fkFkbQ,5724
392
390
  squad/frontend/templates/squad/test_run.jinja2,sha256=smxFEC7XnHu28Wj7iC2WQrGjpuPiqsxASpflbyYGG_A,1176
393
391
  squad/frontend/templates/squad/test_run_suite_metrics.jinja2,sha256=WGjlObw7ZTGoomTmON0O2QRHHdmEBOYf9xMSTWP83F4,1780
394
392
  squad/frontend/templates/squad/test_run_suite_test_details.jinja2,sha256=R6Md26LsUJGrvMfCsFNO67eMgMfyMZdrmF5MS7ydtHo,5478
@@ -419,7 +417,7 @@ squad/frontend/templates/squad/user_settings/profile.jinja2,sha256=l32GBmn3n5Dh0
419
417
  squad/frontend/templates/squad/user_settings/projects.jinja2,sha256=AsMPhI96V5Gt_SjeKKIne9P1pGH8tS_ik8uyFA_aKMQ,935
420
418
  squad/frontend/templates/squad/user_settings/subscriptions.jinja2,sha256=jhmkNMIdXUx2vswuBkaJwM6VpAe4ecV_bRH3Sg0wfT4,2054
421
419
  squad/frontend/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
422
- squad/frontend/templatetags/squad.py,sha256=NYUTUgpRHFfeSep4S2mj0oqYqaZ9oWqUNme5L5OPjX4,7786
420
+ squad/frontend/templatetags/squad.py,sha256=QFIogzfhubm1gA45hZNNfizFpqp7BxElz4Mt1yxAHDQ,7746
423
421
  squad/plugins/__init__.py,sha256=9BSzy2jFIoDpWlhD7odPPrLdW4CC3btBhdFCvB651dM,152
424
422
  squad/plugins/example.py,sha256=BKpwd315lHRIuNXJPteibpwfnI6C5eXYHYdFYBtVmsI,89
425
423
  squad/plugins/gerrit.py,sha256=CqO2KnFQzu9utr_TQ-sGr1wg3ln0B-bS2-c0_i8T5-c,7009
@@ -430,9 +428,9 @@ squad/run/__main__.py,sha256=DOl8JOi4Yg7DdtwnUeGqtYBJ6P2k-D2psAEuYOjWr8w,66
430
428
  squad/run/listener.py,sha256=jBeOQhPGb4EdIREB1QsCzYuumsfJ-TqJPd3nR-0m59g,200
431
429
  squad/run/scheduler.py,sha256=CDJG3q5C0GuQuxwlMOfWTSSJpDdwbR6rzpbJfuA0xuw,277
432
430
  squad/run/worker.py,sha256=jtML0h5qKDuSbpJ6_rpWP4MT_rsGA7a24AhwGxBquzk,594
433
- squad-1.73.dist-info/COPYING,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
434
- squad-1.73.dist-info/METADATA,sha256=NwC6BioPY-C7FkHCTZQJfvFpdYgkcZ4wVAnsOM5ht-s,1245
435
- squad-1.73.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
436
- squad-1.73.dist-info/entry_points.txt,sha256=apCDQydHZtvqV334ql6NhTJUAJeZRdtAm0TVcbbAi5Q,194
437
- squad-1.73.dist-info/top_level.txt,sha256=_x9uqE1XppiiytmVTl_qNgpnXus6Gsef69HqfliE7WI,6
438
- squad-1.73.dist-info/RECORD,,
431
+ squad-1.75.dist-info/COPYING,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
432
+ squad-1.75.dist-info/METADATA,sha256=tnDoktc6-u7r6X5n5HGdAk1sxjAQYXptjBuWrtSjN_w,1245
433
+ squad-1.75.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
434
+ squad-1.75.dist-info/entry_points.txt,sha256=apCDQydHZtvqV334ql6NhTJUAJeZRdtAm0TVcbbAi5Q,194
435
+ squad-1.75.dist-info/top_level.txt,sha256=_x9uqE1XppiiytmVTl_qNgpnXus6Gsef69HqfliE7WI,6
436
+ squad-1.75.dist-info/RECORD,,
@@ -1,65 +0,0 @@
1
- from django.core.paginator import InvalidPage, Paginator
2
- from django.http import Http404
3
- from django.shortcuts import render
4
-
5
- from squad.core.failures import failures_with_confidence
6
- from squad.core.models import Test
7
- from squad.http import auth
8
- from squad.frontend.views import get_build
9
-
10
-
11
- @auth
12
- def failures(request, group_slug, project_slug, build_version):
13
- project = request.project
14
- build = get_build(project, build_version)
15
- environments = project.environments.order_by("slug")
16
-
17
- failures_ids = build.tests.filter(
18
- result=False,
19
- ).exclude(
20
- has_known_issues=True,
21
- ).only(
22
- 'id'
23
- ).distinct('metadata_id').order_by('-metadata_id')
24
-
25
- failures = Test.objects.filter(id__in=failures_ids).only(
26
- 'metadata__suite', 'metadata__name', 'metadata__id',
27
- ).order_by(
28
- 'metadata__suite', 'metadata__name',
29
- ).distinct().values_list(
30
- 'metadata__suite', 'metadata__name', 'metadata__id', named=True,
31
- )
32
-
33
- search = request.GET.get('search', '')
34
- if search:
35
- failures = failures.filter(metadata__name__contains=search)
36
-
37
- try:
38
- page_num = request.GET.get('page', 1)
39
- paginator = Paginator(failures, 25)
40
- paginator.count = failures_ids.count()
41
- page = paginator.page(page_num)
42
- except InvalidPage as ip:
43
- raise Http404(('Invalid page (%(page_number)s): %(message)s') % {
44
- 'page_number': page_num,
45
- 'message': str(ip),
46
- })
47
-
48
- fwc = failures_with_confidence(project, build, page)
49
- rows = {}
50
- for t in fwc:
51
- if t.environment.slug not in rows:
52
- rows[t.environment.slug] = {}
53
-
54
- rows[t.environment.slug][t.full_name] = t
55
-
56
- context = {
57
- "project": project,
58
- "build": build,
59
- "environments": environments,
60
- "page": page,
61
- "rows": rows,
62
- "search": search,
63
- }
64
-
65
- return render(request, 'squad/failures.jinja2', context)