squad 1.84__py3-none-any.whl → 1.86.3__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/api/__init__.py CHANGED
@@ -0,0 +1,40 @@
1
+ from django.core.cache import cache
2
+ from rest_framework.throttling import UserRateThrottle
3
+
4
+
5
+ class SocialUserRateThrottle(UserRateThrottle):
6
+ """
7
+ Limits the rate of API calls that may be made by a given social user.
8
+
9
+ The user id will be used as a unique cache key if the user is
10
+ authenticated. For anonymous requests, the IP address of the request will
11
+ be used.
12
+ """
13
+
14
+ scope = "socialuser"
15
+
16
+ def is_social_user(self, user):
17
+ """
18
+ Social account user might use multiple applications (github, gitlab, google, ...)
19
+ to log in. But all of the login applications would likely point to the same
20
+ django user, which is what we want to rate limit here.
21
+ """
22
+
23
+ key = f"socialuser#{user.id}"
24
+ from allauth.socialaccount.models import SocialAccount
25
+ return cache.get_or_set(key, SocialAccount.objects.filter(user_id=user.id).exists())
26
+
27
+ def get_cache_key(self, request, view):
28
+ if request.user and request.user.is_authenticated:
29
+ if not self.is_social_user(request.user):
30
+ # do not throttle non-social users
31
+ return None
32
+
33
+ ident = request.user.pk
34
+ else:
35
+ ident = self.get_ident(request)
36
+
37
+ return self.cache_format % {
38
+ "scope": self.scope,
39
+ "ident": ident
40
+ }
squad/api/rest.py CHANGED
@@ -173,6 +173,7 @@ class TestJobFilter(filters.FilterSet):
173
173
  "fetched": ['exact', 'in'],
174
174
  "fetch_attempts": ['exact', 'in'],
175
175
  "last_fetch_attempt": ['exact', 'in', 'lt', 'gt', 'lte', 'gte'],
176
+ "created_at": ['exact', 'in', 'lt', 'gt', 'lte', 'gte'],
176
177
  "failure": ['exact', 'in', 'startswith', 'contains', 'icontains'],
177
178
  "can_resubmit": ['exact', 'in'],
178
179
  "resubmitted_count": ['exact', 'in'],
squad/ci/backend/fake.py CHANGED
@@ -60,6 +60,12 @@ class Backend(object):
60
60
  def job_url(self, test_job):
61
61
  return 'https://example.com/job/%s' % test_job.job_id
62
62
 
63
+ def has_resubmit(self):
64
+ return False
65
+
66
+ def has_cancel(self):
67
+ return True
68
+
63
69
  def cancel(self, test_job):
64
70
  return True
65
71
 
squad/ci/backend/lava.py CHANGED
@@ -106,6 +106,9 @@ class Backend(BaseBackend):
106
106
  return job_id
107
107
  return [job_id]
108
108
 
109
+ def has_cancel(self):
110
+ return True
111
+
109
112
  def cancel(self, test_job):
110
113
  if test_job.submitted and test_job.job_id is not None:
111
114
  return self.__cancel_job__(test_job.job_id)
@@ -329,6 +332,9 @@ class Backend(BaseBackend):
329
332
  scheme = socket_url.scheme
330
333
  return '%s://%s:%s' % (scheme, hostname, port)
331
334
 
335
+ def has_resubmit(self):
336
+ return True
337
+
332
338
  def resubmit(self, test_job):
333
339
  with self.handle_job_submission():
334
340
  new_job_id_list = self.__resubmit__(test_job.job_id)
squad/ci/backend/null.py CHANGED
@@ -8,7 +8,7 @@ logger = logging.getLogger('squad.ci.backend')
8
8
  description = "None"
9
9
 
10
10
 
11
- class Backend(object):
11
+ class Backend:
12
12
 
13
13
  """
14
14
  This is the interface that all backends must implement. Depending on the
@@ -39,6 +39,13 @@ class Backend(object):
39
39
  """
40
40
  raise NotImplementedError
41
41
 
42
+ def has_resubmit(self):
43
+ """
44
+ If the backend has a resubmit method implemented, override this to
45
+ return True.
46
+ """
47
+ return False
48
+
42
49
  def resubmit(self, test_job):
43
50
  """
44
51
  Re-submits given test job to the backend service
@@ -84,6 +91,13 @@ class Backend(object):
84
91
  """
85
92
  raise NotImplementedError
86
93
 
94
+ def has_cancel(self):
95
+ """
96
+ If the backend has a cancel method implemented, override this to
97
+ return True.
98
+ """
99
+ return False
100
+
87
101
  def cancel(self, test_job):
