diff options
author | Raphaël Hertzog <hertzog@debian.org> | 2010-01-11 14:46:03 +0100 |
---|---|---|
committer | Raphaël Hertzog <hertzog@debian.org> | 2010-01-11 19:24:21 +0100 |
commit | da19cee896d19264a1c733a93646a37ffb4d1fd0 (patch) | |
tree | dc511931e667985a159872a906958096aa444de5 /scripts/t | |
parent | fa6739b81239f053243014dbbba18c2328cd388c (diff) | |
download | dpkg-da19cee896d19264a1c733a93646a37ffb4d1fd0.tar.gz |
scripts/t/200_Dpkg_Shlibs.t: extend test suite to cover symbol patterns functionality
Signed-off-by: Modestas Vainius <modax@debian.org>
Signed-off-by: Raphaël Hertzog <hertzog@debian.org>
Diffstat (limited to 'scripts/t')
-rw-r--r-- | scripts/t/200_Dpkg_Shlibs.t | 146 | ||||
-rw-r--r-- | scripts/t/200_Dpkg_Shlibs/patterns.cpp | 98 | ||||
-rw-r--r-- | scripts/t/200_Dpkg_Shlibs/patterns.map | 4 | ||||
-rw-r--r-- | scripts/t/200_Dpkg_Shlibs/patterns.symbols | 45 |
4 files changed, 291 insertions, 2 deletions
diff --git a/scripts/t/200_Dpkg_Shlibs.t b/scripts/t/200_Dpkg_Shlibs.t index bd2e9a352..327d6854e 100644 --- a/scripts/t/200_Dpkg_Shlibs.t +++ b/scripts/t/200_Dpkg_Shlibs.t @@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -use Test::More tests => 65; +use Test::More tests => 97; use Cwd; use IO::String; @@ -135,7 +135,7 @@ ok( $sym_file->get_new_symbols($sym_file_old), 'has new symbols' ); ok( $sym_file_old->get_lost_symbols($sym_file), 'has lost symbols' ); is( $sym_file_old->lookup_symbol('__bss_start@Base', ['libc.so.6']), - undef, 'internal symbols are blacklisted'); + undef, 'internal symbols are blacklisted' ); $sym = $sym_file->lookup_symbol('_errno@GLIBC_2.0', ['libc.so.6'], 1); isa_ok($sym, 'Dpkg::Shlibs::Symbol'); @@ -409,3 +409,145 @@ $tmp[1]->{teststruct}{foo} = 3; $tmp[1]->{testfield} = 3; is ( $sym->{teststruct}{foo}, 2, 'struct changed via sclone()' ); is ( $sym->{testfield}, 1, 'original field not changed' ); + +############ Test symbol patterns ########### +sub load_patterns_obj { + $obj = Dpkg::Shlibs::Objdump::Object->new(); + open $objdump, '<', "$tmpdir/objdump.patterns" + or die "$tmpdir/objdump.patterns: $!"; + $obj->_parse($objdump); + close $objdump; + return $obj; +} + +sub load_patterns_symbols { + $sym_file = Dpkg::Shlibs::SymbolFile->new(file => "$datadir/patterns.symbols"); + return $sym_file; +} + +load_patterns_obj(); +$sym_file_dup = load_patterns_symbols(); +load_patterns_symbols(); + +save_load_test($sym_file, 'save -> load test of patterns template', template_mode => 1); + +isnt( $sym_file->get_soname_patterns('libpatterns.so.1') , 0, + "patterns.symbols has patterns" ); + +$sym_file->merge_symbols($obj, '100.MISSING'); + +@tmp = map { $_->get_symbolname() } $sym_file->get_lost_symbols($sym_file_dup); +is_deeply( \@tmp, [], "no LOST symbols if all patterns matched." ); +@tmp = map { $_->get_symbolname() } $sym_file->get_new_symbols($sym_file_dup); +is_deeply( \@tmp, [], "no NEW symbols if all patterns matched." ); + +# Pattern resolution order: aliases (c++, wildcard), generic +$sym = $sym_file->lookup_symbol('VERSION_1@VERSION_1',['libpatterns.so.1']); +is ( $sym->{minver}, '1', "specific VERSION_1 symbol" ); + +$sym = $sym_file->lookup_symbol('_ZN3NSB8Wildcard16wildcard_method1Ev@VERSION_1', ['libpatterns.so.1']); +is ( $sym->{minver}, '1.method1', "specific symbol prefered over pattern" ); + +$sym = $sym_file->lookup_symbol('_ZN3NSB8Wildcard16wildcard_method2Ev@VERSION_1', ['libpatterns.so.1']); +is ( $sym->{minver}, '1.method2', "c++ alias pattern preferred over generic pattern" ); +is ( $sym->get_pattern()->get_symbolname(), 'NSB::Wildcard::wildcard_method2()@VERSION_1' ); + +$sym = $sym_file->lookup_symbol('_ZN3NSB8WildcardD1Ev@VERSION_1', ['libpatterns.so.1']); +is ( $sym->{minver}, '1.generic', 'generic (wildcard & c++) pattern covers the rest (destructor)' ); +is ( $sym->get_pattern()->get_symbolname(), '*@VERSION_1' ); + +# Lookup private pattern +my @private_symnames = sort qw( + _ZN3NSA6ClassA7Private11privmethod1Ei@Base + _ZN3NSA6ClassA7Private11privmethod2Ei@Base + _ZN3NSA6ClassA7PrivateC1Ev@Base + _ZN3NSA6ClassA7PrivateC2Ev@Base + _ZN3NSA6ClassA7PrivateD0Ev@Base + _ZN3NSA6ClassA7PrivateD1Ev@Base + _ZN3NSA6ClassA7PrivateD2Ev@Base + _ZTIN3NSA6ClassA7PrivateE@Base + _ZTSN3NSA6ClassA7PrivateE@Base + _ZTVN3NSA6ClassA7PrivateE@Base +); +$sym = $sym_file->create_symbol('(c++|regex|optional)NSA::ClassA::Private(::.*)?@Base 1'); +$pat = $sym_file->lookup_pattern($sym, ['libpatterns.so.1']); +isnt( $pat, undef, 'pattern for private class has been found' ); +is_deeply( [ sort map { $_->get_symbolname() } $pat->get_pattern_matches() ], + \@private_symnames, "private pattern matched expected symbols" ); +ok( ($pat->get_pattern_matches())[0]->is_optional(), + "private symbol is optional like its pattern" ); +ok( $sym_file->lookup_symbol(($pat->get_pattern_matches())[0]->get_symbolname(), ['libpatterns.so.1']), + "lookup_symbol() finds symbols matched by pattern (after merge)"), + +# Get rid of a private symbol, it should not be lost +delete $obj->{dynsyms}{$private_symnames[0]}; +load_patterns_symbols(); +$sym_file->merge_symbols($obj, '100.MISSING'); + +$pat = $sym_file->lookup_pattern($sym, ['libpatterns.so.1']); +@tmp = map { $_->get_symbolname() } $sym_file->get_lost_symbols($sym_file_dup); +is_deeply( \@tmp, [], "no LOST symbols when got rid of patterned optional symbol." ); +ok( ! $pat->{deprecated} , "there are still matches, pattern is not deprecated." ); + +# Get rid of all private symbols, the pattern should be deprecated. +foreach my $tmp (@private_symnames) { + delete $obj->{dynsyms}{$tmp}; +} +load_patterns_symbols(); +$sym_file->merge_symbols($obj, '100.MISSING'); + +$pat = $sym_file->lookup_pattern($sym, ['libpatterns.so.1'], 1); +@tmp = $sym_file->get_lost_symbols($sym_file_dup); +is_deeply( \@tmp, [ ], + "All private symbols gone, but pattern is not LOST because it is optional." ); +is( $pat->{deprecated}, '100.MISSING', + "All private symbols gone - pattern deprecated." ); + +# Internal symbols. All covered by the pattern? +@tmp = grep { $_->get_symbolname() =~ /Internal/ } values %{$sym_file->{objects}{'libpatterns.so.1'}{syms}}; +$sym = $sym_file->create_symbol('(regex|c++)^_Z(T[ISV])?N3NSA6ClassA8Internal.*@Base$ 1.internal'), +$pat = $sym_file->lookup_pattern($sym, ['libpatterns.so.1']); +is_deeply ([ sort $pat->get_pattern_matches() ], [ sort @tmp ], + "Pattern covers all internal symbols"); +is ( $tmp[0]->{minver}, '1.internal' ); + +# Delete matches of the non-optional pattern +$sym = $sym_file->create_symbol('(c++)"non-virtual thunk to NSB::ClassD::generate_vt(char const*) const@Base" 1'); +$pat = $sym_file->lookup_pattern($sym, ['libpatterns.so.1']); +isnt( $pat, undef, 'lookup_pattern() finds alias-based pattern' ); + +is( scalar($pat->get_pattern_matches()), 2, "two matches for the generate_vt pattern" ); +foreach my $tmp ($pat->get_pattern_matches()) { + delete $obj->{dynsyms}{$tmp->get_symbolname()}; +} +load_patterns_symbols(); +$sym_file->merge_symbols($obj, '100.MISSING'); + +$pat = $sym_file->lookup_pattern($sym, ['libpatterns.so.1'], 1); +@tmp = map { $sym_file->lookup_pattern($_, ['libpatterns.so.1'], 1) } + $sym_file->get_lost_symbols($sym_file_dup); +is_deeply( \@tmp, [ $pat ], "No matches - generate_vt() pattern is LOST." ); +is( $pat->{deprecated}, '100.MISSING', + "No matches - generate_vt() pattern is deprecated." ); + +# Pattern undeprecation when matches are discovered +load_patterns_obj(); +load_patterns_symbols(); + +$pat = $sym_file_dup->lookup_pattern($sym, ['libpatterns.so.1']); +$pat->{deprecated} = '0.1-1'; +$pat = $sym_file->lookup_pattern($sym, ['libpatterns.so.1']); +$pat->{deprecated} = '0.1-1'; + +$sym_file->merge_symbols($obj, '100.FOUND'); +ok( ! $pat->{deprecated}, + "Previously deprecated pattern with matches got undeprecated" ); +is( $pat->{minver}, '100.FOUND', + "Previously deprecated pattern with matches got minver bumped" ); +@tmp = map { $_->get_symbolspec(1) } $sym_file->get_new_symbols($sym_file_dup); +is_deeply( \@tmp, [ $pat->get_symbolspec(1) ], + "Previously deprecated pattern with matches is NEW. Matches themselves are not NEW." ); +foreach my $sym ($pat->get_pattern_matches()) { + ok( ! $sym->{deprecated}, $sym->get_symbolname().": not deprecated" ); + is( $sym->{minver}, '100.FOUND', $sym->get_symbolname().": version bumped" ); +} diff --git a/scripts/t/200_Dpkg_Shlibs/patterns.cpp b/scripts/t/200_Dpkg_Shlibs/patterns.cpp new file mode 100644 index 000000000..ae4e74c17 --- /dev/null +++ b/scripts/t/200_Dpkg_Shlibs/patterns.cpp @@ -0,0 +1,98 @@ +#define EXPORT(x) x {} + +namespace NSA +{ + class ClassA + { + private: + class Private + { + public: + Private(); + virtual ~Private(); + void privmethod1(int); + void privmethod2(int); + }; + Private* p; + class Internal + { + public: + Internal(); + virtual ~Internal(); + void internal_method1(char); + void internal_method2(char); + }; + Internal* i; + public: + ClassA(); + virtual ~ClassA(); + virtual void generate_vt(const char*) const; + }; + + EXPORT(ClassA::Private::Private()); + EXPORT(ClassA::Private::~Private()); + EXPORT(void ClassA::Private::privmethod1(int)); + EXPORT(void ClassA::Private::privmethod2(int)); + + EXPORT(ClassA::Internal::Internal()); + EXPORT(ClassA::Internal::~Internal()); + EXPORT(void ClassA::Internal::internal_method1(char)); + EXPORT(void ClassA::Internal::internal_method2(char)); + + EXPORT(ClassA::ClassA()); + EXPORT(ClassA::~ClassA()); + EXPORT(void ClassA::generate_vt(const char*) const); +}; + +class ClassB +{ + public: + ClassB(); + virtual ~ClassB(); + virtual void generate_vt(const char*) const; +}; + +EXPORT(ClassB::ClassB()); +EXPORT(ClassB::~ClassB()); +EXPORT(void ClassB::generate_vt(const char*) const); + +class ClassC +{ + public: + ClassC(); + virtual ~ClassC(); + virtual void generate_vt(const char*) const; +}; + +EXPORT(ClassC::ClassC()); +EXPORT(ClassC::~ClassC()); +EXPORT(void ClassC::generate_vt(const char*) const); + +namespace NSB +{ + class ClassD : public NSA::ClassA, public ClassB, public ClassC + { + public: + ClassD(); + virtual ~ClassD(); + virtual void generate_vt(const char*) const; + }; + + EXPORT(ClassD::ClassD()); + EXPORT(ClassD::~ClassD()); + EXPORT(void ClassD::generate_vt(const char*) const); + + class Wildcard { + public: + Wildcard(); + ~Wildcard(); + + void wildcard_method1(); + void wildcard_method2(); + }; + + EXPORT(Wildcard::Wildcard()); + EXPORT(Wildcard::~Wildcard()); + EXPORT(void Wildcard::wildcard_method1()); + EXPORT(void Wildcard::wildcard_method2()); +}; diff --git a/scripts/t/200_Dpkg_Shlibs/patterns.map b/scripts/t/200_Dpkg_Shlibs/patterns.map new file mode 100644 index 000000000..15ed95008 --- /dev/null +++ b/scripts/t/200_Dpkg_Shlibs/patterns.map @@ -0,0 +1,4 @@ +VERSION_1 { + global: + _ZN3NSB8Wildcard*; +}; diff --git a/scripts/t/200_Dpkg_Shlibs/patterns.symbols b/scripts/t/200_Dpkg_Shlibs/patterns.symbols new file mode 100644 index 000000000..d8ebe8989 --- /dev/null +++ b/scripts/t/200_Dpkg_Shlibs/patterns.symbols @@ -0,0 +1,45 @@ +libpatterns.so.1 libpatterns1 #MINVER# + (c++)*@VERSION_1 1.generic + (c++|regex|optional)NSA::ClassA::Private(::.*)?@Base 1.private + (c++)NSB::Wildcard::wildcard_method2()@VERSION_1 1.method2 + VERSION_1@VERSION_1 1 + (regex|c++)^_Z(T[ISV])?N3NSA6ClassA8Internal.*@Base$ 1.internal + _ZN3NSA6ClassAC1Ev@Base 1 + _ZN3NSA6ClassAC2Ev@Base 1 + _ZN3NSA6ClassAD0Ev@Base 1 + _ZN3NSA6ClassAD1Ev@Base 1 + _ZN3NSA6ClassAD2Ev@Base 1 + _ZN3NSB6ClassDC1Ev@Base 1 + _ZN3NSB6ClassDC2Ev@Base 1 + _ZN3NSB6ClassDD0Ev@Base 1 + _ZN3NSB6ClassDD1Ev@Base 1 + _ZN3NSB6ClassDD2Ev@Base 1 + _ZN3NSB8Wildcard16wildcard_method1Ev@VERSION_1 1.method1 + _ZN6ClassBC1Ev@Base 1 + _ZN6ClassBC2Ev@Base 1 + _ZN6ClassBD0Ev@Base 1 + _ZN6ClassBD1Ev@Base 1 + _ZN6ClassBD2Ev@Base 1 + _ZN6ClassCC1Ev@Base 1 + _ZN6ClassCC2Ev@Base 1 + _ZN6ClassCD0Ev@Base 1 + _ZN6ClassCD1Ev@Base 1 + _ZN6ClassCD2Ev@Base 1 + _ZNK3NSA6ClassA11generate_vtEPKc@Base 1 + _ZNK3NSB6ClassD11generate_vtEPKc@Base 1 + _ZNK6ClassB11generate_vtEPKc@Base 1 + _ZNK6ClassC11generate_vtEPKc@Base 1 + _ZTI6ClassB@Base 1 + _ZTI6ClassC@Base 1 + _ZTIN3NSA6ClassAE@Base 1 + _ZTIN3NSB6ClassDE@Base 1 + _ZTS6ClassB@Base 1 + _ZTS6ClassC@Base 1 + _ZTSN3NSA6ClassAE@Base 1 + _ZTSN3NSB6ClassDE@Base 1 + _ZTV6ClassB@Base 1 + _ZTV6ClassC@Base 1 + _ZTVN3NSA6ClassAE@Base 1 + _ZTVN3NSB6ClassDE@Base 1 + (c++)"non-virtual thunk to NSB::ClassD::generate_vt(char const*) const@Base" 1 + (c++)"non-virtual thunk to NSB::ClassD::~ClassD()@Base" 1 |