blob: b10a367c183aa2ff5865fba101bfbbadd2e2cd60 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
# frozen_string_literal: true
require_relative "test_helper"
return if RUBY_PLATFORM !~ /linux/
# TODO: determine why these symbols are incorrect on ppc64le
return if RUBY_PLATFORM =~ /powerpc64le/
module Prism
#
# examine a prism dll or static archive for expected external symbols.
# these tests only work on a linux system right now.
#
class LibrarySymbolsTest < TestCase
def setup
super
@libprism_a = File.expand_path("../../build/libprism.a", __dir__)
@libprism_so = File.expand_path("../../build/libprism.so", __dir__)
@prism_so = File.expand_path("../../lib/prism/prism.so", __dir__)
end
# objdump runner and helpers
def objdump(path)
assert_path_exist(path)
%x(objdump --section=.text --syms #{path}).split("\n")
end
def global_objdump_symbols(path)
objdump(path).select { |line| line[17] == "g" }
end
def hidden_global_objdump_symbols(path)
global_objdump_symbols(path).select { |line| line =~ / \.hidden / }
end
def visible_global_objdump_symbols(path)
global_objdump_symbols(path).reject { |line| line =~ / \.hidden / }
end
# nm runner and helpers
def nm(path)
assert_path_exist(path)
%x(nm #{path}).split("\n")
end
def global_nm_symbols(path)
nm(path).select { |line| line[17] == "T" }
end
def local_nm_symbols(path)
nm(path).select { |line| line[17] == "t" }
end
# dig the symbol name out of each line. works for both `objdump` and `nm` output.
def names(symbol_lines)
symbol_lines.map { |line| line.split(/\s+/).last }
end
#
# static archive - libprism.a
#
def test_libprism_a_contains_nothing_globally_visible
omit("libprism.a is not built") unless File.exist?(@libprism_a)
assert_empty(names(visible_global_objdump_symbols(@libprism_a)))
end
def test_libprism_a_contains_hidden_pm_symbols
omit("libprism.a is not built") unless File.exist?(@libprism_a)
names(hidden_global_objdump_symbols(@libprism_a)).tap do |symbols|
assert_includes(symbols, "pm_parse")
assert_includes(symbols, "pm_version")
end
end
#
# shared object - libprism.so
#
def test_libprism_so_exports_only_the_necessary_functions
omit("libprism.so is not built") unless File.exist?(@libprism_so)
names(global_nm_symbols(@libprism_so)).tap do |symbols|
assert_includes(symbols, "pm_parse")
assert_includes(symbols, "pm_version")
end
names(local_nm_symbols(@libprism_so)).tap do |symbols|
assert_includes(symbols, "pm_encoding_utf_8_isupper_char")
end
# TODO: someone who uses this library needs to finish this test
end
#
# shared object - prism.so
#
def test_prism_so_exports_only_the_C_extension_init_function
omit("prism.so is not built") unless File.exist?(@prism_so)
names(global_nm_symbols(@prism_so)).tap do |symbols|
assert_equal(["Init_prism"], symbols)
end
end
end
end
|