)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"bfd81a490f3b3e2b03c51837b213c76650d9bc8a","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add validation for cpu_realtime_mask"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"It\u0027s possible to specify some strange values for the cpu realtime mask"},{"line_number":10,"context_line":"and the code won\u0027t currently complain, so let\u0027s make it a bit more"},{"line_number":11,"context_line":"strict."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"7f515b1d_33008401","line":9,"range":{"start_line":9,"start_character":25,"end_line":9,"end_character":44},"updated":"2017-10-10 00:12:07.000000000","message":"Good to update for accuracy. Please see the following comment.","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"}],"nova/tests/unit/virt/test_hardware.py":[{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"eae5b64a3aca54983d252189bcec3031637c8cc5","unresolved":false,"context_lines":[{"line_number":2948,"context_line":""},{"line_number":2949,"context_line":"    def test_mask_badly_configured(self):"},{"line_number":2950,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2951,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"^0-2\"})"},{"line_number":2952,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":2953,"context_line":"        self.assertRaises("},{"line_number":2954,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f1d235d_8b098c96","side":"PARENT","line":2951,"updated":"2017-07-03 07:44:15.000000000","message":"The test I would like to see is that if we set a mask which do not exclude an existing vCPUs. \n\nExample can you try with ^3, our code is going to accept the mask and so return 0,1,2 as RT vCPUs where we want at least one non-RT vCPUs","commit_id":"47f6795dea03f7c81a9b0bea00527ee7ab49843b"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"116e94c88d937735d357c31f2de60c4117f1bb31","unresolved":false,"context_lines":[{"line_number":2967,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2968,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2969,"context_line":""},{"line_number":2970,"context_line":"    def test_no_std_cpus(self):"},{"line_number":2971,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2972,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":2973,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f1a1f67_28176f54","line":2970,"updated":"2017-07-20 09:13:54.000000000","message":"Please remove these two tests. They can\u0027t work since the syntax is not a mask so they are always returning all CPUs of the guest configured as RT","commit_id":"7b56020d8279edcee9b09bc8339f5ea77154a419"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"84a60c5c6149d57fa59de1b6a6992e20a34e93c8","unresolved":false,"context_lines":[{"line_number":2967,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2968,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2969,"context_line":""},{"line_number":2970,"context_line":"    def test_no_std_cpus(self):"},{"line_number":2971,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2972,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":2973,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f1a1f67_94e0d0ce","line":2970,"in_reply_to":"1f1a1f67_28176f54","updated":"2017-07-20 15:23:50.000000000","message":"I think the two tests are valid, especially since we don\u0027t document anywhere that the specified mask must involve purely exclusion clauses.  (Something like \"0-3,^0\" is technically a valid mask in the current code, at least to the extent that it gives a valid result.)\n\nIn the first test the specified mask makes all vCPUs RT, which causes the validation to fail due to not having any non-RT vCPUs.  With the current mask handling, this is basically checking that we exclude at least one vCPU from being RT.\n\nThe second test ensures that you can\u0027t specify in your mask a vCPU number that isn\u0027t valid for the flavor.\n\nYes, these tests are written in such a way that they could handle the followup patch without being changed, but they\u0027re still valid.","commit_id":"7b56020d8279edcee9b09bc8339f5ea77154a419"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"c6acb7d6daa51201bbc4dba6babbaef3d3505333","unresolved":false,"context_lines":[{"line_number":2967,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2968,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2969,"context_line":""},{"line_number":2970,"context_line":"    def test_no_std_cpus(self):"},{"line_number":2971,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2972,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":2973,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":3,"id":"ff346bd7_3fc54c3d","line":2970,"in_reply_to":"1f1a1f67_94e0d0ce","updated":"2017-07-24 14:33:47.000000000","message":"You are not testing what you are saying at all Chris but  test_no_rt_cpus and test_exclude_out_of_range are doing that.\n\n...Can you provide a test which is working using that syntax ? I don\u0027t think that is possible. That is why I\u0027m saying that these tests do not make sense.","commit_id":"7b56020d8279edcee9b09bc8339f5ea77154a419"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"914004d75287b84a109b15cd128b74df9fff48d4","unresolved":false,"context_lines":[{"line_number":2956,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"^0-2\"})"},{"line_number":2957,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":2958,"context_line":"        self.assertRaises("},{"line_number":2959,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2960,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2961,"context_line":""},{"line_number":2962,"context_line":"    def test_exclude_out_of_range(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_2d38ae3b","line":2959,"range":{"start_line":2959,"start_character":22,"end_line":2959,"end_character":51},"updated":"2017-10-03 19:53:21.000000000","message":"would be great to have separate exceptions for whether the extra spec is invalid or whether it doesn\u0027t exist. :(","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d9d51ddc41645d6939ef9ac47c36fa617c2593eb","unresolved":false,"context_lines":[{"line_number":2967,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2968,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2969,"context_line":""},{"line_number":2970,"context_line":"    def test_explicit_range(self):"},{"line_number":2971,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2972,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2973,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_f1d59fe6","line":2970,"updated":"2017-07-25 06:59:43.000000000","message":"We are passing a concatenated version of the set of vCPUs with the mask. So basically at the end in your example \u0027parse_cpu_specs()\u0027 is receiving:\n\n  \"0-2, 0-2, ^0\"\n\nThe second \u00270-2\u0027 is redundant - The mask should only be \"^0\" so parse_cpu_specs() will receive:\n\n  \"0-2, ^0\"\n\nWhich will exclude vCPU0","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ca1d13de2dae14a52357df54d113bf541d2598e8","unresolved":false,"context_lines":[{"line_number":2967,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2968,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2969,"context_line":""},{"line_number":2970,"context_line":"    def test_explicit_range(self):"},{"line_number":2971,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2972,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2973,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_016ca7cb","line":2970,"in_reply_to":"ff346bd7_0609e3db","updated":"2017-10-03 10:27:33.000000000","message":"+1. It\u0027s unnecessary and a little bit silly, but that doesn\u0027t mean we shouldn\u0027t be allowed to do it","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"59484d52a411b8ed1710ae476b4a02fd20d62929","unresolved":false,"context_lines":[{"line_number":2967,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2968,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2969,"context_line":""},{"line_number":2970,"context_line":"    def test_explicit_range(self):"},{"line_number":2971,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2972,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2973,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_0609e3db","line":2970,"in_reply_to":"ff346bd7_f1d59fe6","updated":"2017-07-26 00:11:27.000000000","message":"If we enforce that the mask must start with a \"^\" then this testcase would be an error scenario.  With the current code the testcase is just here to demonstrate that it works to specify both the RT vCPUs and the exclusion.","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d9d51ddc41645d6939ef9ac47c36fa617c2593eb","unresolved":false,"context_lines":[{"line_number":2974,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":2975,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":2976,"context_line":""},{"line_number":2977,"context_line":"    def test_no_std_cpus(self):"},{"line_number":2978,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2979,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":2980,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_3168c71f","line":2977,"updated":"2017-07-25 06:59:43.000000000","message":"This test do not make sense or your should call it mask_badly_configured or something like that.\n\n\u0027parse_cpu_specs()\u0027 will receive:\n\n  \"0-2, 0-2\"","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"59484d52a411b8ed1710ae476b4a02fd20d62929","unresolved":false,"context_lines":[{"line_number":2974,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":2975,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":2976,"context_line":""},{"line_number":2977,"context_line":"    def test_no_std_cpus(self):"},{"line_number":2978,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2979,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":2980,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_e6281f35","line":2977,"in_reply_to":"ff346bd7_3168c71f","updated":"2017-07-26 00:11:27.000000000","message":"If we enforce that the mask must start with a \"^\" then this testcase wouldn\u0027t be needed, otherwise it\u0027s a valid error scenario.","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ca1d13de2dae14a52357df54d113bf541d2598e8","unresolved":false,"context_lines":[{"line_number":2974,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":2975,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":2976,"context_line":""},{"line_number":2977,"context_line":"    def test_no_std_cpus(self):"},{"line_number":2978,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2979,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":2980,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_61a0fbf4","line":2977,"in_reply_to":"ff346bd7_e6281f35","updated":"2017-10-03 10:27:33.000000000","message":"I would appreciate a more meaningful name, but I do agree with the idea of the test","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d9d51ddc41645d6939ef9ac47c36fa617c2593eb","unresolved":false,"context_lines":[{"line_number":2982,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2983,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2984,"context_line":""},{"line_number":2985,"context_line":"    def test_rt_cpus_out_of_range(self):"},{"line_number":2986,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2987,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-3,^0\"})"},{"line_number":2988,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_d195fbe5","line":2985,"updated":"2017-07-25 06:59:43.000000000","message":"Again this test do not make sense, the syntax is wrong or you should call it mask_badly_configured.\n\n\u0027parse_cpu_specs()\u0027 will receive:\n\n  \"0-2, 0-3, ^0\"\n\nBasically I think \u0027test_exclude_out_of_range\u0027 is enough.","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"59484d52a411b8ed1710ae476b4a02fd20d62929","unresolved":false,"context_lines":[{"line_number":2982,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2983,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2984,"context_line":""},{"line_number":2985,"context_line":"    def test_rt_cpus_out_of_range(self):"},{"line_number":2986,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2987,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-3,^0\"})"},{"line_number":2988,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_e6849f0e","line":2985,"in_reply_to":"ff346bd7_d195fbe5","updated":"2017-07-26 00:11:27.000000000","message":"If we enforce that the mask must start with a \"^\" then this testcase wouldn\u0027t be needed.\n\nWith the current code, this tests the scenario where one of the RT vCPUs is not in the range specified by the flavor.  test_exclude_out_of_range is not enough, because as shown here it\u0027s possible to specify additional RT vCPUs that are outside of the range specified by the flavor.","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ca1d13de2dae14a52357df54d113bf541d2598e8","unresolved":false,"context_lines":[{"line_number":2982,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2983,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2984,"context_line":""},{"line_number":2985,"context_line":"    def test_rt_cpus_out_of_range(self):"},{"line_number":2986,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2987,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-3,^0\"})"},{"line_number":2988,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_41a3bf00","line":2985,"in_reply_to":"ff346bd7_e6849f0e","updated":"2017-10-03 10:27:33.000000000","message":"This looks fine to me, given the recurring theme here","commit_id":"26f05bed8ee2661e38abbc90ed0fee27d478fdf6"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"050268e6657d821fe818f623ed73b7a3bf00ec22","unresolved":false,"context_lines":[{"line_number":2969,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_4ba387b2","line":2972,"updated":"2017-10-05 20:15:05.000000000","message":"Please remove this test it does not make sense and we actually should block such syntax.\n\nWhat is the aim of illustrating that: \"0-3, 0-2, ^0\" ?","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"9dac14d07476a9eb328e9c47a60210b2dda6c740","unresolved":false,"context_lines":[{"line_number":2969,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_b66262d7","line":2972,"in_reply_to":"7f515b1d_4ba387b2","updated":"2017-10-05 20:40:34.000000000","message":"The testcase illustrates the current code behaviour.  If we ever change the behaviour we can change the testcase.","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"c7c20f0bb266cb03b3ccc4599de9b93885f35ecb","unresolved":false,"context_lines":[{"line_number":2969,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_b25a644d","line":2972,"in_reply_to":"7f515b1d_b66262d7","updated":"2017-10-06 07:08:22.000000000","message":"Well you have added a note so that seems reasonable.","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"050268e6657d821fe818f623ed73b7a3bf00ec22","unresolved":false,"context_lines":[{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2976,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2977,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_0b86af14","line":2974,"range":{"start_line":2973,"start_character":8,"end_line":2974,"end_character":38},"updated":"2017-10-05 20:15:05.000000000","message":"Should be the time to prevent it, no?","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"9dac14d07476a9eb328e9c47a60210b2dda6c740","unresolved":false,"context_lines":[{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2976,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2977,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_d6639edc","line":2974,"range":{"start_line":2973,"start_character":8,"end_line":2974,"end_character":38},"in_reply_to":"7f515b1d_0b86af14","updated":"2017-10-05 20:40:34.000000000","message":"Enforcing that the mask is only an exclusion mask would be a user-visible behaviour change that could impact users that are currently (accidentally) setting a full range not just an exclusion range.  As per Jay Pipes\u0027 comment this would be undesirable.\n\nBasically in these tests I\u0027m documenting the current behaviour and testing that we raise an exception for the scenarios that are unambiguously wrong.\n\nThe ambiguity will go away when we introduce the new \"hw:realtime_cpu_set\" since there will be no implicit range involved.","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"ffb2c40d4b4a18b7364b42f287e3db6f9388cd4c","unresolved":false,"context_lines":[{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2976,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2977,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_83feea35","line":2974,"range":{"start_line":2973,"start_character":8,"end_line":2974,"end_character":38},"in_reply_to":"7f515b1d_123b78eb","updated":"2017-10-06 17:57:35.000000000","message":"That\u0027s up to the cores more than me, but the usual rule is to not change user-visible behaviour without a good reason.  And if we\u0027re going to deprecate it anyway I\u0027m not sure it makes sense to change it.","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"bfd81a490f3b3e2b03c51837b213c76650d9bc8a","unresolved":false,"context_lines":[{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2976,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2977,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_93acd8ed","line":2974,"range":{"start_line":2973,"start_character":8,"end_line":2974,"end_character":38},"in_reply_to":"7f515b1d_83feea35","updated":"2017-10-10 00:12:07.000000000","message":"\u003e The ambiguity will go away when we introduce the new \"hw:realtime_cpu_set\" \n\n+1\nI\u0027m ok with not blocking syntax without \u0027^\u0027, but in that case that new feature looks better to me.\n\n\u003e can\u0027t we add a reno note to explain that with this bugfix you could have to update your wrongly configured mask? \n\nIIUC, this bugfix, after all, just ensures that...\n\n  1. vcpu set for RT is specified within the range of vcpu_set\n  2. there are at least 1vCPU for RT and 1 for non-RT.\n\n, which wouldn\u0027t warrant reno. \n\nIf we really want, we can add reno(issue?) and/or update flavor\u0027s document[1] to warn users that \"the current API does NOT block syntax without \u0027^\u0027 explicitly\". But, IMO, the issue wouldn\u0027t warrant reno either because it isn\u0027t \"the code doesn\u0027t work in the way of the mask\" stuff. At least, that should be done in another patch because the purpose of that document is a bit different from the purpose of the fix of this patch.\n\n[1] https://docs.openstack.org/nova/latest/user/flavors.html","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"c7c20f0bb266cb03b3ccc4599de9b93885f35ecb","unresolved":false,"context_lines":[{"line_number":2970,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":2971,"context_line":""},{"line_number":2972,"context_line":"    def test_explicit_range(self):"},{"line_number":2973,"context_line":"        # The mask is not just an exclusion mask.  This is unexpected but"},{"line_number":2974,"context_line":"        # the code doesn\u0027t prevent it."},{"line_number":2975,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":2976,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2,^0\"})"},{"line_number":2977,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f515b1d_123b78eb","line":2974,"range":{"start_line":2973,"start_character":8,"end_line":2974,"end_character":38},"in_reply_to":"7f515b1d_d6639edc","updated":"2017-10-06 07:08:22.000000000","message":"I still have a last question - In such situation can\u0027t we add a reno note to explain that with this bugfix you could have to update your wrongly configured mask?","commit_id":"c9f58f23253ca921f2179ffbf05166a1b03ad128"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"9cef755aada7c351c5237eca7c2b8cde4649b29c","unresolved":false,"context_lines":[{"line_number":3617,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":3618,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":3619,"context_line":""},{"line_number":3620,"context_line":"    def test_invalid_mask_no_exclusion(self):"},{"line_number":3621,"context_line":"        # The mask has no exclusion."},{"line_number":3622,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3623,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":3624,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3625,"context_line":"        self.assertRaises("},{"line_number":3626,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":3627,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":3628,"context_line":""},{"line_number":3629,"context_line":"    def test_invalid_mask_rt_cpus_out_of_range(self):"},{"line_number":3630,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_a7fe8035","line":3627,"range":{"start_line":3620,"start_character":3,"end_line":3627,"end_character":54},"updated":"2020-03-26 03:06:25.000000000","message":"This confuse me. This means all the vcpus are realtime, why we can\u0027t?","commit_id":"568899d85bc6f4f1b20b6cc36525300ac5e86620"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"c24a2b9b1c73a6bf9106c6849389d86201e4a3e6","unresolved":false,"context_lines":[{"line_number":3617,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":3618,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":3619,"context_line":""},{"line_number":3620,"context_line":"    def test_invalid_mask_no_exclusion(self):"},{"line_number":3621,"context_line":"        # The mask has no exclusion."},{"line_number":3622,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3623,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":3624,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3625,"context_line":"        self.assertRaises("},{"line_number":3626,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":3627,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":3628,"context_line":""},{"line_number":3629,"context_line":"    def test_invalid_mask_rt_cpus_out_of_range(self):"},{"line_number":3630,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_aafaaf71","line":3627,"range":{"start_line":3620,"start_character":3,"end_line":3627,"end_character":54},"in_reply_to":"df33271e_1b650546","updated":"2020-03-27 06:48:41.000000000","message":"emm...I confused, the currently behaviour won\u0027t reject that. Just like this test\u0027s example, the mask is \"0-2,0-2\", then it is all the vcpus, but the check is about len(vcpu_rt) \u003c 1, so it won\u0027t raise the exception.","commit_id":"568899d85bc6f4f1b20b6cc36525300ac5e86620"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"06b993a11d22a6200bc2778688dcd2aee73a6a50","unresolved":false,"context_lines":[{"line_number":3617,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":3618,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":3619,"context_line":""},{"line_number":3620,"context_line":"    def test_invalid_mask_no_exclusion(self):"},{"line_number":3621,"context_line":"        # The mask has no exclusion."},{"line_number":3622,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3623,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":3624,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3625,"context_line":"        self.assertRaises("},{"line_number":3626,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":3627,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":3628,"context_line":""},{"line_number":3629,"context_line":"    def test_invalid_mask_rt_cpus_out_of_range(self):"},{"line_number":3630,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_86b6a83d","line":3627,"range":{"start_line":3620,"start_character":3,"end_line":3627,"end_character":54},"in_reply_to":"df33271e_329d7559","updated":"2020-03-30 01:53:04.000000000","message":"\u003e So I\u0027m not sure what to do here. Perhaps we could enforce that\n \u003e either (a) you have at least one non-realtime core *or* (b) you\n \u003e have an emulator thread policy configured?\n \u003e \n\nFeel like the right thing to do.","commit_id":"568899d85bc6f4f1b20b6cc36525300ac5e86620"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"35f43e206feaee37988e8e4d8c0c7e525f25690f","unresolved":false,"context_lines":[{"line_number":3617,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":3618,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":3619,"context_line":""},{"line_number":3620,"context_line":"    def test_invalid_mask_no_exclusion(self):"},{"line_number":3621,"context_line":"        # The mask has no exclusion."},{"line_number":3622,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3623,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":3624,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3625,"context_line":"        self.assertRaises("},{"line_number":3626,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":3627,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":3628,"context_line":""},{"line_number":3629,"context_line":"    def test_invalid_mask_rt_cpus_out_of_range(self):"},{"line_number":3630,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_54af8093","line":3627,"range":{"start_line":3620,"start_character":3,"end_line":3627,"end_character":54},"in_reply_to":"df33271e_86b6a83d","updated":"2020-04-06 16:49:29.000000000","message":"Done","commit_id":"568899d85bc6f4f1b20b6cc36525300ac5e86620"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"dfffb232b81cb6039abb7222fff0227a38730aec","unresolved":false,"context_lines":[{"line_number":3617,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":3618,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":3619,"context_line":""},{"line_number":3620,"context_line":"    def test_invalid_mask_no_exclusion(self):"},{"line_number":3621,"context_line":"        # The mask has no exclusion."},{"line_number":3622,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3623,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":3624,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3625,"context_line":"        self.assertRaises("},{"line_number":3626,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":3627,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":3628,"context_line":""},{"line_number":3629,"context_line":"    def test_invalid_mask_rt_cpus_out_of_range(self):"},{"line_number":3630,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_1b650546","line":3627,"range":{"start_line":3620,"start_character":3,"end_line":3627,"end_character":54},"in_reply_to":"df33271e_a7fe8035","updated":"2020-03-26 10:17:56.000000000","message":"This is the current behavior. Currently, the value needs to be an exclusion mask and it can\u0027t be empty. If it is, \u0027RealtimeMaskNotFoundOrInvalid\u0027 is raised [1]. I don\u0027t know if we should change that behavior. I have been told that for Linux guests, you need to have at least one non-realtime core (ideally core 0), though I don\u0027t know if this applies to other OSes\n\n[1] https://github.com/openstack/nova/blob/20.1.0/nova/virt/hardware.py#L1687-L1689","commit_id":"568899d85bc6f4f1b20b6cc36525300ac5e86620"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"39651c92f946fde662675793c4a9ef36a2c1c979","unresolved":false,"context_lines":[{"line_number":3617,"context_line":"        rt \u003d hw.vcpus_realtime_topology(flavor, image)"},{"line_number":3618,"context_line":"        self.assertEqual(set([1, 2]), rt)"},{"line_number":3619,"context_line":""},{"line_number":3620,"context_line":"    def test_invalid_mask_no_exclusion(self):"},{"line_number":3621,"context_line":"        # The mask has no exclusion."},{"line_number":3622,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3623,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"},{"line_number":3624,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3625,"context_line":"        self.assertRaises("},{"line_number":3626,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"},{"line_number":3627,"context_line":"            hw.vcpus_realtime_topology, flavor, image)"},{"line_number":3628,"context_line":""},{"line_number":3629,"context_line":"    def test_invalid_mask_rt_cpus_out_of_range(self):"},{"line_number":3630,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"}],"source_content_type":"text/x-python","patch_set":8,"id":"df33271e_329d7559","line":3627,"range":{"start_line":3620,"start_character":3,"end_line":3627,"end_character":54},"in_reply_to":"df33271e_aafaaf71","updated":"2020-03-27 12:37:28.000000000","message":"It\u0027s tricky. Let\u0027s say you use a flavor like so:\n\n  openstack flavor create \\\n    --vcpus 4 --disk 5 --ram 2048 \\\n    --property \u0027hw:cpu_policy\u003ddedicated\u0027 \\\n    --property \u0027hw:cpu_realtime\u003dtrue\u0027 \\\n    --property \u0027hw:cpu_realtime_mask\u003d0-3\u0027 \\\n    test.rt\n\nToday, you\u0027ll see the following failure:\n\n  libvirt.libvirtError: invalid argument: Failed to parse bitmap \u0027\u0027\n\nThat\u0027s because we don\u0027t have an emulator thread policy configured and all of cores are set aside for realtime, meaning we end up with an empty emulator thread set [1]. However, we can do what you suggest by configuring an emulator thread policy. For example:\n\n  openstack flavor create \\\n    --vcpus 4 --disk 5 --ram 2048 \\\n    --property \u0027hw:cpu_policy\u003ddedicated\u0027 \\\n    --property \u0027hw:emulator_threads_policy\u003dshare\u0027 \\\n    --property \u0027hw:cpu_realtime\u003dtrue\u0027 \\\n    --property \u0027hw:cpu_realtime_mask\u003d0-3\u0027 \\\n    test.rt\n\nSo I\u0027m not sure what to do here. Perhaps we could enforce that either (a) you have at least one non-realtime core *or* (b) you have an emulator thread policy configured?\n\n[1] https://github.com/openstack/nova/blob/20.1.0/nova/virt/libvirt/driver.py#L4775-L4776","commit_id":"568899d85bc6f4f1b20b6cc36525300ac5e86620"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"82e858114dacf4777ed4753cba3f0a9b03fba781","unresolved":false,"context_lines":[{"line_number":3603,"context_line":"    def test_invalid_mask_exclude_out_of_range(self):"},{"line_number":3604,"context_line":"        # The mask excludes an invalidly high vCPU number."},{"line_number":3605,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3606,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"^3\"})"},{"line_number":3607,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3608,"context_line":"        self.assertRaises("},{"line_number":3609,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_afa80277","line":3606,"updated":"2020-05-14 15:55:11.000000000","message":"This would give you vcpus_rt \u003d\u003d vcpus_set \u003d\u003d 0,1,2, which will only raise if there\u0027s no emulator thread policy, right?\n\nThe test still makes sense, but the naming is misleading, no?","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"03fcdc8439f1bc59a245c26c2f6d3bd1c7d17701","unresolved":false,"context_lines":[{"line_number":3603,"context_line":"    def test_invalid_mask_exclude_out_of_range(self):"},{"line_number":3604,"context_line":"        # The mask excludes an invalidly high vCPU number."},{"line_number":3605,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3606,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"^3\"})"},{"line_number":3607,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3608,"context_line":"        self.assertRaises("},{"line_number":3609,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_d05ea474","line":3606,"in_reply_to":"ff570b3c_0271f5a9","updated":"2020-05-15 14:07:41.000000000","message":"Right, but I don\u0027t see any code that will raise RealtimeMaskNotFoundOrInvalid because of only that. In fact, if you comment out L1723-1724 in the next file, this test will fail.\n\nAs I said in my other comment, this isn\u0027t strictly speaking the same test as test_invalid_mask_no_exclusion_wo_emulator_policy because that one doesn\u0027t use a caret mask whereas this one does, but it tests the same mechanic in the code: vcpu_set \u003d\u003d vcpus_rt and no emulator thread policy.","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"cc66e54ed6a7a19d6a1dc73cf50dbcdcb2ffa500","unresolved":false,"context_lines":[{"line_number":3603,"context_line":"    def test_invalid_mask_exclude_out_of_range(self):"},{"line_number":3604,"context_line":"        # The mask excludes an invalidly high vCPU number."},{"line_number":3605,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3606,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"^3\"})"},{"line_number":3607,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3608,"context_line":"        self.assertRaises("},{"line_number":3609,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_0271f5a9","line":3606,"in_reply_to":"ff570b3c_afa80277","updated":"2020-05-15 09:14:03.000000000","message":"No, it shouldn\u0027t even get that far. The issue isn\u0027t so much that the mask is empty but that 3 is not a valid ID for the list of cores. I could have chosen 4, or 5, or 6, or so on too","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f5d6ea767937a6c984740a29459d4ab0e0f56542","unresolved":false,"context_lines":[{"line_number":3603,"context_line":"    def test_invalid_mask_exclude_out_of_range(self):"},{"line_number":3604,"context_line":"        # The mask excludes an invalidly high vCPU number."},{"line_number":3605,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3606,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"^3\"})"},{"line_number":3607,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3608,"context_line":"        self.assertRaises("},{"line_number":3609,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_2cd96b56","line":3606,"in_reply_to":"ff570b3c_d05ea474","updated":"2020-05-18 10:35:38.000000000","message":"Ah, I understand you now. Yeah, this isn\u0027t testing what it\u0027s supposed to because \u0027^M\u0027 in \u00270-N,^M\u0027 is ignored if M \u003e N. I\u0027m not actually sure how we\u0027d test for this and catch it, so I don\u0027t want to remove this test but rather improve the code to handle that corner case. Open to suggestions.","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"82e858114dacf4777ed4753cba3f0a9b03fba781","unresolved":false,"context_lines":[{"line_number":3619,"context_line":"        self.assertEqual({1, 2}, rt)"},{"line_number":3620,"context_line":""},{"line_number":3621,"context_line":"    def test_invalid_mask_no_exclusion_wo_emulator_policy(self):"},{"line_number":3622,"context_line":"        # The mask has no exclusion and there\u0027s no emulator thread policy"},{"line_number":3623,"context_line":"        # configured"},{"line_number":3624,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3625,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_2feb52b0","line":3622,"updated":"2020-05-14 15:55:11.000000000","message":"... this just repeats the test on L3603?","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"abe2888be6f7e7a0d529afa97724b6807926ecb6","unresolved":false,"context_lines":[{"line_number":3619,"context_line":"        self.assertEqual({1, 2}, rt)"},{"line_number":3620,"context_line":""},{"line_number":3621,"context_line":"    def test_invalid_mask_no_exclusion_wo_emulator_policy(self):"},{"line_number":3622,"context_line":"        # The mask has no exclusion and there\u0027s no emulator thread policy"},{"line_number":3623,"context_line":"        # configured"},{"line_number":3624,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3625,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-2\"})"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_af72c20f","line":3622,"in_reply_to":"ff570b3c_2feb52b0","updated":"2020-05-14 15:56:41.000000000","message":"I guess not, strictly speaking. It doesn\u0027t use a mask to achieve the same effect.","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"82e858114dacf4777ed4753cba3f0a9b03fba781","unresolved":false,"context_lines":[{"line_number":3644,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"},{"line_number":3645,"context_line":"        # an invalid vCPU number."},{"line_number":3646,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3647,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-3,^0\"})"},{"line_number":3648,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3649,"context_line":"        self.assertRaises("},{"line_number":3650,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_4f0fa688","line":3647,"updated":"2020-05-14 15:55:11.000000000","message":"Oh, this\u0027ll cause vcpus_rt to end up being 1,2,3, which is not a subset of vcpus\u003d0,1,2","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"cc66e54ed6a7a19d6a1dc73cf50dbcdcb2ffa500","unresolved":false,"context_lines":[{"line_number":3644,"context_line":"        # The mask is not just an exclusion mask, and the RT range specifies"},{"line_number":3645,"context_line":"        # an invalid vCPU number."},{"line_number":3646,"context_line":"        flavor \u003d objects.Flavor(vcpus\u003d3, memory_mb\u003d2048,"},{"line_number":3647,"context_line":"                                extra_specs\u003d{\"hw:cpu_realtime_mask\": \"0-3,^0\"})"},{"line_number":3648,"context_line":"        image \u003d objects.ImageMeta.from_dict({\"properties\": {}})"},{"line_number":3649,"context_line":"        self.assertRaises("},{"line_number":3650,"context_line":"            exception.RealtimeMaskNotFoundOrInvalid,"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_c29b7dc6","line":3647,"in_reply_to":"ff570b3c_4f0fa688","updated":"2020-05-15 09:14:03.000000000","message":"Yeah, it\u0027s a variation of the first test you\u0027ve commented on","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"}],"nova/virt/hardware.py":[{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d9d51ddc41645d6939ef9ac47c36fa617c2593eb","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"def vcpus_realtime_topology(flavor, image):"},{"line_number":1253,"context_line":"    \"\"\"Determines instance vCPUs used as RT for a given spec\"\"\""},{"line_number":1254,"context_line":"    mask \u003d _get_realtime_mask(flavor, image)"},{"line_number":1255,"context_line":"    if not mask:"},{"line_number":1256,"context_line":"        raise exception.RealtimeMaskNotFoundOrInvalid()"},{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"    vcpus_rt \u003d parse_cpu_spec(\"0-%d,%s\" % (flavor.vcpus - 1, mask))"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_d163bb19","side":"PARENT","line":1255,"updated":"2017-07-25 06:59:43.000000000","message":"Since you are improving validation it should be interesting to check that the users well start the mask with \"^\"","commit_id":"038619cce803c3522701886aa59c0c2750532b3a"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"73eeef087b7f8f4149bcca5025eeec9c0d9ea050","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"def vcpus_realtime_topology(flavor, image):"},{"line_number":1253,"context_line":"    \"\"\"Determines instance vCPUs used as RT for a given spec\"\"\""},{"line_number":1254,"context_line":"    mask \u003d _get_realtime_mask(flavor, image)"},{"line_number":1255,"context_line":"    if not mask:"},{"line_number":1256,"context_line":"        raise exception.RealtimeMaskNotFoundOrInvalid()"},{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"    vcpus_rt \u003d parse_cpu_spec(\"0-%d,%s\" % (flavor.vcpus - 1, mask))"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_eb31f15b","side":"PARENT","line":1255,"in_reply_to":"ff346bd7_c309822c","updated":"2017-07-26 14:50:25.000000000","message":"Arguably we do support it (for certain values of \"support\") since it works currently.  The mask is not invalid, it works perfectly fine. Calling hardware.parse_cpu_spec(\"0-2,0-2,^0\") returns set([1,2])\n\nPersonally, I think \"specify an exclusion mask to show which vCPUs aren\u0027t RT\" is confusing.  It makes more sense for the end-user to specify the set of vCPUS which *are* RT, in which case we should just use the range specified by the user without adding an implicit portion.","commit_id":"038619cce803c3522701886aa59c0c2750532b3a"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"94010df4f29d815205abcbdce6dfa39c86b45a22","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"def vcpus_realtime_topology(flavor, image):"},{"line_number":1253,"context_line":"    \"\"\"Determines instance vCPUs used as RT for a given spec\"\"\""},{"line_number":1254,"context_line":"    mask \u003d _get_realtime_mask(flavor, image)"},{"line_number":1255,"context_line":"    if not mask:"},{"line_number":1256,"context_line":"        raise exception.RealtimeMaskNotFoundOrInvalid()"},{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"    vcpus_rt \u003d parse_cpu_spec(\"0-%d,%s\" % (flavor.vcpus - 1, mask))"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_c309822c","side":"PARENT","line":1255,"in_reply_to":"ff346bd7_c65d1bea","updated":"2017-07-26 07:28:04.000000000","message":"That is not going to break anything, firstable that is not a syntax we support and secondly that is just going to stop the process of starting an instance to inform the users that the mask they are using is not valid and they have to update their image properties.\n\nas explained before it does not make sense to have 0-n,^x-y and we should not demonstrate such scenario by the tests even if the tests are failing.","commit_id":"038619cce803c3522701886aa59c0c2750532b3a"},{"author":{"_account_id":8768,"name":"Chris Friesen","email":"chris.friesen@windriver.com","username":"cbf123"},"change_message_id":"59484d52a411b8ed1710ae476b4a02fd20d62929","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"def vcpus_realtime_topology(flavor, image):"},{"line_number":1253,"context_line":"    \"\"\"Determines instance vCPUs used as RT for a given spec\"\"\""},{"line_number":1254,"context_line":"    mask \u003d _get_realtime_mask(flavor, image)"},{"line_number":1255,"context_line":"    if not mask:"},{"line_number":1256,"context_line":"        raise exception.RealtimeMaskNotFoundOrInvalid()"},{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"    vcpus_rt \u003d parse_cpu_spec(\"0-%d,%s\" % (flavor.vcpus - 1, mask))"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff346bd7_c65d1bea","side":"PARENT","line":1255,"in_reply_to":"ff346bd7_d163bb19","updated":"2017-07-26 00:11:27.000000000","message":"Doing that would allow skipping some of the testcases that you don\u0027t like, but it risks breaking end-users that currently specify a mask of the format \"0-n,^x-y\".   Currently they can specify that and it will work as expected (assuming n is \"num_vcpus-1\"), but if I enforce that the mask must begin with ^ they\u0027ll break.\n\nMy preferred option is my followup-patch which explicitly supports the end-user specifying that type of mask and handles it differently by not assuming all vCPUs are RT to start.  That way it\u0027ll work for both cases (where they specify an explicit full mask, or where they specify just the exclusion portion).","commit_id":"038619cce803c3522701886aa59c0c2750532b3a"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"ca1d13de2dae14a52357df54d113bf541d2598e8","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"def vcpus_realtime_topology(flavor, image):"},{"line_number":1253,"context_line":"    \"\"\"Determines instance vCPUs used as RT for a given spec\"\"\""},{"line_number":1254,"context_line":"    mask \u003d _get_realtime_mask(flavor, image)"},{"line_number":1255,"context_line":"    if not mask:"},{"line_number":1256,"context_line":"        raise exception.RealtimeMaskNotFoundOrInvalid()"},{"line_number":1257,"context_line":""},{"line_number":1258,"context_line":"    vcpus_rt \u003d parse_cpu_spec(\"0-%d,%s\" % (flavor.vcpus - 1, mask))"}],"source_content_type":"text/x-python","patch_set":4,"id":"7f515b1d_417cdf70","side":"PARENT","line":1255,"in_reply_to":"ff346bd7_eb31f15b","updated":"2017-10-03 10:27:33.000000000","message":"We can\u0027t break behavior for existing users unless those existing users were seeing harmful side-effects (which they are not). I also happen to agree with the follow-up, so this makes sense","commit_id":"038619cce803c3522701886aa59c0c2750532b3a"},{"author":{"_account_id":8864,"name":"Artom Lifshitz","email":"notartom@gmail.com","username":"artom"},"change_message_id":"03fcdc8439f1bc59a245c26c2f6d3bd1c7d17701","unresolved":false,"context_lines":[{"line_number":1720,"context_line":""},{"line_number":1721,"context_line":"    # TODO(stephenfin): Do this check in numa_get_constraints instead"},{"line_number":1722,"context_line":"    emu_policy \u003d get_emulator_thread_policy_constraint(flavor)"},{"line_number":1723,"context_line":"    if vcpus_set \u003d\u003d vcpus_rt and not emu_policy:"},{"line_number":1724,"context_line":"        raise exception.RealtimeMaskNotFoundOrInvalid()"},{"line_number":1725,"context_line":""},{"line_number":1726,"context_line":"    if not vcpus_rt.issubset(vcpus_set):"},{"line_number":1727,"context_line":"        msg \u003d _(\"Realtime policy vCPU(s) mask is configured with RT vCPUs \""}],"source_content_type":"text/x-python","patch_set":14,"id":"ff570b3c_b04df09b","line":1724,"range":{"start_line":1723,"start_character":0,"end_line":1724,"end_character":55},"updated":"2020-05-15 14:07:41.000000000","message":"[cont\u0027d] These lines","commit_id":"7e0379a947fbea4e6e901ed870f108888fa1c119"}]}
