11
11
# ANY KIND, either express or implied. See the License for the specific
12
12
# language governing permissions and limitations under the License.
13
13
"""This module contains code to test SageMaker ``LineageQueryResult.visualize()``"""
14
-
15
- import datetime
16
- import logging
14
+ from __future__ import absolute_import
17
15
import time
16
+ import json
18
17
19
18
import pytest
20
19
21
20
import sagemaker .lineage .query
22
21
from sagemaker .lineage .query import LineageQueryDirectionEnum
23
- from tests .integ .sagemaker .lineage .helpers import name , names , retry , LineageResourceHelper
22
+ from tests .integ .sagemaker .lineage .helpers import name , LineageResourceHelper
24
23
25
24
26
25
def test_LineageResourceHelper (sagemaker_session ):
@@ -35,6 +34,7 @@ def test_LineageResourceHelper(sagemaker_session):
35
34
print (e )
36
35
assert False
37
36
37
+
38
38
@pytest .mark .skip ("visualizer load test" )
39
39
def test_wide_graph_visualize (sagemaker_session ):
40
40
lineage_resource_helper = LineageResourceHelper (sagemaker_session = sagemaker_session )
@@ -46,9 +46,11 @@ def test_wide_graph_visualize(sagemaker_session):
46
46
# \ \--> Artifact
47
47
# \---> ...
48
48
try :
49
- for i in range (500 ):
49
+ for i in range (10 ):
50
50
artifact_arn = lineage_resource_helper .create_artifact (artifact_name = name ())
51
- lineage_resource_helper .create_association (source_arn = wide_graph_root_arn , dest_arn = artifact_arn )
51
+ lineage_resource_helper .create_association (
52
+ source_arn = wide_graph_root_arn , dest_arn = artifact_arn
53
+ )
52
54
except Exception as e :
53
55
print (e )
54
56
lineage_resource_helper .clean_all ()
@@ -65,6 +67,7 @@ def test_wide_graph_visualize(sagemaker_session):
65
67
66
68
lineage_resource_helper .clean_all ()
67
69
70
+
68
71
@pytest .mark .skip ("visualizer load test" )
69
72
def test_long_graph_visualize (sagemaker_session ):
70
73
lineage_resource_helper = LineageResourceHelper (sagemaker_session = sagemaker_session )
@@ -74,9 +77,11 @@ def test_long_graph_visualize(sagemaker_session):
74
77
# create long graph
75
78
# Artifact -> Artifact -> ... -> Artifact
76
79
try :
77
- for i in range (20 ):
80
+ for i in range (10 ):
78
81
new_artifact_arn = lineage_resource_helper .create_artifact (artifact_name = name ())
79
- lineage_resource_helper .create_association (source_arn = last_arn , dest_arn = new_artifact_arn )
82
+ lineage_resource_helper .create_association (
83
+ source_arn = last_arn , dest_arn = new_artifact_arn
84
+ )
80
85
last_arn = new_artifact_arn
81
86
except Exception as e :
82
87
print (e )
@@ -85,12 +90,181 @@ def test_long_graph_visualize(sagemaker_session):
85
90
86
91
try :
87
92
lq = sagemaker .lineage .query .LineageQuery (sagemaker_session )
88
- lq_result = lq .query (start_arns = [long_graph_root_arn ], direction = LineageQueryDirectionEnum .DESCENDANTS )
93
+ lq_result = lq .query (
94
+ start_arns = [long_graph_root_arn ], direction = LineageQueryDirectionEnum .DESCENDANTS
95
+ )
89
96
# max depth = 10 -> graph rendered only has length of ten (in DESCENDANTS direction)
90
97
lq_result .visualize (path = "longGraph.html" )
91
98
except Exception as e :
92
99
print (e )
93
100
lineage_resource_helper .clean_all ()
94
101
assert False
95
102
96
- lineage_resource_helper .clean_all ()
103
+ lineage_resource_helper .clean_all ()
104
+
105
+
106
+ def test_graph_visualize (sagemaker_session ):
107
+ lineage_resource_helper = LineageResourceHelper (sagemaker_session = sagemaker_session )
108
+
109
+ # create lineage data
110
+ # image artifact ------> model artifact(startarn) -> model deploy action -> endpoint context
111
+ # /->
112
+ # dataset artifact -/
113
+ try :
114
+ graph_startarn = lineage_resource_helper .create_artifact (
115
+ artifact_name = name (), artifact_type = "Model"
116
+ )
117
+ image_artifact = lineage_resource_helper .create_artifact (
118
+ artifact_name = name (), artifact_type = "Image"
119
+ )
120
+ lineage_resource_helper .create_association (
121
+ source_arn = image_artifact , dest_arn = graph_startarn , association_type = "ContributedTo"
122
+ )
123
+ dataset_artifact = lineage_resource_helper .create_artifact (
124
+ artifact_name = name (), artifact_type = "DataSet"
125
+ )
126
+ lineage_resource_helper .create_association (
127
+ source_arn = dataset_artifact , dest_arn = graph_startarn , association_type = "AssociatedWith"
128
+ )
129
+ modeldeploy_action = lineage_resource_helper .create_action (
130
+ action_name = name (), action_type = "ModelDeploy"
131
+ )
132
+ lineage_resource_helper .create_association (
133
+ source_arn = graph_startarn , dest_arn = modeldeploy_action , association_type = "ContributedTo"
134
+ )
135
+ endpoint_context = lineage_resource_helper .create_context (
136
+ context_name = name (), context_type = "Endpoint"
137
+ )
138
+ lineage_resource_helper .create_association (
139
+ source_arn = modeldeploy_action ,
140
+ dest_arn = endpoint_context ,
141
+ association_type = "AssociatedWith" ,
142
+ )
143
+ time .sleep (1 )
144
+ except Exception as e :
145
+ print (e )
146
+ lineage_resource_helper .clean_all ()
147
+ assert False
148
+
149
+ # visualize
150
+ try :
151
+ lq = sagemaker .lineage .query .LineageQuery (sagemaker_session )
152
+ lq_result = lq .query (start_arns = [graph_startarn ])
153
+ lq_result .visualize (path = "testGraph.html" )
154
+ except Exception as e :
155
+ print (e )
156
+ lineage_resource_helper .clean_all ()
157
+ assert False
158
+
159
+ # check generated graph info
160
+ try :
161
+ fo = open ("testGraph.html" , "r" )
162
+ lines = fo .readlines ()
163
+ for line in lines :
164
+ if "nodes = " in line :
165
+ node = line
166
+ if "edges = " in line :
167
+ edge = line
168
+
169
+ # extract node data
170
+ start = node .find ("[" )
171
+ end = node .find ("]" )
172
+ res = node [start + 1 : end ].split ("}, " )
173
+ res = [i + "}" for i in res ]
174
+ res [- 1 ] = res [- 1 ][:- 1 ]
175
+ node_dict = [json .loads (i ) for i in res ]
176
+
177
+ # extract edge data
178
+ start = edge .find ("[" )
179
+ end = edge .find ("]" )
180
+ res = edge [start + 1 : end ].split ("}, " )
181
+ res = [i + "}" for i in res ]
182
+ res [- 1 ] = res [- 1 ][:- 1 ]
183
+ edge_dict = [json .loads (i ) for i in res ]
184
+
185
+ # check node number
186
+ assert len (node_dict ) == 5
187
+
188
+ # check startarn
189
+ found_value = next (
190
+ dictionary for dictionary in node_dict if dictionary ["id" ] == graph_startarn
191
+ )
192
+ assert found_value ["color" ] == "#146eb4"
193
+ assert found_value ["label" ] == "Model"
194
+ assert found_value ["shape" ] == "star"
195
+ assert found_value ["title" ] == "Artifact"
196
+
197
+ # check image artifact
198
+ found_value = next (
199
+ dictionary for dictionary in node_dict if dictionary ["id" ] == image_artifact
200
+ )
201
+ assert found_value ["color" ] == "#146eb4"
202
+ assert found_value ["label" ] == "Image"
203
+ assert found_value ["shape" ] == "dot"
204
+ assert found_value ["title" ] == "Artifact"
205
+
206
+ # check dataset artifact
207
+ found_value = next (
208
+ dictionary for dictionary in node_dict if dictionary ["id" ] == dataset_artifact
209
+ )
210
+ assert found_value ["color" ] == "#146eb4"
211
+ assert found_value ["label" ] == "DataSet"
212
+ assert found_value ["shape" ] == "dot"
213
+ assert found_value ["title" ] == "Artifact"
214
+
215
+ # check modeldeploy action
216
+ found_value = next (
217
+ dictionary for dictionary in node_dict if dictionary ["id" ] == modeldeploy_action
218
+ )
219
+ assert found_value ["color" ] == "#88c396"
220
+ assert found_value ["label" ] == "ModelDeploy"
221
+ assert found_value ["shape" ] == "dot"
222
+ assert found_value ["title" ] == "Action"
223
+
224
+ # check endpoint context
225
+ found_value = next (
226
+ dictionary for dictionary in node_dict if dictionary ["id" ] == endpoint_context
227
+ )
228
+ assert found_value ["color" ] == "#ff9900"
229
+ assert found_value ["label" ] == "Endpoint"
230
+ assert found_value ["shape" ] == "dot"
231
+ assert found_value ["title" ] == "Context"
232
+
233
+ # check edge number
234
+ assert len (edge_dict ) == 4
235
+
236
+ # check image_artifact -> model_artifact(startarn) edge
237
+ found_value = next (
238
+ dictionary for dictionary in edge_dict if dictionary ["from" ] == image_artifact
239
+ )
240
+ assert found_value ["to" ] == graph_startarn
241
+ assert found_value ["title" ] == "ContributedTo"
242
+
243
+ # check dataset_artifact -> model_artifact(startarn) edge
244
+ found_value = next (
245
+ dictionary for dictionary in edge_dict if dictionary ["from" ] == dataset_artifact
246
+ )
247
+ assert found_value ["to" ] == graph_startarn
248
+ assert found_value ["title" ] == "AssociatedWith"
249
+
250
+ # check model_artifact(startarn) -> modeldeploy_action edge
251
+ found_value = next (
252
+ dictionary for dictionary in edge_dict if dictionary ["from" ] == graph_startarn
253
+ )
254
+ assert found_value ["to" ] == modeldeploy_action
255
+ assert found_value ["title" ] == "ContributedTo"
256
+
257
+ # check modeldeploy_action -> endpoint_context edge
258
+ found_value = next (
259
+ dictionary for dictionary in edge_dict if dictionary ["from" ] == modeldeploy_action
260
+ )
261
+ assert found_value ["to" ] == endpoint_context
262
+ assert found_value ["title" ] == "AssociatedWith"
263
+
264
+ except Exception as e :
265
+ print (e )
266
+ lineage_resource_helper .clean_all ()
267
+ assert False
268
+
269
+ # clean lineage data
270
+ lineage_resource_helper .clean_all ()
0 commit comments