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