--- .gitignore | 2 ++ web/apps/__init__.py | 0 web/apps/test_item/__init__.py | 0 web/apps/test_item/admin.py | 3 ++ web/apps/test_item/models.py | 35 +++++++++++++++++++ web/apps/test_item/tests.py | 3 ++ web/apps/test_item/views.py | 3 ++ web/apps/user_operation/__init__.py | 0 web/apps/user_operation/admin.py | 3 ++ web/apps/user_operation/models.py | 58 ++++++++++++++++++++++++++++++++ web/apps/user_operation/tests.py | 3 ++ web/apps/user_operation/views.py | 3 ++ web/db.sqlite3 | Bin 0 -> 50176 bytes web/db_tools/data/__init__.py | 0 web/db_tools/data/test_branch_date.py | 11 ++++++ web/db_tools/import_test_branch_data.py | 22 ++++++++++++ web/pgperffarm/settings.py | 8 ++++- web/pgperffarm/urls.py | 2 +- 18 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 web/apps/__init__.py create mode 100644 web/apps/test_item/__init__.py create mode 100644 web/apps/test_item/admin.py create mode 100644 web/apps/test_item/models.py create mode 100644 web/apps/test_item/tests.py create mode 100644 web/apps/test_item/views.py create mode 100644 web/apps/user_operation/__init__.py create mode 100644 web/apps/user_operation/admin.py create mode 100644 web/apps/user_operation/models.py create mode 100644 web/apps/user_operation/tests.py create mode 100644 web/apps/user_operation/views.py create mode 100644 web/db.sqlite3 create mode 100644 web/db_tools/data/__init__.py create mode 100644 web/db_tools/data/test_branch_date.py create mode 100644 web/db_tools/import_test_branch_data.py
diff --git a/.gitignore b/.gitignore index 239c691..f6dc301 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ migrations *.psp .DS_Store tags + +.idea \ No newline at end of file diff --git a/web/apps/__init__.py b/web/apps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/apps/test_item/__init__.py b/web/apps/test_item/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/apps/test_item/admin.py b/web/apps/test_item/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/web/apps/test_item/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/web/apps/test_item/models.py b/web/apps/test_item/models.py new file mode 100644 index 0000000..428dc0b --- /dev/null +++ b/web/apps/test_item/models.py @@ -0,0 +1,35 @@ +from datetime import datetime + +from django.db import models + +# Create your models here. +class TestBranch(models.Model): + """ + test brand + """ + branch_name = models.CharField(max_length=128, verbose_name="branch name", help_text="branch name") + add_time = models.DateTimeField(default=datetime.now, verbose_name="branch added time", help_text="branch added time") + + class Meta: + verbose_name = "test branch" + verbose_name_plural = "test branch" + + def __str__(self): + return self.branch_name + +class TestItem(models.Model): + """ + test_item + """ + test_name = models.CharField(max_length=128, verbose_name="test name", help_text="test name") + test_desc = models.TextField(verbose_name="test desc", help_text="test desc") + test_metric = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="test metric", help_text="score>metric means improving;score<=metric means declining;") + test_branch = models.ForeignKey(TestBranch ,verbose_name="test branch", help_text="test branch") + add_time = models.DateTimeField(default=datetime.now, verbose_name="test added time") + + class Meta: + verbose_name = "test_item" + verbose_name_plural = "test_item" + + def __str__(self): + return self.test_name diff --git a/web/apps/test_item/tests.py b/web/apps/test_item/tests.py new file mode 100644 index 0000000..a6019d6 --- /dev/null +++ b/web/apps/test_item/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your test_item here. diff --git a/web/apps/test_item/views.py b/web/apps/test_item/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/web/apps/test_item/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/web/apps/user_operation/__init__.py b/web/apps/user_operation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/apps/user_operation/admin.py b/web/apps/user_operation/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/web/apps/user_operation/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/web/apps/user_operation/models.py b/web/apps/user_operation/models.py new file mode 100644 index 0000000..ca426f1 --- /dev/null +++ b/web/apps/user_operation/models.py @@ -0,0 +1,58 @@ +from datetime import datetime + +from django.db import models +from django.contrib.auth.models import User +from test_item.models import TestItem +# Create your models here. + +class Alias(models.Model): + """ + alias + """ + name = models.CharField(max_length=64, verbose_name="plants name") + + class Meta: + verbose_name = "alias" + verbose_name_plural = "alias" + + def __str__(self): + return self.name + +class UserMachine(models.Model): + """ + user machine + """ + machine_sn = models.CharField(max_length=16, verbose_name="machine sn") + machine_secret = models.CharField(max_length=32, verbose_name="machine secret") + machine_owner = models.ForeignKey(User) + alias = models.ForeignKey(Alias) + os_name = models.CharField(max_length=32, verbose_name="operation system name") + os_version = models.CharField(max_length=32, verbose_name="operation system version") + comp_name = models.CharField(max_length=32, verbose_name="compiler name") + comp_version = models.CharField(max_length=32, verbose_name="compiler version") + is_active = models.BooleanField(default=False, verbose_name="machine is active", help_text="Only when the value is True can the machine submit test results.") + add_time = models.DateTimeField(default=datetime.now, verbose_name="machine added time") + + class Meta: + verbose_name = "user machine" + verbose_name_plural = "user machine" + + def __str__(self): + return self.machine_sn + +class TestResult(models.Model): + """ + test result + """ + test = models.ForeignKey(TestItem) + machine = models.ForeignKey(UserMachine) + result_score = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="result score", help_text="score>metric means improving;score<=metric means declining;") + pg_config = models.TextField(verbose_name="postgresql config", help_text="postgresql config") + os_config = models.TextField(verbose_name="os config", help_text="os config") + result_desc = models.TextField(verbose_name="test result", help_text="test result") + + test_time = models.DateTimeField(verbose_name="test time") + + class Meta: + verbose_name = "test result" + verbose_name_plural = "test result" \ No newline at end of file diff --git a/web/apps/user_operation/tests.py b/web/apps/user_operation/tests.py new file mode 100644 index 0000000..a6019d6 --- /dev/null +++ b/web/apps/user_operation/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your test_item here. diff --git a/web/apps/user_operation/views.py b/web/apps/user_operation/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/web/apps/user_operation/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/web/db.sqlite3 b/web/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..11140436bfc1069fe740f30ca1ec8c762fcc6c09 GIT binary patch literal 50176 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 literal 0 HcmV?d00001 diff --git a/web/db_tools/data/__init__.py b/web/db_tools/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/db_tools/data/test_branch_date.py b/web/db_tools/data/test_branch_date.py new file mode 100644 index 0000000..04d0251 --- /dev/null +++ b/web/db_tools/data/test_branch_date.py @@ -0,0 +1,11 @@ +row_data = [ + { + 'name': 'HEAD', + }, + { + 'name': 'REL_10_STABLE', + }, + { + 'name': 'REL9_6_STABLE', + } +] \ No newline at end of file diff --git a/web/db_tools/import_test_branch_data.py b/web/db_tools/import_test_branch_data.py new file mode 100644 index 0000000..e85b538 --- /dev/null +++ b/web/db_tools/import_test_branch_data.py @@ -0,0 +1,22 @@ +import sys +import os + + +# Use django's model independently +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.extend([BASE_DIR,]) + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pgperffarm.settings") + +# Initialize django +import django +django.setup() + +from test_item.models import TestBranch +from data.test_branch_date import row_data + +for test_branch in row_data: + branch = TestBranch() + branch.name = test_branch["name"] + + branch.save() \ No newline at end of file diff --git a/web/pgperffarm/settings.py b/web/pgperffarm/settings.py index 38fdf8a..f6c9a14 100644 --- a/web/pgperffarm/settings.py +++ b/web/pgperffarm/settings.py @@ -1,5 +1,6 @@ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os +import sys # Load local settings overrides from settings_local import * @@ -16,8 +17,10 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.8/ref/settings/ """ -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, BASE_DIR) +sys.path.insert(0, os.path.join(BASE_DIR, 'apps')) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ @@ -41,6 +44,9 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'django_gravatar', + 'test_item', + 'user_operation', + # 'rest_framework', need Django 1.10+ ) MIDDLEWARE_CLASSES = ( diff --git a/web/pgperffarm/urls.py b/web/pgperffarm/urls.py index 3b439eb..87869de 100644 --- a/web/pgperffarm/urls.py +++ b/web/pgperffarm/urls.py @@ -35,5 +35,5 @@ urlpatterns = [ 'document_root': '/static', }), url(r'^favicon\.ico$', RedirectView.as_view(url='/static/favicon.ico', - permanent=True)) + permanent=True)), ] -- 2.12.0.windows.1