Skip to content

Commit 469cbb8

Browse files
committed
add simple downstream test for running python in from library
1 parent ca2e71c commit 469cbb8

File tree

2 files changed

+152
-2
lines changed

2 files changed

+152
-2
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/control/TopLevelExceptionHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ private void printExc(PException e) {
154154
}
155155

156156
private void handleSystemExit(PException e) {
157-
if (PythonOptions.getOption(context, PythonOptions.PythonInspectFlag) && !getSourceSection().getSource().isInteractive()) {
157+
if (PythonOptions.getOption(context, PythonOptions.InspectFlag) && !getSourceSection().getSource().isInteractive()) {
158158
// Don't exit if -i flag was given and we're not yet running interactively
159159
return;
160160
}

mx.graalpython/mx_graalpython.py

Lines changed: 151 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ def graalpython_gate_runner(args, tasks):
384384
if success not in out.data:
385385
mx.abort('Output from generated SVM image "' + svm_image + '" did not match success pattern:\n' + success)
386386

387+
with Task('GraalPython GraalVM shared-library build', tasks, tags=[GraalPythonTags.downstream, GraalPythonTags.graalvm]) as task:
388+
if task:
389+
run_shared_lib_test()
390+
387391
for name, iterations in sorted(python_test_benchmarks.iteritems()):
388392
with Task('PythonBenchmarksTest:' + name, tasks, tags=[GraalPythonTags.benchmarks]) as task:
389393
if task:
@@ -393,6 +397,151 @@ def graalpython_gate_runner(args, tasks):
393397
mx_gate.add_gate_runner(_suite, graalpython_gate_runner)
394398

395399

400+
def run_shared_lib_test(args=None):
401+
mx.run_mx(
402+
["--dynamicimports", "/substratevm,/vm",
403+
"build", "--force-deprecation-as-warning", "--dependencies",
404+
"GRAAL_MANAGEMENT,POLYGLOT_NATIVE_API_HEADERS,libpolyglot.so.image"],
405+
nonZeroIsFatal=True
406+
)
407+
vmdir = os.path.join(mx.suite("truffle").dir, "..", "vm")
408+
svm_lib_path = os.path.join(vmdir, "mxbuild", "-".join([mx.get_os(), mx.get_arch()]), "libpolyglot.so.image")
409+
fd = name = progname = None
410+
try:
411+
fd, name = tempfile.mkstemp(suffix='.c')
412+
os.write(fd, """
413+
#include "stdio.h"
414+
#include "polyglot_api.h"
415+
416+
#define assert_ok(msg, f) { if (!(f)) { \\
417+
const poly_extended_error_info* error_info; \\
418+
poly_get_last_error_info(isolate_thread, &error_info); \\
419+
fprintf(stderr, "%s\\n", error_info->error_message); \\
420+
return fprintf(stderr, "%s\\n", msg); } } while (0)
421+
422+
poly_isolate global_isolate;
423+
poly_thread isolate_thread;
424+
poly_engine engine;
425+
poly_context context;
426+
427+
static poly_status create_context() {
428+
poly_status status;
429+
430+
if (poly_attach_thread(global_isolate, &isolate_thread)) {
431+
return poly_generic_failure;
432+
}
433+
434+
poly_engine_builder engine_builder;
435+
status = poly_create_engine_builder(isolate_thread, &engine_builder);
436+
if (status != poly_ok) {
437+
return status;
438+
}
439+
status = poly_engine_builder_build(isolate_thread, engine_builder, &engine);
440+
if (status != poly_ok) {
441+
return status;
442+
}
443+
poly_context_builder builder;
444+
status = poly_create_context_builder(isolate_thread, NULL, 0, &builder);
445+
if (status != poly_ok) {
446+
return status;
447+
}
448+
status = poly_context_builder_engine(isolate_thread, builder, engine);
449+
if (status != poly_ok) {
450+
return status;
451+
}
452+
status = poly_context_builder_build(isolate_thread, builder, &context);
453+
if (status != poly_ok) {
454+
return status;
455+
}
456+
457+
poly_destroy_handle(isolate_thread, engine_builder);
458+
poly_destroy_handle(isolate_thread, builder);
459+
460+
return poly_ok;
461+
}
462+
463+
static poly_status tear_down_context() {
464+
poly_status status = poly_context_close(isolate_thread, context, true);
465+
if (status != poly_ok) {
466+
return status;
467+
}
468+
469+
status = poly_destroy_handle(isolate_thread, context);
470+
if (status != poly_ok) {
471+
return status;
472+
}
473+
474+
status = poly_engine_close(isolate_thread, engine, true);
475+
if (status != poly_ok) {
476+
return status;
477+
}
478+
479+
status = poly_destroy_handle(isolate_thread, engine);
480+
if (status != poly_ok) {
481+
return status;
482+
}
483+
484+
if (poly_detach_thread(isolate_thread)) {
485+
return poly_ok;
486+
}
487+
488+
return poly_ok;
489+
}
490+
491+
static int test_basic_python_function() {
492+
assert_ok("Context creation failed.", create_context() == poly_ok);
493+
494+
poly_value func;
495+
assert_ok("function eval failed", poly_context_eval(isolate_thread, context, "python", "test_func", "def test_func(x):\\n return x * x\\ntest_func", &func) == poly_ok);
496+
int32_t arg_value = 42;
497+
poly_value primitive_object;
498+
assert_ok("create argument failed", poly_create_int32(isolate_thread, context, arg_value, &primitive_object) == poly_ok);
499+
poly_value arg[1] = {primitive_object};
500+
poly_value value;
501+
assert_ok("invocation was unsuccessful", poly_value_execute(isolate_thread, func, arg, 1, &value) == poly_ok);
502+
503+
int32_t result_value;
504+
poly_value_as_int32(isolate_thread, value, &result_value);
505+
506+
assert_ok("primitive free failed", poly_destroy_handle(isolate_thread, primitive_object) == poly_ok);
507+
assert_ok("value free failed", poly_destroy_handle(isolate_thread, value) == poly_ok);
508+
assert_ok("value computation was incorrect", result_value == 42 * 42);
509+
assert_ok("func free failed", poly_destroy_handle(isolate_thread, func) == poly_ok);
510+
assert_ok("Context tear down failed.", tear_down_context() == poly_ok);
511+
return 0;
512+
}
513+
514+
int32_t main(int32_t argc, char **argv) {
515+
poly_isolate_params isolate_params = {};
516+
if (poly_create_isolate(&isolate_params, &global_isolate)) {
517+
return 1;
518+
}
519+
if (test_basic_python_function()) {
520+
return 0;
521+
} else {
522+
return 1;
523+
}
524+
}
525+
""")
526+
os.close(fd)
527+
progname = tempfile.mktemp()
528+
mx.run(["cc", "-I%s" % svm_lib_path, "-L%s" % svm_lib_path, name, "-o%s" % progname, "-lpolyglot"], nonZeroIsFatal=True)
529+
mx.run([progname], env={"LD_LIBRARY_PATH": svm_lib_path})
530+
finally:
531+
try:
532+
os.unlink(progname)
533+
except:
534+
pass
535+
try:
536+
os.close(fd)
537+
except:
538+
pass
539+
try:
540+
os.unlink(name)
541+
except:
542+
pass
543+
544+
396545
class ArchiveProject(mx.ArchivableProject):
397546
def __init__(self, suite, name, deps, workingSets, theLicense, **args):
398547
super(ArchiveProject, self).__init__(suite, name, deps, workingSets, theLicense)
@@ -595,5 +744,6 @@ def python_checkcopyrights(args):
595744
'delete-graalpython-if-testdownstream': [delete_self_if_testdownstream, ''],
596745
'python-checkcopyrights': [python_checkcopyrights, 'Make sure code files have copyright notices'],
597746
'punittest': [punittest, ''],
598-
'nativebuild': [nativebuild, '']
747+
'nativebuild': [nativebuild, ''],
748+
'python-so-test': [run_shared_lib_test, ''],
599749
})

0 commit comments

Comments
 (0)