mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-03 17:50:11 +02:00
9589d13ef2
This uses the "What's New" entry for the CurrentVersionCode and includes it as the current WhatsNew metadata for the App class. Things like fastlane supply and Google Play support a "What's New" entry per-APK, but fdroidclient does not current use anything but the current version of this data. Right now, it seems we probably only want to have the latest WhatsNew in the index to save space. In theory, we could make the WhatsNew data structure follow the structure of fastlane/Play, but that would quite a bit of complexity for something that might never be used. fdroidclient#910
200 lines
9.0 KiB
Python
Executable File
200 lines
9.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
|
|
|
|
import inspect
|
|
import logging
|
|
import optparse
|
|
import os
|
|
import sys
|
|
import unittest
|
|
from binascii import unhexlify
|
|
|
|
localmodule = os.path.realpath(
|
|
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..'))
|
|
print('localmodule: ' + localmodule)
|
|
if localmodule not in sys.path:
|
|
sys.path.insert(0, localmodule)
|
|
|
|
import fdroidserver.common
|
|
import fdroidserver.update
|
|
from fdroidserver.common import FDroidPopen
|
|
|
|
|
|
class UpdateTest(unittest.TestCase):
|
|
'''fdroid update'''
|
|
|
|
def testInsertStoreMetadata(self):
|
|
config = dict()
|
|
fdroidserver.common.fill_config_defaults(config)
|
|
config['accepted_formats'] = ('txt', 'yml')
|
|
fdroidserver.update.config = config
|
|
fdroidserver.update.options = fdroidserver.common.options
|
|
os.chdir(os.path.join(localmodule, 'tests'))
|
|
|
|
apps = dict()
|
|
for packageName in ('info.guardianproject.urzip', 'org.videolan.vlc', 'obb.mainpatch.current'):
|
|
apps[packageName] = dict()
|
|
apps[packageName]['id'] = packageName
|
|
apps[packageName]['CurrentVersionCode'] = 0xcafebeef
|
|
apps['info.guardianproject.urzip']['CurrentVersionCode'] = 100
|
|
fdroidserver.update.insert_localized_app_metadata(apps)
|
|
|
|
self.assertEqual(3, len(apps))
|
|
for packageName, app in apps.items():
|
|
self.assertTrue('localized' in app)
|
|
self.assertTrue('en-US' in app['localized'])
|
|
self.assertEqual(1, len(app['localized']))
|
|
if packageName == 'info.guardianproject.urzip':
|
|
self.assertEqual(5, len(app['localized']['en-US']))
|
|
self.assertEqual('full description\n', app['localized']['en-US']['Description'])
|
|
self.assertEqual('title\n', app['localized']['en-US']['Name'])
|
|
self.assertEqual('short description\n', app['localized']['en-US']['Summary'])
|
|
self.assertEqual('video\n', app['localized']['en-US']['Video'])
|
|
self.assertEqual('100\n', app['localized']['en-US']['WhatsNew'])
|
|
elif packageName == 'org.videolan.vlc':
|
|
self.assertEqual('icon.png', app['localized']['en-US']['icon'])
|
|
self.assertEqual(9, len(app['localized']['en-US']['phoneScreenshots']))
|
|
self.assertEqual(15, len(app['localized']['en-US']['sevenInchScreenshots']))
|
|
elif packageName == 'obb.mainpatch.current':
|
|
self.assertEqual('icon.png', app['localized']['en-US']['icon'])
|
|
self.assertEqual('featureGraphic.png', app['localized']['en-US']['featureGraphic'])
|
|
self.assertEqual(1, len(app['localized']['en-US']['phoneScreenshots']))
|
|
self.assertEqual(1, len(app['localized']['en-US']['sevenInchScreenshots']))
|
|
|
|
def javagetsig(self, apkfile):
|
|
getsig_dir = os.path.join(os.path.dirname(__file__), 'getsig')
|
|
if not os.path.exists(getsig_dir + "/getsig.class"):
|
|
logging.critical("getsig.class not found. To fix: cd '%s' && ./make.sh" % getsig_dir)
|
|
sys.exit(1)
|
|
# FDroidPopen needs some config to work
|
|
config = dict()
|
|
fdroidserver.common.fill_config_defaults(config)
|
|
fdroidserver.common.config = config
|
|
p = FDroidPopen(['java', '-cp', os.path.join(os.path.dirname(__file__), 'getsig'),
|
|
'getsig', os.path.join(os.getcwd(), apkfile)])
|
|
sig = None
|
|
for line in p.output.splitlines():
|
|
if line.startswith('Result:'):
|
|
sig = line[7:].strip()
|
|
break
|
|
if p.returncode == 0:
|
|
return sig
|
|
else:
|
|
return None
|
|
|
|
def testGoodGetsig(self):
|
|
# config needed to use jarsigner and keytool
|
|
config = dict()
|
|
fdroidserver.common.fill_config_defaults(config)
|
|
fdroidserver.update.config = config
|
|
apkfile = os.path.join(os.path.dirname(__file__), 'urzip.apk')
|
|
sig = self.javagetsig(apkfile)
|
|
self.assertIsNotNone(sig, "sig is None")
|
|
pysig = fdroidserver.update.getsig(apkfile)
|
|
self.assertIsNotNone(pysig, "pysig is None")
|
|
self.assertEqual(sig, fdroidserver.update.getsig(apkfile),
|
|
"python sig not equal to java sig!")
|
|
self.assertEqual(len(sig), len(pysig),
|
|
"the length of the two sigs are different!")
|
|
try:
|
|
self.assertEqual(unhexlify(sig), unhexlify(pysig),
|
|
"the length of the two sigs are different!")
|
|
except TypeError as e:
|
|
print(e)
|
|
self.assertTrue(False, 'TypeError!')
|
|
|
|
def testBadGetsig(self):
|
|
# config needed to use jarsigner and keytool
|
|
config = dict()
|
|
fdroidserver.common.fill_config_defaults(config)
|
|
fdroidserver.update.config = config
|
|
apkfile = os.path.join(os.path.dirname(__file__), 'urzip-badsig.apk')
|
|
sig = self.javagetsig(apkfile)
|
|
self.assertIsNone(sig, "sig should be None: " + str(sig))
|
|
pysig = fdroidserver.update.getsig(apkfile)
|
|
self.assertIsNone(pysig, "python sig should be None: " + str(sig))
|
|
|
|
apkfile = os.path.join(os.path.dirname(__file__), 'urzip-badcert.apk')
|
|
sig = self.javagetsig(apkfile)
|
|
self.assertIsNone(sig, "sig should be None: " + str(sig))
|
|
pysig = fdroidserver.update.getsig(apkfile)
|
|
self.assertIsNone(pysig, "python sig should be None: " + str(sig))
|
|
|
|
def testScanApksAndObbs(self):
|
|
os.chdir(os.path.join(localmodule, 'tests'))
|
|
if os.path.basename(os.getcwd()) != 'tests':
|
|
raise Exception('This test must be run in the "tests/" subdir')
|
|
|
|
config = dict()
|
|
fdroidserver.common.fill_config_defaults(config)
|
|
config['ndk_paths'] = dict()
|
|
config['accepted_formats'] = ['json', 'txt', 'yml']
|
|
fdroidserver.common.config = config
|
|
fdroidserver.update.config = config
|
|
|
|
fdroidserver.update.options = type('', (), {})()
|
|
fdroidserver.update.options.clean = True
|
|
fdroidserver.update.options.delete_unknown = True
|
|
|
|
apps = fdroidserver.metadata.read_metadata(xref=True)
|
|
knownapks = fdroidserver.common.KnownApks()
|
|
apks, cachechanged = fdroidserver.update.scan_apks({}, 'repo', knownapks, False)
|
|
self.assertEqual(len(apks), 6)
|
|
apk = apks[0]
|
|
self.assertEqual(apk['minSdkVersion'], '4')
|
|
self.assertEqual(apk['targetSdkVersion'], '18')
|
|
self.assertFalse('maxSdkVersion' in apk)
|
|
|
|
fdroidserver.update.insert_obbs('repo', apps, apks)
|
|
for apk in apks:
|
|
if apk['packageName'] == 'obb.mainpatch.current':
|
|
self.assertEqual(apk.get('obbMainFile'), 'main.1619.obb.mainpatch.current.obb')
|
|
self.assertEqual(apk.get('obbPatchFile'), 'patch.1619.obb.mainpatch.current.obb')
|
|
elif apk['packageName'] == 'obb.main.oldversion':
|
|
self.assertEqual(apk.get('obbMainFile'), 'main.1434483388.obb.main.oldversion.obb')
|
|
self.assertIsNone(apk.get('obbPatchFile'))
|
|
elif apk['packageName'] == 'obb.main.twoversions':
|
|
self.assertIsNone(apk.get('obbPatchFile'))
|
|
if apk['versionCode'] == 1101613:
|
|
self.assertEqual(apk.get('obbMainFile'), 'main.1101613.obb.main.twoversions.obb')
|
|
elif apk['versionCode'] == 1101615:
|
|
self.assertEqual(apk.get('obbMainFile'), 'main.1101615.obb.main.twoversions.obb')
|
|
elif apk['versionCode'] == 1101617:
|
|
self.assertEqual(apk.get('obbMainFile'), 'main.1101615.obb.main.twoversions.obb')
|
|
else:
|
|
self.assertTrue(False)
|
|
elif apk['packageName'] == 'info.guardianproject.urzip':
|
|
self.assertIsNone(apk.get('obbMainFile'))
|
|
self.assertIsNone(apk.get('obbPatchFile'))
|
|
|
|
def test_scan_invalid_apk(self):
|
|
os.chdir(os.path.join(localmodule, 'tests'))
|
|
if os.path.basename(os.getcwd()) != 'tests':
|
|
raise Exception('This test must be run in the "tests/" subdir')
|
|
|
|
config = dict()
|
|
fdroidserver.common.fill_config_defaults(config)
|
|
fdroidserver.common.config = config
|
|
fdroidserver.update.config = config
|
|
fdroidserver.update.options.delete_unknown = False
|
|
|
|
knownapks = fdroidserver.common.KnownApks()
|
|
apk = 'fake.ota.update_1234.zip' # this is not an APK, scanning should fail
|
|
(skip, apk, cachechanged) = fdroidserver.update.scan_apk({}, apk, 'repo', knownapks, False)
|
|
|
|
self.assertTrue(skip)
|
|
self.assertIsNone(apk)
|
|
self.assertFalse(cachechanged)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = optparse.OptionParser()
|
|
parser.add_option("-v", "--verbose", action="store_true", default=False,
|
|
help="Spew out even more information than normal")
|
|
(fdroidserver.common.options, args) = parser.parse_args(['--verbose'])
|
|
|
|
newSuite = unittest.TestSuite()
|
|
newSuite.addTest(unittest.makeSuite(UpdateTest))
|
|
unittest.main()
|