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.

Task: 43815
Story: 2009653
Change-Id: Ic0265fcf7ceb811803cdebaa8932fe80dc59a627
(cherry picked from commit 403fa55fe9)
This commit is contained in:
Erik Panter 2021-10-29 11:03:27 +02:00 committed by Takashi Kajinami
parent ef36cb3049
commit 5ea5276a3e
2 changed files with 26 additions and 6 deletions

View File

@ -1549,7 +1549,10 @@ class Stack(collections.abc.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),

View File

@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from datetime import datetime
from datetime import timedelta
from unittest import mock
from oslo_config import cfg
@ -429,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')
@ -460,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',