diff --git a/.travis.yml b/.travis.yml index 3dab550a..8af32606 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,9 @@ matrix: env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk env: ANDROID_HOME=/usr/local/share/android-sdk +# On Ubuntu/trusty 14.04, the PPA is needed on to provide lots of the +# dependencies, but this then also serves as a test of the PPA, which +# is used on Windows Subsystem for Linux. addons: apt: sources: @@ -46,15 +49,13 @@ android: - 'android-sdk-preview-.+' - 'android-sdk-license-.+' -# the PPA is needed on Ubuntu 14.04 precise, and with python3, trusty too -# the pip thing is a hack that can go away with trusty. -# # * ensure java8 is installed since Android SDK doesn't work with Java9 # * Java needs to be at least 1.8.0_131 to have MD5 properly disabled # https://blogs.oracle.com/java-platform-group/oracle-jre-will-no-longer-trust-md5-signed-code-by-default # https://opsech.io/posts/2017/Jun/09/openjdk-april-2017-security-update-131-8u131-and-md5-signed-jars.html install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + set -x; brew update > /dev/null; brew install dash bash python3 gradle jenv; brew install gnu-sed --with-default-names; @@ -74,6 +75,8 @@ install: sudo pip3 install --quiet --editable . ; sudo rm -rf fdroidserver.egg-info; + ls -l /System/Library/Java/JavaVirtualMachines || true; + ls -l /Library/Java/JavaVirtualMachines || true; echo $PATH; echo $JAVA_HOME; jenv versions; @@ -86,11 +89,19 @@ install: which jarsigner; keytool -help; which keytool; + set +x; fi +# The OSX tests seem to run slower, they often timeout. So only run +# the test suite with the installed version of fdroid, instead of the +# three rounds that ./complete-ci-tests does. script: - cd tests - - ./complete-ci-tests + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + ./run-tests; + else + ./complete-ci-tests; + fi after_failure: - cd $TRAVIS_BUILD_DIR diff --git a/fdroidserver/common.py b/fdroidserver/common.py index c6fbf0d2..634de8b5 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -132,6 +132,41 @@ def setup_global_opts(parser): help=_("Restrict output to warnings and errors")) +def _add_java_paths_to_config(pathlist, thisconfig): + def path_version_key(s): + versionlist = [] + for u in re.split('[^0-9]+', s): + try: + versionlist.append(int(u)) + except ValueError: + pass + return versionlist + + for d in sorted(pathlist, key=path_version_key): + if os.path.islink(d): + continue + j = os.path.basename(d) + # the last one found will be the canonical one, so order appropriately + for regex in [ + r'^1\.([6-9])\.0\.jdk$', # OSX + r'^jdk1\.([6-9])\.0_[0-9]+.jdk$', # OSX and Oracle tarball + r'^jdk1\.([6-9])\.0_[0-9]+$', # Oracle Windows + r'^jdk([6-9])-openjdk$', # Arch + r'^java-([6-9])-openjdk$', # Arch + r'^java-([6-9])-jdk$', # Arch (oracle) + r'^java-1\.([6-9])\.0-.*$', # RedHat + r'^java-([6-9])-oracle$', # Debian WebUpd8 + r'^jdk-([6-9])-oracle-.*$', # Debian make-jpkg + r'^java-([6-9])-openjdk-[^c][^o][^m].*$', # Debian + ]: + m = re.match(regex, j) + if not m: + continue + for p in [d, os.path.join(d, 'Contents', 'Home')]: + if os.path.exists(os.path.join(p, 'bin', 'javac')): + thisconfig['java_paths'][m.group(1)] = p + + def fill_config_defaults(thisconfig): for k, v in default_config.items(): if k not in thisconfig: @@ -167,29 +202,7 @@ def fill_config_defaults(thisconfig): pathlist.append(os.getenv('JAVA_HOME')) if os.getenv('PROGRAMFILES') is not None: pathlist += glob.glob(os.path.join(os.getenv('PROGRAMFILES'), 'Java', 'jdk1.[6-9].*')) - for d in sorted(pathlist): - if os.path.islink(d): - continue - j = os.path.basename(d) - # the last one found will be the canonical one, so order appropriately - for regex in [ - r'^1\.([6-9])\.0\.jdk$', # OSX - r'^jdk1\.([6-9])\.0_[0-9]+.jdk$', # OSX and Oracle tarball - r'^jdk1\.([6-9])\.0_[0-9]+$', # Oracle Windows - r'^jdk([6-9])-openjdk$', # Arch - r'^java-([6-9])-openjdk$', # Arch - r'^java-([6-9])-jdk$', # Arch (oracle) - r'^java-1\.([6-9])\.0-.*$', # RedHat - r'^java-([6-9])-oracle$', # Debian WebUpd8 - r'^jdk-([6-9])-oracle-.*$', # Debian make-jpkg - r'^java-([6-9])-openjdk-[^c][^o][^m].*$', # Debian - ]: - m = re.match(regex, j) - if not m: - continue - for p in [d, os.path.join(d, 'Contents', 'Home')]: - if os.path.exists(os.path.join(p, 'bin', 'javac')): - thisconfig['java_paths'][m.group(1)] = p + _add_java_paths_to_config(pathlist, thisconfig) for java_version in ('7', '8', '9'): if java_version not in thisconfig['java_paths']: @@ -506,7 +519,7 @@ def get_extension(filename): def has_extension(filename, ext): - _, f_ext = get_extension(filename) + _ignored, f_ext = get_extension(filename) return ext == f_ext @@ -1732,7 +1745,7 @@ class KnownApks: default_date = datetime.utcnow() self.apks[apkName] = (app, default_date) self.changed = True - _, added = self.apks[apkName] + _ignored, added = self.apks[apkName] return added def getapp(self, apkname): @@ -2238,15 +2251,15 @@ def apk_strip_signatures(signed_apk, strip_manifest=False): os.rename(signed_apk, tmp_apk) with ZipFile(tmp_apk, 'r') as in_apk: with ZipFile(signed_apk, 'w') as out_apk: - for f in in_apk.infolist(): - if not apk_sigfile.match(f.filename): + for info in in_apk.infolist(): + if not apk_sigfile.match(info.filename): if strip_manifest: - if f.filename != 'META-INF/MANIFEST.MF': - buf = in_apk.read(f.filename) - out_apk.writestr(f.filename, buf) + if info.filename != 'META-INF/MANIFEST.MF': + buf = in_apk.read(info.filename) + out_apk.writestr(info, buf) else: - buf = in_apk.read(f.filename) - out_apk.writestr(f.filename, buf) + buf = in_apk.read(info.filename) + out_apk.writestr(info, buf) def apk_implant_signatures(apkpath, signaturefile, signedfile, manifest): @@ -2259,19 +2272,21 @@ def apk_implant_signatures(apkpath, signaturefile, signedfile, manifest): """ # get list of available signature files in metadata with tempfile.TemporaryDirectory() as tmpdir: - # orig_apk = os.path.join(tmpdir, 'orig.apk') - # os.rename(apkpath, orig_apk) apkwithnewsig = os.path.join(tmpdir, 'newsig.apk') with ZipFile(apkpath, 'r') as in_apk: with ZipFile(apkwithnewsig, 'w') as out_apk: for sig_file in [signaturefile, signedfile, manifest]: - out_apk.write(sig_file, arcname='META-INF/' + - os.path.basename(sig_file)) - for f in in_apk.infolist(): - if not apk_sigfile.match(f.filename): - if f.filename != 'META-INF/MANIFEST.MF': - buf = in_apk.read(f.filename) - out_apk.writestr(f.filename, buf) + with open(sig_file, 'rb') as fp: + buf = fp.read() + info = zipfile.ZipInfo('META-INF/' + os.path.basename(sig_file)) + info.compress_type = zipfile.ZIP_DEFLATED + info.create_system = 0 # "Windows" aka "FAT", what Android SDK uses + out_apk.writestr(info, buf) + for info in in_apk.infolist(): + if not apk_sigfile.match(info.filename): + if info.filename != 'META-INF/MANIFEST.MF': + buf = in_apk.read(info.filename) + out_apk.writestr(info, buf) os.remove(apkpath) p = SdkToolsPopen(['zipalign', '-v', '4', apkwithnewsig, apkpath]) if p.returncode != 0: diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 16c40a88..d65eb81a 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -380,8 +380,8 @@ class FieldValidator(): values = [v] for v in values: if not self.compiled.match(v): - warn_or_exception("'%s' is not a valid %s in %s. Regex pattern: %s" - % (v, self.name, appid, self.matching)) + warn_or_exception(_("'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}") + .format(value=v, field=self.name, appid=appid, pattern=self.matching)) # Generic value types @@ -534,7 +534,7 @@ class DescriptionFormatter: if txt.startswith("[["): index = txt.find("]]") if index == -1: - warn_or_exception("Unterminated ]]") + warn_or_exception(_("Unterminated ]]")) url = txt[2:index] if self.linkResolver: url, urltext = self.linkResolver(url) @@ -546,7 +546,7 @@ class DescriptionFormatter: else: index = txt.find("]") if index == -1: - warn_or_exception("Unterminated ]") + warn_or_exception(_("Unterminated ]")) url = txt[1:index] index2 = url.find(' ') if index2 == -1: @@ -555,7 +555,7 @@ class DescriptionFormatter: urltxt = url[index2 + 1:] url = url[:index2] if url == urltxt: - warn_or_exception("Url title is just the URL - use [url]") + warn_or_exception(_("URL title is just the URL, use brackets: [URL]")) res_html += '' + html.escape(urltxt, quote=False) + '' res_plain += urltxt if urltxt != url: @@ -664,7 +664,7 @@ def parse_srclib(metadatapath): try: f, v = line.split(':', 1) except ValueError: - warn_or_exception("Invalid metadata in %s:%d" % (line, n)) + warn_or_exception(_("Invalid metadata in %s:%d") % (line, n)) if f == "Subdir": thisinfo[f] = v.split(',') @@ -734,7 +734,8 @@ def read_metadata(xref=True, check_vcs=[]): + glob.glob('.fdroid.yml')): packageName, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath)) if packageName in apps: - warn_or_exception("Found multiple metadata files for " + packageName) + warn_or_exception(_("Found multiple metadata files for {appid}") + .format(path=packageName)) app = parse_metadata(metadatapath, packageName in check_vcs) check_metadata(app) apps[app.id] = app @@ -745,14 +746,14 @@ def read_metadata(xref=True, check_vcs=[]): def linkres(appid): if appid in apps: return ("fdroid.app:" + appid, "Dummy name - don't know yet") - warn_or_exception("Cannot resolve app id " + appid) + warn_or_exception(_("Cannot resolve app id {appid}").format(appid=appid)) for appid, app in apps.items(): try: description_html(app.Description, linkres) except MetaDataException as e: - warn_or_exception("Problem with description of " + appid + - " - " + str(e)) + warn_or_exception(_("Problem with description of {appid}: {error}") + .format(appid=appid, error=str(e))) return apps @@ -795,7 +796,8 @@ def get_default_app_info(metadatapath=None): manifestroot = fdroidserver.common.parse_xml(os.path.join(root, 'AndroidManifest.xml')) break if manifestroot is None: - warn_or_exception("Cannot find a packageName for {0}!".format(metadatapath)) + warn_or_exception(_("Cannot find a packageName for {path}!") + .format(path=metadatapath)) appid = manifestroot.attrib['package'] app = App() @@ -915,17 +917,17 @@ def _decode_bool(s): return True if bool_false.match(s): return False - warn_or_exception("Invalid bool '%s'" % s) + warn_or_exception(_("Invalid boolean '%s'") % s) def parse_metadata(metadatapath, check_vcs=False): '''parse metadata file, optionally checking the git repo for metadata first''' - _, ext = fdroidserver.common.get_extension(metadatapath) + _ignored, ext = fdroidserver.common.get_extension(metadatapath) accepted = fdroidserver.common.config['accepted_formats'] if ext not in accepted: - warn_or_exception('"%s" is not an accepted format, convert to: %s' % ( - metadatapath, ', '.join(accepted))) + warn_or_exception(_('"{path}" is not an accepted format, convert to: {formats}') + .format(path=metadatapath, formats=', '.join(accepted))) app = App() app.metadatapath = metadatapath @@ -943,7 +945,8 @@ def parse_metadata(metadatapath, check_vcs=False): elif ext == 'yml': parse_yaml_metadata(mf, app) else: - warn_or_exception('Unknown metadata format: %s' % metadatapath) + warn_or_exception(_('Unknown metadata format: {path}') + .format(path=metadatapath)) if check_vcs and app.Repo: build_dir = fdroidserver.common.get_build_dir(app) @@ -970,7 +973,7 @@ def parse_metadata(metadatapath, check_vcs=False): else: root_dir = '.' paths = fdroidserver.common.manifest_paths(root_dir, build.gradle) - _, _, app.id = fdroidserver.common.parse_androidmanifests(paths, app) + _ignored, _ignored, app.id = fdroidserver.common.parse_androidmanifests(paths, app) return app @@ -1162,12 +1165,12 @@ def parse_txt_metadata(mf, app): def add_buildflag(p, build): if not p.strip(): - warn_or_exception("Empty build flag at {1}" - .format(buildlines[0], linedesc)) + warn_or_exception(_("Empty build flag at {linedesc}") + .format(linedesc=linedesc)) bv = p.split('=', 1) if len(bv) != 2: - warn_or_exception("Invalid build flag at {0} in {1}" - .format(buildlines[0], linedesc)) + warn_or_exception(_("Invalid build flag at {line} in {linedesc}") + .format(line=buildlines[0], linedesc=linedesc)) pk, pv = bv pk = pk.lstrip() @@ -1186,7 +1189,8 @@ def parse_txt_metadata(mf, app): v = "".join(lines) parts = [p.replace("\\,", ",") for p in re.split(build_line_sep, v)] if len(parts) < 3: - warn_or_exception("Invalid build format: " + v + " in " + mf.name) + warn_or_exception(_("Invalid build format: {value} in {name}") + .format(value=v, name=mf.name)) build = Build() build.versionName = parts[0] build.versionCode = parts[1] @@ -1214,7 +1218,8 @@ def parse_txt_metadata(mf, app): try: int(versionCode) except ValueError: - warn_or_exception('Invalid versionCode: "' + versionCode + '" is not an integer!') + warn_or_exception(_('Invalid versionCode: "{versionCode}" is not an integer!') + .format(versionCode=versionCode)) def add_comments(key): if not curcomments: @@ -1247,8 +1252,8 @@ def parse_txt_metadata(mf, app): del buildlines[:] else: if not build.commit and not build.disable: - warn_or_exception("No commit specified for {0} in {1}" - .format(build.versionName, linedesc)) + warn_or_exception(_("No commit specified for {versionName} in {linedesc}") + .format(versionName=build.versionName, linedesc=linedesc)) app.builds.append(build) add_comments('build:' + build.versionCode) @@ -1263,10 +1268,10 @@ def parse_txt_metadata(mf, app): try: f, v = line.split(':', 1) except ValueError: - warn_or_exception("Invalid metadata in " + linedesc) + warn_or_exception(_("Invalid metadata in: ") + linedesc) if f not in app_fields: - warn_or_exception('Unrecognised app field: ' + f) + warn_or_exception(_('Unrecognised app field: ') + f) # Translate obsolete fields... if f == 'Market Version': @@ -1282,8 +1287,8 @@ def parse_txt_metadata(mf, app): if ftype == TYPE_MULTILINE: mode = 1 if v: - warn_or_exception("Unexpected text on same line as " - + f + " in " + linedesc) + warn_or_exception(_("Unexpected text on same line as {field} in {linedesc}") + .format(field=f, linedesc=linedesc)) elif ftype == TYPE_STRING: app[f] = v elif ftype == TYPE_LIST: @@ -1300,24 +1305,26 @@ def parse_txt_metadata(mf, app): elif ftype == TYPE_BUILD_V2: vv = v.split(',') if len(vv) != 2: - warn_or_exception('Build should have comma-separated', - 'versionName and versionCode,', - 'not "{0}", in {1}'.format(v, linedesc)) + warn_or_exception(_('Build should have comma-separated ' + 'versionName and versionCode, ' + 'not "{value}", in {linedesc}') + .format(value=v, linedesc=linedesc)) build = Build() build.versionName = vv[0] build.versionCode = vv[1] check_versionCode(build.versionCode) if build.versionCode in vc_seen: - warn_or_exception('Duplicate build recipe found for versionCode %s in %s' - % (build.versionCode, linedesc)) + warn_or_exception(_('Duplicate build recipe found for versionCode {versionCode} in {linedesc}') + .format(versionCode=build.versionCode, linedesc=linedesc)) vc_seen.add(build.versionCode) del buildlines[:] mode = 3 elif ftype == TYPE_OBSOLETE: pass # Just throw it away! else: - warn_or_exception("Unrecognised field '" + f + "' in " + linedesc) + warn_or_exception(_("Unrecognised field '{field}' in {linedesc}") + .format(field=f, linedesc=linedesc)) elif mode == 1: # Multiline field if line == '.': mode = 0 @@ -1338,11 +1345,14 @@ def parse_txt_metadata(mf, app): # Mode at end of file should always be 0 if mode == 1: - warn_or_exception(f + " not terminated in " + mf.name) + warn_or_exception(_("{field} not terminated in {name}") + .format(field=f, name=mf.name)) if mode == 2: - warn_or_exception("Unterminated continuation in " + mf.name) + warn_or_exception(_("Unterminated continuation in {name}") + .format(name=mf.name)) if mode == 3: - warn_or_exception("Unterminated build in " + mf.name) + warn_or_exception(_("Unterminated build in {name}") + .format(name=mf.name)) return app @@ -1498,11 +1508,11 @@ def write_txt(mf, app): def write_metadata(metadatapath, app): - _, ext = fdroidserver.common.get_extension(metadatapath) + _ignored, ext = fdroidserver.common.get_extension(metadatapath) accepted = fdroidserver.common.config['accepted_formats'] if ext not in accepted: - warn_or_exception('Cannot write "%s", not an accepted format, use: %s' - % (metadatapath, ', '.join(accepted))) + warn_or_exception(_('Cannot write "{path}", not an accepted format, use: {formats}') + .format(path=metadatapath, formats=', '.join(accepted))) try: with open(metadatapath, 'w', encoding='utf8') as mf: @@ -1514,7 +1524,7 @@ def write_metadata(metadatapath, app): os.remove(metadatapath) raise e - warn_or_exception('Unknown metadata format: %s' % metadatapath) + warn_or_exception(_('Unknown metadata format: %s') % metadatapath) def add_metadata_arguments(parser): diff --git a/fdroidserver/scanner.py b/fdroidserver/scanner.py index 030ac7c4..cad0026b 100644 --- a/fdroidserver/scanner.py +++ b/fdroidserver/scanner.py @@ -185,7 +185,7 @@ def scan_source(build_dir, build): continue path_in_build_dir = os.path.relpath(filepath, build_dir) - _, ext = common.get_extension(path_in_build_dir) + _ignored, ext = common.get_extension(path_in_build_dir) if ext == 'so': count += handleproblem('shared library', path_in_build_dir, filepath) diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 6b31f162..574f1c24 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -824,7 +824,7 @@ def insert_localized_app_metadata(apps): locale = segments[-2] destdir = os.path.join('repo', packageName, locale) for f in glob.glob(os.path.join(root, d, '*.*')): - _, extension = common.get_extension(f) + _ignored, extension = common.get_extension(f) if extension in ALLOWED_EXTENSIONS: screenshotdestdir = os.path.join(destdir, d) os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True) @@ -846,24 +846,24 @@ def insert_localized_app_metadata(apps): base, extension = common.get_extension(filename) if packageName not in apps: - logging.warning('Found "%s" graphic without metadata for app "%s"!' - % (filename, packageName)) + logging.warning(_('Found "{path}" graphic without metadata for app "{name}"!') + .format(path=filename, name=packageName)) continue graphics = _get_localized_dict(apps[packageName], locale) if extension not in ALLOWED_EXTENSIONS: - logging.warning('Only PNG and JPEG are supported for graphics, found: ' + f) + logging.warning(_('Only PNG and JPEG are supported for graphics, found: {path}').format(path=f)) elif base in GRAPHIC_NAMES: # there can only be zero or one of these per locale graphics[base] = filename elif screenshotdir in SCREENSHOT_DIRS: # there can any number of these per locale - logging.debug('adding to ' + screenshotdir + ': ' + f) + logging.debug(_('adding to {name}: {path}').format(name=screenshotdir, path=f)) if screenshotdir not in graphics: graphics[screenshotdir] = [] graphics[screenshotdir].append(filename) else: - logging.warning('Unsupported graphics file found: ' + f) + logging.warning(_('Unsupported graphics file found: {path}').format(path=f)) def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False): @@ -1625,7 +1625,7 @@ def move_apk_between_sections(from_dir, to_dir, apk): for density in all_screen_densities: from_icon_dir = get_icon_dir(from_dir, density) to_icon_dir = get_icon_dir(to_dir, density) - if density not in apk['icons']: + if density not in apk.get('icons', []): continue _move_file(from_icon_dir, to_icon_dir, apk['icons'][density], True) if 'srcname' in apk: diff --git a/tests/build.TestCase b/tests/build.TestCase index 9391a042..b595f3fa 100755 --- a/tests/build.TestCase +++ b/tests/build.TestCase @@ -74,4 +74,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(BuildTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/common.TestCase b/tests/common.TestCase index 3a10b7bb..ecd16a8d 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -92,6 +92,41 @@ class CommonTest(unittest.TestCase): else: print('no build-tools found: ' + build_tools) + def test_find_java_root_path(self): + tmptestsdir = tempfile.mkdtemp(prefix='test_find_java_root_path', dir=self.tmpdir) + os.chdir(tmptestsdir) + + all_pathlists = [ + ([ # Debian + '/usr/lib/jvm/java-1.5.0-gcj-5-amd64', + '/usr/lib/jvm/java-8-openjdk-amd64', + '/usr/lib/jvm/java-1.8.0-openjdk-amd64', + ], '/usr/lib/jvm/java-8-openjdk-amd64'), + ([ # OSX + '/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk', + '/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk', + '/System/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk', + ], '/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk'), + ] + + for pathlist, choice in all_pathlists: + # strip leading / to make relative paths to test without root + pathlist = [p[1:] for p in pathlist] + + # create test file used in common._add_java_paths_to_config() + for p in pathlist: + if p.startswith('/System') or p.startswith('/Library'): + basedir = os.path.join(p, 'Contents', 'Home', 'bin') + else: + basedir = os.path.join(p, 'bin') + os.makedirs(basedir) + open(os.path.join(basedir, 'javac'), 'w').close() + + config = dict() + config['java_paths'] = dict() + fdroidserver.common._add_java_paths_to_config(pathlist, config) + self.assertEqual(config['java_paths']['8'], choice[1:]) + def testIsApkDebuggable(self): config = dict() fdroidserver.common.fill_config_defaults(config) @@ -177,7 +212,7 @@ class CommonTest(unittest.TestCase): def test_prepare_sources_refresh(self): packageName = 'org.fdroid.ci.test.app' - testdir = tempfile.mkdtemp(prefix='test_verify_apks', dir=self.tmpdir) + testdir = tempfile.mkdtemp(prefix='test_prepare_sources_refresh', dir=self.tmpdir) print('testdir', testdir) os.chdir(testdir) os.mkdir('build') @@ -462,4 +497,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(CommonTest)) - unittest.main() + unittest.main(failfast=True) diff --git a/tests/exception.TestCase b/tests/exception.TestCase index 01d0a5af..6c2f0c3e 100755 --- a/tests/exception.TestCase +++ b/tests/exception.TestCase @@ -62,4 +62,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(ExceptionTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/import.TestCase b/tests/import.TestCase index 9c7b99d5..a41028c9 100755 --- a/tests/import.TestCase +++ b/tests/import.TestCase @@ -54,4 +54,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(ImportTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/index.TestCase b/tests/index.TestCase index bf76b812..4a7463fb 100755 --- a/tests/index.TestCase +++ b/tests/index.TestCase @@ -236,4 +236,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(IndexTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/install.TestCase b/tests/install.TestCase index ce516117..27573eae 100755 --- a/tests/install.TestCase +++ b/tests/install.TestCase @@ -43,4 +43,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(InstallTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/lint.TestCase b/tests/lint.TestCase index 158c5cb1..f2a411c5 100755 --- a/tests/lint.TestCase +++ b/tests/lint.TestCase @@ -53,4 +53,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(LintTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index f3d58077..306f1c46 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -129,4 +129,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(MetadataTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/publish.TestCase b/tests/publish.TestCase index 7a31d39e..8e165608 100755 --- a/tests/publish.TestCase +++ b/tests/publish.TestCase @@ -144,4 +144,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(PublishTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/signatures.TestCase b/tests/signatures.TestCase index 42a69c7c..bd6648cd 100755 --- a/tests/signatures.TestCase +++ b/tests/signatures.TestCase @@ -62,4 +62,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(SignaturesTest)) - unittest.main() + unittest.main(failfast=False) diff --git a/tests/update.TestCase b/tests/update.TestCase index 76a93802..8a88fc4e 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -576,4 +576,4 @@ if __name__ == "__main__": newSuite = unittest.TestSuite() newSuite.addTest(unittest.makeSuite(UpdateTest)) - unittest.main() + unittest.main(failfast=False)