Example #1
0
 def test_numbered_only(self):
     # Crazy ordering and nonsequential numbers don't matter.
     # It's okay to have a 'resources' without a 'required'.
     # A trait that's repeated shows up in both spots.
     qs = ('resources1=VCPU:2,MEMORY_MB:2048'
           '&required42=CUSTOM_GOLD'
           '&resources99=DISK_GB:5'
           '&resources42=CUSTOM_MAGIC:123'
           '&required1=HW_CPU_X86_VMX,CUSTOM_GOLD')
     expected = [
         pl.RequestGroup(
             resources={
                 'VCPU': 2,
                 'MEMORY_MB': 2048,
             },
             required_traits={
                 'HW_CPU_X86_VMX',
                 'CUSTOM_GOLD',
             },
         ),
         pl.RequestGroup(
             resources={
                 'CUSTOM_MAGIC': 123,
             },
             required_traits={
                 'CUSTOM_GOLD',
             },
         ),
         pl.RequestGroup(
             resources={
                 'DISK_GB': 5,
             },
         ),
     ]
     self.assertRequestGroupsEqual(expected, self.do_parse(qs))
Example #2
0
    def test_forbidden_separate_groups_no_conflict(self):
        qs = ('resources1=CUSTOM_MAGIC:1&required1=CUSTOM_PHYSNET1'
              '&resources2=CUSTOM_MAGIC:1&required2=!CUSTOM_PHYSNET1')
        expected = [
            pl.RequestGroup(
                use_same_provider=True,
                resources={
                    'CUSTOM_MAGIC': 1,
                },
                required_traits={
                    'CUSTOM_PHYSNET1',
                }
            ),
            pl.RequestGroup(
                use_same_provider=True,
                resources={
                    'CUSTOM_MAGIC': 1,
                },
                forbidden_traits={
                    'CUSTOM_PHYSNET1',
                }
            ),
        ]

        self.assertRequestGroupsEqual(
            expected, self.do_parse(qs, version=(1, 22)))
Example #3
0
    def test_forbidden_two_groups(self):
        qs = ('resources=VCPU:2,MEMORY_MB:2048&resources1=CUSTOM_MAGIC:1'
              '&required1=CUSTOM_PHYSNET1,!CUSTOM_PHYSNET2')
        expected = [
            pl.RequestGroup(
                use_same_provider=False,
                resources={
                    'VCPU': 2,
                    'MEMORY_MB': 2048,
                },
            ),
            pl.RequestGroup(
                resources={
                    'CUSTOM_MAGIC': 1,
                },
                required_traits={
                    'CUSTOM_PHYSNET1',
                },
                forbidden_traits={
                    'CUSTOM_PHYSNET2',
                }
            ),
        ]

        self.assertRequestGroupsEqual(
            expected, self.do_parse(qs, version=(1, 22)))
Example #4
0
 def test_member_of_multiple_aggs_numbered(self):
     """Numbered resources with multiple member_of query params."""
     agg1_uuid = uuidsentinel.agg1
     agg2_uuid = uuidsentinel.agg2
     agg3_uuid = uuidsentinel.agg3
     agg4_uuid = uuidsentinel.agg4
     qs = ('resources1=VCPU:2'
           '&member_of1=%s'
           '&member_of1=%s'
           '&resources2=VCPU:2'
           '&member_of2=in:%s,%s' % (
               agg1_uuid, agg2_uuid, agg3_uuid, agg4_uuid))
     expected = [
         pl.RequestGroup(
             resources={
                 'VCPU': 2,
             },
             member_of=[
                 set([agg1_uuid]),
                 set([agg2_uuid])
             ]
         ),
         pl.RequestGroup(
             resources={
                 'VCPU': 2,
             },
             member_of=[
                 set([agg3_uuid, agg4_uuid]),
             ]
         ),
     ]
     self.assertRequestGroupsEqual(
         expected, self.do_parse(qs, version=(1, 24)))
