1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
2 // Copyright (c) Lawrence Livermore National Security, LLC and other Ascent
3 // Project developers. See top-level LICENSE AND COPYRIGHT files for dates and
4 // other details. No copyright assignment is required to contribute to Ascent.
5 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
6
7 //-----------------------------------------------------------------------------
8 ///
9 /// file: t_flow_python_script_filter.cpp
10 ///
11 //-----------------------------------------------------------------------------
12
13 #include "gtest/gtest.h"
14
15 #include <flow.hpp>
16 #include <flow_python_script_filter.hpp>
17
18 #include <iostream>
19 #include <math.h>
20
21 #include "t_config.hpp"
22 #include "t_utils.hpp"
23
24
25
26 using namespace std;
27 using namespace conduit;
28 using namespace ascent;
29 using namespace flow;
30
31
32 //-----------------------------------------------------------------------------
33 class SrcFilter: public Filter
34 {
35 public:
SrcFilter()36 SrcFilter()
37 : Filter()
38 {}
39
~SrcFilter()40 virtual ~SrcFilter()
41 {}
42
43
declare_interface(Node & i)44 virtual void declare_interface(Node &i)
45 {
46 i["type_name"] = "src";
47 i["output_port"] = "true";
48 i["port_names"] = DataType::empty();
49 i["default_params"]["value"].set((int)0);
50 }
51
52
execute()53 virtual void execute()
54 {
55 int val = params()["value"].value();
56
57 // set output
58 Node *res = new Node();
59 res->set(val);
60 set_output<Node>(res);
61
62 // the registry will take care of deleting the data
63 // when all consuming filters have executed.
64 ASCENT_INFO("SrcFilter::execute: " << name()
65 << " source filter result = "
66 << res->to_json());
67 }
68 };
69
70
71 //-----------------------------------------------------------------------------
TEST(flow_python_script_filter,simple_execute)72 TEST(flow_python_script_filter, simple_execute)
73 {
74 flow::filters::register_builtin();
75
76 Workspace::register_filter_type<SrcFilter>();
77
78 Workspace w;
79
80 Node src_params;
81 src_params["value"] = 21;
82
83 w.graph().add_filter("src","v",src_params);
84
85 Node py_params;
86 py_params["source"] = "val = flow_input().value() * 2\n"
87 "print(val)\n"
88 "assert val == 42\n"
89 "flow_set_output(val)\n";
90
91 w.graph().add_filter("python_script","py", py_params);
92
93 // // src, dest, port
94 w.graph().connect("v","py","in");
95 //
96 w.print();
97 //
98 w.execute();
99
100 Workspace::clear_supported_filter_types();
101 }
102
103
104
105 //-----------------------------------------------------------------------------
TEST(flow_python_script_filter,simple_execute_mock_file_source)106 TEST(flow_python_script_filter, simple_execute_mock_file_source)
107 {
108 flow::filters::register_builtin();
109
110 Workspace::register_filter_type<SrcFilter>();
111
112 Workspace w;
113
114 Node src_params;
115 src_params["value"] = 21;
116
117 w.graph().add_filter("src","v",src_params);
118
119 Node py_params;
120 py_params["source"] = "val = flow_input().value() * 2\n"
121 "print(val)\n"
122 "assert val == 42\n"
123 "print(__file__)\n"
124 "assert __file__ == 'my_mock_script.py'\n"
125 "flow_set_output(val)\n";
126
127 py_params["source_file"] = "my_mock_script.py";
128 w.graph().add_filter("python_script","py", py_params);
129
130 // // src, dest, port
131 w.graph().connect("v","py","in");
132 //
133 w.print();
134 //
135 w.execute();
136
137 Workspace::clear_supported_filter_types();
138 }
139 //-----------------------------------------------------------------------------
TEST(flow_python_script_filter,simple_execute_echo)140 TEST(flow_python_script_filter, simple_execute_echo)
141 {
142 flow::filters::register_builtin();
143
144 Workspace::register_filter_type<SrcFilter>();
145
146 Workspace w;
147
148 Node src_params;
149 src_params["value"] = 21;
150
151 w.graph().add_filter("src","v",src_params);
152
153 Node py_params;
154 py_params["source"] = "val = flow_input().value() * 2\n"
155 "print(val)\n"
156 "assert val == 42\n"
157 "flow_set_output(val)\n";
158 py_params["echo"] = "true";
159
160 w.graph().add_filter("python_script","py", py_params);
161
162 // // src, dest, port
163 w.graph().connect("v","py","in");
164 //
165 w.print();
166 //
167 w.execute();
168
169 Workspace::clear_supported_filter_types();
170 }
171
172 //-----------------------------------------------------------------------------
TEST(flow_python_script_filter,simple_execute_file)173 TEST(flow_python_script_filter, simple_execute_file)
174 {
175 flow::filters::register_builtin();
176
177 Workspace::register_filter_type<SrcFilter>();
178
179 Workspace w;
180
181 Node src_params;
182 src_params["value"] = 21;
183
184 string output_path = prepare_output_dir();
185
186 string script_fname = conduit::utils::join_file_path(output_path,
187 "tout_test_flow_filter_script.py");
188
189 ofstream ofs;
190 ofs.open(script_fname);
191 ofs << "val = flow_input().value() * 2\n"
192 << "print(val)\n"
193 << "assert val == 42\n"
194 << "print(__file__)\n"
195 << "assert __file__ == '" << script_fname << "'\n"
196 << "flow_set_output(val)\n";
197 ofs.close();
198
199
200 w.graph().add_filter("src","v",src_params);
201
202 Node py_params;
203 py_params["interpreter/reset"] = "true";
204 py_params["file"] = script_fname;
205
206 w.graph().add_filter("python_script","py", py_params);
207
208 // // src, dest, port
209 w.graph().connect("v","py","in");
210 //
211 w.print();
212 //
213 w.execute();
214 //
215 w.print();
216 Workspace::clear_supported_filter_types();
217 }
218
219 //-----------------------------------------------------------------------------
TEST(flow_python_script_filter,simple_execute_bad_file)220 TEST(flow_python_script_filter, simple_execute_bad_file)
221 {
222 flow::filters::register_builtin();
223
224 Workspace::register_filter_type<SrcFilter>();
225
226 Workspace w;
227
228 Node src_params;
229 src_params["value"] = 21;
230
231 string output_path = prepare_output_dir();
232
233 string script_fname = "/blargh/path/to/bad/script.py";
234
235 w.graph().add_filter("src","v",src_params);
236
237 Node py_params;
238
239 py_params["file"] = script_fname;
240
241 w.graph().add_filter("python_script","py", py_params);
242
243 // // src, dest, port
244 w.graph().connect("v","py","in");
245 //
246 w.print();
247
248 EXPECT_THROW(w.execute(),
249 conduit::Error);
250
251 Workspace::clear_supported_filter_types();
252 }
253
254
255 //-----------------------------------------------------------------------------
TEST(flow_python_script_filter,exe_override_interface_func_names)256 TEST(flow_python_script_filter, exe_override_interface_func_names)
257 {
258 flow::filters::register_builtin();
259
260 Workspace::register_filter_type<SrcFilter>();
261
262 Workspace w;
263
264 Node src_params;
265 src_params["value"] = 21;
266
267 w.graph().add_filter("src","v",src_params);
268
269 Node py_params;
270 // test customized input() and set_output() names
271 py_params["interface/input"] = "give_me_data";
272 py_params["interface/set_output"] = "here_is_some_data";
273 py_params["interpreter/reset"] = "true";
274 py_params["source"] = "val = give_me_data().value() * 2\nprint(val)\nhere_is_some_data(val)";
275
276 py_params["source"] = "val = give_me_data().value() * 2\n"
277 "print(val)\n"
278 "here_is_some_data(val)";
279
280 w.graph().add_filter("python_script","py", py_params);
281
282 // // src, dest, port
283 w.graph().connect("v","py","in");
284
285 w.print();
286 w.execute();
287
288 Workspace::clear_supported_filter_types();
289 }
290
291
292 //-----------------------------------------------------------------------------
TEST(flow_python_script_filter,exe_override_interface_mod_and_func_names)293 TEST(flow_python_script_filter, exe_override_interface_mod_and_func_names)
294 {
295 flow::filters::register_builtin();
296
297 Workspace::register_filter_type<SrcFilter>();
298
299 Workspace w;
300
301 Node src_params;
302 src_params["value"] = 42;
303
304 w.graph().add_filter("src","v",src_params);
305
306 // we will change the name of the binding module to be called mine
307
308 std::ostringstream py_src_oss;
309 py_src_oss << "import mine\n"
310 << "val = mine.give_me_data().value() * 2\n"
311 << "print(val)\n"
312 << "mine.here_is_some_data(val)\n";
313
314 Node py_params;
315 // test customized mod name, and input() and set_output() names
316 py_params["interface/module"] = "mine";
317 py_params["interface/input"] = "give_me_data";
318 py_params["interface/set_output"] = "here_is_some_data";
319 py_params["interpreter/reset"] = "true";
320 py_params["source"] = py_src_oss.str();
321
322
323 w.graph().add_filter("python_script","py", py_params);
324
325 // // src, dest, port
326 w.graph().connect("v","py","in");
327
328 w.print();
329 w.execute();
330
331 Workspace::clear_supported_filter_types();
332 }
333
334
335
336
337
338
339
340