summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/supervisord.conf1
-rw-r--r--conf/uwsgi.ini1
-rw-r--r--omaha_server/crash/admin.py4
-rw-r--r--omaha_server/crash/forms.py23
-rw-r--r--omaha_server/crash/models.py6
-rw-r--r--omaha_server/crash/tests/test_forms.py37
-rw-r--r--omaha_server/omaha/admin.py18
-rw-r--r--omaha_server/omaha/static/statistics/js/live_charts.js20
-rw-r--r--pavement.py2
9 files changed, 91 insertions, 21 deletions
diff --git a/conf/supervisord.conf b/conf/supervisord.conf
index a186f26..ea6312a 100644
--- a/conf/supervisord.conf
+++ b/conf/supervisord.conf
@@ -10,6 +10,7 @@ autorestart=true
command=/usr/local/bin/uwsgi --ini /srv/omaha/conf/uwsgi.ini
autostart=true
autorestart=true
+stopsignal=QUIT
[program:celery]
command=celery worker -B -A omaha_server --loglevel=INFO
diff --git a/conf/uwsgi.ini b/conf/uwsgi.ini
index dac8d63..d4c0b8f 100644
--- a/conf/uwsgi.ini
+++ b/conf/uwsgi.ini
@@ -6,3 +6,4 @@ chunked-input-limit = 25000000
chunked-input-timeout = 300
socket-timeout = 300
buffer-size = 65535
+master = 1
diff --git a/omaha_server/crash/admin.py b/omaha_server/crash/admin.py
index e45f1f1..8483449 100644
--- a/omaha_server/crash/admin.py
+++ b/omaha_server/crash/admin.py
@@ -114,11 +114,11 @@ class CrashAdmin(admin.ModelAdmin):
archive_field.short_description = 'Instrumental file'
def os_field(self, obj):
- return obj.stacktrace_json['system_info']['os'] if obj.stacktrace_json else ''
+ return obj.stacktrace_json.get('system_info', {}).get('os', '') if obj.stacktrace_json else ''
os_field.short_description = 'OS'
def cpu_architecture_field(self, obj):
- return obj.stacktrace_json['system_info']['cpu_arch'] if obj.stacktrace_json else ''
+ return obj.stacktrace_json.get('system_info', {}).get('cpu_arch', '') if obj.stacktrace_json else ''
cpu_architecture_field.short_description = "CPU Architecture"
def sentry_link_field(self, obj):
diff --git a/omaha_server/crash/forms.py b/omaha_server/crash/forms.py
index 27cbb16..233e97a 100644
--- a/omaha_server/crash/forms.py
+++ b/omaha_server/crash/forms.py
@@ -52,17 +52,20 @@ class CrashFrom(forms.ModelForm):
def clean_upload_file_minidump(self):
file = self.cleaned_data["upload_file_minidump"]
- if file.name.endswith('.tar'):
- t_file = BytesIO(file.read())
- t_file = tarfile.open(fileobj=t_file, mode='r')
- self.cleaned_data['archive_file'] = file
- dump_name = filter(lambda i: i.endswith('.dmp'), t_file.getnames())
+ if file and file.name.endswith('.tar'):
try:
- file_name = next(dump_name)
- file = t_file.extractfile(file_name)
- file = SimpleUploadedFile(file_name, file.read())
- except StopIteration:
- return None
+ t_file = BytesIO(file.read())
+ t_file = tarfile.open(fileobj=t_file, mode='r')
+ self.cleaned_data['archive_file'] = file
+ dump_name = filter(lambda i: i.endswith('.dmp'), t_file.getnames())
+ try:
+ file_name = next(dump_name)
+ file = t_file.extractfile(file_name)
+ file = SimpleUploadedFile(file_name, file.read())
+ except StopIteration:
+ return None
+ except tarfile.TarError as err:
+ raise forms.ValidationError('The tar file is broken, error: {0}'.format(err.message))
return file
def clean_minidump_size(self):
diff --git a/omaha_server/crash/models.py b/omaha_server/crash/models.py
index aa18980..434b26a 100644
--- a/omaha_server/crash/models.py
+++ b/omaha_server/crash/models.py
@@ -65,9 +65,13 @@ class Crash(BaseModel):
class Meta(BaseModel.Meta):
verbose_name_plural = 'Crashes'
+ def __unicode__(self):
+ return u"Crash #{0}".format(self.id) + (" ({0})".format(self.signature) if self.signature else '')
+
@property
def size(self):
- return self.archive_size + self.minidump_size
+ return self.archive_size + self.minidump_size
+
class CrashDescription(BaseModel):
crash = models.OneToOneField(Crash, related_name='crash_description')
diff --git a/omaha_server/crash/tests/test_forms.py b/omaha_server/crash/tests/test_forms.py
index 9e41e82..9ddf202 100644
--- a/omaha_server/crash/tests/test_forms.py
+++ b/omaha_server/crash/tests/test_forms.py
@@ -19,6 +19,8 @@ the License.
"""
import os
+import string
+import random
from django.test import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -32,6 +34,10 @@ SYM_FILE = os.path.join(TEST_DATA_DIR, 'BreakpadTestApp.sym')
TAR_FILE = os.path.join(TEST_DATA_DIR, 'foo.tar')
+def string_generator(size, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits):
+ return ''.join(random.choice(chars) for _ in range(size))
+
+
class SymbolsAdminFormTest(TestCase):
def test_form(self):
form_data = {}
@@ -78,4 +84,33 @@ class CrashFormTest(TestCase):
self.assertEqual(form.cleaned_data['upload_file_minidump'].name, '7b05e196-7e23-416b-bd13-99287924e214.dmp')
self.assertEqual(form.cleaned_data['archive'].name, 'foo.tar')
self.assertEqual(form.cleaned_data['archive_size'], 85504)
- self.assertEqual(form.cleaned_data['minidump_size'], 14606) \ No newline at end of file
+ self.assertEqual(form.cleaned_data['minidump_size'], 14606)
+
+ def test_invalid_data(self):
+ with open(TAR_FILE, 'rb') as f:
+ form_file_data = dict(upload_file_minidump=SimpleUploadedFile(
+ "foo.tar", f.read(100)))
+ form_data = dict(
+ appid=string_generator(40),
+ userid=string_generator(40),
+ meta=string_generator(40),
+ stacktrace=string_generator(40),
+ stacktrace_json=string_generator(40),
+ signature=string_generator(256),
+ ip=string_generator(40),
+ groupid=string_generator(40),
+ eventid=string_generator(40),
+ )
+
+ form = CrashFrom(form_data, form_file_data)
+ self.assertFalse(form.is_valid())
+ self.assertIn('upload_file_minidump', form.errors)
+ self.assertIn('appid', form.errors)
+ self.assertIn('userid', form.errors)
+ self.assertIn('meta', form.errors)
+ self.assertNotIn('stacktrace', form.errors)
+ self.assertIn('stacktrace_json', form.errors)
+ self.assertIn('signature', form.errors)
+ self.assertIn('ip', form.errors)
+ self.assertIn('groupid', form.errors)
+ self.assertIn('eventid', form.errors)
diff --git a/omaha_server/omaha/admin.py b/omaha_server/omaha/admin.py
index b3c7ffc..8519567 100644
--- a/omaha_server/omaha/admin.py
+++ b/omaha_server/omaha/admin.py
@@ -17,11 +17,18 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
"""
+import copy
from django.contrib import admin
+from django.contrib.admin import utils
+from django.utils.encoding import smart_text
+
+from dynamic_preferences.models import GlobalPreferenceModel, UserPreferenceModel
+from versionfield import VersionField
+
from omaha.models import Channel, Platform, Application, Version, Action, PartialUpdate, Data
from omaha.forms import ApplicationAdminForm, VersionAdminForm, ActionAdminForm, DataAdminForm
-from dynamic_preferences.models import GlobalPreferenceModel, UserPreferenceModel
+
admin.site.unregister(GlobalPreferenceModel)
admin.site.unregister(UserPreferenceModel)
@@ -68,3 +75,12 @@ class VersionAdmin(admin.ModelAdmin):
list_filter = ('channel__name', 'platform__name', 'app__name',)
readonly_fields = ('file_hash',)
form = VersionAdminForm
+
+
+def my_display_for_field(value, field, *args, **kwargs):
+ if isinstance(field, VersionField):
+ return smart_text(value)
+ return django_display_for_field(value, field, *args, **kwargs)
+
+django_display_for_field = copy.deepcopy(utils.display_for_field)
+utils.display_for_field = my_display_for_field \ No newline at end of file
diff --git a/omaha_server/omaha/static/statistics/js/live_charts.js b/omaha_server/omaha/static/statistics/js/live_charts.js
index 31263b4..18f6da5 100644
--- a/omaha_server/omaha/static/statistics/js/live_charts.js
+++ b/omaha_server/omaha/static/statistics/js/live_charts.js
@@ -28,20 +28,29 @@ function getVersions(data){
function getData(data){
- return getVersions(data).map(function(d){
+ var result = getVersions(data).map(function(d){
return {
key: d,
values: data[d]
}
});
+
+ if (result.length) {
+ result.map(function(x){
+ x.values.pop();
+ });
+ }
+ return result;
}
function getHours(data){
if (Object.keys(data).length) {
- return data[Object.keys(data)[0]].map(function (d) {
- return new Date(d[0])
+ var res = data[Object.keys(data)[0]].map(function (d) {
+ return new Date(d[0]);
});
+ res.pop();
+ return res;
}
else return [];
}
@@ -70,7 +79,10 @@ function makePlatformGraph(chartName, chartDataName, data, platform){
.y(function(d) { return d[1] })
.useInteractiveGuideline(true)
.showControls(false);
-
+ chart.interactiveLayer.tooltip.headerFormatter(function(d) {
+ var top_limit = moment(d, 'MMMM DD hh:mm a').add(1, 'h');
+ return d + ' - ' + top_limit.format('hh:mm A');
+ });
chart.xAxis.showMaxMin(false)
.tickValues(hours.filter(function(d, i){
return !(i % tickSize);
diff --git a/pavement.py b/pavement.py
index 5b459c2..e63f951 100644
--- a/pavement.py
+++ b/pavement.py
@@ -82,8 +82,6 @@ def loaddata():
@task
def migrate():
- sh('./manage.py migrate sites --noinput', cwd='omaha_server')
- sh('./manage.py migrate auth --noinput', cwd='omaha_server')
sh('./manage.py migrate --noinput', cwd='omaha_server')