From 785180ddc7a31bcee1494c7935406cccde902b0d Mon Sep 17 00:00:00 2001 From: Erik Panter Date: Fri, 29 Oct 2021 11:03:27 +0200 Subject: [PATCH] Fix None comparision when sorting by `updated_at` When sorting resource candidates in `_get_best_existing_rsrc_db`, resources with the same score are sorted by `updated_at`, which can be `None`. If that is the case, use `created_at` instead. (victoria to ussuri) Conflicts: heat/tests/test_convg_stack.py Resolved conflict caused by the following commit. commit fd6cf83554db68752278d37f577ba984d9f831b2 Use unittest.mock instead of third party mock Task: 43815 Story: 2009653 Change-Id: Ic0265fcf7ceb811803cdebaa8932fe80dc59a627 (cherry picked from commit 403fa55fe94ae1063d2cb4b8db3b63b76b1ee5cf) (cherry picked from commit 5ea5276a3e76829fd72345e3aae7482cbd260b51) (cherry picked from commit aa31864de4fe480674a0669c05a024ab28c3c429) (cherry picked from commit 26a20de88c0b578422e9847c1210d10f10b04854) --- heat/engine/stack.py | 5 ++++- heat/tests/test_convg_stack.py | 28 +++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/heat/engine/stack.py b/heat/engine/stack.py index 1b5f653870..801fce0a00 100644 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -1499,7 +1499,10 @@ class Stack(collections.Mapping): # Rolling back to previous resource score += 10 - return score, ext_rsrc.updated_at + last_changed_at = ext_rsrc.updated_at + if last_changed_at is None: + last_changed_at = ext_rsrc.created_at + return score, last_changed_at candidates = sorted((r for r in self.ext_rsrcs_db.values() if r.name == rsrc_name), diff --git a/heat/tests/test_convg_stack.py b/heat/tests/test_convg_stack.py index 1d2476d0b7..466ea11c96 100644 --- a/heat/tests/test_convg_stack.py +++ b/heat/tests/test_convg_stack.py @@ -11,7 +11,10 @@ # License for the specific language governing permissions and limitations # under the License. +from datetime import datetime +from datetime import timedelta import mock + from oslo_config import cfg from heat.common import template_format @@ -428,22 +431,32 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase): stack.prev_raw_template_id = 2 stack.t.id = 3 - def db_resource(current_template_id): + def db_resource(current_template_id, + created_at=None, + updated_at=None): db_res = resource_objects.Resource(stack.context) db_res['id'] = current_template_id db_res['name'] = 'A' db_res['current_template_id'] = current_template_id - db_res['action'] = 'CREATE' + db_res['action'] = 'UPDATE' if updated_at else 'CREATE' db_res['status'] = 'COMPLETE' - db_res['updated_at'] = None + db_res['updated_at'] = updated_at + db_res['created_at'] = created_at db_res['replaced_by'] = None return db_res + start_time = datetime.utcfromtimestamp(0) + + def t(minutes): + return start_time + timedelta(minutes=minutes) + a_res_2 = db_resource(2) a_res_3 = db_resource(3) - a_res_1 = db_resource(1) + a_res_0 = db_resource(0, created_at=t(0), updated_at=t(1)) + a_res_1 = db_resource(1, created_at=t(2)) existing_res = {a_res_2.id: a_res_2, a_res_3.id: a_res_3, + a_res_0.id: a_res_0, a_res_1.id: a_res_1} stack.ext_rsrcs_db = existing_res best_res = stack._get_best_existing_rsrc_db('A') @@ -459,9 +472,14 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase): # no resource with current template id as 3 or 2 del existing_res[2] best_res = stack._get_best_existing_rsrc_db('A') - # should return resource with template id 1 existing in DB + # should return resource with template id 1 which is the newest self.assertEqual(a_res_1.id, best_res.id) + del existing_res[1] + best_res = stack._get_best_existing_rsrc_db('A') + # should return resource with template id 0 existing in the db + self.assertEqual(a_res_0.id, best_res.id) + @mock.patch.object(parser.Stack, '_converge_create_or_update') def test_updated_time_stack_create(self, mock_ccu, mock_cr): stack = parser.Stack(utils.dummy_context(), 'convg_updated_time_test',