buildzr 0.0.17__tar.gz → 0.0.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {buildzr-0.0.17 → buildzr-0.0.18}/PKG-INFO +1 -1
- buildzr-0.0.18/buildzr/__about__.py +1 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/dsl.py +7 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/test_dsl.py +84 -1
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/test_explorer.py +2 -2
- buildzr-0.0.17/buildzr/__about__.py +0 -1
- {buildzr-0.0.17 → buildzr-0.0.18}/.gitignore +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/CONTRIBUTING.md +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/LICENSE.md +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/README.md +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/color.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/explorer.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/expression.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/factory/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/factory/gen_id.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/interfaces/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/interfaces/interfaces.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/dsl/relations.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/encoders/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/encoders/encoder.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/models/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/models/generate.sh +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/models/models.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/sinks/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/sinks/interfaces.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/buildzr/sinks/json_sink.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/pyproject.toml +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/abstract_builder.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/__init__.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/component_view.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/container_view.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/container_view_sugar.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/groups.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/implied_relationships.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/nested_groups.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/simple.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/simple_dsl.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/system_context_view.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/samples/system_landscape_view.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/test_expression.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/test_typehints.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/test_views.py +0 -0
- {buildzr-0.0.17 → buildzr-0.0.18}/tests/test_workspaces.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = "0.0.18"
|
@@ -139,6 +139,9 @@ class Workspace(DslWorkspaceElement):
|
|
139
139
|
If we have relationship s.ss >> do >> a.b.c, then create s.ss >> do >> a.b and s.ss >> do >> a.
|
140
140
|
And so on...
|
141
141
|
|
142
|
+
Relationships of `SoftwareSystemInstance`s and `ContainerInstance`s are
|
143
|
+
skipped.
|
144
|
+
|
142
145
|
This process is idempotent, which means this can be called multiple times
|
143
146
|
without duplicating similar relationships.
|
144
147
|
"""
|
@@ -155,6 +158,10 @@ class Workspace(DslWorkspaceElement):
|
|
155
158
|
destination = relationship.destination
|
156
159
|
destination_parent = destination.parent
|
157
160
|
|
161
|
+
if isinstance(source, (SoftwareSystemInstance, ContainerInstance)) or \
|
162
|
+
isinstance(destination, (SoftwareSystemInstance, ContainerInstance)):
|
163
|
+
continue
|
164
|
+
|
158
165
|
while destination_parent is not None and \
|
159
166
|
isinstance(source, DslElement) and \
|
160
167
|
not isinstance(source.model, buildzr.models.Workspace) and \
|
@@ -15,6 +15,7 @@ from buildzr.dsl import (
|
|
15
15
|
SystemContextView,
|
16
16
|
DeploymentEnvironment,
|
17
17
|
DeploymentNode,
|
18
|
+
DeploymentView,
|
18
19
|
InfrastructureNode,
|
19
20
|
DeploymentGroup,
|
20
21
|
SoftwareSystemInstance,
|
@@ -394,6 +395,10 @@ def test_implied_relationship() -> Optional[None]:
|
|
394
395
|
assert w.u.model.relationships[1].id in system_context_view_relationships
|
395
396
|
assert w.u.model.relationships[1].linkedRelationshipId == w.u.model.relationships[0].id
|
396
397
|
|
398
|
+
import os
|
399
|
+
os.remove('workspace.test.json')
|
400
|
+
os.remove('workspace2.test.json')
|
401
|
+
|
397
402
|
def test_tags_on_elements() -> Optional[None]:
|
398
403
|
|
399
404
|
u = Person('My User', tags={'admin'})
|
@@ -1099,4 +1104,82 @@ def test_json_sink_empty_views() -> Optional[None]:
|
|
1099
1104
|
assert data
|
1100
1105
|
|
1101
1106
|
import os
|
1102
|
-
os.remove("test.json")
|
1107
|
+
os.remove("test.json")
|
1108
|
+
def test_deployment_instance_relationships_with_implied_relationships() -> Optional[None]:
|
1109
|
+
"""
|
1110
|
+
Test that deployment instance relationships are created correctly when
|
1111
|
+
implied_relationships=True, without creating duplicates.
|
1112
|
+
|
1113
|
+
This test ensures:
|
1114
|
+
1. Container relationships automatically create ContainerInstance relationships
|
1115
|
+
2. No duplicate instance relationships are created when implied_relationships=True
|
1116
|
+
3. Instance relationships are only created once, even with multiple view/export calls
|
1117
|
+
"""
|
1118
|
+
|
1119
|
+
with Workspace('deployment-test', implied_relationships=True) as w:
|
1120
|
+
# Create containers with relationships
|
1121
|
+
ecommerce = SoftwareSystem('E-Commerce System')
|
1122
|
+
with ecommerce:
|
1123
|
+
api_gateway = Container('API Gateway', technology='Kong')
|
1124
|
+
order_svc = Container('Order Service', technology='Node.js')
|
1125
|
+
db = Container('Database', technology='MongoDB')
|
1126
|
+
|
1127
|
+
# Define container relationships
|
1128
|
+
api_gateway >> "Routes to" >> order_svc
|
1129
|
+
order_svc >> "Stores in" >> db
|
1130
|
+
|
1131
|
+
# Create deployment with container instances
|
1132
|
+
with DeploymentEnvironment('Production') as prod:
|
1133
|
+
with DeploymentNode('AWS', technology='Cloud Provider'):
|
1134
|
+
api_gw_instance = ContainerInstance(api_gateway)
|
1135
|
+
order_instance = ContainerInstance(order_svc)
|
1136
|
+
db_instance = ContainerInstance(db)
|
1137
|
+
|
1138
|
+
# Create views and export (triggers implied relationships multiple times)
|
1139
|
+
SystemContextView(
|
1140
|
+
software_system_selector=ecommerce,
|
1141
|
+
key='test-system-context',
|
1142
|
+
description="Test System Context",
|
1143
|
+
)
|
1144
|
+
|
1145
|
+
DeploymentView(
|
1146
|
+
environment=prod,
|
1147
|
+
key='test-deployment',
|
1148
|
+
)
|
1149
|
+
|
1150
|
+
# Export multiple times to ensure idempotency
|
1151
|
+
w.to_json('test_deployment1.json')
|
1152
|
+
w.to_json('test_deployment2.json')
|
1153
|
+
|
1154
|
+
# Verify instance relationships exist
|
1155
|
+
assert api_gw_instance.model.relationships is not None
|
1156
|
+
assert order_instance.model.relationships is not None
|
1157
|
+
|
1158
|
+
# Get all instance relationships
|
1159
|
+
api_gw_rels = api_gw_instance.model.relationships
|
1160
|
+
order_rels = order_instance.model.relationships
|
1161
|
+
|
1162
|
+
# Should have exactly 1 relationship from api_gw_instance to order_instance
|
1163
|
+
api_to_order_rels = [
|
1164
|
+
r for r in api_gw_rels
|
1165
|
+
if r.destinationId == order_instance.model.id
|
1166
|
+
]
|
1167
|
+
assert len(api_to_order_rels) == 1, f"Expected 1 relationship, found {len(api_to_order_rels)}"
|
1168
|
+
assert api_to_order_rels[0].description == "Routes to"
|
1169
|
+
|
1170
|
+
# Should have exactly 1 relationship from order_instance to db_instance
|
1171
|
+
order_to_db_rels = [
|
1172
|
+
r for r in order_rels
|
1173
|
+
if r.destinationId == db_instance.model.id
|
1174
|
+
]
|
1175
|
+
assert len(order_to_db_rels) == 1, f"Expected 1 relationship, found {len(order_to_db_rels)}"
|
1176
|
+
assert order_to_db_rels[0].description == "Stores in"
|
1177
|
+
|
1178
|
+
# Verify linkedRelationshipId is set correctly
|
1179
|
+
assert api_to_order_rels[0].linkedRelationshipId is not None
|
1180
|
+
assert order_to_db_rels[0].linkedRelationshipId is not None
|
1181
|
+
|
1182
|
+
# Clean up
|
1183
|
+
import os
|
1184
|
+
os.remove('test_deployment1.json')
|
1185
|
+
os.remove('test_deployment2.json')
|
@@ -90,7 +90,7 @@ def test_walk_relationships(workspace: Workspace) -> Optional[None]:
|
|
90
90
|
|
91
91
|
# 5 explicit relationships.
|
92
92
|
# Add one additional implied relationship.
|
93
|
-
# And four additional from container instances for each two container instance (2x2=4
|
93
|
+
# And four additional from container instances for each two container instance (2x2=4).
|
94
94
|
#
|
95
95
|
# Explanation: if we have containers A and B with relationship A >> "Uses" >> B,
|
96
96
|
# and container instances ci_A_1, ci_A_2, ci_B_1, ci_B_2, then we have the
|
@@ -99,7 +99,7 @@ def test_walk_relationships(workspace: Workspace) -> Optional[None]:
|
|
99
99
|
# ci_A_1 >> "Uses" >> ci_B_2
|
100
100
|
# ci_A_2 >> "Uses" >> ci_B_1
|
101
101
|
# ci_A_2 >> "Uses" >> ci_B_2
|
102
|
-
assert len(relationships) ==
|
102
|
+
assert len(relationships) == 10
|
103
103
|
|
104
104
|
for relationship in relationships:
|
105
105
|
relationship_set = (
|
@@ -1 +0,0 @@
|
|
1
|
-
VERSION = "0.0.17"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|