diff options
-rw-r--r-- | omaha_server/crash/models.py | 18 | ||||
-rw-r--r-- | omaha_server/crash/serializers.py | 3 | ||||
-rw-r--r-- | omaha_server/crash/tests/test_serializers.py | 5 | ||||
-rw-r--r-- | omaha_server/crash/utils.py | 6 | ||||
-rw-r--r-- | omaha_server/feedback/models.py | 10 | ||||
-rw-r--r-- | omaha_server/omaha/api.py | 10 | ||||
-rw-r--r-- | omaha_server/omaha/tables.py | 6 | ||||
-rw-r--r-- | omaha_server/omaha/tests/test_api.py | 73 | ||||
-rw-r--r-- | omaha_server/omaha/views_admin.py | 7 | ||||
-rw-r--r-- | omaha_server/sparkle/api.py | 4 | ||||
-rw-r--r-- | omaha_server/sparkle/tests/test_api.py | 20 |
11 files changed, 138 insertions, 24 deletions
diff --git a/omaha_server/crash/models.py b/omaha_server/crash/models.py index 434b26a..d7a4dd0 100644 --- a/omaha_server/crash/models.py +++ b/omaha_server/crash/models.py @@ -33,16 +33,24 @@ from omaha.models import BaseModel from crash.managers import CrashManager, SymbolsManager -def crash_upload_to(obj, filename): +def upload_to(directory, obj, filename): now = timezone.now() - return os.path.join(*map(str, ['minidump', now.year, now.month, + max_length = 255 + path = os.path.join(*map(str, [directory, now.year, now.month, now.day, uuid.uuid4(), filename])) + if len(path) > max_length: + name, ext = os.path.splitext(path) + ext_length = len(ext) + path = name[:max_length-ext_length] + ext + return path + + +def crash_upload_to(obj, filename): + return upload_to('minidump', obj, filename) def crash_archive_upload_to(obj, filename): - now = timezone.now() - return os.path.join(*map(str, ['minidump_archive', now.year, now.month, - now.day, uuid.uuid4(), filename])) + return upload_to('minidump_archive', obj, filename) class Crash(BaseModel): diff --git a/omaha_server/crash/serializers.py b/omaha_server/crash/serializers.py index 97e181f..81c714e 100644 --- a/omaha_server/crash/serializers.py +++ b/omaha_server/crash/serializers.py @@ -59,8 +59,9 @@ class SymbolsSerializer(serializers.HyperlinkedModelSerializer): class CrashSerializer(serializers.HyperlinkedModelSerializer): meta = serializers.DictField() + stacktrace_json = serializers.DictField() class Meta: model = Crash fields = ('id', 'upload_file_minidump', 'archive', 'appid', 'userid', - 'meta', 'signature', 'created', 'modified',) + 'meta', 'signature', 'stacktrace_json', 'created', 'modified',) diff --git a/omaha_server/crash/tests/test_serializers.py b/omaha_server/crash/tests/test_serializers.py index ecc8ab9..34350ec 100644 --- a/omaha_server/crash/tests/test_serializers.py +++ b/omaha_server/crash/tests/test_serializers.py @@ -74,6 +74,9 @@ class CrashSerializerTest(TestCase): lang='en', version='1.0.0.1', ) + stacktrace_json = dict( + crashing_thread={}, + ) app_id = '{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}' user_id = '{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}' crash = Crash.objects.create( @@ -81,6 +84,7 @@ class CrashSerializerTest(TestCase): userid=user_id, upload_file_minidump=SimpleUploadedFile('./dump.dat', b''), meta=meta, + stacktrace_json=stacktrace_json ) self.assertDictEqual(CrashSerializer(crash).data, dict(id=crash.id, @@ -90,5 +94,6 @@ class CrashSerializerTest(TestCase): userid=str(crash.userid), meta=meta, signature=crash.signature, + stacktrace_json=crash.stacktrace_json, created=crash.created.strftime('%Y-%m-%dT%H:%M:%S.%fZ'), modified=crash.modified.strftime('%Y-%m-%dT%H:%M:%S.%fZ'))) diff --git a/omaha_server/crash/utils.py b/omaha_server/crash/utils.py index 8990722..1cceb76 100644 --- a/omaha_server/crash/utils.py +++ b/omaha_server/crash/utils.py @@ -113,13 +113,15 @@ def send_stacktrace_sentry(crash): crashdump_url=crash.upload_file_minidump.url, ) + tags = {} if crash.meta: extra.update(crash.meta) - + ver = crash.meta.get('ver') + if ver: + tags['ver'] = ver if crash.archive: extra['archive_url'] = crash.archive.url - tags = {} tags.update(stacktrace.get('system_info', {})) if crash.appid: diff --git a/omaha_server/feedback/models.py b/omaha_server/feedback/models.py index 7c8713c..bb2ab2e 100644 --- a/omaha_server/feedback/models.py +++ b/omaha_server/feedback/models.py @@ -31,10 +31,18 @@ from jsonfield import JSONField from omaha.models import BaseModel from feedback.managers import FeedbackManager + def upload_to(directory, obj, filename): now = timezone.now() - return os.path.join(*map(str, [directory, now.year, now.month, + max_length = 100 + path = os.path.join(*map(str, [directory, now.year, now.month, now.day, uuid.uuid4(), filename])) + if len(path) > max_length: + name, ext = os.path.splitext(path) + ext_length = len(ext) + path = name[:max_length-ext_length] + ext + return path + def screenshot_upload_to(obj, filename): return upload_to('screenshot', obj, filename) diff --git a/omaha_server/omaha/api.py b/omaha_server/omaha/api.py index 4fda594..92d7a79 100644 --- a/omaha_server/omaha/api.py +++ b/omaha_server/omaha/api.py @@ -74,7 +74,7 @@ class StandardResultsSetPagination(pagination.PageNumberPagination): max_page_size = 100 -class AppViewSet(BaseView): +class AppViewSet(viewsets.ModelViewSet): """ API endpoint that allows applications to be viewed. @@ -152,12 +152,12 @@ class AppViewSet(BaseView): serializer_class = AppSerializer -class DataViewSet(BaseView): +class DataViewSet(viewsets.ModelViewSet): queryset = Data.objects.all().order_by('-id') serializer_class = DataSerializer -class PlatformViewSet(BaseView): +class PlatformViewSet(viewsets.ModelViewSet): queryset = Platform.objects.all().order_by('-id') serializer_class = PlatformSerializer @@ -167,12 +167,12 @@ class ChannelViewSet(viewsets.ModelViewSet): serializer_class = ChannelSerializer -class VersionViewSet(BaseView, mixins.UpdateModelMixin): +class VersionViewSet(viewsets.ModelViewSet): queryset = Version.objects.all().order_by('-id') serializer_class = VersionSerializer -class ActionViewSet(BaseView): +class ActionViewSet(viewsets.ModelViewSet): queryset = Action.objects.all().order_by('-id') serializer_class = ActionSerializer diff --git a/omaha_server/omaha/tables.py b/omaha_server/omaha/tables.py index ea7cc06..e1a4c30 100644 --- a/omaha_server/omaha/tables.py +++ b/omaha_server/omaha/tables.py @@ -75,12 +75,12 @@ class VersionsUsageTable(tables.Table): nextversion = tables.Column(verbose_name='Current Version') last_update = tables.DateTimeColumn(accessor='request.created', order_by='-request__created', verbose_name='Last update') - ip = tables.Column(accessor='request.ip') - platform = tables.Column(accessor='request.os.platform') + ip = tables.Column(accessor='request.ip', verbose_name='IP') + platform = tables.Column(accessor='request.os.platform', verbose_name='Platform') class Meta: model = AppRequest - orderable = False + orderable = True attrs = {'class': 'paleblue table table-striped table-bordered table-hover table-condensed', 'id': 'usage-table'} fields = ('userid', 'nextversion', 'last_update', 'ip', 'platform') diff --git a/omaha_server/omaha/tests/test_api.py b/omaha_server/omaha/tests/test_api.py index 09f0cb0..35a33b3 100644 --- a/omaha_server/omaha/tests/test_api.py +++ b/omaha_server/omaha/tests/test_api.py @@ -122,6 +122,20 @@ class AppTest(BaseTest, APITestCase): obj = Application.objects.get(id=response.data['id']) self.assertEqual(response.data, self.serializer(obj).data) + @is_private() + def test_update(self): + data = dict(id='test_id', name='test_name', data_set=[]) + response = self.client.post(reverse(self.url), data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + obj_id = response.data['id'] + obj = Application.objects.get(id=obj_id) + self.assertEqual(obj.name, 'test_name') + url = reverse(self.url_detail, kwargs=dict(pk=obj_id)) + response = self.client.patch(url, dict(name='test_other_name')) + self.assertEqual(response.status_code, status.HTTP_200_OK) + obj = Application.objects.get(id=obj_id) + self.assertEqual(obj.name, 'test_other_name') + class DataTest(BaseTest, APITestCase): url = 'data-list' @@ -138,6 +152,21 @@ class DataTest(BaseTest, APITestCase): obj = Data.objects.get(id=response.data['id']) self.assertEqual(response.data, self.serializer(obj).data) + @is_private() + def test_update(self): + app = ApplicationFactory.create() + data = dict(name=0, app=app.pk) + response = self.client.post(reverse(self.url), data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + obj_id = response.data['id'] + obj = Data.objects.get(id=obj_id) + self.assertEqual(obj.name, 0) + url = reverse(self.url_detail, kwargs=dict(pk=obj_id)) + response = self.client.patch(url, dict(name=1)) + self.assertEqual(response.status_code, status.HTTP_200_OK) + obj = Data.objects.get(id=obj_id) + self.assertEqual(obj.name, 1) + class PlatformTest(BaseTest, APITestCase): url = 'platform-list' @@ -157,6 +186,20 @@ class PlatformTest(BaseTest, APITestCase): obj = Platform.objects.get(id=response.data['id']) self.assertEqual(response.data, self.serializer(obj).data) + @is_private() + def test_create(self): + data = dict(name='test_name') + response = self.client.post(reverse(self.url), data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + obj_id = response.data['id'] + obj = Platform.objects.get(id=obj_id) + self.assertEqual(obj.name, 'test_name') + url = reverse(self.url_detail, kwargs=dict(pk=obj_id)) + response = self.client.patch(url, dict(name='test_name2')) + self.assertEqual(response.status_code, status.HTTP_200_OK) + obj = Platform.objects.get(id=obj_id) + self.assertEqual(obj.name, 'test_name2') + class ChannelTest(BaseTest, APITestCase): url = 'channel-list' @@ -172,6 +215,19 @@ class ChannelTest(BaseTest, APITestCase): obj = Channel.objects.get(id=response.data['id']) self.assertEqual(response.data, self.serializer(obj).data) + @is_private() + def test_update(self): + data = dict(name='test_name') + response = self.client.post(reverse(self.url), data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + obj_id = response.data['id'] + obj = Channel.objects.get(id=obj_id) + self.assertEqual(response.data, self.serializer(obj).data) + url = reverse(self.url_detail, kwargs=dict(pk=obj_id)) + response = self.client.patch(url, dict(name='test_name2')) + self.assertEqual(response.status_code, status.HTTP_200_OK) + obj = Channel.objects.get(id=obj_id) + self.assertEqual(obj.name, 'test_name2') class VersionTest(BaseTest, APITestCase): url = 'version-list' @@ -221,7 +277,6 @@ class VersionTest(BaseTest, APITestCase): self.assertEqual(response.status_code, status.HTTP_201_CREATED) obj_id = response.data['id'] version = Version.objects.get(id=obj_id) - self.assertEqual(response.data, self.serializer(version).data) self.assertEqual(version.file_size, len(b'content')) self.assertFalse(version.is_enabled) url = reverse(self.url_detail, kwargs=dict(pk=obj_id)) @@ -247,6 +302,22 @@ class ActionTest(BaseTest, APITestCase): obj = Action.objects.get(id=response.data['id']) self.assertEqual(response.data, self.serializer(obj).data) + @is_private() + def test_update(self): + version = VersionFactory.create() + data = dict(event=1, version=version.pk) + response = self.client.post(reverse(self.url), data, format='json') + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + obj_id = response.data['id'] + obj = Action.objects.get(id=obj_id) + self.assertEqual(response.data, self.serializer(obj).data) + url = reverse(self.url_detail, kwargs=dict(pk=obj_id)) + response = self.client.patch(url, dict(event=2)) + self.assertEqual(response.status_code, status.HTTP_200_OK) + obj = Action.objects.get(id=obj_id) + self.assertEqual(obj.event, 2) + + class LiveStatistics(APITestCase): maxDiff = None diff --git a/omaha_server/omaha/views_admin.py b/omaha_server/omaha/views_admin.py index 3dbb0e9..f074836 100644 --- a/omaha_server/omaha/views_admin.py +++ b/omaha_server/omaha/views_admin.py @@ -131,9 +131,6 @@ class VersionsUsageView(StaffMemberRequiredMixin, SingleTableView): def get_queryset(self): qs = super(VersionsUsageView, self).get_queryset() - - qs = qs.select_related('request', 'request__os') - qs = qs.order_by('-request__created') self.appid = None try: @@ -145,7 +142,9 @@ class VersionsUsageView(StaffMemberRequiredMixin, SingleTableView): qs = qs.filter(events__eventtype__in=[2, 3], events__eventresult=1) qs = qs.distinct('request__userid').order_by('request__userid', '-request__created') - return list(qs) + qs = qs.only('id') + sortable_qs = self.model.objects.filter(id__in=qs).select_related('request', 'request__os') + return sortable_qs def get_context_data(self, **kwargs): context = super(VersionsUsageView, self).get_context_data(**kwargs) diff --git a/omaha_server/sparkle/api.py b/omaha_server/sparkle/api.py index 594ad1f..005db7f 100644 --- a/omaha_server/sparkle/api.py +++ b/omaha_server/sparkle/api.py @@ -18,12 +18,12 @@ License for the specific language governing permissions and limitations under the License. """ -from omaha.api import BaseView +from rest_framework import viewsets from sparkle.serializers import SparkleVersionSerializer from sparkle.models import SparkleVersion -class SparkleVersionViewSet(BaseView): +class SparkleVersionViewSet(viewsets.ModelViewSet): queryset = SparkleVersion.objects.all().order_by('-id') serializer_class = SparkleVersionSerializer diff --git a/omaha_server/sparkle/tests/test_api.py b/omaha_server/sparkle/tests/test_api.py index d70f981..d05247f 100644 --- a/omaha_server/sparkle/tests/test_api.py +++ b/omaha_server/sparkle/tests/test_api.py @@ -66,3 +66,23 @@ class VersionTest(BaseTest, APITestCase): self.assertEqual(response.data, self.serializer(version).data) self.assertEqual(version.file_size, len(b'content')) self.assertTrue(version.is_enabled) + + @is_private() + @temporary_media_root(MEDIA_URL='http://cache.pack.google.com/edgedl/chrome/install/782.112/') + def test_update(self): + data = dict( + app=ApplicationFactory.create().id, + channel=ChannelFactory.create().id, + version='1.2.3.4', + file=SimpleUploadedFile("chrome.exe", b'content'), + ) + response = self.client.post(reverse(self.url), data) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + obj_id = response.data['id'] + version = SparkleVersion.objects.get(id=obj_id) + self.assertEqual(version.version, '1.2.3.4') + url = reverse(self.url_detail, kwargs=dict(pk=obj_id)) + response = self.client.patch(url, dict(version='1.2.3.5')) + self.assertEqual(response.status_code, status.HTTP_200_OK) + version = SparkleVersion.objects.get(id=obj_id) + self.assertEqual(version.version, '1.2.3.5') |