Upgrade service tests

This commit is contained in:
Marc 2014-10-01 21:03:16 +00:00
parent 276c02c2fd
commit 647bc43a5a
11 changed files with 94 additions and 61 deletions

View File

@ -1,4 +1,5 @@
from orchestra.apps.accounts.models import Account
from orchestra.core import services
def get_related_objects(origin, max_depth=2):
@ -9,7 +10,6 @@ def get_related_objects(origin, max_depth=2):
flexibility. A more comprehensive approach may be considered if
a use-case calls for it.
"""
def related_iterator(node):
for field in node._meta.virtual_fields:
if hasattr(field, 'ct_field'):
@ -26,7 +26,7 @@ def get_related_objects(origin, max_depth=2):
return None
node = models[-1]
if len(models) > 1:
if hasattr(node, 'account') or isinstance(node, Account):
if type(node) in services:
return node
for related in related_iterator(node):
if related and related not in models:

View File

@ -14,7 +14,7 @@ from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from orchestra.core import accounts
from orchestra.core import accounts, services
from orchestra.models import queryset
from orchestra.utils.python import import_class
@ -71,6 +71,7 @@ class OrderQuerySet(models.QuerySet):
for order in orders:
bp = service.handler.get_billing_point(order, **options)
end = max(end, bp)
# FIXME exclude cancelled except cancelled and billed > ini
qs = qs | Q(
Q(service=service, account=account_id, registered_on__lt=end) &
Q(Q(billed_until__isnull=True) | Q(billed_until__lt=end))
@ -236,27 +237,26 @@ class MetricStorage(models.Model):
accounts.register(Order)
_excluded_models = (MetricStorage, LogEntry, Order, ContentType, MigrationRecorder.Migration)
# TODO build a cache hash table {model: related, model: None}
@receiver(post_delete, dispatch_uid="orders.cancel_orders")
def cancel_orders(sender, **kwargs):
if sender not in _excluded_models:
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
instance = kwargs['instance']
if hasattr(instance, 'account'):
if type(instance) in services:
for order in Order.objects.by_object(instance).active():
order.cancel()
else:
elif not hasattr(instance, 'account'):
related = helpers.get_related_objects(instance)
if related and related != instance:
Order.update_orders(related)
@receiver(post_save, dispatch_uid="orders.update_orders")
def update_orders(sender, **kwargs):
if sender not in _excluded_models:
if sender._meta.app_label not in settings.ORDERS_EXCLUDED_APPS:
instance = kwargs['instance']
if hasattr(instance, 'account'):
if type(instance) in services:
Order.update_orders(instance)
else:
elif not hasattr(instance, 'account'):
related = helpers.get_related_objects(instance)
if related and related != instance:
Order.update_orders(related)

View File

@ -6,3 +6,16 @@ ORDERS_BILLING_BACKEND = getattr(settings, 'ORDERS_BILLING_BACKEND',
ORDERS_SERVICE_MODEL = getattr(settings, 'ORDERS_SERVICE_MODEL', 'services.Service')
ORDERS_EXCLUDED_APPS = getattr(settings, 'ORDERS_EXCLUDED_APPS', (
'orders',
'admin',
'contenttypes',
'auth',
'migrations',
'sessions',
'orchestration',
'bills',
# Do not put services here (plans)
))

View File

@ -177,8 +177,7 @@ def create_resource_relation():
data = self.obj.resource_set.get(resource__name=attr)
except ResourceData.DoesNotExist:
model = self.obj._meta.model_name
resource = Resource.objects.get(content_type__model=model,
name=attr, is_active=True)
resource = Resource.objects.get(content_type__model=model, name=attr, is_active=True)
data = ResourceData(content_object=self.obj, resource=resource)
return data

View File

@ -1,16 +1,9 @@
from orchestra.apps.accounts.models import Account
from orchestra.apps.users.models import User
from orchestra.utils.tests import BaseTestCase, random_ascii
# TODO remove this shit
class BaseBillingTest(BaseTestCase):
def create_account(self):
account = Account.objects.create()
username = 'account_%s' % random_ascii(5)
user = User.objects.create_user(username=username, account=account)
account.user = user
account.save()
return account
pass
# TODO web disk

View File

@ -5,7 +5,7 @@ from dateutil.relativedelta import relativedelta
from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from orchestra.apps.users.models import User
from orchestra.apps.systemusers.models import SystemUser
from orchestra.utils.tests import random_ascii
from ... import settings
@ -18,8 +18,8 @@ class FTPBillingTest(BaseBillingTest):
def create_ftp_service(self):
return Service.objects.create(
description="FTP Account",
content_type=ContentType.objects.get_for_model(User),
match='not user.is_main and user.has_posix()',
content_type=ContentType.objects.get_for_model(SystemUser),
match='not systemuser.is_main',
billing_period=Service.ANUAL,
billing_point=Service.FIXED_DATE,
is_fee=False,
@ -36,10 +36,7 @@ class FTPBillingTest(BaseBillingTest):
if not account:
account = self.create_account()
username = '%s_ftp' % random_ascii(10)
user = User.objects.create_user(username=username, account=account)
POSIX = user._meta.get_field_by_name('posix')[0].model
POSIX.objects.create(user=user)
return user
return SystemUser.objects.create_user(username, account=account)
def test_ftp_account_1_year_fiexed(self):
service = self.create_ftp_service()

View File

@ -13,7 +13,7 @@ from . import BaseBillingTest
class BaseTrafficBillingTest(BaseBillingTest):
METRIC = 'account.resources.traffic.used'
TRAFFIC_METRIC = 'account.resources.traffic.used'
def create_traffic_service(self):
service = Service.objects.create(
@ -23,7 +23,7 @@ class BaseTrafficBillingTest(BaseBillingTest):
billing_period=Service.MONTHLY,
billing_point=Service.FIXED_DATE,
is_fee=False,
metric=self.METRIC,
metric=self.TRAFFIC_METRIC,
pricing_period=Service.BILLING_PERIOD,
rate_algorithm=Service.STEP_PRICE,
on_cancel=Service.NOTHING,
@ -50,7 +50,7 @@ class BaseTrafficBillingTest(BaseBillingTest):
return self.resource
def report_traffic(self, account, value):
MonitorData.objects.create(monitor='FTPTraffic', content_object=account.user, value=value)
MonitorData.objects.create(monitor='FTPTraffic', content_object=account.systemusers.get(), value=value)
data = ResourceData.get_or_create(account, self.resource)
data.update()
@ -90,7 +90,7 @@ class TrafficBillingTest(BaseTrafficBillingTest):
class TrafficPrepayBillingTest(BaseTrafficBillingTest):
METRIC = ("max("
TRAFFIC_METRIC = ("max("
"(account.resources.traffic.used or 0) - "
"getattr(account.miscellaneous.filter(is_active=True, service__name='traffic prepay').last(), 'amount', 0)"
", 0)"
@ -126,8 +126,8 @@ class TrafficPrepayBillingTest(BaseTrafficBillingTest):
def test_traffic_prepay(self):
self.create_traffic_service()
self.create_prepay_service()
account = self.create_account()
self.create_traffic_resource()
account = self.create_account()
now = timezone.now()
self.create_prepay(10, account=account)

View File

@ -5,8 +5,8 @@ from django.contrib.contenttypes.models import ContentType
from django.utils import timezone
from orchestra.apps.accounts.models import Account
from orchestra.apps.users.models import User
from orchestra.utils.tests import BaseTestCase
from orchestra.apps.systemusers.models import SystemUser
from orchestra.utils.tests import BaseTestCase, random_ascii
from .. import helpers
from ..models import Service, Plan
@ -28,22 +28,14 @@ class Order(object):
class HandlerTests(BaseTestCase):
DEPENDENCIES = (
'orchestra.apps.orders',
'orchestra.apps.users',
'orchestra.apps.users.roles.posix',
'orchestra.apps.systemusers',
)
def create_account(self):
account = Account.objects.create()
user = User.objects.create_user(username='rata_palida', account=account)
account.user = user
account.save()
return account
def create_ftp_service(self):
service = Service.objects.create(
description="FTP Account",
content_type=ContentType.objects.get_for_model(User),
match='not user.is_main and user.has_posix()',
content_type=ContentType.objects.get_for_model(SystemUser),
match='not systemuser.is_main',
billing_period=Service.ANUAL,
billing_point=Service.FIXED_DATE,
is_fee=False,

View File

@ -15,6 +15,7 @@ class SystemUserQuerySet(models.QuerySet):
user = super(SystemUserQuerySet, self).create(username=username, **kwargs)
user.set_password(password)
user.save(update_fields=['password'])
return user
class SystemUser(models.Model):

View File

@ -2,6 +2,7 @@ from functools import partial
from django.conf import settings
from django.core.urlresolvers import reverse
from selenium.webdriver.support.select import Select
from orchestra.apps.accounts.models import Account
from orchestra.apps.orchestration.models import Server, Route
@ -9,6 +10,7 @@ from orchestra.utils.system import run
from orchestra.utils.tests import BaseLiveServerTestCase, random_ascii
from ... import backends
from ...models import SystemUser
r = partial(run, silent=True, display=False)
@ -40,6 +42,9 @@ class SystemUserMixin(object):
def update(self):
raise NotImplementedError
def disable(self):
raise NotImplementedError
def test_create_systemuser(self):
username = '%s_systemuser' % random_ascii(10)
password = '@!?%spppP001' % random_ascii(5)
@ -56,6 +61,15 @@ class SystemUserMixin(object):
self.delete(username)
self.assertEqual(1, r("id %s" % username, error_codes=[0,1]).return_code)
def test_update_systemuser(self):
pass
# TODO
def test_disable_systemuser(self):
pass
# TODO
# TODO test with ftp and ssh clients?
class RESTSystemUserMixin(SystemUserMixin):
def setUp(self):
@ -73,16 +87,38 @@ class RESTSystemUserMixin(SystemUserMixin):
pass
# TODO
class AdminSystemUserMixin(SystemUserMixin):
def setUp(self):
super(AdminSystemUserMixin, self).setUp()
self.admin_login()
def add(self, username, password):
pass
url = self.live_server_url + reverse('admin:systemusers_systemuser_add')
self.selenium.get(url)
username_field = self.selenium.find_element_by_id('id_username')
username_field.send_keys(username)
password_field = self.selenium.find_element_by_id('id_password1')
password_field.send_keys(password)
password_field = self.selenium.find_element_by_id('id_password2')
password_field.send_keys(password)
account_input = self.selenium.find_element_by_id('id_account')
account_select = Select(account_input)
account_select.select_by_value(str(self.account.pk))
username_field.submit()
self.assertNotEqual(url, self.selenium.current_url)
def delete(self, username):
user = SystemUser.objects.get(username=username)
url = self.live_server_url + reverse('admin:systemusers_systemuser_delete', args=(user.pk,))
self.selenium.get(url)
confirmation = self.selenium.find_element_by_name('post')
confirmation.submit()
def disable(self, username):
pass
def update(self):

View File

@ -12,6 +12,10 @@ from xvfbwrapper import Xvfb
from orchestra.apps.accounts.models import Account
def random_ascii(length):
return ''.join([random.choice(string.hexdigits) for i in range(0, length)]).lower()
class AppDependencyMixin(object):
DEPENDENCIES = ()
@ -49,13 +53,15 @@ class AppDependencyMixin(object):
class BaseTestCase(TestCase, AppDependencyMixin):
pass
def create_account(self, superuser=False):
username = '%s_superaccount' % random_ascii(5)
password = 'orchestra'
if superuser:
return Account.objects.create_superuser(username, password=password, email='orchestra@orchestra.org')
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
class BaseLiveServerTestCase(AppDependencyMixin, LiveServerTestCase):
ACCOUNT_USERNAME = 'orchestra'
ACCOUNT_PASSWORD = 'orchestra'
@classmethod
def setUpClass(cls):
cls.vdisplay = Xvfb()
@ -70,11 +76,11 @@ class BaseLiveServerTestCase(AppDependencyMixin, LiveServerTestCase):
super(BaseLiveServerTestCase, cls).tearDownClass()
def create_account(self, superuser=False):
username = '%s_superaccount' % random_ascii(5)
password = 'orchestra'
if superuser:
return Account.objects.create_superuser(self.ACCOUNT_USERNAME,
password=self.ACCOUNT_PASSWORD, email='orchestra@orchestra.org')
return Account.objects.create_user(self.ACCOUNT_USERNAME,
password=self.ACCOUNT_PASSWORD, email='orchestra@orchestra.org')
return Account.objects.create_superuser(username, password=password, email='orchestra@orchestra.org')
return Account.objects.create_user(username, password=password, email='orchestra@orchestra.org')
def setUp(self):
super(BaseLiveServerTestCase, self).setUp()
@ -96,7 +102,3 @@ class BaseLiveServerTestCase(AppDependencyMixin, LiveServerTestCase):
def rest_login(self):
self.rest.login(username=self.ACCOUNT_USERNAME, password=self.ACCOUNT_PASSWORD)
def random_ascii(length):
return ''.join([random.choice(string.hexdigits) for i in range(0, length)]).lower()