1#!/usr/bin/env python3
2
3from __future__ import print_function
4
5import os
6import unittest
7
8from vndk_definition_tool import GenericRefs
9
10
11SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
12
13
14class MockELF(object):
15    # pylint: disable=too-few-public-methods
16    def __init__(self, exported_symbols):
17        self.exported_symbols = exported_symbols
18
19
20class MockLib(object):
21    # pylint: disable=too-few-public-methods
22    def __init__(self, path, exported_symbols):
23        self.path = path
24        self.elf = MockELF(exported_symbols)
25
26
27class GenericRefsTest(unittest.TestCase):
28    def setUp(self):
29        self.ref = GenericRefs()
30        self.ref.add('/system/lib/libc.so',
31                     MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
32        self.ref.add('/system/lib/libm.so',
33                     MockELF({'cos', 'sin', 'tan'}))
34        self.ref.add('/system/lib64/libc.so',
35                     MockELF({'fclose', 'fopen', 'fread', 'fwrite'}))
36        self.ref.add('/system/lib64/libm.so',
37                     MockELF({'cos', 'sin', 'tan'}))
38
39
40    def test_create_from_sym_dir(self):
41        input_dir = os.path.join(SCRIPT_DIR, 'testdata', 'test_generic_refs')
42
43        g = GenericRefs.create_from_sym_dir(input_dir)
44        self.assertEqual(4, len(g.refs))
45
46        self.assertIn('/system/lib/libc.so', g.refs)
47        self.assertIn('/system/lib/libm.so', g.refs)
48        self.assertIn('/system/lib64/libc.so', g.refs)
49        self.assertIn('/system/lib64/libm.so', g.refs)
50
51        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
52                         g.refs['/system/lib/libc.so'].exported_symbols)
53        self.assertEqual({'fclose', 'fopen', 'fread', 'fwrite'},
54                         g.refs['/system/lib64/libc.so'].exported_symbols)
55
56        self.assertEqual({'cos', 'sin', 'tan'},
57                         g.refs['/system/lib/libm.so'].exported_symbols)
58        self.assertEqual({'cos', 'sin', 'tan'},
59                         g.refs['/system/lib64/libm.so'].exported_symbols)
60
61
62    def test_classify_lib(self):
63        libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
64        libc_sup = MockLib('/system/lib/libc.so',
65                           {'fclose', 'fopen', 'fread', 'fwrite', 'open'})
66        libc_eq = MockLib('/system/lib/libc.so',
67                          {'fclose', 'fopen', 'fread', 'fwrite'})
68        libfoo = MockLib('/system/lib/libfoo.so', {})
69
70        self.assertEqual(GenericRefs.MODIFIED, self.ref.classify_lib(libc_sub))
71        self.assertEqual(GenericRefs.EXPORT_SUPER_SET,
72                         self.ref.classify_lib(libc_sup))
73        self.assertEqual(GenericRefs.EXPORT_EQUAL,
74                         self.ref.classify_lib(libc_eq))
75        self.assertEqual(GenericRefs.NEW_LIB, self.ref.classify_lib(libfoo))
76
77
78    def test_is_equivalent_lib(self):
79        libc_sub = MockLib('/system/lib/libc.so', {'fclose', 'fopen', 'fread'})
80        libc_sup = MockLib('/system/lib/libc.so',
81                           {'fclose', 'fopen', 'fread', 'fwrite', 'open'})
82        libc_eq = MockLib('/system/lib/libc.so',
83                          {'fclose', 'fopen', 'fread', 'fwrite'})
84
85        self.assertFalse(self.ref.is_equivalent_lib(libc_sub))
86        self.assertFalse(self.ref.is_equivalent_lib(libc_sup))
87
88        self.assertTrue(self.ref.is_equivalent_lib(libc_eq))
89
90
91    def test_has_same_name_lib(self):
92        self.assertTrue(self.ref.has_same_name_lib(
93            MockLib('/vendor/lib/libc.so', {})))
94        self.assertFalse(self.ref.has_same_name_lib(
95            MockLib('/vendor/lib/lib_does_not_exist.so', {})))
96