3 # http://www.drdobbs.com/testing/unit-testing-with-python/240165163
16 from binascii import unhexlify
17 from distutils.version import LooseVersion
19 localmodule = os.path.realpath(
20 os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..'))
21 print('localmodule: ' + localmodule)
22 if localmodule not in sys.path:
23 sys.path.insert(0, localmodule)
25 import fdroidserver.common
26 import fdroidserver.exception
27 import fdroidserver.metadata
28 import fdroidserver.update
29 from fdroidserver.common import FDroidPopen
32 class UpdateTest(unittest.TestCase):
35 def testInsertStoreMetadata(self):
37 fdroidserver.common.fill_config_defaults(config)
38 config['accepted_formats'] = ('txt', 'yml')
39 fdroidserver.update.config = config
40 fdroidserver.update.options = fdroidserver.common.options
41 os.chdir(os.path.join(localmodule, 'tests'))
43 shutil.rmtree(os.path.join('repo', 'info.guardianproject.urzip'), ignore_errors=True)
45 shutil.rmtree(os.path.join('build', 'com.nextcloud.client'), ignore_errors=True)
46 shutil.copytree(os.path.join('source-files', 'com.nextcloud.client'), os.path.join('build', 'com.nextcloud.client'))
48 shutil.rmtree(os.path.join('build', 'com.nextcloud.client.dev'), ignore_errors=True)
49 shutil.copytree(os.path.join('source-files', 'com.nextcloud.client.dev'),
50 os.path.join('build', 'com.nextcloud.client.dev'))
53 for packageName in ('info.guardianproject.urzip', 'org.videolan.vlc', 'obb.mainpatch.current',
54 'com.nextcloud.client', 'com.nextcloud.client.dev'):
55 apps[packageName] = fdroidserver.metadata.App()
56 apps[packageName]['id'] = packageName
57 apps[packageName]['CurrentVersionCode'] = 0xcafebeef
59 apps['info.guardianproject.urzip']['CurrentVersionCode'] = 100
61 buildnextcloudclient = fdroidserver.metadata.Build()
62 buildnextcloudclient.gradle = ['generic']
63 apps['com.nextcloud.client']['builds'] = [buildnextcloudclient]
65 buildnextclouddevclient = fdroidserver.metadata.Build()
66 buildnextclouddevclient.gradle = ['versionDev']
67 apps['com.nextcloud.client.dev']['builds'] = [buildnextclouddevclient]
69 fdroidserver.update.insert_localized_app_metadata(apps)
71 appdir = os.path.join('repo', 'info.guardianproject.urzip', 'en-US')
72 self.assertTrue(os.path.isfile(os.path.join(appdir, 'icon.png')))
73 self.assertTrue(os.path.isfile(os.path.join(appdir, 'featureGraphic.png')))
75 self.assertEqual(5, len(apps))
76 for packageName, app in apps.items():
77 self.assertTrue('localized' in app)
78 self.assertTrue('en-US' in app['localized'])
79 self.assertEqual(1, len(app['localized']))
80 if packageName == 'info.guardianproject.urzip':
81 self.assertEqual(7, len(app['localized']['en-US']))
82 self.assertEqual('full description\n', app['localized']['en-US']['description'])
83 self.assertEqual('title\n', app['localized']['en-US']['name'])
84 self.assertEqual('short description\n', app['localized']['en-US']['summary'])
85 self.assertEqual('video\n', app['localized']['en-US']['video'])
86 self.assertEqual('icon.png', app['localized']['en-US']['icon'])
87 self.assertEqual('featureGraphic.png', app['localized']['en-US']['featureGraphic'])
88 self.assertEqual('100\n', app['localized']['en-US']['whatsNew'])
89 elif packageName == 'org.videolan.vlc':
90 self.assertEqual('icon.png', app['localized']['en-US']['icon'])
91 self.assertEqual(9, len(app['localized']['en-US']['phoneScreenshots']))
92 self.assertEqual(15, len(app['localized']['en-US']['sevenInchScreenshots']))
93 elif packageName == 'obb.mainpatch.current':
94 self.assertEqual('icon.png', app['localized']['en-US']['icon'])
95 self.assertEqual('featureGraphic.png', app['localized']['en-US']['featureGraphic'])
96 self.assertEqual(1, len(app['localized']['en-US']['phoneScreenshots']))
97 self.assertEqual(1, len(app['localized']['en-US']['sevenInchScreenshots']))
98 elif packageName == 'com.nextcloud.client':
99 self.assertEqual('Nextcloud', app['localized']['en-US']['name'])
100 self.assertEqual(1073, len(app['localized']['en-US']['description']))
101 self.assertEqual(78, len(app['localized']['en-US']['summary']))
102 elif packageName == 'com.nextcloud.client.dev':
103 self.assertEqual('Nextcloud Dev', app['localized']['en-US']['name'])
104 self.assertEqual(586, len(app['localized']['en-US']['description']))
105 self.assertEqual(79, len(app['localized']['en-US']['summary']))
107 def test_insert_triple_t_metadata(self):
108 importer = os.path.join(localmodule, 'tests', 'tmp', 'importer')
109 packageName = 'org.fdroid.ci.test.app'
110 if not os.path.isdir(importer):
111 logging.warning('skipping test_insert_triple_t_metadata, import.TestCase must run first!')
113 tmpdir = os.path.join(localmodule, '.testfiles')
114 if not os.path.exists(tmpdir):
116 tmptestsdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=tmpdir)
117 packageDir = os.path.join(tmptestsdir, 'build', packageName)
118 shutil.copytree(importer, packageDir)
120 # always use the same commit so these tests work when ci-test-app.git is updated
121 repo = git.Repo(packageDir)
122 for remote in repo.remotes:
124 repo.git.reset('--hard', 'b9e5d1a0d8d6fc31d4674b2f0514fef10762ed4f')
125 repo.git.clean('-fdx')
127 os.mkdir(os.path.join(tmptestsdir, 'metadata'))
129 metadata['Description'] = 'This is just a test app'
130 with open(os.path.join(tmptestsdir, 'metadata', packageName + '.yml'), 'w') as fp:
131 yaml.dump(metadata, fp)
134 fdroidserver.common.fill_config_defaults(config)
135 config['accepted_formats'] = ('yml')
136 fdroidserver.common.config = config
137 fdroidserver.update.config = config
138 fdroidserver.update.options = fdroidserver.common.options
139 os.chdir(tmptestsdir)
141 apps = fdroidserver.metadata.read_metadata(xref=True)
142 fdroidserver.update.copy_triple_t_store_metadata(apps)
144 # TODO ideally, this would compare the whole dict like in metadata.TestCase's test_read_metadata()
146 'ar', 'ast_ES', 'az', 'ca', 'ca_ES', 'cs-CZ', 'cs_CZ', 'da',
147 'da-DK', 'de', 'de-DE', 'el', 'en-US', 'es', 'es-ES', 'es_ES', 'et',
148 'fi', 'fr', 'fr-FR', 'he_IL', 'hi-IN', 'hi_IN', 'hu', 'id', 'it',
149 'it-IT', 'it_IT', 'iw-IL', 'ja', 'ja-JP', 'kn_IN', 'ko', 'ko-KR',
150 'ko_KR', 'lt', 'nb', 'nb_NO', 'nl', 'nl-NL', 'no', 'pl', 'pl-PL',
151 'pl_PL', 'pt', 'pt-BR', 'pt-PT', 'pt_BR', 'ro', 'ro_RO', 'ru-RU',
152 'ru_RU', 'sv-SE', 'sv_SE', 'te', 'tr', 'tr-TR', 'uk', 'uk_UA', 'vi',
153 'vi_VN', 'zh-CN', 'zh_CN', 'zh_TW',
155 locales = sorted(list(apps['org.fdroid.ci.test.app']['localized'].keys()))
156 self.assertEqual(correctlocales, locales)
158 def javagetsig(self, apkfile):
159 getsig_dir = os.path.join(os.path.dirname(__file__), 'getsig')
160 if not os.path.exists(getsig_dir + "/getsig.class"):
161 logging.critical("getsig.class not found. To fix: cd '%s' && ./make.sh" % getsig_dir)
163 # FDroidPopen needs some config to work
165 fdroidserver.common.fill_config_defaults(config)
166 fdroidserver.common.config = config
167 p = FDroidPopen(['java', '-cp', os.path.join(os.path.dirname(__file__), 'getsig'),
168 'getsig', os.path.join(os.getcwd(), apkfile)])
170 for line in p.output.splitlines():
171 if line.startswith('Result:'):
172 sig = line[7:].strip()
174 if p.returncode == 0:
179 def testGoodGetsig(self):
180 # config needed to use jarsigner and keytool
182 fdroidserver.common.fill_config_defaults(config)
183 fdroidserver.update.config = config
184 apkfile = os.path.join(os.path.dirname(__file__), 'urzip.apk')
185 sig = self.javagetsig(apkfile)
186 self.assertIsNotNone(sig, "sig is None")
187 pysig = fdroidserver.update.getsig(apkfile)
188 self.assertIsNotNone(pysig, "pysig is None")
189 self.assertEqual(sig, fdroidserver.update.getsig(apkfile),
190 "python sig not equal to java sig!")
191 self.assertEqual(len(sig), len(pysig),
192 "the length of the two sigs are different!")
194 self.assertEqual(unhexlify(sig), unhexlify(pysig),
195 "the length of the two sigs are different!")
196 except TypeError as e:
198 self.assertTrue(False, 'TypeError!')
200 def testBadGetsig(self):
201 """getsig() should still be able to fetch the fingerprint of bad signatures"""
202 # config needed to use jarsigner and keytool
204 fdroidserver.common.fill_config_defaults(config)
205 fdroidserver.update.config = config
207 apkfile = os.path.join(os.path.dirname(__file__), 'urzip-badsig.apk')
208 sig = fdroidserver.update.getsig(apkfile)
209 self.assertEqual(sig, 'e0ecb5fc2d63088e4a07ae410a127722',
210 "python sig should be: " + str(sig))
212 apkfile = os.path.join(os.path.dirname(__file__), 'urzip-badcert.apk')
213 sig = fdroidserver.update.getsig(apkfile)
214 self.assertEqual(sig, 'e0ecb5fc2d63088e4a07ae410a127722',
215 "python sig should be: " + str(sig))
217 def testScanApksAndObbs(self):
218 os.chdir(os.path.join(localmodule, 'tests'))
219 if os.path.basename(os.getcwd()) != 'tests':
220 raise Exception('This test must be run in the "tests/" subdir')
223 fdroidserver.common.fill_config_defaults(config)
224 config['ndk_paths'] = dict()
225 config['accepted_formats'] = ['json', 'txt', 'yml']
226 fdroidserver.common.config = config
227 fdroidserver.update.config = config
229 fdroidserver.update.options = type('', (), {})()
230 fdroidserver.update.options.clean = True
231 fdroidserver.update.options.delete_unknown = True
232 fdroidserver.update.options.rename_apks = False
233 fdroidserver.update.options.allow_disabled_algorithms = False
235 apps = fdroidserver.metadata.read_metadata(xref=True)
236 knownapks = fdroidserver.common.KnownApks()
237 apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False)
238 self.assertEqual(len(apks), 11)
240 self.assertEqual(apk['packageName'], 'com.politedroid')
241 self.assertEqual(apk['versionCode'], 3)
242 self.assertEqual(apk['minSdkVersion'], '3')
243 self.assertEqual(apk['targetSdkVersion'], '3')
244 self.assertFalse('maxSdkVersion' in apk)
246 self.assertEqual(apk['packageName'], 'obb.main.oldversion')
247 self.assertEqual(apk['versionCode'], 1444412523)
248 self.assertEqual(apk['minSdkVersion'], '4')
249 self.assertEqual(apk['targetSdkVersion'], '18')
250 self.assertFalse('maxSdkVersion' in apk)
252 fdroidserver.update.insert_obbs('repo', apps, apks)
254 if apk['packageName'] == 'obb.mainpatch.current':
255 self.assertEqual(apk.get('obbMainFile'), 'main.1619.obb.mainpatch.current.obb')
256 self.assertEqual(apk.get('obbPatchFile'), 'patch.1619.obb.mainpatch.current.obb')
257 elif apk['packageName'] == 'obb.main.oldversion':
258 self.assertEqual(apk.get('obbMainFile'), 'main.1434483388.obb.main.oldversion.obb')
259 self.assertIsNone(apk.get('obbPatchFile'))
260 elif apk['packageName'] == 'obb.main.twoversions':
261 self.assertIsNone(apk.get('obbPatchFile'))
262 if apk['versionCode'] == 1101613:
263 self.assertEqual(apk.get('obbMainFile'), 'main.1101613.obb.main.twoversions.obb')
264 elif apk['versionCode'] == 1101615:
265 self.assertEqual(apk.get('obbMainFile'), 'main.1101615.obb.main.twoversions.obb')
266 elif apk['versionCode'] == 1101617:
267 self.assertEqual(apk.get('obbMainFile'), 'main.1101615.obb.main.twoversions.obb')
269 self.assertTrue(False)
270 elif apk['packageName'] == 'info.guardianproject.urzip':
271 self.assertIsNone(apk.get('obbMainFile'))
272 self.assertIsNone(apk.get('obbPatchFile'))
274 def test_scan_apk(self):
276 fdroidserver.common.fill_config_defaults(config)
277 fdroidserver.update.config = config
278 os.chdir(os.path.join(localmodule, 'tests'))
279 if os.path.basename(os.getcwd()) != 'tests':
280 raise Exception('This test must be run in the "tests/" subdir')
282 apk_info = fdroidserver.update.scan_apk('org.dyndns.fules.ck_20.apk')
284 self.assertEqual(apk_info['icons_src'], {'240': 'res/drawable-hdpi-v4/icon_launcher.png',
285 '120': 'res/drawable-ldpi-v4/icon_launcher.png',
286 '160': 'res/drawable-mdpi-v4/icon_launcher.png',
287 '-1': 'res/drawable-mdpi-v4/icon_launcher.png'})
288 self.assertEqual(apk_info['icons'], {})
289 self.assertEqual(apk_info['features'], [])
290 self.assertEqual(apk_info['antiFeatures'], set())
291 self.assertEqual(apk_info['versionName'], 'v1.6pre2')
292 self.assertEqual(apk_info['hash'],
293 '897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8')
294 self.assertEqual(apk_info['packageName'], 'org.dyndns.fules.ck')
295 self.assertEqual(apk_info['versionCode'], 20)
296 self.assertEqual(apk_info['size'], 132453)
297 self.assertEqual(apk_info['nativecode'],
298 ['arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86', 'x86_64'])
299 self.assertEqual(apk_info['minSdkVersion'], '7')
300 self.assertEqual(apk_info['sig'], '9bf7a6a67f95688daec75eab4b1436ac')
301 self.assertEqual(apk_info['hashType'], 'sha256')
302 self.assertEqual(apk_info['targetSdkVersion'], '8')
304 def test_scan_apk_no_sig(self):
306 fdroidserver.common.fill_config_defaults(config)
307 fdroidserver.update.config = config
308 os.chdir(os.path.join(localmodule, 'tests'))
309 if os.path.basename(os.getcwd()) != 'tests':
310 raise Exception('This test must be run in the "tests/" subdir')
312 with self.assertRaises(fdroidserver.exception.BuildException):
313 fdroidserver.update.scan_apk('urzip-release-unsigned.apk')
315 def test_process_apk(self):
317 def _build_yaml_representer(dumper, data):
318 '''Creates a YAML representation of a Build instance'''
319 return dumper.represent_dict(data)
322 fdroidserver.common.fill_config_defaults(config)
323 fdroidserver.update.config = config
324 os.chdir(os.path.join(localmodule, 'tests'))
325 if os.path.basename(os.getcwd()) != 'tests':
326 raise Exception('This test must be run in the "tests/" subdir')
328 config['ndk_paths'] = dict()
329 config['accepted_formats'] = ['json', 'txt', 'yml']
330 fdroidserver.common.config = config
331 fdroidserver.update.config = config
333 fdroidserver.update.options = type('', (), {})()
334 fdroidserver.update.options.clean = True
335 fdroidserver.update.options.rename_apks = False
336 fdroidserver.update.options.delete_unknown = True
337 fdroidserver.update.options.allow_disabled_algorithms = False
339 for icon_dir in fdroidserver.update.get_all_icon_dirs('repo'):
340 if not os.path.exists(icon_dir):
341 os.makedirs(icon_dir)
343 knownapks = fdroidserver.common.KnownApks()
344 apkList = ['../urzip.apk', '../org.dyndns.fules.ck_20.apk']
346 for apkName in apkList:
347 _, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'repo', knownapks,
349 # Don't care about the date added to the repo and relative apkName
352 # avoid AAPT application name bug
355 # ensure that icons have been extracted properly
356 if apkName == '../urzip.apk':
357 self.assertEqual(apk['icon'], 'info.guardianproject.urzip.100.png')
358 if apkName == '../org.dyndns.fules.ck_20.apk':
359 self.assertEqual(apk['icon'], 'org.dyndns.fules.ck.20.png')
360 for density in fdroidserver.update.screen_densities:
361 icon_path = os.path.join(fdroidserver.update.get_icon_dir('repo', density),
363 self.assertTrue(os.path.isfile(icon_path))
364 self.assertTrue(os.path.getsize(icon_path) > 1)
366 savepath = os.path.join('metadata', 'apk', apk['packageName'] + '.yaml')
367 # Uncomment to save APK metadata
368 # with open(savepath, 'w') as f:
369 # yaml.add_representer(fdroidserver.metadata.Build, _build_yaml_representer)
370 # yaml.dump(apk, f, default_flow_style=False)
372 with open(savepath, 'r') as f:
373 frompickle = yaml.load(f)
375 self.assertEqual(apk, frompickle)
377 def test_process_apk_signed_by_disabled_algorithms(self):
378 os.chdir(os.path.join(localmodule, 'tests'))
379 if os.path.basename(os.getcwd()) != 'tests':
380 raise Exception('This test must be run in the "tests/" subdir')
383 fdroidserver.common.fill_config_defaults(config)
384 fdroidserver.update.config = config
386 config['ndk_paths'] = dict()
387 config['accepted_formats'] = ['json', 'txt', 'yml']
388 fdroidserver.common.config = config
389 fdroidserver.update.config = config
391 fdroidserver.update.options = type('', (), {})()
392 fdroidserver.update.options.clean = True
393 fdroidserver.update.options.verbose = True
394 fdroidserver.update.options.rename_apks = False
395 fdroidserver.update.options.delete_unknown = True
396 fdroidserver.update.options.allow_disabled_algorithms = False
398 knownapks = fdroidserver.common.KnownApks()
399 apksourcedir = os.getcwd()
400 tmpdir = os.path.join(localmodule, '.testfiles')
401 if not os.path.exists(tmpdir):
403 tmptestsdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name,
405 print('tmptestsdir', tmptestsdir)
406 os.chdir(tmptestsdir)
409 # setup the repo, create icons dirs, etc.
410 fdroidserver.update.process_apks({}, 'repo', knownapks)
411 fdroidserver.update.process_apks({}, 'archive', knownapks)
413 disabledsigs = ['org.bitbucket.tickytacky.mirrormirror_2.apk', ]
414 for apkName in disabledsigs:
415 shutil.copy(os.path.join(apksourcedir, apkName),
416 os.path.join(tmptestsdir, 'repo'))
418 skip, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'repo',
420 allow_disabled_algorithms=True,
421 archive_bad_sig=False)
422 self.assertFalse(skip)
423 self.assertIsNotNone(apk)
424 self.assertTrue(cachechanged)
425 self.assertFalse(os.path.exists(os.path.join('archive', apkName)))
426 self.assertTrue(os.path.exists(os.path.join('repo', apkName)))
428 javac = config['jarsigner'].replace('jarsigner', 'javac')
429 v = subprocess.check_output([javac, '-version'], stderr=subprocess.STDOUT)[6:-1].decode('utf-8')
430 if LooseVersion(v) < LooseVersion('1.8.0_132'):
431 print('SKIPPING: running tests with old Java (' + v + ')')
434 # this test only works on systems with fully updated Java/jarsigner
435 # that has MD5 listed in jdk.jar.disabledAlgorithms in java.security
436 # https://blogs.oracle.com/java-platform-group/oracle-jre-will-no-longer-trust-md5-signed-code-by-default
437 skip, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'repo',
439 allow_disabled_algorithms=False,
440 archive_bad_sig=True)
441 self.assertTrue(skip)
442 self.assertIsNone(apk)
443 self.assertFalse(cachechanged)
444 self.assertTrue(os.path.exists(os.path.join('archive', apkName)))
445 self.assertFalse(os.path.exists(os.path.join('repo', apkName)))
447 skip, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'archive',
449 allow_disabled_algorithms=False,
450 archive_bad_sig=False)
451 self.assertFalse(skip)
452 self.assertIsNotNone(apk)
453 self.assertTrue(cachechanged)
454 self.assertTrue(os.path.exists(os.path.join('archive', apkName)))
455 self.assertFalse(os.path.exists(os.path.join('repo', apkName)))
457 # ensure that icons have been moved to the archive as well
458 for density in fdroidserver.update.screen_densities:
459 icon_path = os.path.join(fdroidserver.update.get_icon_dir('archive', density),
461 self.assertTrue(os.path.isfile(icon_path))
462 self.assertTrue(os.path.getsize(icon_path) > 1)
464 badsigs = ['urzip-badcert.apk', 'urzip-badsig.apk', 'urzip-release-unsigned.apk', ]
465 for apkName in badsigs:
466 shutil.copy(os.path.join(apksourcedir, apkName),
467 os.path.join(tmptestsdir, 'repo'))
469 skip, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'repo',
471 allow_disabled_algorithms=False,
472 archive_bad_sig=False)
473 self.assertTrue(skip)
474 self.assertIsNone(apk)
475 self.assertFalse(cachechanged)
477 def test_process_invalid_apk(self):
478 os.chdir(os.path.join(localmodule, 'tests'))
479 if os.path.basename(os.getcwd()) != 'tests':
480 raise Exception('This test must be run in the "tests/" subdir')
483 fdroidserver.common.fill_config_defaults(config)
484 fdroidserver.common.config = config
485 fdroidserver.update.config = config
486 fdroidserver.update.options.delete_unknown = False
488 knownapks = fdroidserver.common.KnownApks()
489 apk = 'fake.ota.update_1234.zip' # this is not an APK, scanning should fail
490 (skip, apk, cachechanged) = fdroidserver.update.process_apk({}, apk, 'repo', knownapks,
493 self.assertTrue(skip)
494 self.assertIsNone(apk)
495 self.assertFalse(cachechanged)
497 def test_translate_per_build_anti_features(self):
498 os.chdir(os.path.join(localmodule, 'tests'))
499 if os.path.basename(os.getcwd()) != 'tests':
500 raise Exception('This test must be run in the "tests/" subdir')
503 fdroidserver.common.fill_config_defaults(config)
504 config['ndk_paths'] = dict()
505 config['accepted_formats'] = ['json', 'txt', 'yml']
506 fdroidserver.common.config = config
507 fdroidserver.update.config = config
509 fdroidserver.update.options = type('', (), {})()
510 fdroidserver.update.options.clean = True
511 fdroidserver.update.options.delete_unknown = True
512 fdroidserver.update.options.rename_apks = False
513 fdroidserver.update.options.allow_disabled_algorithms = False
515 apps = fdroidserver.metadata.read_metadata(xref=True)
516 knownapks = fdroidserver.common.KnownApks()
517 apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False)
518 fdroidserver.update.translate_per_build_anti_features(apps, apks)
519 self.assertEqual(len(apks), 11)
522 if apk['packageName'] == 'com.politedroid' and apk['versionCode'] == 3:
523 antiFeatures = apk.get('antiFeatures')
524 self.assertTrue('KnownVuln' in antiFeatures)
525 self.assertEqual(3, len(antiFeatures))
527 self.assertTrue(foundtest)
529 def test_create_metadata_from_template(self):
530 tmpdir = os.path.join(localmodule, '.testfiles')
531 if not os.path.exists(tmpdir):
533 tmptestsdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name,
535 print('tmptestsdir', tmptestsdir)
536 os.chdir(tmptestsdir)
539 shutil.copy(os.path.join(localmodule, 'tests', 'urzip.apk'), 'repo')
542 fdroidserver.common.fill_config_defaults(config)
543 config['ndk_paths'] = dict()
544 config['accepted_formats'] = ['json', 'txt', 'yml']
545 fdroidserver.common.config = config
546 fdroidserver.update.config = config
548 fdroidserver.update.options = type('', (), {})()
549 fdroidserver.update.options.clean = True
550 fdroidserver.update.options.delete_unknown = False
551 fdroidserver.update.options.rename_apks = False
552 fdroidserver.update.options.allow_disabled_algorithms = False
554 knownapks = fdroidserver.common.KnownApks()
555 apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks, False)
556 self.assertEqual(1, len(apks))
559 testfile = 'metadata/info.guardianproject.urzip.yml'
560 # create empty 0 byte .yml file, run read_metadata, it should work
561 open(testfile, 'a').close()
562 apps = fdroidserver.metadata.read_metadata(xref=True)
563 self.assertEqual(1, len(apps))
566 # test using internal template
567 apps = fdroidserver.metadata.read_metadata(xref=True)
568 self.assertEqual(0, len(apps))
569 fdroidserver.update.create_metadata_from_template(apk)
570 self.assertTrue(os.path.exists(testfile))
571 apps = fdroidserver.metadata.read_metadata(xref=True)
572 self.assertEqual(1, len(apps))
573 for app in apps.values():
574 self.assertEqual('urzip', app['Name'])
575 self.assertEqual(1, len(app['Categories']))
578 # test using external template.yml
580 self.assertFalse(os.path.exists(testfile))
581 shutil.copy(os.path.join(localmodule, 'examples', 'template.yml'), tmptestsdir)
582 fdroidserver.update.create_metadata_from_template(apk)
583 self.assertTrue(os.path.exists(testfile))
584 apps = fdroidserver.metadata.read_metadata(xref=True)
585 self.assertEqual(1, len(apps))
586 for app in apps.values():
587 self.assertEqual('urzip', app['Name'])
588 self.assertEqual(1, len(app['Categories']))
589 self.assertEqual('Internet', app['Categories'][0])
591 with open(testfile) as fp:
593 self.assertEqual('urzip', data['Name'])
594 self.assertEqual('urzip', data['Summary'])
597 if __name__ == "__main__":
598 parser = optparse.OptionParser()
599 parser.add_option("-v", "--verbose", action="store_true", default=False,
600 help="Spew out even more information than normal")
601 (fdroidserver.common.options, args) = parser.parse_args(['--verbose'])
603 newSuite = unittest.TestSuite()
604 newSuite.addTest(unittest.makeSuite(UpdateTest))
605 unittest.main(failfast=False)