|
| 1 | +import odd_models |
1 | 2 | import pytest
|
2 | 3 | import sqlalchemy
|
3 |
| -from odd_models import DataEntity |
4 |
| -from odd_models.models import DataEntityType |
5 | 4 | from pydantic import SecretStr
|
6 | 5 | from testcontainers.mysql import MySqlContainer
|
7 | 6 |
|
| 7 | +from odd_collector.adapters.mysql.adapter import Adapter |
| 8 | +from odd_collector.domain.plugin import MySQLPlugin |
8 | 9 | from tests.integration.helpers import find_by_name, find_by_type
|
9 | 10 |
|
10 |
| -create_tables = """ |
11 |
| -CREATE TABLE Persons ( |
12 |
| - PersonID int, |
13 |
| - LastName varchar(255), |
14 |
| - FirstName varchar(255), |
15 |
| - Address varchar(255), |
16 |
| - City varchar(255) |
17 |
| -);""" |
18 |
| - |
19 |
| -create_view = """ |
20 |
| -CREATE VIEW persons_names AS |
21 |
| -SELECT LastName, FirstName |
22 |
| -FROM Persons |
23 |
| -WHERE City = 'Sandnes'; |
24 |
| -""" |
25 |
| - |
26 |
| -create_view_from_view = """ |
27 |
| -CREATE VIEW persons_last_names AS |
28 |
| -SELECT LastName |
29 |
| -FROM persons_names; |
30 |
| -""" |
31 | 11 |
|
32 |
| -from odd_collector.adapters.mysql.adapter import Adapter |
33 |
| -from odd_collector.domain.plugin import MySQLPlugin |
| 12 | +def create_primary_schema(connection: sqlalchemy.engine.Connection): |
| 13 | + create_tables = """ |
| 14 | + CREATE TABLE Persons ( |
| 15 | + PersonID int, |
| 16 | + LastName varchar(255), |
| 17 | + FirstName varchar(255), |
| 18 | + Address varchar(255), |
| 19 | + City varchar(255) |
| 20 | + );""" |
| 21 | + |
| 22 | + create_view = """ |
| 23 | + CREATE VIEW persons_names AS |
| 24 | + SELECT LastName, FirstName |
| 25 | + FROM Persons; |
| 26 | + """ |
| 27 | + |
| 28 | + create_view_from_view = """ |
| 29 | + CREATE VIEW persons_last_names AS |
| 30 | + SELECT LastName |
| 31 | + FROM persons_names; |
| 32 | + """ |
| 33 | + |
| 34 | + connection.exec_driver_sql(create_tables) |
| 35 | + connection.exec_driver_sql(create_view) |
| 36 | + connection.exec_driver_sql(create_view_from_view) |
| 37 | + |
| 38 | + |
| 39 | +def create_other_schema(connection: sqlalchemy.engine.Connection): |
| 40 | + create_other_schema = """ |
| 41 | + CREATE DATABASE `other_schema`; |
| 42 | + """ |
| 43 | + |
| 44 | + create_tables = """ |
| 45 | + CREATE TABLE `other_schema`.`Persons` ( |
| 46 | + PersonID int, |
| 47 | + LastName varchar(255), |
| 48 | + FirstName varchar(255), |
| 49 | + Address varchar(255), |
| 50 | + City varchar(255) |
| 51 | + );""" |
| 52 | + |
| 53 | + create_view = """ |
| 54 | + CREATE VIEW `other_schema`.`persons_names` AS |
| 55 | + SELECT LastName, FirstName |
| 56 | + FROM `other_schema`.`Persons`; |
| 57 | + """ |
| 58 | + |
| 59 | + create_view_from_view = """ |
| 60 | + CREATE VIEW `other_schema`.`persons_last_names` AS |
| 61 | + SELECT LastName |
| 62 | + FROM `other_schema`.`persons_names`; |
| 63 | + """ |
| 64 | + |
| 65 | + connection.exec_driver_sql(create_other_schema) |
| 66 | + connection.exec_driver_sql(create_tables) |
| 67 | + connection.exec_driver_sql(create_view) |
| 68 | + connection.exec_driver_sql(create_view_from_view) |
| 69 | + |
| 70 | + |
| 71 | +def entities_are_unique(entities: list[odd_models.DataEntity]): |
| 72 | + return len(entities) == len({e.oddrn for e in entities}) |
34 | 73 |
|
35 | 74 |
|
36 |
| -@pytest.mark.integration |
37 |
| -def test_mysql(): |
38 |
| - with MySqlContainer() as mysql: |
| 75 | +@pytest.fixture(scope="module") |
| 76 | +def data_entities() -> odd_models.DataEntityList: |
| 77 | + with MySqlContainer(MYSQL_USER="root") as mysql: |
39 | 78 | engine = sqlalchemy.create_engine(mysql.get_connection_url())
|
40 | 79 |
|
41 | 80 | with engine.connect() as connection:
|
42 |
| - connection.exec_driver_sql(create_tables) |
43 |
| - connection.exec_driver_sql(create_view) |
44 |
| - connection.exec_driver_sql(create_view_from_view) |
| 81 | + create_primary_schema(connection) |
| 82 | + create_other_schema(connection) |
45 | 83 |
|
46 | 84 | config = MySQLPlugin(
|
47 | 85 | type="mysql",
|
48 | 86 | name="test_mysql",
|
49 | 87 | database="test",
|
50 | 88 | password=SecretStr("test"),
|
51 |
| - user="test", |
| 89 | + user="root", |
52 | 90 | host=mysql.get_container_host_ip(),
|
53 |
| - port=mysql.get_exposed_port(3306), |
| 91 | + port=int(mysql.get_exposed_port(3306)), |
54 | 92 | )
|
55 | 93 |
|
56 |
| - data_entities = Adapter(config).get_data_entity_list() |
57 |
| - database_services: list[DataEntity] = find_by_type( |
58 |
| - data_entities, DataEntityType.DATABASE_SERVICE |
59 |
| - ) |
60 |
| - assert len(database_services) == 1 |
61 |
| - database_service = database_services[0] |
62 |
| - assert len(database_service.data_entity_group.entities_list) == 3 |
| 94 | + return Adapter(config).get_data_entity_list() |
| 95 | + |
| 96 | + |
| 97 | +def test_entities_are_unique(data_entities: odd_models.DataEntityList): |
| 98 | + assert entities_are_unique(data_entities.items) |
| 99 | + |
| 100 | + |
| 101 | +def test_fetch_one_database_from_config(data_entities: odd_models.DataEntityList): |
| 102 | + databases: list[odd_models.DataEntity] = find_by_type( |
| 103 | + data_entities, odd_models.DataEntityType.DATABASE_SERVICE |
| 104 | + ) |
| 105 | + assert len(databases) == 1 |
| 106 | + database = databases[0] |
| 107 | + assert database.data_entity_group is not None |
| 108 | + assert len(database.data_entity_group.entities_list) == 3 |
| 109 | + |
| 110 | + entities = database.data_entity_group.entities_list |
| 111 | + assert len(entities) == len(set(entities)) |
| 112 | + |
| 113 | + |
| 114 | +def test_fetch_only_one_table(data_entities: odd_models.DataEntityList): |
| 115 | + tables = find_by_type(data_entities, odd_models.DataEntityType.TABLE) |
| 116 | + |
| 117 | + assert entities_are_unique(tables) |
| 118 | + |
| 119 | + table = tables[0] |
| 120 | + |
| 121 | + assert len(tables) == 1 |
| 122 | + assert table.dataset is not None |
| 123 | + assert len(table.dataset.field_list) == 5 |
| 124 | + assert entities_are_unique(table.dataset.field_list) |
| 125 | + |
| 126 | + |
| 127 | +def test_fetch_two_views(data_entities: odd_models.DataEntityList): |
| 128 | + views = find_by_type(data_entities, odd_models.DataEntityType.VIEW) |
| 129 | + assert len(views) == 2 |
| 130 | + assert entities_are_unique(views) |
| 131 | + |
| 132 | + |
| 133 | +def test_view_depends_on_table(data_entities: odd_models.DataEntityList): |
| 134 | + table_entity = find_by_name(data_entities, "Persons") |
| 135 | + entity = find_by_name(data_entities, "persons_names") |
63 | 136 |
|
64 |
| - tables = find_by_type(data_entities, DataEntityType.TABLE) |
65 |
| - assert len(tables) == 1 |
66 |
| - table = tables[0] |
67 |
| - assert len(table.dataset.field_list) == 5 |
| 137 | + assert len(entity.dataset.field_list) == 2 |
| 138 | + assert len(entity.data_transformer.inputs) == 1 |
| 139 | + assert entity.data_transformer.inputs[0] == table_entity.oddrn |
68 | 140 |
|
69 |
| - views = find_by_type(data_entities, DataEntityType.VIEW) |
70 |
| - assert len(views) == 2 |
71 | 141 |
|
72 |
| - persons_view = find_by_name(data_entities, "persons_names") |
73 |
| - assert len(persons_view.dataset.field_list) == 2 |
74 |
| - assert len(persons_view.data_transformer.inputs) == 1 |
75 |
| - assert persons_view.data_transformer.inputs[0] == table.oddrn |
| 142 | +def test_view_depends_on_view(data_entities: odd_models.DataEntityList): |
| 143 | + view_entity = find_by_name(data_entities, "persons_names") |
| 144 | + entity = find_by_name(data_entities, "persons_last_names") |
| 145 | + assert len(entity.data_transformer.inputs) == 1 |
| 146 | + assert entity.data_transformer.inputs[0] == view_entity.oddrn |
76 | 147 |
|
77 |
| - last_names_view = find_by_name(data_entities, "persons_last_names") |
78 |
| - assert len(last_names_view.dataset.field_list) == 1 |
79 |
| - assert len(last_names_view.data_transformer.inputs) == 1 |
80 |
| - assert last_names_view.data_transformer.inputs[0] == persons_view.oddrn |
81 | 148 |
|
82 |
| - assert data_entities.json() |
| 149 | +def test_decoding_data_entities(data_entities: odd_models.DataEntityList): |
| 150 | + assert data_entities.json() |
0 commit comments