Ejemplo n.º 1
0
    def setUp(self):
        self.tearDown()

        self.cluster = Cluster(hostname='test.example.test', slug='OSL_TEST')
        self.cluster.save()
        self.vm = VirtualMachine(hostname='vm1.example.bak',
                                 cluster=self.cluster)
        self.vm.save()

        User(id=1, username='******').save()
        settings.ANONYMOUS_USER_ID = 1

        self.user = User(id=2, username='******')
        self.user.set_password('secret')
        self.user.save()
        self.user1 = User(id=3, username='******')
        self.user1.set_password('secret')
        self.user1.grant("admin", self.cluster)
        self.user1.grant("admin", self.vm)
        self.user1.save()
        self.user2 = User(id=4, username="******")
        self.user2.set_password("secret")
        self.user2.is_superuser = True
        self.user2.save()

        self.c = Client()
Ejemplo n.º 2
0
    def setUp(self):
        self.tearDown()

        self.user = User(id=2, username='******')
        self.user.set_password('secret')
        self.user.save()

        self.group = Group(name='testing_group')
        self.group.save()

        self.cluster0 = Cluster(hostname='test0', slug='OSL_TEST0')
        self.cluster0.save()
        self.cluster1 = Cluster(hostname='test1', slug='OSL_TEST1')
        self.cluster1.save()

        self.vm0 = VirtualMachine(hostname='vm0', cluster=self.cluster0)
        self.vm1 = VirtualMachine(hostname='vm1', cluster=self.cluster0,
                                  owner=self.user.get_profile())
        # self.vm2 = VirtualMachine(hostname='vm2', cluster=cluster0)
        self.vm3 = VirtualMachine(hostname='vm3', cluster=self.cluster1)
        self.vm4 = VirtualMachine(hostname='vm4', cluster=self.cluster1,
                                  owner=self.user.get_profile())
        # self.vm5 = VirtualMachine(hostname='vm5', cluster=cluster1)
        self.vm0.save()
        self.vm1.save()
        self.vm3.save()
        self.vm4.save()

        self.c = Client()
        self.owner = self.user.get_profile()
Ejemplo n.º 3
0
    def setUp(self):
        self.tearDown()

        self.user = User(id=2, username='******')
        self.user.set_password('secret')
        self.user.save()

        self.group = Group(name='testing_group')
        self.group.save()

        self.cluster0 = Cluster(hostname='test0', slug='OSL_TEST0')
        self.cluster0.save()
        self.cluster1 = Cluster(hostname='test1', slug='OSL_TEST1')
        self.cluster1.save()

        self.vm0 = VirtualMachine(hostname='vm0', cluster=self.cluster0)
        self.vm1 = VirtualMachine(hostname='vm1',
                                  cluster=self.cluster0,
                                  owner=self.user.get_profile())
        # self.vm2 = VirtualMachine(hostname='vm2', cluster=cluster0)
        self.vm3 = VirtualMachine(hostname='vm3', cluster=self.cluster1)
        self.vm4 = VirtualMachine(hostname='vm4',
                                  cluster=self.cluster1,
                                  owner=self.user.get_profile())
        # self.vm5 = VirtualMachine(hostname='vm5', cluster=cluster1)
        self.vm0.save()
        self.vm1.save()
        self.vm3.save()
        self.vm4.save()

        self.c = Client()
        self.owner = self.user.get_profile()
Ejemplo n.º 4
0
 def create_virtual_machine(self, cluster=None, hostname="vm1.example.bak"):
     if cluster is None:
         cluster = Cluster(hostname="test.example.bak", slug="OSL_TEST", username="******", password="******")
     cluster.save()
     cluster.sync_nodes()
     vm = VirtualMachine(cluster=cluster, hostname=hostname)
     vm.save()
     return vm, cluster
Ejemplo n.º 5
0
    def setUp(self):
        # Cluster
        cluster = Cluster(hostname='test.cluster.gwm',
                          slug='test',
                          username='******',
                          password='******')
        # cluster.info = INFO
        cluster.save()

        # Template
        template_data = dict(
            template_name='new.vm.template',
            description='A new template.',
            cluster=cluster.id,
            start=True,
            name_check=True,
            disk_template='plain',
            disk_count=0,
            memory=256,
            vcpus=2,
            root_path='/',
            kernel_path='',
            cdrom_image_path='',
            serial_console=False,
            nic_type='paravirtual',
            disk_type='paravirtual',
            nic_count=0,
            boot_order='disk',
            os='image+ubuntu-lucid',
        )
        data = template_data.copy()
        data['cluster'] = cluster
        del data['disk_count']
        del data['nic_count']
        template = VirtualMachineTemplate(**data)
        template.save()

        # Template Fields
        fields = vars(template).keys()

        # Users
        self.create_users([
            ('superuser', {
                'is_superuser': True
            }),
            'cluster_admin',
        ])
        self.cluster_admin.grant('admin', cluster)

        self.users = [self.superuser, self.cluster_admin]
        self.template = template
        self.cluster = cluster
        self.template_data = template_data
        self.template_fields = fields
Ejemplo n.º 6
0
    def setUp(self):
        # Cluster
        cluster = Cluster(hostname='test.cluster.gwm', slug='test',
                          username='******', password='******')
        # cluster.info = INFO
        cluster.save()

        # Template
        template_data = dict(
            template_name='new.vm.template',
            description='A new template.',
            cluster=cluster.id,
            start=True,
            name_check=True,
            disk_template='plain',
            disk_count=0,
            memory=256,
            vcpus=2,
            root_path='/',
            kernel_path='',
            cdrom_image_path='',
            serial_console=False,
            nic_type='paravirtual',
            disk_type='paravirtual',
            nic_count=0,
            boot_order='disk',
            os='image+ubuntu-lucid',
        )
        data = template_data.copy()
        data['cluster'] = cluster
        del data['disk_count']
        del data['nic_count']
        template = VirtualMachineTemplate(**data)
        template.save()

        # Template Fields
        fields = vars(template).keys()

        # Users
        self.create_users([
            ('superuser', {'is_superuser': True}),
            'cluster_admin',
        ])
        self.cluster_admin.grant('admin', cluster)

        self.users = [self.superuser, self.cluster_admin]
        self.template = template
        self.cluster = cluster
        self.template_data = template_data
        self.template_fields = fields
Ejemplo n.º 7
0
    def test_get_quota(self):
        """
        Tests cluster.get_quota() method

        Verifies:
            * if no user is passed, return default quota values
            * if user has quota, return values from Quota
            * if user doesn't have quota, return default cluster values
        """
        default_quota = {'default': 1, 'ram': 1,
                         'virtual_cpus': None, 'disk': 3}
        user_quota = {'default': 0, 'ram': 4, 'virtual_cpus': 5, 'disk': None}

        cluster = Cluster(hostname='foo.fake.hostname')
        cluster.__dict__.update(default_quota)
        cluster.save()
        user = User(username='******')
        user.save()

        # default quota
        self.assertEqual(default_quota, cluster.get_quota())

        # user without quota, defaults to default
        self.assertEqual(default_quota, cluster.get_quota(user.get_profile()))

        # user with custom quota
        quota = Quota(cluster=cluster, user=user.get_profile())
        quota.__dict__.update(user_quota)
        quota.save()
        self.assertEqual(user_quota, cluster.get_quota(user.get_profile()))

        quota.delete()
        cluster.delete()
        user.delete()
Ejemplo n.º 8
0
    def test_view_list(self):
        """
        Tests displaying the list of clusters
        """
        url = '/clusters/'

        # create extra user and tests
        cluster1 = Cluster(hostname='cluster1', slug='cluster1')
        cluster1.save()

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(self.c.login(username=self.unauthorized.username,
                                     password='******'))
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEquals('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/cluster/list.html')
        clusters = response.context['cluster_list']
        self.assertFalse(clusters)

        # authorized permissions
        self.assertTrue(self.c.login(username=self.cluster_admin.username,
                                     password='******'))
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEquals('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/cluster/list.html')
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertTrue(cluster1 not in clusters)
        self.assertEqual(1, len(clusters))

        # authorized (superuser)
        self.assertTrue(self.c.login(username=self.superuser.username,
                                     password='******'))
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEquals('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/cluster/list.html')
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertTrue(cluster1 in clusters)
        self.assertEqual(2, len(clusters))

        cluster1.delete()
