v2 / vlib / v / tests / plugin_interface_shared_library_test.v
81 lines · 78 sloc · 2.11 KB · bc05b2d7d2982cea963d4da3d2786f85dec7382f
Raw
1import dl
2import os
3import rand
4
5const vexe = @VEXE
6
7fn test_interface_from_shared_library_can_call_methods() {
8 if os.user_os() != 'linux' {
9 return
10 }
11 workdir := os.join_path(os.vtmp_dir(), 'v_plugin_interface_shared_${rand.ulid()}')
12 os.mkdir_all(workdir) or { panic(err) }
13 defer {
14 os.rmdir_all(workdir) or {}
15 }
16 lib_src := os.join_path(workdir, 'plugin.v')
17 host_src := os.join_path(workdir, 'host.v')
18 lib_bin := os.join_path(workdir, 'plugin')
19 lib_so := os.join_path(workdir, 'plugin${dl.dl_ext}')
20 lib_path := lib_so.replace('\\', '\\\\')
21 library_code := [
22 'module main',
23 '',
24 'pub interface Plugin {',
25 '\tprint_msg()',
26 '}',
27 '',
28 'pub struct MyPlugin {}',
29 '',
30 'pub fn (p MyPlugin) print_msg() {',
31 "\tprintln('Hello, World!')",
32 '}',
33 '',
34 "@[export: 'create_plugin']",
35 'pub fn create_plugin() Plugin {',
36 '\treturn MyPlugin{}',
37 '}',
38 ].join('\n')
39 host_code := [
40 'module main',
41 '',
42 'import dl.loader',
43 '',
44 'pub interface Plugin {',
45 '\tprint_msg()',
46 '}',
47 '',
48 'type CreatePlugin = fn () Plugin',
49 '',
50 "const lib_path = '${lib_path}'",
51 '',
52 'fn main() {',
53 '\tmut dl_loader := loader.get_or_create_dynamic_lib_loader(',
54 '\t\tkey: lib_path',
55 '\t\tpaths: [lib_path]',
56 '\t) or { panic(err) }',
57 '\tdefer {',
58 '\t\tdl_loader.unregister()',
59 '\t}',
60 "\tcreate_plugin_sym := dl_loader.get_sym('create_plugin') or { panic(err) }",
61 '\tcreate_plugin := CreatePlugin(create_plugin_sym)',
62 '\tplugin := create_plugin()',
63 '\tplugin.print_msg()',
64 '}',
65 ].join('\n')
66 os.write_file(lib_src, library_code) or { panic(err) }
67 os.write_file(host_src, host_code) or { panic(err) }
68 compile_lib_cmd := '${os.quoted_path(vexe)} -d no_backtrace -shared -o ${os.quoted_path(lib_bin)} ${os.quoted_path(lib_src)}'
69 run_cmd(compile_lib_cmd) or { panic(err) }
70 run_host_cmd := '${os.quoted_path(vexe)} -d no_backtrace run ${os.quoted_path(host_src)}'
71 res := run_cmd(run_host_cmd) or { panic(err) }
72 assert res.output.contains('Hello, World!')
73}
74
75fn run_cmd(cmd string) !os.Result {
76 res := os.execute(cmd)
77 if res.exit_code != 0 {
78 return error('command failed:\n${cmd}\n${res.output}')
79 }
80 return res
81}
82