"Fossies" - the Fresh Open Source Software Archive

Member "masakari-9.0.0/masakari/tests/unit/api/openstack/ha/test_segments.py" (13 May 2020, 14666 Bytes) of package /linux/misc/openstack/masakari-9.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_segments.py": 8.0.0_vs_9.0.0.

    1 # Copyright (c) 2016 NTT DATA
    2 # All Rights Reserved.
    3 #
    4 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    5 #    not use this file except in compliance with the License. You may obtain
    6 #    a copy of the License at
    7 #
    8 #         http://www.apache.org/licenses/LICENSE-2.0
    9 #
   10 #    Unless required by applicable law or agreed to in writing, software
   11 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   12 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   13 #    License for the specific language governing permissions and limitations
   14 #    under the License.
   15 
   16 """Tests for the failover segment api."""
   17 
   18 from unittest import mock
   19 
   20 import ddt
   21 from oslo_serialization import jsonutils
   22 from six.moves import http_client as http
   23 from webob import exc
   24 
   25 from masakari.api.openstack.ha import segments
   26 from masakari import exception
   27 from masakari.ha import api as ha_api
   28 from masakari.objects import base as obj_base
   29 from masakari.objects import segment as segment_obj
   30 from masakari import test
   31 from masakari.tests.unit.api.openstack import fakes
   32 from masakari.tests import uuidsentinel
   33 
   34 
   35 def _make_segment_obj(segment_dict):
   36     return segment_obj.FailoverSegment(**segment_dict)
   37 
   38 
   39 def _make_segments_list(segments_list):
   40     return segment_obj.FailoverSegment(objects=[
   41         _make_segment_obj(a) for a in segments_list])
   42 
   43 FAILOVER_SEGMENT_LIST = [
   44     {"name": "segment1", "id": "1", "service_type": "COMPUTE",
   45      "recovery_method": "auto", "uuid": uuidsentinel.fake_segment,
   46      "description": "failover_segment for compute"},
   47 
   48     {"name": "segment2", "id": "2", "service_type": "CINDER",
   49      "recovery_method": "reserved_host", "uuid": uuidsentinel.fake_segment2,
   50      "description": "failover_segment for cinder"}
   51 ]
   52 
   53 FAILOVER_SEGMENT_LIST = _make_segments_list(FAILOVER_SEGMENT_LIST)
   54 
   55 FAILOVER_SEGMENT = {"name": "segment1", "id": "1",
   56                     "service_type": "COMPUTE", "recovery_method": "auto",
   57                     "uuid": uuidsentinel.fake_segment,
   58                     "description": "failover_segment for compute"}
   59 
   60 FAILOVER_SEGMENT = _make_segment_obj(FAILOVER_SEGMENT)
   61 
   62 
   63 @ddt.ddt
   64 class FailoverSegmentTestCase(test.TestCase):
   65     """Test Case for failover segment api."""
   66 
   67     bad_request = exception.ValidationError
   68 
   69     def setUp(self):
   70         super(FailoverSegmentTestCase, self).setUp()
   71         self.controller = segments.SegmentsController()
   72         self.req = fakes.HTTPRequest.blank('/v1/segments',
   73                                            use_admin_context=True)
   74         self.context = self.req.environ['masakari.context']
   75 
   76     @property
   77     def app(self):
   78         return fakes.wsgi_app_v1(init_only='segments')
   79 
   80     def _assert_segment_data(self, expected, actual):
   81         self.assertTrue(obj_base.obj_equal_prims(expected, actual),
   82                         "The failover segment objects were not equal")
   83 
   84     @mock.patch.object(ha_api.FailoverSegmentAPI, 'get_all')
   85     def test_index(self, mock_get_all):
   86 
   87         mock_get_all.return_value = FAILOVER_SEGMENT_LIST
   88 
   89         result = self.controller.index(self.req)
   90         result = result['segments']
   91         self._assert_segment_data(FAILOVER_SEGMENT_LIST,
   92                                   _make_segments_list(result))
   93 
   94     @mock.patch.object(ha_api.FailoverSegmentAPI, 'get_all')
   95     def test_index_marker_not_found(self, mock_get_all):
   96         fake_request = fakes.HTTPRequest.blank('/v1/segments?marker=12345',
   97                                                use_admin_context=True)
   98         mock_get_all.side_effect = exception.MarkerNotFound(marker="12345")
   99         self.assertRaises(exc.HTTPBadRequest, self.controller.index,
  100                           fake_request)
  101 
  102     @ddt.data(
  103         # limit negative
  104         'limit=-1',
  105 
  106         # invalid sort key
  107         'sort_key=abcd',
  108 
  109         # invalid sort dir
  110         'sort_dir=abcd')
  111     def test_index_invalid(self, param):
  112         req = fakes.HTTPRequest.blank("/v1/segments?%s" % param,
  113                                       use_admin_context=True)
  114 
  115         self.assertRaises(exc.HTTPBadRequest, self.controller.index, req)
  116 
  117     @mock.patch.object(ha_api.FailoverSegmentAPI, 'create_segment')
  118     def test_create(self, mock_create):
  119         body = {
  120             "segment": {
  121                 "name": "segment1",
  122                 "service_type": "COMPUTE",
  123                 "recovery_method": "auto",
  124                 "description": "failover_segment for compute"
  125             }
  126         }
  127         mock_create.return_value = FAILOVER_SEGMENT
  128         result = self.controller.create(self.req, body=body)
  129         result = result['segment']
  130         self._assert_segment_data(FAILOVER_SEGMENT, _make_segment_obj(result))
  131 
  132     @mock.patch.object(ha_api.FailoverSegmentAPI, 'create_segment')
  133     def test_create_with_duplicate_segment_name(self, mock_create):
  134         body = {
  135             "segment": {
  136                 "name": "segment1",
  137                 "service_type": "COMPUTE",
  138                 "recovery_method": "auto",
  139                 "description": "failover_segment for compute"
  140             }
  141         }
  142         mock_create.side_effect = (exception.
  143                                    FailoverSegmentExists(name='segment1'))
  144         self.assertRaises(exc.HTTPConflict, self.controller.create,
  145                           self.req, body=body)
  146 
  147     @mock.patch('masakari.rpc.get_client')
  148     @mock.patch.object(ha_api.FailoverSegmentAPI, 'create_segment')
  149     def test_create_success_with_201_response_code(
  150         self, mock_client, mock_create):
  151         body = {
  152             "segment": {
  153                 "name": "segment1",
  154                 "service_type": "COMPUTE",
  155                 "recovery_method": "auto",
  156                 "description": "failover_segment for compute"
  157             }
  158         }
  159         fake_req = self.req
  160         fake_req.headers['Content-Type'] = 'application/json'
  161         fake_req.method = 'POST'
  162         fake_req.body = jsonutils.dump_as_bytes(body)
  163         resp = fake_req.get_response(self.app)
  164         self.assertEqual(http.CREATED, resp.status_code)
  165 
  166     @ddt.data(
  167         # no segment
  168         {"body": {
  169             "name": "segment1",
  170             "service_type": "COMPUTE",
  171             "recovery_method": "auto",
  172             "description": "failover_segment for compute"}},
  173 
  174         # no name
  175         {"body": {
  176             "segment": {
  177                 "service_type": "COMPUTE",
  178                 "recovery_method": "auto",
  179                 "description": "failover_segment for compute"}}},
  180 
  181         # name with leading trailing spaces
  182         {"body": {
  183             "segment": {
  184                 "name": "    segment1    ",
  185                 "service_type": "COMPUTE",
  186                 "recovery_method": "auto",
  187                 "description": "failover_segment for compute"}}},
  188 
  189         # null name
  190         {"body": {
  191             "segment": {
  192                 "name": "",
  193                 "service_type": "COMPUTE",
  194                 "recovery_method": "auto",
  195                 "description": "failover_segment for compute"}}},
  196 
  197         # name too long
  198         {"body": {
  199             "segment": {
  200                 "name": "segment1" * 255,
  201                 "service_type": "COMPUTE",
  202                 "recovery_method": "auto",
  203                 "description": "failover_segment for compute"}}},
  204 
  205         # extra invalid args
  206         {"body": {
  207             "segment": {
  208                 "name": "segment1" * 255,
  209                 "service_type": "COMPUTE",
  210                 "recovery_method": "auto",
  211                 "description": "failover_segment for compute",
  212                 "foo": "fake_foo"}}}
  213     )
  214     @ddt.unpack
  215     def test_create_failure(self, body):
  216         self.assertRaises(self.bad_request, self.controller.create,
  217                           self.req, body=body)
  218 
  219     @mock.patch.object(ha_api.FailoverSegmentAPI, 'get_segment')
  220     def test_show(self, mock_get_segment):
  221 
  222         mock_get_segment.return_value = FAILOVER_SEGMENT
  223 
  224         result = self.controller.show(self.req, uuidsentinel.fake_segment)
  225         result = result['segment']
  226         self._assert_segment_data(FAILOVER_SEGMENT, _make_segment_obj(result))
  227 
  228     @mock.patch.object(ha_api.FailoverSegmentAPI, 'get_segment')
  229     def test_show_with_non_existing_id(self, mock_get_segment):
  230 
  231         mock_get_segment.side_effect = exception.FailoverSegmentNotFound(
  232             id="2")
  233         self.assertRaises(exc.HTTPNotFound,
  234                           self.controller.show, self.req, "2")
  235 
  236     @ddt.data(
  237         {"body": {"segment": {"name": "segment1", "service_type": "COMPUTE",
  238                               "recovery_method": "auto"}}},
  239 
  240         # with name only
  241         {"body": {"segment": {"name": "segment1"}}}
  242 
  243     )
  244     @ddt.unpack
  245     @mock.patch.object(ha_api.FailoverSegmentAPI, 'update_segment')
  246     def test_update(self, mock_update_segment, body):
  247         mock_update_segment.return_value = FAILOVER_SEGMENT
  248 
  249         result = self.controller.update(self.req, uuidsentinel.fake_segment,
  250                                         body=body)
  251 
  252         result = result['segment']
  253         self._assert_segment_data(FAILOVER_SEGMENT, _make_segment_obj(result))
  254 
  255     @ddt.data(
  256         # no updates
  257         {"test_data": {"segment": {}}},
  258 
  259         # no update key
  260         {"test_data": {"asdf": {}}},
  261 
  262         # wrong updates
  263         {"test_data": {"segment": {"name": "disable", "foo": "bar"}}},
  264 
  265         # null name
  266         {"test_data": {"segment": {"name": ""}}},
  267 
  268         # name too long
  269         {"test_data": {"segment": {"name": "x" * 256}}}
  270     )
  271     @ddt.unpack
  272     def test_update_failure(self, test_data):
  273         self.assertRaises(self.bad_request, self.controller.update,
  274                           self.req, uuidsentinel.fake_segment, body=test_data)
  275 
  276     @mock.patch.object(ha_api.FailoverSegmentAPI, 'update_segment')
  277     def test_update_with_non_exising_segment(self, mock_update_segment):
  278 
  279         test_data = {"segment": {"name": "segment11"}}
  280         mock_update_segment.side_effect = exception.FailoverSegmentNotFound(
  281             id="2")
  282         self.assertRaises(exc.HTTPNotFound, self.controller.update,
  283                 self.req, "2", body=test_data)
  284 
  285     @mock.patch.object(ha_api.FailoverSegmentAPI, 'update_segment')
  286     def test_update_with_duplicated_name(self, mock_update_segment):
  287         test_data = {"segment": {"name": "segment1"}}
  288         mock_update_segment.side_effect = exception.FailoverSegmentExists(
  289             name="segment1")
  290         self.assertRaises(exc.HTTPConflict, self.controller.update,
  291                 self.req, uuidsentinel.fake_segment, body=test_data)
  292 
  293     @mock.patch.object(ha_api.FailoverSegmentAPI, 'delete_segment')
  294     def test_delete_segment(self, mock_delete):
  295 
  296         self.controller.delete(self.req, uuidsentinel.fake_segment)
  297         self.assertTrue(mock_delete.called)
  298 
  299     @mock.patch.object(ha_api.FailoverSegmentAPI, 'delete_segment')
  300     def test_delete_segment_not_found(self, mock_delete):
  301 
  302         mock_delete.side_effect = exception.FailoverSegmentNotFound(
  303             id=uuidsentinel.fake_segment)
  304         self.assertRaises(exc.HTTPNotFound, self.controller.delete,
  305                 self.req, uuidsentinel.fake_segment)
  306 
  307     @mock.patch('masakari.rpc.get_client')
  308     @mock.patch.object(ha_api.FailoverSegmentAPI, 'delete_segment')
  309     def test_delete_segment_with_204_status(self, mock_client, mock_delete):
  310         url = '/v1/segments/%s' % uuidsentinel.fake_segment
  311         fake_req = fakes.HTTPRequest.blank(url, use_admin_context=True)
  312         fake_req.headers['Content-Type'] = 'application/json'
  313         fake_req.method = 'DELETE'
  314         resp = fake_req.get_response(self.app)
  315         self.assertEqual(http.NO_CONTENT, resp.status_code)
  316 
  317 
  318 class FailoverSegmentTestCasePolicyNotAuthorized(test.NoDBTestCase):
  319     """Test Case for failover segment non admin."""
  320 
  321     def setUp(self):
  322         super(FailoverSegmentTestCasePolicyNotAuthorized, self).setUp()
  323         self.controller = segments.SegmentsController()
  324         self.req = fakes.HTTPRequest.blank('/v1/segments')
  325         self.context = self.req.environ['masakari.context']
  326 
  327     def _check_rule(self, exc, rule_name):
  328         self.assertEqual(
  329             "Policy doesn't allow %s to be performed." % rule_name,
  330             exc.format_message())
  331 
  332     def test_index_no_admin(self):
  333         rule_name = "os_masakari_api:segments:index"
  334         self.policy.set_rules({rule_name: "project:non_fake"})
  335         exc = self.assertRaises(exception.PolicyNotAuthorized,
  336                                 self.controller.index,
  337                                 self.req)
  338         self._check_rule(exc, rule_name)
  339 
  340     def test_create_no_admin(self):
  341         rule_name = "os_masakari_api:segments:create"
  342         self.policy.set_rules({rule_name: "project:non_fake"})
  343         body = {
  344             "segment": {
  345                 "name": "segment1",
  346                 "service_type": "COMPUTE",
  347                 "recovery_method": "auto",
  348                 "description": "failover_segment for compute"
  349             }
  350         }
  351         exc = self.assertRaises(exception.PolicyNotAuthorized,
  352                                 self.controller.create,
  353                                 self.req, body=body)
  354         self._check_rule(exc, rule_name)
  355 
  356     def test_show_no_admin(self):
  357         rule_name = "os_masakari_api:segments:detail"
  358         self.policy.set_rules({rule_name: "project:non_fake"})
  359         exc = self.assertRaises(exception.PolicyNotAuthorized,
  360                                 self.controller.show,
  361                                 self.req, uuidsentinel.fake_segment)
  362         self._check_rule(exc, rule_name)
  363 
  364     def test_update_no_admin(self):
  365         rule_name = "os_masakari_api:segments:update"
  366         self.policy.set_rules({rule_name: "project:non_fake"})
  367         body = {
  368             "segment": {
  369                 "name": "segment1",
  370                 "service_type": "COMPUTE",
  371                 "recovery_method": "auto",
  372                 "description": "failover_segment for compute"
  373             }
  374         }
  375         exc = self.assertRaises(exception.PolicyNotAuthorized,
  376                                 self.controller.update,
  377                                 self.req, uuidsentinel.fake_segment, body=body)
  378         self._check_rule(exc, rule_name)
  379 
  380     def test_delete_no_admin(self):
  381         rule_name = "os_masakari_api:segments:delete"
  382         self.policy.set_rules({rule_name: "project:non_fake"})
  383         exc = self.assertRaises(exception.PolicyNotAuthorized,
  384                                 self.controller.delete,
  385                                 self.req, uuidsentinel.fake_segment)
  386         self._check_rule(exc, rule_name)