• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1""" Test suite for the code in msilib """
2import os
3import unittest
4from test.support.import_helper import import_module
5from test.support.os_helper import TESTFN, unlink
6msilib = import_module('msilib')
7import msilib.schema
8
9
10def init_database():
11    path = TESTFN + '.msi'
12    db = msilib.init_database(
13        path,
14        msilib.schema,
15        'Python Tests',
16        'product_code',
17        '1.0',
18        'PSF',
19    )
20    return db, path
21
22
23class MsiDatabaseTestCase(unittest.TestCase):
24
25    def test_view_fetch_returns_none(self):
26        db, db_path = init_database()
27        properties = []
28        view = db.OpenView('SELECT Property, Value FROM Property')
29        view.Execute(None)
30        while True:
31            record = view.Fetch()
32            if record is None:
33                break
34            properties.append(record.GetString(1))
35        view.Close()
36        db.Close()
37        self.assertEqual(
38            properties,
39            [
40                'ProductName', 'ProductCode', 'ProductVersion',
41                'Manufacturer', 'ProductLanguage',
42            ]
43        )
44        self.addCleanup(unlink, db_path)
45
46    def test_view_non_ascii(self):
47        db, db_path = init_database()
48        view = db.OpenView("SELECT 'ß-розпад' FROM Property")
49        view.Execute(None)
50        record = view.Fetch()
51        self.assertEqual(record.GetString(1), 'ß-розпад')
52        view.Close()
53        db.Close()
54        self.addCleanup(unlink, db_path)
55
56    def test_summaryinfo_getproperty_issue1104(self):
57        db, db_path = init_database()
58        try:
59            sum_info = db.GetSummaryInformation(99)
60            title = sum_info.GetProperty(msilib.PID_TITLE)
61            self.assertEqual(title, b"Installation Database")
62
63            sum_info.SetProperty(msilib.PID_TITLE, "a" * 999)
64            title = sum_info.GetProperty(msilib.PID_TITLE)
65            self.assertEqual(title, b"a" * 999)
66
67            sum_info.SetProperty(msilib.PID_TITLE, "a" * 1000)
68            title = sum_info.GetProperty(msilib.PID_TITLE)
69            self.assertEqual(title, b"a" * 1000)
70
71            sum_info.SetProperty(msilib.PID_TITLE, "a" * 1001)
72            title = sum_info.GetProperty(msilib.PID_TITLE)
73            self.assertEqual(title, b"a" * 1001)
74        finally:
75            db = None
76            sum_info = None
77            os.unlink(db_path)
78
79    def test_database_open_failed(self):
80        with self.assertRaises(msilib.MSIError) as cm:
81            msilib.OpenDatabase('non-existent.msi', msilib.MSIDBOPEN_READONLY)
82        self.assertEqual(str(cm.exception), 'open failed')
83
84    def test_database_create_failed(self):
85        db_path = os.path.join(TESTFN, 'test.msi')
86        with self.assertRaises(msilib.MSIError) as cm:
87            msilib.OpenDatabase(db_path, msilib.MSIDBOPEN_CREATE)
88        self.assertEqual(str(cm.exception), 'create failed')
89
90    def test_get_property_vt_empty(self):
91        db, db_path = init_database()
92        summary = db.GetSummaryInformation(0)
93        self.assertIsNone(summary.GetProperty(msilib.PID_SECURITY))
94        db.Close()
95        self.addCleanup(unlink, db_path)
96
97    def test_directory_start_component_keyfile(self):
98        db, db_path = init_database()
99        self.addCleanup(unlink, db_path)
100        self.addCleanup(db.Close)
101        self.addCleanup(msilib._directories.clear)
102        feature = msilib.Feature(db, 0, 'Feature', 'A feature', 'Python')
103        cab = msilib.CAB('CAB')
104        dir = msilib.Directory(db, cab, None, TESTFN, 'TARGETDIR',
105                               'SourceDir', 0)
106        dir.start_component(None, feature, None, 'keyfile')
107
108    def test_getproperty_uninitialized_var(self):
109        db, db_path = init_database()
110        self.addCleanup(unlink, db_path)
111        self.addCleanup(db.Close)
112        si = db.GetSummaryInformation(0)
113        with self.assertRaises(msilib.MSIError):
114            si.GetProperty(-1)
115
116    def test_FCICreate(self):
117        filepath = TESTFN + '.txt'
118        cabpath = TESTFN + '.cab'
119        self.addCleanup(unlink, filepath)
120        with open(filepath, 'wb'):
121            pass
122        self.addCleanup(unlink, cabpath)
123        msilib.FCICreate(cabpath, [(filepath, 'test.txt')])
124        self.assertTrue(os.path.isfile(cabpath))
125
126
127class Test_make_id(unittest.TestCase):
128    #http://msdn.microsoft.com/en-us/library/aa369212(v=vs.85).aspx
129    """The Identifier data type is a text string. Identifiers may contain the
130    ASCII characters A-Z (a-z), digits, underscores (_), or periods (.).
131    However, every identifier must begin with either a letter or an
132    underscore.
133    """
134
135    def test_is_no_change_required(self):
136        self.assertEqual(
137            msilib.make_id("short"), "short")
138        self.assertEqual(
139            msilib.make_id("nochangerequired"), "nochangerequired")
140        self.assertEqual(
141            msilib.make_id("one.dot"), "one.dot")
142        self.assertEqual(
143            msilib.make_id("_"), "_")
144        self.assertEqual(
145            msilib.make_id("a"), "a")
146        #self.assertEqual(
147        #    msilib.make_id(""), "")
148
149    def test_invalid_first_char(self):
150        self.assertEqual(
151            msilib.make_id("9.short"), "_9.short")
152        self.assertEqual(
153            msilib.make_id(".short"), "_.short")
154
155    def test_invalid_any_char(self):
156        self.assertEqual(
157            msilib.make_id(".s\x82ort"), "_.s_ort")
158        self.assertEqual(
159            msilib.make_id(".s\x82o?*+rt"), "_.s_o___rt")
160
161
162if __name__ == '__main__':
163    unittest.main()
164