Ejemplo n.º 9
0
class TestVMWizardAdvancedForm(TestCase):

    def setUp(self):
        # XXX #8895 means we need a cluster here
        self.cluster = Cluster()
        self.cluster.hostname = "cluster.example.com"
        self.cluster.save()

        self.pnode = Node()
        self.pnode.cluster = self.cluster
        self.pnode.hostname = "pnode.example.com"
        self.pnode.save()

        self.snode = Node()
        self.snode.cluster = self.cluster
        self.snode.hostname = "snode.example.com"
        self.snode.save()

        self.valid_data = {
            "pnode": self.pnode.id,
            "snode": self.snode.id,
        }

    def tearDown(self):
        self.pnode.delete()
        self.snode.delete()
        self.cluster.delete()

    def test_trivial(self):
        pass

    def test_validate_valid(self):
        form = VMWizardAdvancedForm(self.valid_data)
        self.assertTrue(form.is_valid(), form.errors)

    def test_validate_ip_check_without_name_check(self):
        data = self.valid_data.copy()
        data["ip_check"] = True
        form = VMWizardAdvancedForm(data)
        self.assertFalse(form.is_valid(),
                         "IP check shouldn't be allowed without name check")

    def test_validate_pnode_equals_snode(self):
        invalid_data = self.valid_data.copy()
        invalid_data["snode"] = invalid_data["pnode"]
        form = VMWizardAdvancedForm(invalid_data)
        self.assertFalse(form.is_valid(),
                         "The secondary node cannot be the primary node.")
Ejemplo n.º 10
0
    def setUp(self):
        utils.get_rapi_client = lambda: XenRapiProxy

        # self.patches = (
        #     (self.rapi, 'GetNodes', lambda x: NODES),
        #     (self.rapi, 'GetNode', lambda y, x: NODE),
        #     (self.rapi, 'GetInfo', lambda x: XEN_INFO),
        #     (self.rapi, 'GetOperatingSystems',
        #      lambda x: XEN_OPERATING_SYSTEMS),
        #     (self.rapi, 'GetInstance', lambda x, y: XEN_HVM_INSTANCE),
        # )

        super(TestHvmModifyVirtualMachineForm, self).setUp()

        self.vm, self.cluster = self.create_virtual_machine(
            cluster=Cluster(
                hostname='xen-hvm.cluster',
                slug='xen-hvm',
                username='******',
                password='******',
            ),
            hostname='xen-hvm.virtualmachine')

        self.cluster.info = XEN_INFO.copy()
        self.cluster.info['default_hypervisor'] = 'xen-hvm'
        self.vm.refresh()
        self.vm.info = XEN_HVM_INSTANCE.copy()

        # data custom to HVM
        self.data['os'] = 'debootstrap+default'
        self.data['boot_order'] = 'cd'
Ejemplo n.º 11
0
def get_used_resources(cluster_user):
    """ help function for querying resources used for a given cluster_user """
    resources = {}
    owned_vms = cluster_user.virtual_machines.all()
    used = cluster_user.used_resources()
    clusters = cluster_user.permissable.get_objects_any_perms(Cluster)
    quotas = Cluster.get_quotas(clusters, cluster_user)

    for cluster, quota in quotas.items():
        resources[cluster] = {
            "used": used.pop(cluster.id)
            if cluster.id in used else USED_NOTHING,
            "set": quota
        }
        resources[cluster]["total"] = owned_vms.filter(cluster=cluster).count()
        resources[cluster]["running"] = owned_vms \
            .filter(cluster=cluster, status="running").count()

    # add any clusters that have used resources
    # but no perms (and thus no quota)
    # since we know they don't have a custom quota just add the default quota
    if used:
        for cluster in Cluster.objects.filter(pk__in=used):
            resources[cluster] = {"used": used[cluster.id],
                                  "set": cluster.get_default_quota()}
            resources[cluster]["total"] = owned_vms \
                .filter(cluster=cluster).count()
            resources[cluster]["running"] = owned_vms \
                .filter(cluster=cluster, status="running").count()

    return resources
