# Copyright 2014 Citrix Systems # # 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 mock import requests from neutron.services.loadbalancer.drivers.netscaler import ( ncc_client, netscaler_driver ) from neutron.tests.unit import testlib_api NCC_CLIENT_CLASS = ('neutron.services.loadbalancer.drivers' '.netscaler.ncc_client.NSClient') TESTURI_SCHEME = 'http' TESTURI_HOSTNAME = '1.1.1.1' TESTURI_PORT = 4433 TESTURI_PATH = '/ncc_service/1.0' TESTURI = '%s://%s:%s%s' % (TESTURI_SCHEME, TESTURI_HOSTNAME, TESTURI_PORT, TESTURI_PATH) TEST_USERNAME = 'user211' TEST_PASSWORD = '@30xHl5cT' TEST_TENANT_ID = '9c5245a2-0432-9d4c-4829-9bd7028603a1' TESTVIP_ID = '52ab5d71-6bb2-457f-8414-22a4ba55efec' class TestNSClient(testlib_api.WebTestCase): """A Unit test for the NetScaler NCC client module.""" def setUp(self): self.log = mock.patch.object(ncc_client, 'LOG').start() super(TestNSClient, self).setUp() # mock the requests.request function call self.request_method_mock = mock.Mock() requests.request = self.request_method_mock self.testclient = self._get_nsclient() def test_instantiate_nsclient_with_empty_uri(self): """Asserts that a call with empty URI will raise an exception.""" self.assertRaises(ncc_client.NCCException, ncc_client.NSClient, '', TEST_USERNAME, TEST_PASSWORD) def test_create_resource_with_no_connection(self): """Asserts that a call with no connection will raise an exception.""" # mock a connection object that fails to establish a connection self.request_method_mock.side_effect = ( requests.exceptions.ConnectionError()) resource_path = netscaler_driver.VIPS_RESOURCE resource_name = netscaler_driver.VIP_RESOURCE resource_body = self._get_testvip_httpbody_for_create() # call method under test: create_resource() and assert that # it raises an exception self.assertRaises(ncc_client.NCCException, self.testclient.create_resource, TEST_TENANT_ID, resource_path, resource_name, resource_body) def test_create_resource_with_error(self): """Asserts that a failed create call raises an exception.""" # create a mock object to represent a valid http response # with a failure status code. fake_response = requests.Response() fake_response.status_code = requests.codes.unauthorized fake_response.headers = [] requests.request.return_value = fake_response resource_path = netscaler_driver.VIPS_RESOURCE resource_name = netscaler_driver.VIP_RESOURCE resource_body = self._get_testvip_httpbody_for_create() # call method under test: create_resource # and assert that it raises the expected exception. self.assertRaises(ncc_client.NCCException, self.testclient.create_resource, TEST_TENANT_ID, resource_path, resource_name, resource_body) def test_create_resource(self): """Asserts that a correct call will succeed.""" # obtain the mock object that corresponds to the call of request() fake_response = requests.Response() fake_response.status_code = requests.codes.created fake_response.headers = [] self.request_method_mock.return_value = fake_response resource_path = netscaler_driver.VIPS_RESOURCE resource_name = netscaler_driver.VIP_RESOURCE resource_body = self._get_testvip_httpbody_for_create() # call method under test: create_resource() self.testclient.create_resource(TEST_TENANT_ID, resource_path, resource_name, resource_body) # assert that request() was called # with the expected params. resource_url = "%s/%s" % (self.testclient.service_uri, resource_path) self.request_method_mock.assert_called_once_with( 'POST', url=resource_url, headers=mock.ANY, data=mock.ANY) def test_update_resource_with_error(self): """Asserts that a failed update call raises an exception.""" # create a valid http response with a failure status code. fake_response = requests.Response() fake_response.status_code = requests.codes.unauthorized fake_response.headers = [] # obtain the mock object that corresponds to the call of request() self.request_method_mock.return_value = fake_response resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, TESTVIP_ID) resource_name = netscaler_driver.VIP_RESOURCE resource_body = self._get_testvip_httpbody_for_update() # call method under test: update_resource() and # assert that it raises the expected exception. self.assertRaises(ncc_client.NCCException, self.testclient.update_resource, TEST_TENANT_ID, resource_path, resource_name, resource_body) def test_update_resource(self): """Asserts that a correct update call will succeed.""" # create a valid http response with a successful status code. fake_response = requests.Response() fake_response.status_code = requests.codes.ok fake_response.headers = [] # obtain the mock object that corresponds to the call of request() self.request_method_mock.return_value = fake_response resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, TESTVIP_ID) resource_name = netscaler_driver.VIP_RESOURCE resource_body = self._get_testvip_httpbody_for_update() # call method under test: update_resource. self.testclient.update_resource(TEST_TENANT_ID, resource_path, resource_name, resource_body) resource_url = "%s/%s" % (self.testclient.service_uri, resource_path) # assert that requests.request() was called with the # expected params. self.request_method_mock.assert_called_once_with( 'PUT', url=resource_url, headers=mock.ANY, data=mock.ANY) def test_delete_resource_with_error(self): """Asserts that a failed delete call raises an exception.""" # create a valid http response with a failure status code. fake_response = requests.Response() fake_response.status_code = requests.codes.unauthorized fake_response.headers = [] resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, TESTVIP_ID) # call method under test: create_resource self.assertRaises(ncc_client.NCCException, self.testclient.remove_resource, TEST_TENANT_ID, resource_path) def test_delete_resource(self): """Asserts that a correct delete call will succeed.""" # create a valid http response with a failure status code. fake_response = requests.Response() fake_response.status_code = requests.codes.ok fake_response.headers = [] # obtain the mock object that corresponds to the call of request() self.request_method_mock.return_value = fake_response resource_path = "%s/%s" % (netscaler_driver.VIPS_RESOURCE, TESTVIP_ID) resource_url = "%s/%s" % (self.testclient.service_uri, resource_path) # call method under test: create_resource self.testclient.remove_resource(TEST_TENANT_ID, resource_path) # assert that httplib.HTTPConnection request() was called with the # expected params self.request_method_mock.assert_called_once_with( 'DELETE', url=resource_url, headers=mock.ANY, data=mock.ANY) def _get_nsclient(self): return ncc_client.NSClient(TESTURI, TEST_USERNAME, TEST_PASSWORD) def _get_testvip_httpbody_for_create(self): body = { 'name': 'vip1', 'address': '10.0.0.3', 'pool_id': 'da477c13-24cd-4c9f-8c19-757a61ef3b9d', 'protocol': 'HTTP', 'protocol_port': 80, 'admin_state_up': True, } return body def _get_testvip_httpbody_for_update(self): body = {} body['name'] = 'updated vip1' body['admin_state_up'] = False return body