# Copyright (c) 2015 VMware, Inc. # # 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 copy from unittest import mock from oslo_log import log from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase from vmware_nsxlib.tests.unit.v3 import test_constants from vmware_nsxlib.v3 import nsx_constants LOG = log.getLogger(__name__) class NsxLibQosTestCase(nsxlib_testcase.NsxClientTestCase): def _body(self, qos_marking=None, dscp=None, description=test_constants.FAKE_NAME): body = { "resource_type": "QosSwitchingProfile", "tags": [] } if qos_marking: body = self.nsxlib.qos_switching_profile._update_dscp_in_args( body, qos_marking, dscp) body["display_name"] = test_constants.FAKE_NAME body["description"] = description return body def _body_with_shaping(self, shaping_enabled=False, burst_size=None, peak_bandwidth=None, average_bandwidth=None, description=test_constants.FAKE_NAME, qos_marking=None, dscp=0, direction=nsx_constants.EGRESS, body=None): if body is None: body = copy.deepcopy(test_constants.FAKE_QOS_PROFILE) body["display_name"] = test_constants.FAKE_NAME body["description"] = description resource_type = (nsx_constants.EGRESS_SHAPING if direction == nsx_constants.EGRESS else nsx_constants.INGRESS_SHAPING) for shaper in body["shaper_configuration"]: if shaper["resource_type"] == resource_type: shaper["enabled"] = shaping_enabled if burst_size: shaper["burst_size_bytes"] = burst_size if peak_bandwidth: shaper["peak_bandwidth_mbps"] = peak_bandwidth if average_bandwidth: shaper["average_bandwidth_mbps"] = average_bandwidth break if qos_marking: body = self.nsxlib.qos_switching_profile._update_dscp_in_args( body, qos_marking, dscp) return body def test_create_qos_switching_profile(self): """Test creating a qos-switching profile returns the correct response """ with mock.patch.object(self.nsxlib.client, 'create') as create: self.nsxlib.qos_switching_profile.create( tags=[], name=test_constants.FAKE_NAME, description=test_constants.FAKE_NAME) create.assert_called_with( 'switching-profiles', self._body()) def test_update_qos_switching_profile(self): """Test updating a qos-switching profile returns the correct response """ original_profile = self._body() new_description = "Test" with mock.patch.object(self.nsxlib.client, 'get', return_value=original_profile): with mock.patch.object(self.nsxlib.client, 'update') as update: # update the description of the profile self.nsxlib.qos_switching_profile.update( test_constants.FAKE_QOS_PROFILE['id'], tags=[], description=new_description) update.assert_called_with( 'switching-profiles/%s' % test_constants.FAKE_QOS_PROFILE['id'], self._body(description=new_description), headers=None) def _enable_qos_switching_profile_shaping( self, direction=nsx_constants.EGRESS, new_burst_size=100): """Test updating a qos-switching profile returns the correct response """ original_burst = 10 original_profile = self._body_with_shaping(direction=direction, burst_size=original_burst) peak_bandwidth = 200 average_bandwidth = 300 qos_marking = "untrusted" dscp = 10 with mock.patch.object(self.nsxlib.client, 'get', return_value=original_profile): with mock.patch.object(self.nsxlib.client, 'update') as update: # update the bw shaping of the profile self.nsxlib.qos_switching_profile.update_shaping( test_constants.FAKE_QOS_PROFILE['id'], shaping_enabled=True, burst_size=new_burst_size, peak_bandwidth=peak_bandwidth, average_bandwidth=average_bandwidth, qos_marking=qos_marking, dscp=dscp, direction=direction) actual_body = copy.deepcopy(update.call_args[0][1]) actual_path = update.call_args[0][0] expected_path = ('switching-profiles/%s' % test_constants.FAKE_QOS_PROFILE['id']) expected_burst = (new_burst_size if new_burst_size is not None else original_burst) expected_body = self._body_with_shaping( shaping_enabled=True, burst_size=expected_burst, peak_bandwidth=peak_bandwidth, average_bandwidth=average_bandwidth, qos_marking="untrusted", dscp=10, direction=direction) self.assertEqual(expected_path, actual_path) self.assertEqual(expected_body, actual_body) def test_enable_qos_switching_profile_egress_shaping(self): self._enable_qos_switching_profile_shaping( direction=nsx_constants.EGRESS) def test_enable_qos_switching_profile_ingress_shaping(self): self._enable_qos_switching_profile_shaping( direction=nsx_constants.INGRESS) def test_update_qos_switching_profile_with_burst_size(self): self._enable_qos_switching_profile_shaping( direction=nsx_constants.EGRESS, new_burst_size=101) def test_update_qos_switching_profile_without_burst_size(self): self._enable_qos_switching_profile_shaping( direction=nsx_constants.EGRESS, new_burst_size=None) def test_update_qos_switching_profile_zero_burst_size(self): self._enable_qos_switching_profile_shaping( direction=nsx_constants.EGRESS, new_burst_size=0) def _disable_qos_switching_profile_shaping( self, direction=nsx_constants.EGRESS): """Test updating a qos-switching profile. Returns the correct response """ burst_size = 100 peak_bandwidth = 200 average_bandwidth = 300 original_profile = self._body_with_shaping( shaping_enabled=True, burst_size=burst_size, peak_bandwidth=peak_bandwidth, average_bandwidth=average_bandwidth, qos_marking="untrusted", dscp=10, direction=direction) with mock.patch.object(self.nsxlib.client, 'get', return_value=original_profile): with mock.patch.object(self.nsxlib.client, 'update') as update: # update the bw shaping of the profile self.nsxlib.qos_switching_profile.update_shaping( test_constants.FAKE_QOS_PROFILE['id'], shaping_enabled=False, qos_marking="trusted", direction=direction) actual_body = copy.deepcopy(update.call_args[0][1]) actual_path = update.call_args[0][0] expected_path = ('switching-profiles/%s' % test_constants.FAKE_QOS_PROFILE['id']) expected_body = self._body_with_shaping(qos_marking="trusted", direction=direction) self.assertEqual(expected_path, actual_path) self.assertEqual(expected_body, actual_body) def test_disable_qos_switching_profile_egress_shaping(self): self._disable_qos_switching_profile_shaping( direction=nsx_constants.EGRESS) def test_disable_qos_switching_profile_ingress_shaping(self): self._disable_qos_switching_profile_shaping( direction=nsx_constants.INGRESS) def test_delete_qos_switching_profile(self): """Test deleting qos-switching-profile""" with mock.patch.object(self.nsxlib.client, 'delete') as delete: self.nsxlib.qos_switching_profile.delete( test_constants.FAKE_QOS_PROFILE['id']) delete.assert_called_with( 'switching-profiles/%s' % test_constants.FAKE_QOS_PROFILE['id'], headers=None) def test_qos_switching_profile_set_shaping(self): """Test updating a qos-switching profile returns the correct response """ egress_peak_bandwidth = 200 egress_average_bandwidth = 300 egress_burst_size = 500 ingress_peak_bandwidth = 100 ingress_average_bandwidth = 400 ingress_burst_size = 600 qos_marking = "untrusted" dscp = 10 original_profile = self._body_with_shaping() with mock.patch.object(self.nsxlib.client, 'get', return_value=original_profile): with mock.patch.object(self.nsxlib.client, 'update') as update: # update the bw shaping of the profile self.nsxlib.qos_switching_profile.set_profile_shaping( test_constants.FAKE_QOS_PROFILE['id'], ingress_bw_enabled=True, ingress_burst_size=ingress_burst_size, ingress_peak_bandwidth=ingress_peak_bandwidth, ingress_average_bandwidth=ingress_average_bandwidth, egress_bw_enabled=True, egress_burst_size=egress_burst_size, egress_peak_bandwidth=egress_peak_bandwidth, egress_average_bandwidth=egress_average_bandwidth, qos_marking=qos_marking, dscp=dscp) actual_body = copy.deepcopy(update.call_args[0][1]) actual_path = update.call_args[0][0] expected_path = ('switching-profiles/%s' % test_constants.FAKE_QOS_PROFILE['id']) expected_body = self._body_with_shaping( shaping_enabled=True, burst_size=egress_burst_size, peak_bandwidth=egress_peak_bandwidth, average_bandwidth=egress_average_bandwidth, qos_marking="untrusted", dscp=10, direction=nsx_constants.EGRESS) # Add the other direction to the body expected_body = self._body_with_shaping( shaping_enabled=True, burst_size=ingress_burst_size, peak_bandwidth=ingress_peak_bandwidth, average_bandwidth=ingress_average_bandwidth, direction=nsx_constants.INGRESS, body=expected_body) self.assertEqual(expected_path, actual_path) self.assertEqual(expected_body, actual_body)