Example #5
0
 def test_numbered_and_unnumbered(self):
     qs = ('resources=VCPU:3,MEMORY_MB:4096,DISK_GB:10'
           '&required=HW_CPU_X86_VMX,CUSTOM_MEM_FLASH,STORAGE_DISK_SSD'
           '&resources1=SRIOV_NET_VF:2'
           '&required1=CUSTOM_PHYSNET_PRIVATE'
           '&resources2=SRIOV_NET_VF:1,NET_INGRESS_BYTES_SEC:20000'
           ',NET_EGRESS_BYTES_SEC:10000'
           '&required2=CUSTOM_SWITCH_BIG,CUSTOM_PHYSNET_PROD'
           '&resources3=CUSTOM_MAGIC:123')
     expected = [
         pl.RequestGroup(
             use_same_provider=False,
             resources={
                 'VCPU': 3,
                 'MEMORY_MB': 4096,
                 'DISK_GB': 10,
             },
             required_traits={
                 'HW_CPU_X86_VMX',
                 'CUSTOM_MEM_FLASH',
                 'STORAGE_DISK_SSD',
             },
         ),
         pl.RequestGroup(
             resources={
                 'SRIOV_NET_VF': 2,
             },
             required_traits={
                 'CUSTOM_PHYSNET_PRIVATE',
             },
         ),
         pl.RequestGroup(
             resources={
                 'SRIOV_NET_VF': 1,
                 'NET_INGRESS_BYTES_SEC': 20000,
                 'NET_EGRESS_BYTES_SEC': 10000,
             },
             required_traits={
                 'CUSTOM_SWITCH_BIG',
                 'CUSTOM_PHYSNET_PROD',
             },
         ),
        pl.RequestGroup(
            resources={
                'CUSTOM_MAGIC': 123,
            },
        ),
     ]
     self.assertRequestGroupsEqual(expected, self.do_parse(qs))
Example #6
0
 def test_forbidden_one_group(self):
     """When forbidden are allowed this will parse, but otherwise will
     indicate an invalid trait.
     """
     qs = ('resources=VCPU:2,MEMORY_MB:2048'
           '&required=CUSTOM_PHYSNET1,!CUSTOM_SWITCH_BIG')
     expected_forbidden = [
         pl.RequestGroup(use_same_provider=False,
                         resources={
                             'VCPU': 2,
                             'MEMORY_MB': 2048,
                         },
                         required_traits={
                             'CUSTOM_PHYSNET1',
                         },
                         forbidden_traits={
                             'CUSTOM_SWITCH_BIG',
                         }),
     ]
     expected_message = (
         "Invalid query string parameters: Expected 'required' parameter "
         "value of the form: HW_CPU_X86_VMX,CUSTOM_MAGIC. Got: "
         "CUSTOM_PHYSNET1,!CUSTOM_SWITCH_BIG")
     exc = self.assertRaises(webob.exc.HTTPBadRequest, self.do_parse, qs)
     self.assertEqual(expected_message, six.text_type(exc))
     self.assertRequestGroupsEqual(expected_forbidden,
                                   self.do_parse(qs, version=(1, 22)))
Example #7
0
 def test_member_of_forbidden_aggs(self):
     agg1_uuid = uuidsentinel.agg1
     agg2_uuid = uuidsentinel.agg2
     agg3_uuid = uuidsentinel.agg3
     agg4_uuid = uuidsentinel.agg4
     qs = ('resources=VCPU:2'
           '&member_of=%s'
           '&member_of=%s'
           '&member_of=!%s'
           '&member_of=!%s' % (agg1_uuid, agg2_uuid, agg3_uuid, agg4_uuid))
     expected = [
         pl.RequestGroup(
             use_same_provider=False,
             resources={
                 'VCPU': 2,
             },
             member_of=[
                 set([agg1_uuid]),
                 set([agg2_uuid]),
             ],
             forbidden_aggs=set([agg3_uuid, agg4_uuid]),
         ),
     ]
     self.assertRequestGroupsEqual(expected,
                                   self.do_parse(qs, version=(1, 32)))
Example #8
0
 def test_member_of_single_agg(self):
     """Unnumbered resources with one member_of query param."""
     agg1_uuid = uuidsentinel.agg1
     qs = ('resources=VCPU:2,MEMORY_MB:2048' '&member_of=%s' % agg1_uuid)
     expected = [
         pl.RequestGroup(use_same_provider=False,
                         resources={
                             'VCPU': 2,
                             'MEMORY_MB': 2048,
                         },
                         member_of=[set([agg1_uuid])]),
     ]
     self.assertRequestGroupsEqual(expected, self.do_parse(qs))
Example #9
0
 def test_unnumbered_resources_only(self):
     """Validate the bit that can be used for 1.10 and earlier."""
     qs = 'resources=VCPU:2,MEMORY_MB:2048,DISK_GB:5,CUSTOM_MAGIC:123'
     expected = [
         pl.RequestGroup(
             use_same_provider=False,
             resources={
                 'VCPU': 2,
                 'MEMORY_MB': 2048,
                 'DISK_GB': 5,
                 'CUSTOM_MAGIC': 123,
             },
         ),
     ]
     self.assertRequestGroupsEqual(expected, self.do_parse(qs))
Example #10
0
 def test_good_suffix_1_33(self):
     qs = ('resources_car_HOUSE_10=CUSTOM_MAGIC:1'
           '&required_car_HOUSE_10=CUSTOM_PHYSNET1')
     expected = [
         pl.RequestGroup(use_same_provider=True,
                         resources={
                             'CUSTOM_MAGIC': 1,
                         },
                         required_traits={
                             'CUSTOM_PHYSNET1',
                         }),
     ]
     self.assertRequestGroupsEqual(expected,
                                   self.do_parse(qs, version=(1, 33)))
     self.assertRaises(webob.exc.HTTPBadRequest,
                       self.do_parse,
                       qs,
                       version=(1, 22))
