Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
[VDCA-584] Added Org system tests (#258)
Browse files Browse the repository at this point in the history
* Added Org system tests.
* Added proper license header to all the system test files.
* Standardized Client.get_org_by_name() and Client.get_org_list() method's output format
* Handled fallout of the changes to Client.get_org_by_name() and Client.get_org_list()'s output.
* Fixed a bug in Utils.get_admin_href() and Utils.get_admin_extension_href() to make them idempotent.
  • Loading branch information
rocknes committed Jun 26, 2018
1 parent 84cf4b4 commit ea2a2d5
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 26 deletions.
14 changes: 6 additions & 8 deletions pyvcloud/system_test_framework/environment.py
Expand Up @@ -284,11 +284,11 @@ def create_org(cls):
system = System(cls._sys_admin_client,
admin_resource=cls._sys_admin_client.get_admin())
org_name = cls._config['vcd']['default_org_name']
org_list = cls._sys_admin_client.get_org_list()
for org in [o for o in org_list.Org if hasattr(org_list, 'Org')]:
if org.get('name').lower() == org_name.lower():
org_resource_list = cls._sys_admin_client.get_org_list()
for org_resource in org_resource_list:
if org_resource.get('name').lower() == org_name.lower():
cls._logger.debug('Reusing existing org ' + org_name + '.')
cls._org_href = org.get('href')
cls._org_href = org_resource.get('href')
return
cls._logger.debug('Creating new org ' + org_name)
system.create_org(org_name=org_name,
Expand All @@ -297,10 +297,8 @@ def create_org(cls):
# The following contraption is required to get the non admin href of
# the org. The result of create_org() contains the admin version of
# the href, since we created the org as a sys admin.
org_list = cls._sys_admin_client.get_org_list()
for org in [o for o in org_list.Org if hasattr(org_list, 'Org')]:
if org.get('name').lower() == org_name.lower():
cls._org_href = org.get('href')
org_resource = cls._sys_admin_client.get_org_by_name(org_name)
cls._org_href = org_resource.get('href')

@classmethod
def create_users(cls):
Expand Down
41 changes: 35 additions & 6 deletions pyvcloud/vcd/client.py
Expand Up @@ -1086,7 +1086,14 @@ def get_query_list(self):
return self._get_wk_resource(_WellKnownEndpoint.QUERY_LIST)

def get_org(self):
"""Returns the logged in org."""
"""Returns the logged in org.
:return: a sparse representation of the logged in org. The returned
object has an 'Org' XML element with 'name', 'href', and 'type'
attribute.
:rtype: lxml.objectify.ObjectifiedElement
"""
return self._get_wk_resource(_WellKnownEndpoint.LOGGED_IN_ORG)

def get_extensibility(self):
Expand All @@ -1098,23 +1105,45 @@ def get_extension(self):
return self._get_wk_resource(_WellKnownEndpoint.EXTENSION)

def get_org_list(self):
"""Returns the list of organizations."""
return self._get_wk_resource(_WellKnownEndpoint.ORG_LIST)
"""Returns the list of organizations visible to the user.
:return: a list of objects, where each object contains EntityType.ORG
XML data which represents a single organization.
:rtype: list
"""
orgs = self._get_wk_resource(_WellKnownEndpoint.ORG_LIST)
result = []
if hasattr(orgs, 'Org'):
for org in orgs.Org:
org_resource = self.get_resource(org.get('href'))
result.append(org_resource)
return result

def get_org_by_name(self, org_name):
"""Retrieve an organization.
:param str org_name: name of the organization to be retrieved.
:return: an object containing OrgRecord XML element.
:return: object containing EntityType.ORG XML data representing the
organization.
:rtype: lxml.objectify.ObjectifiedElement
:raises: EntityNotFoundException: if organization with the provided
name couldn't be found.
"""
orgs = self.get_org_list()
# Avoid using get_org_list() to fetch all orgs and then filter the
# result by organization name, since get_org_list() will fetch details
# of all the organizations before filtering, it's expensive. In the
# following implementation, we delay the REST call to fetch
# organization details until we have narrowed down our target to
# exactly 1 organization.
orgs = self._get_wk_resource(_WellKnownEndpoint.ORG_LIST)
if hasattr(orgs, 'Org'):
for org in orgs.Org:
if org.get('name').lower() == org_name.lower():
return org
return self.get_resource(org.get('href'))
raise EntityNotFoundException('org \'%s\' not found' % org_name)

def get_user_in_org(self, user_name, org_href):
Expand Down
6 changes: 3 additions & 3 deletions pyvcloud/vcd/system.py
Expand Up @@ -77,9 +77,9 @@ def delete_org(self, org_name, force=None, recursive=None):
and any objects it contains that are in a state that normally
allows removal.
"""
org = self.client.get_org_by_name(org_name)
org_href = get_admin_href(org.get('href'))
return self.client.delete_resource(org_href, force, recursive)
org_resource = self.client.get_org_by_name(org_name)
org_admin_href = get_admin_href(org_resource.get('href'))
return self.client.delete_resource(org_admin_href, force, recursive)

def list_provider_vdcs(self):
"""List provider vdcs in the system organization.
Expand Down
17 changes: 15 additions & 2 deletions pyvcloud/vcd/utils.py
Expand Up @@ -606,25 +606,38 @@ def stdout_xml(the_xml, is_colorized=True):
def get_admin_href(href):
"""Returns admin version of a given vCD url.
This function is idempotent, which also means that if input href is already
an admin href no further action would be taken.
:param str href: the href whose admin version we need.
:return: admin version of the href.
:rtype: str
"""
return href.replace('/api/', '/api/admin/')
if '/api/admin/extension/' in href:
return href.replace('/api/admin/extension', '/api/admin/')
elif '/api/admin/' in href:
return href
else:
return href.replace('/api/', '/api/admin/')


def get_admin_extension_href(href):
"""Returns sys admin version of a given vCD url.
This function is idempotent, which also means that if input href is already
an admin extension href no further action would be taken.
:param str href: the href whose sys admin version we need.
:return: sys admin version of the href.
:rtype: str
"""
if '/api/admin/' in href:
if '/api/admin/extension/' in href:
return href
elif '/api/admin/' in href:
return href.replace('/api/admin/', '/api/admin/extension/')
else:
return href.replace('/api/', '/api/admin/extension/')
15 changes: 15 additions & 0 deletions system_tests/catalog_tests.py
@@ -1,3 +1,18 @@
# VMware vCloud Director Python SDK
# Copyright (c) 2018 VMware, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import shutil
import tempfile
Expand Down
18 changes: 11 additions & 7 deletions system_tests/cleanup_test.py
@@ -1,13 +1,17 @@
# VMware vCloud Director Python SDK
# Copyright (c) 2018 VMware, Inc. All Rights Reserved.
#
# This product is licensed to you under the
# Apache License, Version 2.0 (the "License").
# You may not use this product except in compliance with the License.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# This product may include a number of subcomponents with
# separate copyright notices and license terms. Your use of the source
# code for the these subcomponents is subject to the terms and
# conditions of the subcomponent's license, as noted in the LICENSE file.
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest

Expand Down
15 changes: 15 additions & 0 deletions system_tests/idisk_tests.py
@@ -1,3 +1,18 @@
# VMware vCloud Director Python SDK
# Copyright (c) 2018 VMware, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest

from pyvcloud.system_test_framework.base_test import BaseTestCase
Expand Down
163 changes: 163 additions & 0 deletions system_tests/org_tests.py
@@ -0,0 +1,163 @@
# VMware vCloud Director Python SDK
# Copyright (c) 2018 VMware, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest
from uuid import uuid1

from pyvcloud.system_test_framework.base_test import BaseTestCase
from pyvcloud.system_test_framework.environment import developerModeAware
from pyvcloud.system_test_framework.environment import Environment

from pyvcloud.vcd.client import TaskStatus
from pyvcloud.vcd.exceptions import EntityNotFoundException
from pyvcloud.vcd.exceptions import VcdTaskException
from pyvcloud.vcd.org import Org
from pyvcloud.vcd.system import System


class TestOrg(BaseTestCase):
"""Test Org functionalities implemented in pyvcloud."""

# All tests in this module should be run as System Administrator
_client = None

_new_org_name = 'test_org_' + str(uuid1())
_new_org_full_name = 'Test Org'
_new_org_enabled = True
_new_org_admin_href = None

_non_existent_org_name = '_non_existent_org_' + str(uuid1())

def test_0000_setup(self):
"""Setup a Org required for other tests in this module.
Create an Org as per the configuration stated above. Tests
System.create_org() method.
This test passes if org href is not None.
"""
TestOrg._client = Environment.get_sys_admin_client()
sys_admin_resource = TestOrg._client.get_admin()
system = System(TestOrg._client, admin_resource=sys_admin_resource)
result = system.create_org(TestOrg._new_org_name,
TestOrg._new_org_full_name,
TestOrg._new_org_enabled)
TestOrg._new_org_admin_href = result.get('href')

self.assertIsNotNone(TestOrg._new_org_admin_href)

def test_0010_list_orgs(self):
"""Test the method Client.get_org_list().
This test passes if the expected organization name is in the list of
organizations returned by the method.
"""
orgs = TestOrg._client.get_org_list()
org_names = []
for org_resource in orgs:
org_names.append(org_resource.get('name'))

self.assertIn(TestOrg._new_org_name, org_names)

def test_0020_get_org(self):
"""Test the method Client.get_org_by_name().
Invoke the method with the name of the organization created in setup.
This test passes if the organization detail retrieved by the method is
not None, and the details e.g. name of the organization, are correct.
"""
org_resource = TestOrg._client.get_org_by_name(TestOrg._new_org_name)
self.assertIsNotNone(org_resource)
org = Org(TestOrg._client, resource=org_resource)
self.assertEqual(TestOrg._new_org_name, org.get_name())

def test_0030_get_non_existent_org(self):
"""Test the method Client.get_org_by_name().
Invoke the method with the name of a bogus organization.
This test passes if the operation fails with an
EntityNotFoundException.
"""
try:
TestOrg._client.get_org_by_name(TestOrg._non_existent_org_name)
self.fail('Should not be able to fetch organization ' +
TestOrg._non_existent_org_name)
except EntityNotFoundException as e:
return

def test_0040_enable_disable_org(self):
"""Test the method Org.update_org().
First disable the organization then re-enable it.
This test passes if the state of organization matches our expectation
after each operation.
"""
logger = Environment.get_default_logger()
org = Org(TestOrg._client, href=TestOrg._new_org_admin_href)
logger.debug('Disabling org: ' + TestOrg._new_org_name)
updated_org = org.update_org(is_enabled=False)
self.assertFalse(updated_org['IsEnabled'])

logger.debug('Re-enabling org: ' + TestOrg._new_org_name)
updated_org = org.update_org(is_enabled=True)
self.assertTrue(updated_org['IsEnabled'])

def test_0050_delete_no_force_enabled_org(self):
"""Test the method System.delete_org() with force = recursive = False.
Invoke delete operation on an enabled organization with 'force' and
'recursive' flag set to False. An enabled organization can't be deleted
unless 'force' flag is set to True.
This test passes if the operation fails with a VcdTaskException.
"""
try:
sys_admin_resource = TestOrg._client.get_admin()
system = System(TestOrg._client, admin_resource=sys_admin_resource)
task = system.delete_org(org_name=TestOrg._new_org_name,
force=False,
recursive=False)
TestOrg._client.get_task_monitor().wait_for_success(task=task)
self.fail('Deletion of org ' + TestOrg._new_org_name + 'shouldn\'t'
'succeeded.')
except VcdTaskException as e:
return

@developerModeAware
def test_9998_teardown(self):
"""Test the method System.delete_org() with force = recursive = True.
Invoke the method for the organization created by setup.
This test passes if no errors are generated while deleting the org.
"""
sys_admin_resource = TestOrg._client.get_admin()
system = System(TestOrg._client, admin_resource=sys_admin_resource)
task = system.delete_org(org_name=TestOrg._new_org_name,
force=True,
recursive=True)
result = TestOrg._client.get_task_monitor().wait_for_success(task=task)
self.assertEqual(result.get('status'), TaskStatus.SUCCESS.value)

def test_9999_cleanup(self):
"""Release all resources held by this object for testing purposes."""
TestOrg._client.logout()


if __name__ == '__main__':
unittest.main()
15 changes: 15 additions & 0 deletions system_tests/vapp_tests.py
@@ -1,3 +1,18 @@
# VMware vCloud Director Python SDK
# Copyright (c) 2018 VMware, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest
from uuid import uuid1

Expand Down

0 comments on commit ea2a2d5

Please sign in to comment.