Ejemplo n.º 12
0
    def test_view_delete_superuser(self):
        """
        Superusers can delete clusters.
        """

        cluster = Cluster(hostname='test.cluster.bak', slug='cluster1')
        cluster.save()
        url = '/cluster/%s/edit/' % cluster.slug

        self.assertTrue(
            self.c.login(username=self.superuser.username, password='******'))
        response = self.c.delete(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertEquals('application/json', response['content-type'])
        self.assertEquals('1', response.content)
        self.assertFalse(Cluster.objects.all().filter(id=cluster.id).exists())
Ejemplo n.º 13
0
    def test_view_delete_superuser(self):
        """
        Superusers can delete clusters.
        """

        cluster = Cluster(hostname='test.cluster.bak', slug='cluster1')
        cluster.save()
        url = '/cluster/%s/edit/' % cluster.slug

        self.assertTrue(self.c.login(username=self.superuser.username,
                                     password='******'))
        response = self.c.delete(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertEquals('application/json', response['content-type'])
        self.assertEquals('1', response.content)
        self.assertFalse(Cluster.objects.all().filter(id=cluster.id).exists())
Ejemplo n.º 14
0
class TestVMWizardAdvancedForm(TestCase):
    def setUp(self):
        # XXX #8895 means we need a cluster here
        self.cluster = Cluster()
        self.cluster.hostname = "cluster.example.com"
        self.cluster.save()

        self.pnode = Node()
        self.pnode.cluster = self.cluster
        self.pnode.hostname = "pnode.example.com"
        self.pnode.save()

        self.snode = Node()
        self.snode.cluster = self.cluster
        self.snode.hostname = "snode.example.com"
        self.snode.save()

        self.valid_data = {
            "pnode": self.pnode.id,
            "snode": self.snode.id,
        }

    def tearDown(self):
        self.pnode.delete()
        self.snode.delete()
        self.cluster.delete()

    def test_trivial(self):
        pass

    def test_validate_valid(self):
        form = VMWizardAdvancedForm(self.valid_data)
        self.assertTrue(form.is_valid(), form.errors)

    def test_validate_ip_check_without_name_check(self):
        data = self.valid_data.copy()
        data["ip_check"] = True
        form = VMWizardAdvancedForm(data)
        self.assertFalse(form.is_valid(),
                         "IP check shouldn't be allowed without name check")

    def test_validate_pnode_equals_snode(self):
        invalid_data = self.valid_data.copy()
        invalid_data["snode"] = invalid_data["pnode"]
        form = VMWizardAdvancedForm(invalid_data)
        self.assertFalse(form.is_valid(),
                         "The secondary node cannot be the primary node.")
Ejemplo n.º 15
0
    def test_view_delete_authorized(self):
        """
        Users with admin on the cluster should be able to delete the cluster.
        """

        cluster = Cluster(hostname='test.cluster.bak', slug='cluster1')
        cluster.save()
        url = '/cluster/%s/edit/' % cluster.slug

        self.user.grant('admin', cluster)
        self.assertTrue(self.c.login(username=self.user.username,
                                     password='******'))
        response = self.c.delete(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertEquals('application/json', response['content-type'])
        self.assertEquals('1', response.content)
        self.assertFalse(Cluster.objects.all().filter(id=cluster.id).exists())
Ejemplo n.º 16
0
    def test_view_delete_authorized(self):
        """
        Users with admin on the cluster should be able to delete the cluster.
        """

        cluster = Cluster(hostname='test.cluster.bak', slug='cluster1')
        cluster.save()
        url = '/cluster/%s/edit/' % cluster.slug

        self.user.grant('admin', cluster)
        self.assertTrue(
            self.c.login(username=self.user.username, password='******'))
        response = self.c.delete(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertEquals('application/json', response['content-type'])
        self.assertEquals('1', response.content)
        self.assertFalse(Cluster.objects.all().filter(id=cluster.id).exists())
Ejemplo n.º 17
0
    def test_missing_in_ganeti(self):
        """
        Tests missing_in_ganeti property
        """
        cluster = Cluster(hostname='ganeti.example.test')
        cluster.save()
        vm_current = VirtualMachine(cluster=cluster,
                                    hostname='gimager2.example.bak')
        vm_removed = VirtualMachine(cluster=cluster,
                                    hostname='does.not.exist.org')
        vm_current.save()
        vm_removed.save()

        self.assertEqual([u'does.not.exist.org'], cluster.missing_in_ganeti)

        vm_current.delete()
        vm_removed.delete()
        cluster.delete()
Ejemplo n.º 18
0
    def setUp(self):
        user = User(id=2, username='******')
        user.set_password('secret')
        user.save()

        group = Group(name='testing_group')
        group.save()

        cluster = Cluster(hostname='test.example.test', slug='OSL_TEST')
        cluster.save()

        self.create_standard_users()
        self.create_users(['cluster_admin'])
        self.cluster_admin.grant('admin', cluster)

        self.user = user
        self.group = group
        self.cluster = cluster
        self.c = Client()
Ejemplo n.º 19
0
    def setUp(self):
        user = User(id=2, username='******')
        user.set_password('secret')
        user.save()

        group = Group(name='testing_group')
        group.save()

        cluster = Cluster(hostname='test.example.test', slug='OSL_TEST')
        cluster.save()

        self.create_standard_users()
        self.create_users(['cluster_admin'])
        self.cluster_admin.grant('admin', cluster)

        self.user = user
        self.group = group
        self.cluster = cluster
        self.c = Client()
Ejemplo n.º 20
0
 def create_virtual_machine(self, cluster=None, hostname='vm1.example.bak'):
     cluster = cluster if cluster else Cluster(hostname='test.example.bak',
                                               slug='OSL_TEST',
                                               username='******',
                                               password='******')
     cluster.save()
     cluster.sync_nodes()
     vm = VirtualMachine(cluster=cluster, hostname=hostname)
     vm.save()
     return vm, cluster
Ejemplo n.º 21
0
    def test_save(self):
        """
        test saving a cluster object

        Verifies:
            * object is saved and queryable
            * hash is updated
        """

        # XXX any reason why these are in a single test?
        cluster = Cluster()
        cluster.save()
        self.assertTrue(cluster.hash)
        cluster.delete()

        cluster = Cluster(hostname='foo.fake.hostname', slug='different')
        cluster.save()
        self.assertTrue(cluster.hash)
        cluster.delete()
Ejemplo n.º 22
0
    def setUp(self):
        # XXX #8895 means we need a cluster here
        self.cluster = Cluster()
        self.cluster.hostname = "cluster.example.com"
        self.cluster.save()

        self.pnode = Node()
        self.pnode.cluster = self.cluster
        self.pnode.hostname = "pnode.example.com"
        self.pnode.save()

        self.snode = Node()
        self.snode.cluster = self.cluster
        self.snode.hostname = "snode.example.com"
        self.snode.save()

        self.valid_data = {
            "pnode": self.pnode.id,
            "snode": self.snode.id,
        }
Ejemplo n.º 23
0
def get_rapi(hash, cluster):
    """
    Retrieves the cached Ganeti RAPI client for a given hash.  The Hash is
    derived from the connection credentials required for a cluster.  If the
    client is not yet cached, it will be created and added.

    If a hash does not correspond to any cluster then Cluster.DoesNotExist will
    be raised.

    @param cluster - either a cluster object, or ID of object.  This is used
    for resolving the cluster if the client is not already found.  The id is
    used rather than the hash, because the hash is mutable.

    @return a Ganeti RAPI client.
    """
    # preventing circular imports
    from ganeti_webmgr.clusters.models import Cluster

    rapi_client = get_rapi_client()

    if hash in RAPI_CACHE:
        return RAPI_CACHE[hash]

    # always look up the instance, even if we were given a Cluster instance
    # it ensures we are retrieving the latest credentials.  This helps avoid
    # stale credentials.  Retrieve only the values because we don't actually
    # need another Cluster instance here.
    if isinstance(cluster, (Cluster,)):
        cluster = cluster.id
    (credentials,) = Cluster.objects.filter(id=cluster) \
        .values_list('hash', 'hostname', 'port', 'username', 'password')
    hash, host, port, user, password = credentials
    user = user or None
    # decrypt password
    # XXX django-fields only stores str, convert to None if needed
    password = Cluster.decrypt_password(password) if password else None
    password = None if password in ('None', '') else password

    # now that we know hash is fresh, check cache again. The original hash
    # could have been stale. This avoids constructing a new RAPI that already
    # exists.
    if hash in RAPI_CACHE:
        return RAPI_CACHE[hash]

    # delete any old version of the client that was cached.
    if cluster in RAPI_CACHE_HASHES:
        del RAPI_CACHE[RAPI_CACHE_HASHES[cluster]]

    # Set connect timeout in settings.py so that you do not learn patience.
    rapi = rapi_client(host, port, user, password,
                       timeout=settings.RAPI_CONNECT_TIMEOUT)
    RAPI_CACHE[hash] = rapi
    RAPI_CACHE_HASHES[cluster] = hash
    return rapi
Ejemplo n.º 24
0
    def test_sync_virtual_machines(self):
        """
        Tests synchronizing cached virtuals machines (stored in db) with info
        the ganeti cluster is storing

        Verifies:
            * VMs no longer in ganeti are deleted
            * VMs missing from the database are added
        """
        cluster = Cluster(hostname='ganeti.example.test')
        cluster.save()
        vm_missing = 'gimager.example.bak'
        vm_current = VirtualMachine(cluster=cluster,
                                    hostname='gimager2.example.bak')
        vm_removed = VirtualMachine(cluster=cluster,
                                    hostname='does.not.exist.org')
        vm_current.save()
        vm_removed.save()

        cluster.sync_virtual_machines()
        self.assertTrue(
            VirtualMachine.objects.get(cluster=cluster, hostname=vm_missing),
            'missing vm was not created')
        self.assertTrue(
            VirtualMachine.objects.get(cluster=cluster,
                                       hostname=vm_current.hostname),
            'previously existing vm was not created')
        self.assertTrue(
            VirtualMachine.objects.filter(cluster=cluster,
                                          hostname=vm_removed.hostname),
            "vm not in ganeti was not removed from db")

        cluster.sync_virtual_machines(True)
        self.assertFalse(
            VirtualMachine.objects.filter(cluster=cluster,
                                          hostname=vm_removed.hostname),
            'vm not present in ganeti was not removed from db')

        vm_removed.delete()
        vm_current.delete()
        cluster.delete()
Ejemplo n.º 25
0
    def test_sync_virtual_machines(self):
        """
        Tests synchronizing cached virtuals machines (stored in db) with info
        the ganeti cluster is storing

        Verifies:
            * VMs no longer in ganeti are deleted
            * VMs missing from the database are added
        """
        cluster = Cluster(hostname='ganeti.example.test')
        cluster.save()
        vm_missing = 'gimager.example.bak'
        vm_current = VirtualMachine(cluster=cluster,
                                    hostname='gimager2.example.bak')
        vm_removed = VirtualMachine(cluster=cluster,
                                    hostname='does.not.exist.org')
        vm_current.save()
        vm_removed.save()

        cluster.sync_virtual_machines()
        self.assertTrue(VirtualMachine.objects.get(cluster=cluster,
                                                   hostname=vm_missing),
                        'missing vm was not created')
        self.assertTrue(
            VirtualMachine.objects.get(
                cluster=cluster,
                hostname=vm_current.hostname),
            'previously existing vm was not created')
        self.assertTrue(
            VirtualMachine.objects.filter(
                cluster=cluster,
                hostname=vm_removed.hostname),
            "vm not in ganeti was not removed from db")

        cluster.sync_virtual_machines(True)
        self.assertFalse(
            VirtualMachine.objects.filter(
                cluster=cluster,
                hostname=vm_removed.hostname),
            'vm not present in ganeti was not removed from db')

        vm_removed.delete()
        vm_current.delete()
        cluster.delete()
Ejemplo n.º 26
0
    def test_get_quota(self):
        """
        Tests cluster.get_quota() method

        Verifies:
            * if no user is passed, return default quota values
            * if user has quota, return values from Quota
            * if user doesn't have quota, return default cluster values
        """
        default_quota = {
            'default': 1,
            'ram': 1,
            'virtual_cpus': None,
            'disk': 3
        }
        user_quota = {'default': 0, 'ram': 4, 'virtual_cpus': 5, 'disk': None}

        cluster = Cluster(hostname='foo.fake.hostname')
        cluster.__dict__.update(default_quota)
        cluster.save()
        user = User(username='******')
        user.save()

        # default quota
        self.assertEqual(default_quota, cluster.get_quota())

        # user without quota, defaults to default
        self.assertEqual(default_quota, cluster.get_quota(user.get_profile()))

        # user with custom quota
        quota = Quota(cluster=cluster, user=user.get_profile())
        quota.__dict__.update(user_quota)
        quota.save()
        self.assertEqual(user_quota, cluster.get_quota(user.get_profile()))

        quota.delete()
        cluster.delete()
        user.delete()
Ejemplo n.º 27
0
    def test_view_list(self):
        """
        Tests displaying the list of clusters
        """
        url = '/clusters/'

        # create extra user and tests
        cluster1 = Cluster(hostname='cluster1', slug='cluster1')
        cluster1.save()

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(
            self.c.login(username=self.unauthorized.username,
                         password='******'))
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEquals('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/cluster/list.html')
        clusters = response.context['cluster_list']
        self.assertFalse(clusters)

        # authorized permissions
        self.assertTrue(
            self.c.login(username=self.cluster_admin.username,
                         password='******'))
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEquals('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/cluster/list.html')
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertTrue(cluster1 not in clusters)
        self.assertEqual(1, len(clusters))

        # authorized (superuser)
        self.assertTrue(
            self.c.login(username=self.superuser.username, password='******'))
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEquals('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/cluster/list.html')
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertTrue(cluster1 in clusters)
        self.assertEqual(2, len(clusters))

        cluster1.delete()
Ejemplo n.º 28
0
    def setUp(self):
        utils.get_rapi_client = lambda: XenRapiProxy

        super(TestPvmModifyVirtualMachineForm, self).setUp()

        self.vm, self.cluster = self.create_virtual_machine(
            cluster=Cluster(
                hostname='xen-pvm.cluster',
                slug='xen-pvm',
                username='******',
                password='******',
            ),
            hostname='pvm.virtualmachine')

        self.cluster.info = XEN_INFO.copy()
        self.vm.info = XEN_PVM_INSTANCE.copy()
        self.vm.refresh()

        self.data['os'] = 'debootstrap+default'
Ejemplo n.º 29
0
    def setUp(self):
        super(TestKvmModifyVirtualMachineForm, self).setUp()

        self.vm, self.cluster = self.create_virtual_machine(
            cluster=Cluster(
                hostname='kvm.cluster',
                slug='kvm',
                username='******',
                password='******',
            ),
            hostname='kvm.virtualmachine')

        self.cluster.info = INFO.copy()
        self.cluster.refresh()
        self.vm.info = INSTANCE.copy()
        self.vm.refresh()

        self.data['os'] = 'image+ubuntu-lucid'
        self.data['boot_order'] = 'disk'
Ejemplo n.º 30
0
    def test_parse_info(self):
        """
        Test parsing values from cached info

        Verifies:
            * mtime and ctime are parsed
            * ram, virtual_cpus, and disksize are parsed
        """
        cluster = Cluster(hostname='foo.fake.hostname')
        cluster.save()
        cluster.info = INFO

        self.assertEqual(cluster.ctime,
                         datetime.fromtimestamp(1270685309.818239))
        self.assertEqual(cluster.mtime,
                         datetime.fromtimestamp(1283552454.2998919))

        cluster.delete()
Ejemplo n.º 31
0
    def setUp(self):
        # XXX #8895 means we need a cluster here
        self.cluster = Cluster()
        self.cluster.hostname = "cluster.example.com"
        self.cluster.save()

        self.pnode = Node()
        self.pnode.cluster = self.cluster
        self.pnode.hostname = "pnode.example.com"
        self.pnode.save()

        self.snode = Node()
        self.snode.cluster = self.cluster
        self.snode.hostname = "snode.example.com"
        self.snode.save()

        self.valid_data = {
            "pnode": self.pnode.id,
            "snode": self.snode.id,
        }
Ejemplo n.º 32
0
    def test_missing_in_ganeti(self):
        """
        Tests missing_in_ganeti property
        """
        cluster = Cluster(hostname='ganeti.example.test')
        cluster.save()
        vm_current = VirtualMachine(cluster=cluster,
                                    hostname='gimager2.example.bak')
        vm_removed = VirtualMachine(cluster=cluster,
                                    hostname='does.not.exist.org')
        vm_current.save()
        vm_removed.save()

        self.assertEqual([u'does.not.exist.org'], cluster.missing_in_ganeti)

        vm_current.delete()
        vm_removed.delete()
        cluster.delete()
Ejemplo n.º 33
0
    def test_parse_info(self):
        """
        Test parsing values from cached info

        Verifies:
            * mtime and ctime are parsed
            * ram, virtual_cpus, and disksize are parsed
        """
        cluster = Cluster(hostname='foo.fake.hostname')
        cluster.save()
        cluster.info = INFO

        self.assertEqual(cluster.ctime,
                         datetime.fromtimestamp(1270685309.818239))
        self.assertEqual(cluster.mtime,
                         datetime.fromtimestamp(1283552454.2998919))

        cluster.delete()
Ejemplo n.º 34
0
    def test_set_quota(self):
        """
        Tests cluster.set_quota()

        Verifies:
            * passing values with no quota, creates a new quota object
            * passing values with an existing quota, updates it.
            * passing a None with an existing quota deletes it
            * passing a None with no quota, does nothing
        """
        default_quota = {'default': 1, 'ram': 1,
                         'virtual_cpus': None, 'disk': 3}
        user_quota = {'default': 0, 'ram': 4, 'virtual_cpus': 5, 'disk': None}
        user_quota2 = {'default': 0, 'ram': 7, 'virtual_cpus': 8, 'disk': 9}

        cluster = Cluster(hostname='foo.fake.hostname')
        cluster.__dict__.update(default_quota)
        cluster.save()
        user = User(username='******')
        user.save()

        # create new quota
        cluster.set_quota(user.get_profile(), user_quota)
        query = Quota.objects.filter(cluster=cluster, user=user.get_profile())
        self.assertTrue(query.exists())
        self.assertEqual(user_quota, cluster.get_quota(user.get_profile()))

        # update quota with new values
        cluster.set_quota(user.get_profile(), user_quota2)
        query = Quota.objects.filter(cluster=cluster, user=user.get_profile())
        self.assertEqual(1, query.count())
        self.assertEqual(user_quota2, cluster.get_quota(user.get_profile()))

        # delete quota
        cluster.set_quota(user.get_profile(), None)
        query = Quota.objects.filter(cluster=cluster, user=user.get_profile())
        self.assertFalse(query.exists())
        self.assertEqual(default_quota, cluster.get_quota(user.get_profile()))

        cluster.delete()
        user.delete()
Ejemplo n.º 35
0
class ImportViews(TestCase):

    def setUp(self):
        self.tearDown()

        self.user = User(id=2, username='******')
        self.user.set_password('secret')
        self.user.save()

        self.group = Group(name='testing_group')
        self.group.save()

        self.cluster0 = Cluster(hostname='test0', slug='OSL_TEST0')
        self.cluster0.save()
        self.cluster1 = Cluster(hostname='test1', slug='OSL_TEST1')
        self.cluster1.save()

        self.vm0 = VirtualMachine(hostname='vm0', cluster=self.cluster0)
        self.vm1 = VirtualMachine(hostname='vm1', cluster=self.cluster0,
                                  owner=self.user.get_profile())
        # self.vm2 = VirtualMachine(hostname='vm2', cluster=cluster0)
        self.vm3 = VirtualMachine(hostname='vm3', cluster=self.cluster1)
        self.vm4 = VirtualMachine(hostname='vm4', cluster=self.cluster1,
                                  owner=self.user.get_profile())
        # self.vm5 = VirtualMachine(hostname='vm5', cluster=cluster1)
        self.vm0.save()
        self.vm1.save()
        self.vm3.save()
        self.vm4.save()

        self.c = Client()
        self.owner = self.user.get_profile()

    def tearDown(self):
        VirtualMachine.objects.all().delete()
        Cluster.objects.all().delete()
        Organization.objects.all().delete()
        Profile.objects.all().delete()
        User.objects.all().delete()
        Group.objects.all().delete()

    def test_orphans_view(self):
        """
        Test orphans view
        """
        url = '/import/orphans/'

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(self.c.login(username=self.user.username,
                                     password='******'))
        response = self.c.get(url)
        self.assertEqual(403, response.status_code)

        # authorized get (cluster admin perm)
        self.user.grant('admin', self.cluster0)
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertEqual([(self.vm0.id, 'test0', 'vm0')],
                         response.context['vms'])
        self.user.revoke_all(self.cluster0)

        # authorized get (superuser)
        self.user.is_superuser = True
        self.user.save()
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertEqual([(self.vm0.id, 'test0', 'vm0'),
                         (self.vm3.id, 'test1', 'vm3')],
                         response.context['vms'])
        self.user.is_superuser = False
        self.user.save()

        # POST - invalid vm
        self.user.grant('admin', self.cluster0)
        data = {'virtual_machines': [-1], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertTrue(response.context['form'].errors)

        # POST - invalid owner
        data = {'virtual_machines': [self.vm0.id], 'owner': -1}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertTrue(response.context['form'].errors)

        # POST - user does not have perms for cluster
        data = {'virtual_machines': [self.vm3.id], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertTrue(response.context['form'].errors)

        # POST - success
        data = {'virtual_machines': [self.vm0.id], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertFalse(response.context['form'].errors)
        self.assertEqual([], response.context['vms'])

    def test_missing_ganeti(self):
        """
        Tests view for Virtual Machines missing from ganeti
        """
        url = '/import/missing/'
        self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2']
        self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5']

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(self.c.login(username=self.user.username,
                                     password='******'))
        response = self.c.get(url)
        self.assertEqual(403, response.status_code)

        # authorized get (cluster admin perm)
        self.user.grant('admin', self.cluster0)
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertEqual([('vm1', 'test0', 'vm1')], response.context['vms'])
        self.user.revoke_all(self.cluster0)

        # authorized get (superuser)
        self.user.is_superuser = True
        self.user.save()
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertEqual([('vm1', 'test0', 'vm1'),
                         ('vm4', 'test1', 'vm4')],
                         response.context['vms'])
        self.user.is_superuser = False
        self.user.save()

        # POST - invalid vm
        self.user.grant('admin', self.cluster0)
        data = {'virtual_machines': [-1]}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertTrue(response.context['form'].errors)

        # POST - user does not have perms for cluster
        data = {'virtual_machines': [self.vm3.hostname]}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertTrue(response.context['form'].errors)

        # POST - success
        data = {'virtual_machines': ['vm1']}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertFalse(response.context['form'].errors)
        self.assertEqual([], response.context['vms'])

    def test_missing_db(self):
        """
        Tests view for Virtual Machines missing from database
        """
        url = '/import/missing_db/'
        self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2']
        self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5']

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(self.c.login(username=self.user.username,
                                     password='******'))
        response = self.c.get(url)
        self.assertEqual(403, response.status_code)

        # authorized get (cluster admin perm)
        self.user.grant('admin', self.cluster0)
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')

        cid_vm_hostname = Template('$cid:$hostname')
        c_vm2 = cid_vm_hostname.substitute(
            cid=self.cluster0.id, hostname='vm2')
        self.assertEqual([(c_vm2, u'test0', u'vm2')],
                         response.context['vms'])
        self.user.revoke_all(self.cluster0)

        # authorized get (superuser)
        self.user.is_superuser = True
        self.user.save()
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        c_vm5 = cid_vm_hostname.substitute(
            cid=self.cluster1.id, hostname='vm5')
        self.assertEqual([(c_vm2, u'test0', u'vm2'),
                          (c_vm5, u'test1', u'vm5')],
                         response.context['vms'])
        self.user.is_superuser = False
        self.user.save()

        # POST - invalid vm
        self.user.grant('admin', self.cluster0)
        data = {'virtual_machines': [-1]}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertTrue(response.context['form'].errors)

        # POST - invalid owner
        data = {'virtual_machines': [self.vm0.id], 'owner': -1}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertTrue(response.context['form'].errors)

        # POST - user does not have perms for cluster
        data = {'virtual_machines': [self.vm3.hostname],
                'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertTrue(response.context['form'].errors)

        # POST - success
        data = {'virtual_machines': [c_vm2], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertFalse(response.context['form'].errors)
        self.assertEqual([], response.context['vms'])
        self.assertTrue(VirtualMachine.objects.filter(hostname='vm2').exists())
Ejemplo n.º 36
0
    def test_used_resources(self):
        """
        Tests retrieving dictionary of resources used by a cluster user
        """
        c1 = Cluster(hostname="testing1", slug="test1")
        c2 = Cluster(hostname="testing2", slug="test2")
        c3 = Cluster(hostname="testing3", slug="test3")
        user = User(username="******")
        quota = {"disk": 26, "ram": 6, "virtual_cpus": 14}

        for i in (c1, c2, c3, user):
            i.save()

        owner = user.get_profile()
        c1.set_quota(owner, quota)
        c3.set_quota(owner, quota)

        # test used_resources returns zeros for no values
        result = owner.used_resources(cluster=c1)
        self.assertEqual(0, result['ram'])
        self.assertEqual(0, result['disk'])
        self.assertEqual(0, result['virtual_cpus'])

        vm11 = VirtualMachine(hostname="1one", owner=owner,
                              cluster=c1, status="running")
        vm21 = VirtualMachine(hostname="2one", owner=owner,
                              cluster=c2, status="running")
        vm31 = VirtualMachine(hostname="3one", owner=owner,
                              cluster=c2, status="running")

        vm12 = VirtualMachine(hostname="1two", owner=owner,
                              cluster=c1, status="running",
                              ram=1, virtual_cpus=3, disk_size=6)
        vm22 = VirtualMachine(hostname="2two", owner=owner,
                              cluster=c2, status="running",
                              ram=1, virtual_cpus=3, disk_size=6)
        vm32 = VirtualMachine(hostname="3two", owner=owner,
                              cluster=c3, status="running",
                              ram=1, virtual_cpus=3, disk_size=6)

        vm13 = VirtualMachine(hostname="1three", owner=owner,
                              cluster=c1, status="stopped",
                              ram=1, virtual_cpus=3, disk_size=6)
        vm23 = VirtualMachine(hostname="2three", owner=owner,
                              cluster=c2, status="stopped",
                              ram=1, virtual_cpus=3, disk_size=6)
        vm33 = VirtualMachine(hostname="3three", owner=owner,
                              cluster=c3, status="stopped",
                              ram=1, virtual_cpus=3, disk_size=6)

        for i in (vm11, vm12, vm13, vm21, vm22, vm23, vm31, vm32, vm33):
            i.save()

        # multiple clusters - every VM
        result = owner.used_resources(cluster=None, only_running=False)
        self.assertTrue(c1.id in result.keys())
        self.assertTrue(c2.id in result.keys())
        self.assertTrue(c3.id in result.keys())
        self.assertEqual(result[c1.id]["disk"], 12)
        self.assertEqual(result[c1.id]["ram"], 2)
        self.assertEqual(result[c1.id]["virtual_cpus"], 6)
        self.assertEqual(result[c1.id], result[c3.id])

        # multiple clusters - only running VMs
        result = owner.used_resources(cluster=None, only_running=True)
        self.assertTrue(c1.id in result.keys())
        self.assertTrue(c2.id in result.keys())
        self.assertTrue(c3.id in result.keys())
        self.assertEqual(result[c1.id]["disk"], 12)
        self.assertEqual(result[c1.id]["ram"], 1)
        self.assertEqual(result[c1.id]["virtual_cpus"], 3)
        self.assertEqual(result[c1.id], result[c3.id])

        # single cluster - every VM
        result = owner.used_resources(cluster=c1, only_running=False)
        self.assertEqual(result["disk"], 12)
        self.assertEqual(result["ram"], 2)
        self.assertEqual(result["virtual_cpus"], 6)

        # single cluster - only running VMs
        result = owner.used_resources(cluster=c1, only_running=True)
        self.assertEqual(result["disk"], 12)
        self.assertEqual(result["ram"], 1)
        self.assertEqual(result["virtual_cpus"], 3)
Ejemplo n.º 37
0
 def test_instantiation(self):
     """
     Test creating a Cluster Object
     """
     Cluster()
Ejemplo n.º 38
0
    def test_set_quota(self):
        """
        Tests cluster.set_quota()

        Verifies:
            * passing values with no quota, creates a new quota object
            * passing values with an existing quota, updates it.
            * passing a None with an existing quota deletes it
            * passing a None with no quota, does nothing
        """
        default_quota = {
            'default': 1,
            'ram': 1,
            'virtual_cpus': None,
            'disk': 3
        }
        user_quota = {'default': 0, 'ram': 4, 'virtual_cpus': 5, 'disk': None}
        user_quota2 = {'default': 0, 'ram': 7, 'virtual_cpus': 8, 'disk': 9}

        cluster = Cluster(hostname='foo.fake.hostname')
        cluster.__dict__.update(default_quota)
        cluster.save()
        user = User(username='******')
        user.save()

        # create new quota
        cluster.set_quota(user.get_profile(), user_quota)
        query = Quota.objects.filter(cluster=cluster, user=user.get_profile())
        self.assertTrue(query.exists())
        self.assertEqual(user_quota, cluster.get_quota(user.get_profile()))

        # update quota with new values
        cluster.set_quota(user.get_profile(), user_quota2)
        query = Quota.objects.filter(cluster=cluster, user=user.get_profile())
        self.assertEqual(1, query.count())
        self.assertEqual(user_quota2, cluster.get_quota(user.get_profile()))

        # delete quota
        cluster.set_quota(user.get_profile(), None)
        query = Quota.objects.filter(cluster=cluster, user=user.get_profile())
        self.assertFalse(query.exists())
        self.assertEqual(default_quota, cluster.get_quota(user.get_profile()))

        cluster.delete()
        user.delete()
Ejemplo n.º 39
0
    def test_save(self):
        """
        test saving a cluster object

        Verifies:
            * object is saved and queryable
            * hash is updated
        """

        # XXX any reason why these are in a single test?
        cluster = Cluster()
        cluster.save()
        self.assertTrue(cluster.hash)
        cluster.delete()

        cluster = Cluster(hostname='foo.fake.hostname', slug='different')
        cluster.save()
        self.assertTrue(cluster.hash)
        cluster.delete()
Ejemplo n.º 40
0
class ImportViews(TestCase):
    def setUp(self):
        self.tearDown()

        self.user = User(id=2, username='******')
        self.user.set_password('secret')
        self.user.save()

        self.group = Group(name='testing_group')
        self.group.save()

        self.cluster0 = Cluster(hostname='test0', slug='OSL_TEST0')
        self.cluster0.save()
        self.cluster1 = Cluster(hostname='test1', slug='OSL_TEST1')
        self.cluster1.save()

        self.vm0 = VirtualMachine(hostname='vm0', cluster=self.cluster0)
        self.vm1 = VirtualMachine(hostname='vm1',
                                  cluster=self.cluster0,
                                  owner=self.user.get_profile())
        # self.vm2 = VirtualMachine(hostname='vm2', cluster=cluster0)
        self.vm3 = VirtualMachine(hostname='vm3', cluster=self.cluster1)
        self.vm4 = VirtualMachine(hostname='vm4',
                                  cluster=self.cluster1,
                                  owner=self.user.get_profile())
        # self.vm5 = VirtualMachine(hostname='vm5', cluster=cluster1)
        self.vm0.save()
        self.vm1.save()
        self.vm3.save()
        self.vm4.save()

        self.c = Client()
        self.owner = self.user.get_profile()

    def tearDown(self):
        VirtualMachine.objects.all().delete()
        Cluster.objects.all().delete()
        Organization.objects.all().delete()
        Profile.objects.all().delete()
        User.objects.all().delete()
        Group.objects.all().delete()

    def test_orphans_view(self):
        """
        Test orphans view
        """
        url = '/import/orphans/'

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(
            self.c.login(username=self.user.username, password='******'))
        response = self.c.get(url)
        self.assertEqual(403, response.status_code)

        # authorized get (cluster admin perm)
        self.user.grant('admin', self.cluster0)
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertEqual([(self.vm0.id, 'test0', 'vm0')],
                         response.context['vms'])
        self.user.revoke_all(self.cluster0)

        # authorized get (superuser)
        self.user.is_superuser = True
        self.user.save()
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertEqual([(self.vm0.id, 'test0', 'vm0'),
                          (self.vm3.id, 'test1', 'vm3')],
                         response.context['vms'])
        self.user.is_superuser = False
        self.user.save()

        # POST - invalid vm
        self.user.grant('admin', self.cluster0)
        data = {'virtual_machines': [-1], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertTrue(response.context['form'].errors)

        # POST - invalid owner
        data = {'virtual_machines': [self.vm0.id], 'owner': -1}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertTrue(response.context['form'].errors)

        # POST - user does not have perms for cluster
        data = {'virtual_machines': [self.vm3.id], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertTrue(response.context['form'].errors)

        # POST - success
        data = {'virtual_machines': [self.vm0.id], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/orphans.html')
        self.assertFalse(response.context['form'].errors)
        self.assertEqual([], response.context['vms'])

    def test_missing_ganeti(self):
        """
        Tests view for Virtual Machines missing from ganeti
        """
        url = '/import/missing/'
        self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2']
        self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5']

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(
            self.c.login(username=self.user.username, password='******'))
        response = self.c.get(url)
        self.assertEqual(403, response.status_code)

        # authorized get (cluster admin perm)
        self.user.grant('admin', self.cluster0)
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertEqual([('vm1', 'test0', 'vm1')], response.context['vms'])
        self.user.revoke_all(self.cluster0)

        # authorized get (superuser)
        self.user.is_superuser = True
        self.user.save()
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertEqual([('vm1', 'test0', 'vm1'), ('vm4', 'test1', 'vm4')],
                         response.context['vms'])
        self.user.is_superuser = False
        self.user.save()

        # POST - invalid vm
        self.user.grant('admin', self.cluster0)
        data = {'virtual_machines': [-1]}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertTrue(response.context['form'].errors)

        # POST - user does not have perms for cluster
        data = {'virtual_machines': [self.vm3.hostname]}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertTrue(response.context['form'].errors)

        # POST - success
        data = {'virtual_machines': ['vm1']}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing.html')
        self.assertFalse(response.context['form'].errors)
        self.assertEqual([], response.context['vms'])

    def test_missing_db(self):
        """
        Tests view for Virtual Machines missing from database
        """
        url = '/import/missing_db/'
        self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2']
        self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5']

        # anonymous user
        response = self.c.get(url, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # unauthorized user
        self.assertTrue(
            self.c.login(username=self.user.username, password='******'))
        response = self.c.get(url)
        self.assertEqual(403, response.status_code)

        # authorized get (cluster admin perm)
        self.user.grant('admin', self.cluster0)
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')

        cid_vm_hostname = Template('$cid:$hostname')
        c_vm2 = cid_vm_hostname.substitute(cid=self.cluster0.id,
                                           hostname='vm2')
        self.assertEqual([(c_vm2, u'test0', u'vm2')], response.context['vms'])
        self.user.revoke_all(self.cluster0)

        # authorized get (superuser)
        self.user.is_superuser = True
        self.user.save()
        response = self.c.get(url)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        c_vm5 = cid_vm_hostname.substitute(cid=self.cluster1.id,
                                           hostname='vm5')
        self.assertEqual([(c_vm2, u'test0', u'vm2'),
                          (c_vm5, u'test1', u'vm5')], response.context['vms'])
        self.user.is_superuser = False
        self.user.save()

        # POST - invalid vm
        self.user.grant('admin', self.cluster0)
        data = {'virtual_machines': [-1]}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertTrue(response.context['form'].errors)

        # POST - invalid owner
        data = {'virtual_machines': [self.vm0.id], 'owner': -1}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertTrue(response.context['form'].errors)

        # POST - user does not have perms for cluster
        data = {
            'virtual_machines': [self.vm3.hostname],
            'owner': self.owner.id
        }
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertTrue(response.context['form'].errors)

        # POST - success
        data = {'virtual_machines': [c_vm2], 'owner': self.owner.id}
        response = self.c.post(url, data)
        self.assertEqual(200, response.status_code)
        self.assertEqual('text/html; charset=utf-8', response['content-type'])
        self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html')
        self.assertFalse(response.context['form'].errors)
        self.assertEqual([], response.context['vms'])
        self.assertTrue(VirtualMachine.objects.filter(hostname='vm2').exists())
Ejemplo n.º 41
0
    def test_view_overview(self):
        """
        Tests overview (status) page
        """
        # TODO: in future, add Ganeti errors checking

        cluster1 = Cluster(hostname='cluster1', slug='cluster1')
        cluster1.save()
        vm1 = VirtualMachine(hostname='vm2.example.bak', cluster=cluster1)
        vm1.save()
        job = Job(job_id=233, obj=self.vm, cluster=self.cluster,
                  finished="2011-01-07 21:59", status="error")
        job.save()
        job1 = Job(job_id=1234, obj=vm1, cluster=cluster1,
                   finished="2011-01-05 21:59", status="error")
        job1.save()
        job.rapi.GetJobStatus.response = JOB_ERROR

        url = "/"
        args = []
        template = "ganeti/overview.html"
        mimetype = "text/html; charset=utf-8"
        status = 200

        # anonymous user
        response = self.c.get(url % args, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # authorized user (non-admin)
        self.user.grant("admin", self.vm)
        self.user.save()
        self.assertTrue(self.c.login(username=self.user.username,
                        password='******'))
        response = self.c.get(url % args)
        self.assertEqual(status, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster not in clusters)
        self.assertEqual(0, len(clusters))
        self.assertEqual(0, response.context["orphaned"])
        self.assertEqual(0, response.context["missing"])
        self.assertEqual(0, response.context["import_ready"])

        # authorized user (admin on one cluster)
        self.assertTrue(self.c.login(username=self.user1.username,
                        password='******'))
        response = self.c.get(url % args)
        self.assertEqual(status, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertEqual(1, len(clusters))
        self.assertEqual(1, response.context["orphaned"])
        self.assertEqual(1, response.context["missing"])
        self.assertEqual(2, response.context["import_ready"])

        # authorized user (superuser)
        self.assertTrue(self.c.login(username=self.user2.username,
                        password='******'))
        response = self.c.get(url % args)
        self.assertEqual(status, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertTrue(cluster1 in clusters)
        self.assertEqual(2, len(clusters))
        self.assertEqual(2, response.context["orphaned"])
        self.assertEqual(2, response.context["missing"])
        self.assertEqual(4, response.context["import_ready"])
Ejemplo n.º 42
0
    def test_used_resources(self):
        """
        Tests retrieving dictionary of resources used by a cluster user
        """
        c1 = Cluster(hostname="testing1", slug="test1")
        c2 = Cluster(hostname="testing2", slug="test2")
        c3 = Cluster(hostname="testing3", slug="test3")
        user = User(username="******")
        quota = {"disk": 26, "ram": 6, "virtual_cpus": 14}

        for i in (c1, c2, c3, user):
            i.save()

        owner = user.get_profile()
        c1.set_quota(owner, quota)
        c3.set_quota(owner, quota)

        # test used_resources returns zeros for no values
        result = owner.used_resources(cluster=c1)
        self.assertEqual(0, result['ram'])
        self.assertEqual(0, result['disk'])
        self.assertEqual(0, result['virtual_cpus'])

        vm11 = VirtualMachine(hostname="1one",
                              owner=owner,
                              cluster=c1,
                              status="running")
        vm21 = VirtualMachine(hostname="2one",
                              owner=owner,
                              cluster=c2,
                              status="running")
        vm31 = VirtualMachine(hostname="3one",
                              owner=owner,
                              cluster=c2,
                              status="running")

        vm12 = VirtualMachine(hostname="1two",
                              owner=owner,
                              cluster=c1,
                              status="running",
                              ram=1,
                              virtual_cpus=3,
                              disk_size=6)
        vm22 = VirtualMachine(hostname="2two",
                              owner=owner,
                              cluster=c2,
                              status="running",
                              ram=1,
                              virtual_cpus=3,
                              disk_size=6)
        vm32 = VirtualMachine(hostname="3two",
                              owner=owner,
                              cluster=c3,
                              status="running",
                              ram=1,
                              virtual_cpus=3,
                              disk_size=6)

        vm13 = VirtualMachine(hostname="1three",
                              owner=owner,
                              cluster=c1,
                              status="stopped",
                              ram=1,
                              virtual_cpus=3,
                              disk_size=6)
        vm23 = VirtualMachine(hostname="2three",
                              owner=owner,
                              cluster=c2,
                              status="stopped",
                              ram=1,
                              virtual_cpus=3,
                              disk_size=6)
        vm33 = VirtualMachine(hostname="3three",
                              owner=owner,
                              cluster=c3,
                              status="stopped",
                              ram=1,
                              virtual_cpus=3,
                              disk_size=6)

        for i in (vm11, vm12, vm13, vm21, vm22, vm23, vm31, vm32, vm33):
            i.save()

        # multiple clusters - every VM
        result = owner.used_resources(cluster=None, only_running=False)
        self.assertTrue(c1.id in result.keys())
        self.assertTrue(c2.id in result.keys())
        self.assertTrue(c3.id in result.keys())
        self.assertEqual(result[c1.id]["disk"], 12)
        self.assertEqual(result[c1.id]["ram"], 2)
        self.assertEqual(result[c1.id]["virtual_cpus"], 6)
        self.assertEqual(result[c1.id], result[c3.id])

        # multiple clusters - only running VMs
        result = owner.used_resources(cluster=None, only_running=True)
        self.assertTrue(c1.id in result.keys())
        self.assertTrue(c2.id in result.keys())
        self.assertTrue(c3.id in result.keys())
        self.assertEqual(result[c1.id]["disk"], 12)
        self.assertEqual(result[c1.id]["ram"], 1)
        self.assertEqual(result[c1.id]["virtual_cpus"], 3)
        self.assertEqual(result[c1.id], result[c3.id])

        # single cluster - every VM
        result = owner.used_resources(cluster=c1, only_running=False)
        self.assertEqual(result["disk"], 12)
        self.assertEqual(result["ram"], 2)
        self.assertEqual(result["virtual_cpus"], 6)

        # single cluster - only running VMs
        result = owner.used_resources(cluster=c1, only_running=True)
        self.assertEqual(result["disk"], 12)
        self.assertEqual(result["ram"], 1)
        self.assertEqual(result["virtual_cpus"], 3)
Ejemplo n.º 43
0
class TestGeneralViews(TestCase, ViewTestMixin):

    def setUp(self):
        self.tearDown()

        self.cluster = Cluster(hostname='test.example.test', slug='OSL_TEST')
        self.cluster.save()
        self.vm = VirtualMachine(hostname='vm1.example.bak',
                                 cluster=self.cluster)
        self.vm.save()

        User(id=1, username='******').save()
        settings.ANONYMOUS_USER_ID = 1

        self.user = User(id=2, username='******')
        self.user.set_password('secret')
        self.user.save()
        self.user1 = User(id=3, username='******')
        self.user1.set_password('secret')
        self.user1.grant("admin", self.cluster)
        self.user1.grant("admin", self.vm)
        self.user1.save()
        self.user2 = User(id=4, username="******")
        self.user2.set_password("secret")
        self.user2.is_superuser = True
        self.user2.save()

        self.c = Client()

    def tearDown(self):
        SSHKey.objects.all().delete()
        Cluster.objects.all().delete()
        User.objects.all().delete()
        Group.objects.all().delete()
        Job.objects.all().delete()

    def test_view_overview(self):
        """
        Tests overview (status) page
        """
        # TODO: in future, add Ganeti errors checking

        cluster1 = Cluster(hostname='cluster1', slug='cluster1')
        cluster1.save()
        vm1 = VirtualMachine(hostname='vm2.example.bak', cluster=cluster1)
        vm1.save()
        job = Job(job_id=233, obj=self.vm, cluster=self.cluster,
                  finished="2011-01-07 21:59", status="error")
        job.save()
        job1 = Job(job_id=1234, obj=vm1, cluster=cluster1,
                   finished="2011-01-05 21:59", status="error")
        job1.save()
        job.rapi.GetJobStatus.response = JOB_ERROR

        url = "/"
        args = []
        template = "ganeti/overview.html"
        mimetype = "text/html; charset=utf-8"
        status = 200

        # anonymous user
        response = self.c.get(url % args, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # authorized user (non-admin)
        self.user.grant("admin", self.vm)
        self.user.save()
        self.assertTrue(self.c.login(username=self.user.username,
                        password='******'))
        response = self.c.get(url % args)
        self.assertEqual(status, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster not in clusters)
        self.assertEqual(0, len(clusters))
        self.assertEqual(0, response.context["orphaned"])
        self.assertEqual(0, response.context["missing"])
        self.assertEqual(0, response.context["import_ready"])

        # authorized user (admin on one cluster)
        self.assertTrue(self.c.login(username=self.user1.username,
                        password='******'))
        response = self.c.get(url % args)
        self.assertEqual(status, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertEqual(1, len(clusters))
        self.assertEqual(1, response.context["orphaned"])
        self.assertEqual(1, response.context["missing"])
        self.assertEqual(2, response.context["import_ready"])

        # authorized user (superuser)
        self.assertTrue(self.c.login(username=self.user2.username,
                        password='******'))
        response = self.c.get(url % args)
        self.assertEqual(status, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)
        clusters = response.context['cluster_list']
        self.assertTrue(self.cluster in clusters)
        self.assertTrue(cluster1 in clusters)
        self.assertEqual(2, len(clusters))
        self.assertEqual(2, response.context["orphaned"])
        self.assertEqual(2, response.context["missing"])
        self.assertEqual(4, response.context["import_ready"])

    def test_used_resources(self):
        """ tests the used_resources view """

        group0 = Group.objects.create(name='group0')
        group1 = Group.objects.create(name='group1')
        self.user.groups.add(group0)
        self.user1.groups.add(group1)

        url = "/used_resources/"
        args = {}
        template = "ganeti/overview/used_resources_data.html"
        mimetype = "text/html; charset=utf-8"

        # anonymous user
        response = self.c.get(url, args, follow=True)
        self.assertEqual(200, response.status_code)
        self.assertTemplateUsed(response, 'registration/login.html')

        # 404 - no id
        self.assertTrue(self.c.login(username=self.user.username,
                        password='******'))
        response = self.c.get(url, {})
        self.assertEqual(404, response.status_code)

        # 404 - invalid id
        response = self.c.get(url, {'id': 1234567})
        self.assertEqual(404, response.status_code)

        # unauthorized user (different user)
        response = self.c.get(url, {'id': self.user2.get_profile().pk})
        self.assertEqual(403, response.status_code)

        # unauthorized user (in different group)
        self.assertTrue(self.c.login(username=self.user.username,
                        password='******'))
        response = self.c.get(url, {'id': group1.organization.pk})
        self.assertEqual(403, response.status_code)

        # authorized user (same user)
        response = self.c.get(url, {'id': self.user.get_profile().pk})
        self.assertEqual(200, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)

        # authorized user (in group)
        response = self.c.get(url, {'id': group0.organization.pk})
        self.assertEqual(200, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)

        # authorized user (superuser)
        self.assertTrue(self.c.login(username=self.user2.username,
                        password='******'))
        response = self.c.get(url, {'id': self.user.get_profile().pk})
        self.assertEqual(200, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)

        # authorized user (superuser)
        self.assertTrue(self.c.login(username=self.user2.username,
                        password='******'))
        response = self.c.get(url, {'id': group1.organization.pk})
        self.assertEqual(200, response.status_code)
        self.assertEqual(mimetype, response['content-type'])
        self.assertTemplateUsed(response, template)

    def test_view_ssh_keys(self):
        """ tests retrieving all sshkeys from the gwm instance """

        # add some keys
        SSHKey.objects.create(key="ssh-rsa test test@test", user=self.user)
        SSHKey.objects.create(key="ssh-dsa test asd@asd", user=self.user)
        SSHKey.objects.create(key="ssh-dsa test foo@bar", user=self.user1)

        self.user.revoke_all(self.vm)
        self.user.revoke_all(self.cluster)
        self.user1.revoke_all(self.vm)
        self.user1.revoke_all(self.cluster)
        self.user2.revoke_all(self.vm)
        self.user2.revoke_all(self.cluster)

        # get API key
        # import settings
        key = settings.WEB_MGR_API_KEY

        url = '/keys/%s/'
        args = (key,)

        # cluster without users who have admin perms
        response = self.c.get(url % args)
        self.assertEqual(200, response.status_code)
        self.assertEquals("application/json", response["content-type"])
        self.assertEqual(len(json.loads(response.content)), 0)
        self.assertNotContains(response, "test@test")
        self.assertNotContains(response, "asd@asd")

        # vm with users who have admin perms
        # grant admin permission to first user
        self.user.grant("admin", self.vm)
        self.user1.grant("admin", self.cluster)

        response = self.c.get(url % args)
        self.assertEqual(200, response.status_code)
        self.assertEquals("application/json", response["content-type"])
        self.assertEqual(len(json.loads(response.content)), 3)
        self.assertContains(response, "test@test", count=1)
        self.assertContains(response, "asd@asd", count=1)
        self.assertContains(response, "foo@bar", count=1)