From c85dd7f8b69af150c4048d7cd43251cda6357950 Mon Sep 17 00:00:00 2001 From: Hong Hui Xiao Date: Tue, 28 Mar 2017 21:11:50 +0800 Subject: [PATCH] Add hierarchical dependency to current model In the case of LogicalRouter and LogicalRouterPort, LogicalRouterPort has a reference to LogicalSwitch. So LogicalRouter should depend on LogicalSwitch. But LogicalRouterPort is not a first class db model, so LogicalRouterPort will not be count in when calculate dependency. This patch addresses this issue by adding the dependency of non-first class model to current model. Change-Id: I37308d1ed70df9b5f5053f2f71cc5c0790af9cec Partially-Implements: bp refactor-nb-api --- dragonflow/db/model_framework.py | 13 ++++++++---- dragonflow/tests/unit/test_model_framework.py | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/dragonflow/db/model_framework.py b/dragonflow/db/model_framework.py index 9db44b485..2ec33d69e 100644 --- a/dragonflow/db/model_framework.py +++ b/dragonflow/db/model_framework.py @@ -194,7 +194,7 @@ class _CommonBase(models.Base): @classmethod def dependencies(cls): - deps = [] + deps = set() for key, field in cls.iterate_over_fields(): if isinstance(field, fields.ListField): types = field.items_types @@ -203,11 +203,16 @@ class _CommonBase(models.Base): for field_type in types: try: - deps.append(field_type.get_proxied_model()) + deps.add(field_type.get_proxied_model()) except AttributeError: - pass + if issubclass(field_type, ModelBase): + # If the field is not a reference, and it is a df + # model(derived from ModelBase), it is considered as + # non-first class model. And its dependency + # will be treated as current model's dependency. + deps |= field_type.dependencies() - return set(deps) + return deps @classmethod def is_first_class(cls): diff --git a/dragonflow/tests/unit/test_model_framework.py b/dragonflow/tests/unit/test_model_framework.py index d5dcf374f..34b6743dc 100644 --- a/dragonflow/tests/unit/test_model_framework.py +++ b/dragonflow/tests/unit/test_model_framework.py @@ -135,6 +135,18 @@ class EmbeddingModel2(mf.ModelBase): emb_required = fields.EmbeddedField(EmbeddedModel, required=True) +@mf.construct_nb_db_model +class ReffingNonFirstClassModel(mf.ModelBase): + ref1 = df_fields.ReferenceField(ReffedModel) + + +@mf.register_model +@mf.construct_nb_db_model +class ReffingModel3(mf.ModelBase): + table_name = 'ReffingModel3' + ref = fields.ListField(ReffingNonFirstClassModel) + + class TestModelFramework(tests_base.BaseTestCase): def test_lookup(self): self.assertEqual(ModelTest, mf.get_model('ModelTest')) @@ -418,3 +430,11 @@ class TestModelFramework(tests_base.BaseTestCase): (emb1, emb2, emb3), embedding1.iterate_embedded_model_instances(), ) + + def test_hierarchical_dependency(self): + sorted_models = mf.iter_models_by_dependency_order() + self.assertLess( + sorted_models.index(ReffedModel), + sorted_models.index(ReffingModel3) + ) + self.assertIn(ReffedModel, ReffingModel3.dependencies())