88
102
  """
89
103
  Cancels the job if the backend allows it. It will not raise any
@@ -32,6 +32,11 @@ requests_session = None
32
32
 
33
33
 
34
34
  class Backend(BaseBackend):
35
+ def has_resubmit(self):
36
+ return False
37
+
38
+ def has_cancel(self):
39
+ return True
35
40
 
36
41
  @staticmethod
37
42
  def get_session():
@@ -414,6 +419,12 @@ class Backend(BaseBackend):
414
419
  endpoint = f'groups/{tux_group}/projects/{tux_user}/{result_type.lower()}s/{tux_uid}/cancel'
415
420
  url = urljoin(self.data.url, endpoint)
416
421
  response = requests.post(url)
422
+
423
+ testjob.fetched = True
424
+ testjob.submitted = True
425
+ testjob.job_status = "Canceled"
426
+ testjob.save()
427
+
417
428
  return response.status_code == 200
418
429
 
419
430
  def supports_callbacks(self):
squad/ci/models.py CHANGED
@@ -382,7 +382,7 @@ class TestJob(models.Model):
382
382
  if self.job_status == "Canceled":
383
383
  return False
384
384
 
385
- if self.job_id is not None:
385
+ if self.job_id is not None and self.backend.get_implementation().has_cancel():
386
386
  return self.backend.get_implementation().cancel(self)
387
387
 
388
388
  self.fetched = True
@@ -56,7 +56,7 @@
56
56
  <div class='pull-right clearfix' ng-controller='CancelController' title="{{ _('Cancel all jobs') }}">
57
57
  <a class="btn" ng-click="cancel_all({{ build.id }})" ng-class="{'btn-info': !done, 'btn-success': done, 'btn-danger': error}" ng-disabled="done" >
58
58
  <span ng-class="{'fa':true, 'fa-recycle':!done, 'fa-check': done && !error, 'fa-spin': loading, 'fa-close': error}" ng-disabled="done"></span>
59
- {{ _('Cancell all jobs') }}
59
+ {{ _('Cancel all jobs') }}
60
60
  </a>
61
61
  </div>
62
62
  <br />
@@ -107,7 +107,7 @@
107
107
  ng-class="{'fa':true, 'fa-recycle':!done, 'fa-check': done && !error, 'fa-spin': loading, 'fa-close': error}"
108
108
  ng-disabled="done">
109
109
  </span>
110
- {{ _('%s - manual fetch') % testjob.job_id }}
110
+ {{ _('manual fetch') }}
111
111
  </a>
112
112
  </div>
113
113
  {% endif %}
@@ -122,11 +122,12 @@
122
122
  ng-class="{'fa':true, 'fa-recycle':!done, 'fa-check': done && !error, 'fa-spin': loading, 'fa-close': error}"
123
123
  ng-disabled="done">
124
124
  </span>
125
- {{ _('%s - cancel') % testjob.job_id }}
125
+ {{ _('cancel %s') % testjob.backend.get_implementation().has_cancel() }}
126
126
  </a>
127
127
  </div>
128
128
  {% endif %}
129
129
  <div class='pull-right' ng-controller='ResubmitController'>
130
+ {% if testjob.backend.get_implementation().has_resubmit() %}
130
131
  <a
131
132
  class="btn"
132
133
  ng-click="resubmit({{testjob.id}}, true)"
@@ -138,9 +139,10 @@
138
139
  ng-disabled="done"
139
140
  title="{{ _('Resubmit job no matter the status') }}">
140
141
  </span>
141
- {{ _('%s - force resubmit') % testjob.job_id }}
142
+ {{ _('force resubmit') }}
142
143
  </a>
143
- {% if testjob.can_resubmit %}
144
+ {% endif %}
145
+ {% if testjob.can_resubmit and testjob.backend.get_implementation().has_resubmit() %}
144
146
  <a
145
147
  class="btn"
146
148
  ng-click="resubmit({{testjob.id}}, false)"
@@ -152,7 +154,7 @@
152
154
  ng-disabled="done"
153
155
  title="{{ _('Resubmit job') }}">
154
156
  </span>
155
- {{ _('%s - resubmit') % testjob.job_id }}
157
+ {{ _('resubmit') }}
156
158
  </a>
157
159
  {% endif %}
158
160
  </div>
squad/settings.py CHANGED
@@ -13,6 +13,7 @@ https://docs.djangoproject.com/en/1.9/ref/settings/
13
13
  from celery.schedules import crontab
14
14
  from django.conf import global_settings
15
15
  from email.utils import parseaddr
16
+ from importlib.util import find_spec
16
17
  from glob import glob
17
18
  import contextlib
18
19
  import json
@@ -55,30 +56,23 @@ ALLOWED_HOSTS = ['*']
55
56
 
56
57
  # Application definition
57
58
 
58
- try:
59
- import imp
60
- imp.find_module('django_extensions')
59
+ django_extensions = None
60
+ if find_spec('django_extensions'):
61
61
  django_extensions = 'django_extensions'
62
- except ImportError:
63
- django_extensions = None
64
62
 
65
63
  django_toolbar = None
66
64
  django_toolbar_middleware = None
67
- try:
68
-
65
+ django_toolbar_module_spec = find_spec('debug_toolbar')
66
+ if django_toolbar_module_spec:
69
67
  DEBUG_TOOLBAR_CONFIG = {
70
68
  'JQUERY_URL': '',
71
69
  'SHOW_COLLAPSED': True,
72
70
  'SHOW_TOOLBAR_CALLBACK': 'squad.frontend.utils.show_debug_toolbar',
73
71
  }
74
72
 
75
- import imp
76
- imp.find_module('debug_toolbar')
77
73
  django_toolbar = 'debug_toolbar'
78
74
  django_toolbar_middleware = 'debug_toolbar.middleware.DebugToolbarMiddleware'
79
75
  INTERNAL_IPS = ['127.0.0.1']
80
- except ImportError:
81
- pass
82
76
 
83
77
 
84
78
  django_allauth_middleware = None
@@ -445,6 +439,9 @@ if SENTRY_DSN:
445
439
  # Django's default is 2.5MB, which is a bit low
446
440
  DATA_UPLOAD_MAX_MEMORY_SIZE = 10485760 # 10MB
447
441
 
442
+ # Django requires that this specification is present in settings.py
443
+ DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
444
+
448
445
  try:
449
446
  from squad.local_settings import * # noqa: F401,F403
450
447
  except ImportError:
squad/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.84'
1
+ __version__ = '1.86.3'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: squad
3
- Version: 1.84
3
+ Version: 1.86.3
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=Wzg1nS96OKZ38qEXtIat9XaZc1HigUJr3ktMuwVhf98,14546
10
+ squad/settings.py,sha256=YB2g6mHaa4sct04u7DHGr_RSLugxMTDGaMnZl69Yp7o,14652
11
11
  squad/socialaccount.py,sha256=vySqPwQ3qVVpahuJ-Snln8K--yzRL3bw4Nx27AsB39A,789
12
12
  squad/urls.py,sha256=JiEfVW8YlzLPE52c2aHzdn5kVVKK4o22w8h5KOA6QhQ,2776
13
- squad/version.py,sha256=iYQr9swGixaODcYVOitfNf5n_8R1RQPqLfDR2pJ9kOg,21
13
+ squad/version.py,sha256=Zroio3ZOXQsWya00gzHIk2KPUahZ7osQXHfabhsnwPw,23
14
14
  squad/wsgi.py,sha256=SF8T0cQ0OPVyuYjO5YXBIQzvSXQHV0M2BTmd4gP1rPs,387
15
- squad/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ squad/api/__init__.py,sha256=CJiVakfAlHVN5mIFRVQYZQfuNUhUgWVbsdYTME4tq7U,1349
16
16
  squad/api/apps.py,sha256=Trk72p-iV1uGn0o5mdJn5HARUoHGbfgO49jwXvpkmdQ,141
17
17
  squad/api/ci.py,sha256=ymG-eMKXpJgrVUiZcqJW-dYZQKvm1LkdR3TUMe4OSoM,6943
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=mbQQsOB-bdNGfQ76sbGxBgNRi9CMd99SNMQpda5DknY,77097
20
+ squad/api/rest.py,sha256=X3WX6tkqWl2H59fCJCNc3NIEkP4GoXImQLyCmvUlrMQ,77172
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=kuFlbiyZiD0i9jwwmkL3Y22LwJ3bx2oJs28d1g2DPA0,3898
@@ -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=Y03PaDasx-6LzTZz0o6dmpGD6Ch1whCXPjKpxqbhV2Y,15967
28
+ squad/ci/models.py,sha256=Fm-4b3SDgMh9HXzqjOd4iZDRMJ1D9AnZ2cg7i2OR248,16018
29
29
  squad/ci/tasks.py,sha256=xoiOyh0HKLiKsAnQbolMRq4E9RcvP4xFgR0S9d_bgm4,3782
30
30
  squad/ci/utils.py,sha256=38zHpw8xkZDSFlkG-2BwSK6AkcddK9OkN9LXuQ3SHR0,97
31
31
  squad/ci/backend/__init__.py,sha256=yhpotXT9F4IdAOXvGQ3-17eOHAFwoaqf9SnMX17ab30,534
32
- squad/ci/backend/fake.py,sha256=M3vpu1yoDz-fb8irygdTlQ8dQZwISMcR_H_VN_e_lB0,2243
33
- squad/ci/backend/lava.py,sha256=HrjDeRDySAs98D65baUZVpS11tSiNV0sPMYc7qMahk4,33511
34
- squad/ci/backend/null.py,sha256=EF_d9YlaVMwVrwT3MfZNFjE0N7AIfArOPsMAPVHv-W8,5106
35
- squad/ci/backend/tuxsuite.py,sha256=XnV5ee9eSSKyxZDO-pXibpP_TU4iCBHA8opaZ_3upXk,17296
32
+ squad/ci/backend/fake.py,sha256=9sPKndsGd5GDNPp35v-zfJWXZCbge-yXH3RBQGgTlPk,2340
33
+ squad/ci/backend/lava.py,sha256=EXwEksjdOi_ZrUoMkBTyxVjqVOnJvEFNg_LWqUKaIgA,33607
34
+ squad/ci/backend/null.py,sha256=0CVylWELIZw3JyzCROB4XXAjgQUi15YjQz5caRfTNBo,5434
35
+ squad/ci/backend/tuxsuite.py,sha256=Gq4cbmCRKglKSFL2ltH4vNkUTigmZnIO_8FZH6OJnPg,17521
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
@@ -394,7 +394,7 @@ squad/frontend/templates/squad/test_run_suite_metrics.jinja2,sha256=WGjlObw7ZTGo
394
394
  squad/frontend/templates/squad/test_run_suite_test_details.jinja2,sha256=HGGnxDoFpyPgiH34aIVRrQysLn7KLYtDITUeQikYOoY,5657
395
395
  squad/frontend/templates/squad/test_run_suite_tests.jinja2,sha256=S5VJMIoc18W46iHtSSLYC_3C3Wj1saXU83wR-JvF8GI,935
396
396
  squad/frontend/templates/squad/testjob.jinja2,sha256=hQLavgkYJ3qAKJMG7cHnmJGC1jdwCnox2w9oQvLzn7U,324
397
- squad/frontend/templates/squad/testjobs.jinja2,sha256=eanRBdFf4aBbSAwNr_ZObTWFnk407bvBYEbj675zsJI,9491
397
+ squad/frontend/templates/squad/testjobs.jinja2,sha256=a90ltfoIWORB4i1mubA3cfQzX1IoSMqhYpAUc38RZSk,9632
398
398
  squad/frontend/templates/squad/testjobs_progress.jinja2,sha256=4_o53GOdcClRdiNQxPHwvXPI9Ia07gTJRu5SGrCJ7s4,2638
399
399
  squad/frontend/templates/squad/tests-details-nav.jinja2,sha256=WDi4vf0ctRK1dK1Z3IirBuyn5Dq9_qg_9A1P3GrB31U,664
400
400
  squad/frontend/templates/squad/tests.jinja2,sha256=2AaEoCHJiCzXu_36XOq0ihiGqxh_2U2w88dheBlIwy8,4970
@@ -431,9 +431,9 @@ squad/run/__main__.py,sha256=DOl8JOi4Yg7DdtwnUeGqtYBJ6P2k-D2psAEuYOjWr8w,66
431
431
  squad/run/listener.py,sha256=jBeOQhPGb4EdIREB1QsCzYuumsfJ-TqJPd3nR-0m59g,200
432
432
  squad/run/scheduler.py,sha256=CDJG3q5C0GuQuxwlMOfWTSSJpDdwbR6rzpbJfuA0xuw,277
433
433
  squad/run/worker.py,sha256=jtML0h5qKDuSbpJ6_rpWP4MT_rsGA7a24AhwGxBquzk,594
434
- squad-1.84.dist-info/COPYING,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
435
- squad-1.84.dist-info/METADATA,sha256=dBPaVg5mgtHDW700uN5rSz9rCLcT9Xsfw-vwh-Y_E4E,1234
436
- squad-1.84.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
437
- squad-1.84.dist-info/entry_points.txt,sha256=apCDQydHZtvqV334ql6NhTJUAJeZRdtAm0TVcbbAi5Q,194
438
- squad-1.84.dist-info/top_level.txt,sha256=_x9uqE1XppiiytmVTl_qNgpnXus6Gsef69HqfliE7WI,6
439
- squad-1.84.dist-info/RECORD,,
434
+ squad-1.86.3.dist-info/COPYING,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
435
+ squad-1.86.3.dist-info/METADATA,sha256=EnJrMFG-4ivsJncbuLs1S-_wOSjgR45ViaH0i6Og76E,1236
436
+ squad-1.86.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
437
+ squad-1.86.3.dist-info/entry_points.txt,sha256=apCDQydHZtvqV334ql6NhTJUAJeZRdtAm0TVcbbAi5Q,194
438
+ squad-1.86.3.dist-info/top_level.txt,sha256=_x9uqE1XppiiytmVTl_qNgpnXus6Gsef69HqfliE7WI,6
439
+ squad-1.86.3.dist-info/RECORD,,
File without changes
File without changes