Example #11
0
 def test_member_of_multiple_aggs(self):
     """Unnumbered resources with multiple member_of query params."""
     agg1_uuid = uuidsentinel.agg1
     agg2_uuid = uuidsentinel.agg2
     qs = ('resources=VCPU:2,MEMORY_MB:2048'
           '&member_of=%s'
           '&member_of=%s' % (agg1_uuid, agg2_uuid))
     expected = [
         pl.RequestGroup(use_same_provider=False,
                         resources={
                             'VCPU': 2,
                             'MEMORY_MB': 2048,
                         },
                         member_of=[set([agg1_uuid]),
                                    set([agg2_uuid])]),
     ]
     self.assertRequestGroupsEqual(expected,
                                   self.do_parse(qs, version=(1, 24)))
Example #12
0
 def test_unnumbered_only(self):
     """Unnumbered resources & traits - no numbered groupings."""
     qs = ('resources=VCPU:2,MEMORY_MB:2048'
           '&required=HW_CPU_X86_VMX,CUSTOM_GOLD')
     expected = [
         pl.RequestGroup(
             use_same_provider=False,
             resources={
                 'VCPU': 2,
                 'MEMORY_MB': 2048,
             },
             required_traits={
                 'HW_CPU_X86_VMX',
                 'CUSTOM_GOLD',
             },
         ),
     ]
     self.assertRequestGroupsEqual(expected, self.do_parse(qs))
Example #13
0
 def get_request_group(suffix):
     if suffix not in by_suffix:
         rq_grp = placement_lib.RequestGroup(use_same_provider=bool(suffix))
         by_suffix[suffix] = rq_grp
     return by_suffix[suffix]
Example #14
0
    def test_shared_provider_capacity(self):
        """Sets up a resource provider that shares DISK_GB inventory via an
        aggregate, a couple resource providers representing "local disk"
        compute nodes and ensures the _get_providers_sharing_capacity()
        function finds that provider and not providers of "local disk".
        """
        # Create the two "local disk" compute node providers
        cn1 = self._create_provider('cn1')
        cn2 = self._create_provider('cn2')

        # Populate the two compute node providers with inventory.  One has
        # DISK_GB.  Both should be excluded from the result (one doesn't have
        # the requested resource; but neither is a sharing provider).
        for cn in (cn1, cn2):
            tb.add_inventory(cn, orc.VCPU, 24,
                             allocation_ratio=16.0)
            tb.add_inventory(cn, orc.MEMORY_MB, 32768,
                             min_unit=64,
                             max_unit=32768,
                             step_size=64,
                             allocation_ratio=1.5)
            if cn is cn1:
                tb.add_inventory(cn, orc.DISK_GB, 2000,
                                 min_unit=100,
                                 max_unit=2000,
                                 step_size=10)

        # Create the shared storage pool
        ss1 = self._create_provider('shared storage 1')
        ss2 = self._create_provider('shared storage 2')

        # Give the shared storage pool some inventory of DISK_GB
        for ss, disk_amount in ((ss1, 2000), (ss2, 1000)):
            tb.add_inventory(ss, orc.DISK_GB, disk_amount,
                             min_unit=100,
                             max_unit=2000,
                             step_size=10)
            # Mark the shared storage pool as having inventory shared among
            # any provider associated via aggregate
            tb.set_traits(ss, "MISC_SHARES_VIA_AGGREGATE")

        # OK, now that has all been set up, let's verify that we get the ID of
        # the shared storage pool
        got_ids = res_ctx.get_sharing_providers(self.ctx)
        self.assertEqual(set([ss1.id, ss2.id]), got_ids)

        request = placement_lib.RequestGroup(
            use_same_provider=False,
            resources={orc.VCPU: 2,
                       orc.MEMORY_MB: 256,
                       orc.DISK_GB: 1500})
        has_trees = res_ctx._has_provider_trees(self.ctx)
        sharing = res_ctx.get_sharing_providers(self.ctx)
        rg_ctx = res_ctx.RequestGroupSearchContext(
            self.ctx, request, has_trees, sharing)

        VCPU_ID = orc.STANDARDS.index(orc.VCPU)
        DISK_GB_ID = orc.STANDARDS.index(orc.DISK_GB)

        rps_sharing_vcpu = rg_ctx.get_rps_with_shared_capacity(VCPU_ID)
        self.assertEqual(set(), rps_sharing_vcpu)

        rps_sharing_dist = rg_ctx.get_rps_with_shared_capacity(DISK_GB_ID)
        self.assertEqual(set([ss1.id]), rps_sharing_dist)