diff --git a/src/inmanta/data_pg.py b/src/inmanta/data_pg.py index 3ba02f8915..882763d2d3 100644 --- a/src/inmanta/data_pg.py +++ b/src/inmanta/data_pg.py @@ -1849,18 +1849,20 @@ async def get_list(cls, order_by_column=None, order="ASC", limit=None, offset=No order_by_statement = f"ORDER BY {order_by_column} {order} " if order_by_column else "" limit_statement = f"LIMIT {limit} " if limit is not None and limit > 0 else "" offset_statement = f"OFFSET {offset} " if offset is not None and offset > 0 else "" - query = f"SELECT c.*, SUM(CASE WHEN r.status NOT IN({transient_states}) THEN 1 ELSE 0 END) AS done ," + \ - f"to_json(array(SELECT jsonb_build_object('status', r2.status, 'id', r2.resource_version_id) " + \ - f" FROM {Resource.table_name()} AS r2 " \ - f" WHERE c.environment=r2.environment AND c.version=r2.model" \ - f" )) AS status " + \ - f"FROM {cls.table_name()} AS c LEFT OUTER JOIN {Resource.table_name()} AS r " + \ - f"ON c.environment = r.environment AND c.version = r.model " + \ - f"{where_statement} " + \ - f"GROUP BY c.environment, c.version " + \ - f"{order_by_statement} " + \ - f"{limit_statement} " + \ - f"{offset_statement}" + query = f"""SELECT c.*, + SUM(CASE WHEN r.status NOT IN({transient_states}) THEN 1 ELSE 0 END) AS done, + to_json(array(SELECT jsonb_build_object('status', r2.status, 'id', r2.resource_id) + FROM {Resource.table_name()} AS r2 + WHERE c.environment=r2.environment AND c.version=r2.model + ) + ) AS status + FROM {cls.table_name()} AS c LEFT OUTER JOIN {Resource.table_name()} AS r + ON c.environment = r.environment AND c.version = r.model + {where_statement} + GROUP BY c.environment, c.version + {order_by_statement} + {limit_statement} + {offset_statement}""" query_result = await cls._fetch_query(query, *values) result = [] for record in query_result: diff --git a/tests/test_data_pg.py b/tests/test_data_pg.py index 4470b14097..d55fbed274 100644 --- a/tests/test_data_pg.py +++ b/tests/test_data_pg.py @@ -657,6 +657,41 @@ async def test_model_get_list(init_dataclasses_and_load_schema): assert not cms +@pytest.mark.asyncio +async def test_model_serialization(init_dataclasses_and_load_schema): + project = data.Project(name="test") + await project.insert() + + env = data.Environment(name="dev", project=project.id, repo_url="", repo_branch="") + await env.insert() + + version = int(time.time()) + now = datetime.datetime.now() + cm = data.ConfigurationModel(environment=env.id, version=version, date=now, total=1, version_info={}) + await cm.insert() + + assert cm.done == 0 + + path = "/etc/file" + key = "std::File[agent1,path=" + path + "]" + resource = data.Resource.new(environment=env.id, resource_version_id=key + ",v=%d" % version, + attributes={"path": path}, status=const.ResourceState.deployed) + await resource.insert() + + cm = await data.ConfigurationModel.get_one(environment=env.id, version=version) + dct = cm.to_dict() + assert dct['version'] == version + assert dct['environment'] == env.id + assert dct['date'] == now + assert not dct['released'] + assert not dct['deployed'] + assert dct['result'] == const.VersionState.pending + assert dct['version_info'] == {} + assert dct['total'] == 1 + assert dct['done'] == 1 + assert dct['status'] == {str(uuid.uuid5(env.id, key)): {"id": key, "status": const.ResourceState.deployed.name}} + + @pytest.mark.asyncio async def test_model_delete_cascade(init_dataclasses_and_load_schema): project = data.Project(name="test")