From 7ff32bc4b0c7bea6d9d073a4b1c1b3a186cbd689 Mon Sep 17 00:00:00 2001 From: SilentGhost Date: Tue, 19 Nov 2024 20:36:41 +0100 Subject: [PATCH] Refactor TestCase files into python modules Convert all TestCase files into standard python modules to be run and discovered by unittest. --- .gitlab-ci.yml | 24 +- MANIFEST.in | 41 ++-- README.md | 6 +- hooks/pre-commit | 8 +- pyproject.toml | 10 +- tests/__init__.py | 0 tests/init.TestCase | 91 -------- tests/run-tests | 10 +- tests/{api.TestCase => test_api.py} | 30 +-- tests/{build.TestCase => test_build.py} | 44 +--- ...kupdates.TestCase => test_checkupdates.py} | 57 ++--- tests/{common.TestCase => test_common.py} | 149 +++++------- tests/{deploy.TestCase => test_deploy.py} | 49 +--- .../{exception.TestCase => test_exception.py} | 37 +-- tests/{github.TestCase => test_github.py} | 47 +--- tests/{gpgsign.TestCase => test_gpgsign.py} | 43 +--- ...and.TestCase => test_import_subcommand.py} | 52 ++--- tests/{index.TestCase => test_index.py} | 82 ++----- tests/test_init.py | 58 +++++ tests/{install.TestCase => test_install.py} | 32 --- tests/{lint.TestCase => test_lint.py} | 54 ++--- tests/{main.TestCase => test_main.py} | 41 +--- tests/{metadata.TestCase => test_metadata.py} | 75 ++---- tests/{net.TestCase => test_net.py} | 37 +-- tests/{nightly.TestCase => test_nightly.py} | 80 +++---- tests/{publish.TestCase => test_publish.py} | 60 ++--- ...writemeta.TestCase => test_rewritemeta.py} | 39 +--- tests/{scanner.TestCase => test_scanner.py} | 78 ++----- ...signatures.TestCase => test_signatures.py} | 47 +--- .../{signindex.TestCase => test_signindex.py} | 31 --- tests/{update.TestCase => test_update.py} | 220 ++++++++---------- tests/{vcs.TestCase => test_vcs.py} | 45 +--- tests/{verify.TestCase => test_verify.py} | 41 +--- tests/testcommon.py | 13 -- 34 files changed, 471 insertions(+), 1260 deletions(-) create mode 100644 tests/__init__.py delete mode 100755 tests/init.TestCase rename tests/{api.TestCase => test_api.py} (82%) rename tests/{build.TestCase => test_build.py} (97%) rename tests/{checkupdates.TestCase => test_checkupdates.py} (93%) rename tests/{common.TestCase => test_common.py} (96%) rename tests/{deploy.TestCase => test_deploy.py} (97%) rename tests/{exception.TestCase => test_exception.py} (55%) rename tests/{github.TestCase => test_github.py} (79%) rename tests/{gpgsign.TestCase => test_gpgsign.py} (60%) rename tests/{import_subcommand.TestCase => test_import_subcommand.py} (83%) rename tests/{index.TestCase => test_index.py} (93%) create mode 100755 tests/test_init.py rename tests/{install.TestCase => test_install.py} (92%) rename tests/{lint.TestCase => test_lint.py} (93%) rename tests/{main.TestCase => test_main.py} (90%) rename tests/{metadata.TestCase => test_metadata.py} (97%) rename tests/{net.TestCase => test_net.py} (85%) rename tests/{nightly.TestCase => test_nightly.py} (89%) rename tests/{publish.TestCase => test_publish.py} (90%) rename tests/{rewritemeta.TestCase => test_rewritemeta.py} (89%) rename tests/{scanner.TestCase => test_scanner.py} (93%) rename tests/{signatures.TestCase => test_signatures.py} (57%) rename tests/{signindex.TestCase => test_signindex.py} (89%) rename tests/{update.TestCase => test_update.py} (93%) rename tests/{vcs.TestCase => test_vcs.py} (66%) rename tests/{verify.TestCase => test_verify.py} (69%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 071dffe0..48f62c4a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -252,7 +252,6 @@ lint_format_bandit_checks: setup.py fdroidserver/*.py tests/*.py - tests/*.TestCase || set_error - shellcheck --exclude SC2046,SC2090 --severity=warning --color tests/run-tests || set_error @@ -619,10 +618,10 @@ Windows: - python -m pip install --upgrade babel pip setuptools - python -m pip install -e . - - $files = @(Get-ChildItem tests\*.TestCase) + - $files = @(Get-ChildItem tests\test_*.py) - foreach ($f in $files) { write-output $f; - python $f; + python -m unittest $f; if( $LASTEXITCODE -eq 0 ) { write-output "SUCCESS $f"; } else { @@ -631,15 +630,16 @@ Windows: } # these are the tests that must pass - - python tests\checkupdates.TestCase - - python tests\exception.TestCase - - python tests\import_subcommand.TestCase - - python tests\init.TestCase - - python tests\lint.TestCase - - python tests\main.TestCase - - python tests\metadata.TestCase - - python tests\rewritemeta.TestCase - - python tests\vcs.TestCase + - python -m unittest -k + checkupdates + exception + import_subcommand + test_lint + test_metadata + test_rewritemeta + test_vcs + tests.test_init + tests.test_main after_script: - Copy-Item C:\ProgramData\chocolatey\logs\chocolatey.log artifacts: diff --git a/MANIFEST.in b/MANIFEST.in index 76ddec7d..d847e172 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -50,7 +50,6 @@ include README.md include tests/aosp_testkey_debug.keystore include tests/apk.embedded_1.apk include tests/bad-unicode-*.apk -include tests/build.TestCase include tests/build-tools/17.0.0/aapt-output-com.moez.QKSMS_182.txt include tests/build-tools/17.0.0/aapt-output-com.politedroid_3.txt include tests/build-tools/17.0.0/aapt-output-com.politedroid_4.txt @@ -547,9 +546,7 @@ include tests/build-tools/28.0.3/aapt-output-obb.main.twoversions_1101617.txt include tests/build-tools/28.0.3/aapt-output-souch.smsbypass_9.txt include tests/build-tools/generate.sh include tests/check-fdroid-apk -include tests/checkupdates.TestCase include tests/com.fake.IpaApp_1000000000001.ipa -include tests/common.TestCase include tests/config.py include tests/config/antiFeatures.yml include tests/config/categories.yml @@ -569,10 +566,8 @@ include tests/config/ic_antifeature_upstreamnonfree.xml include tests/config/ro/antiFeatures.yml include tests/config/zh-rCN/antiFeatures.yml include tests/corrupt-featureGraphic.png -include tests/deploy.TestCase include tests/dummy-keystore.jks include tests/dump_internal_metadata_format.py -include tests/exception.TestCase include tests/extra/manual-vmtools-test.py include tests/funding-usernames.yaml include tests/get_android_tools_versions/android-ndk-r10e/RELEASE.TXT @@ -591,10 +586,6 @@ include tests/gnupghome/secring.gpg include tests/gnupghome/trustdb.gpg include tests/gradle-maven-blocks.yaml include tests/gradle-release-checksums.py -include tests/import_subcommand.TestCase -include tests/index.TestCase -include tests/init.TestCase -include tests/install.TestCase include tests/IsMD5Disabled.java include tests/issue-1128-min-sdk-30-poc.apk include tests/issue-1128-poc1.apk @@ -604,8 +595,6 @@ include tests/issue-1128-poc3b.apk include tests/janus.apk include tests/keystore.jks include tests/key-tricks.py -include tests/lint.TestCase -include tests/main.TestCase include tests/metadata/apk/info.guardianproject.urzip.yaml include tests/metadata/apk/org.dyndns.fules.ck.yaml include tests/metadata/app.with.special.build.params.yml @@ -660,10 +649,7 @@ include tests/metadata-rewrite-yml/app.with.special.build.params.yml include tests/metadata-rewrite-yml/fake.ota.update.yml include tests/metadata-rewrite-yml/org.fdroid.fdroid.yml include tests/metadata/souch.smsbypass.yml -include tests/metadata.TestCase include tests/minimal_targetsdk_30_unsigned.apk -include tests/net.TestCase -include tests/nightly.TestCase include tests/Norway_bouvet_europe_2.obf.zip include tests/no_targetsdk_minsdk1_unsigned.apk include tests/no_targetsdk_minsdk30_unsigned.apk @@ -674,7 +660,6 @@ include tests/org.bitbucket.tickytacky.mirrormirror_3.apk include tests/org.bitbucket.tickytacky.mirrormirror_4.apk include tests/org.dyndns.fules.ck_20.apk include tests/org.sajeg.fallingblocks_3.apk -include tests/publish.TestCase include tests/repo/com.example.test.helloworld_1.apk include tests/repo/com.politedroid_3.apk include tests/repo/com.politedroid_4.apk @@ -732,13 +717,9 @@ include tests/repo/patch.1619.obb.mainpatch.current.obb include tests/repo/souch.smsbypass_9.apk include tests/repo/urzip-*.apk include tests/repo/v1.v2.sig_1020.apk -include tests/rewritemeta.TestCase include tests/run-tests include tests/SANAPPSI.RSA include tests/SANAPPSI.SF -include tests/scanner.TestCase -include tests/signatures.TestCase -include tests/signindex.TestCase include tests/signindex/guardianproject.jar include tests/signindex/guardianproject-v1.jar include tests/signindex/testy.jar @@ -864,7 +845,27 @@ include tests/source-files/yuriykulikov/AlarmClock/gradle/wrapper/gradle-wrapper include tests/source-files/Zillode/syncthing-silk/build.gradle include tests/SpeedoMeterApp.main_1.apk include tests/testcommon.py +include tests/test_build.py +include tests/test_checkupdates.py +include tests/test_common.py +include tests/test_deploy.py +include tests/test_exception.py include tests/test_gradlew-fdroid +include tests/test_import_subcommand.py +include tests/test_index.py +include tests/test_init.py +include tests/test_install.py +include tests/test_lint.py +include tests/test_main.py +include tests/test_metadata.py +include tests/test_nightly.py +include tests/test_publish.py +include tests/test_rewritemeta.py +include tests/test_scanner.py +include tests/test_signatures.py +include tests/test_signindex.py +include tests/test_update.py +include tests/test_vcs.py include tests/triple-t-2/build/org.piwigo.android/app/build.gradle include tests/triple-t-2/build/org.piwigo.android/app/.gitignore include tests/triple-t-2/build/org.piwigo.android/app/src/debug/res/values/constants.xml @@ -921,7 +922,6 @@ include tests/triple-t-multiple/build/ch.admin.bag.covidcertificate.wallet/verif include tests/triple-t-multiple/build/ch.admin.bag.covidcertificate.wallet/wallet/src/main/play/listings/en-US/title.txt include tests/triple-t-multiple/metadata/ch.admin.bag.covidcertificate.verifier.yml include tests/triple-t-multiple/metadata/ch.admin.bag.covidcertificate.wallet.yml -include tests/update.TestCase include tests/urzip.apk include tests/urzip-badcert.apk include tests/urzip-badsig.apk @@ -931,4 +931,3 @@ include tests/v2.only.sig_2.apk include tests/valid-package-names/random-package-names include tests/valid-package-names/RandomPackageNames.java include tests/valid-package-names/test.py -include tests/vcs.TestCase diff --git a/README.md b/README.md index adc33128..41f725cb 100644 --- a/README.md +++ b/README.md @@ -53,13 +53,13 @@ To run the full test suite: tests/run-tests -To run the tests for individual Python modules, see the _.TestCase_ files, e.g.: +To run the tests for individual Python modules, see the `tests/test_*.py` files, e.g.: - tests/metadata.TestCase + python -m unittest tests/test_metadata.py It is also possible to run individual tests: - tests/metadata.TestCase MetadataTest.test_rewrite_yaml_special_build_params + python -m unittest tests.test_metadata.MetadataTest.test_rewrite_yaml_special_build_params There is a growing test suite that has good coverage on a number of key parts of this code base. It does not yet cover all the code, and there are some parts diff --git a/hooks/pre-commit b/hooks/pre-commit index c1761aa8..784cc9ee 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -9,7 +9,7 @@ exec 1>&2 files=`git diff-index --cached HEAD 2>&1 | sed 's/^:.* //' | uniq | cut -b100-500` if [ -z "$files" ]; then PY_FILES="fdroid makebuildserver setup.py fdroidserver/*.py examples/*.py tests/*-release-checksums.py" - PY_TEST_FILES="tests/*.TestCase" + PY_TEST_FILES="tests/test_*.py" SH_FILES="hooks/pre-commit" BASH_FILES="gradlew-fdroid jenkins-build-all jenkins-setup-build-environment jenkins-test completion/bash-completion buildserver/provision-*" RB_FILES="buildserver/Vagrantfile" @@ -27,12 +27,12 @@ else for f in $files; do test -e $f || continue case $f in + test_*.py) + PY_TEST_FILES+=" $f" + ;; *.py) PY_FILES+=" $f" ;; - *.TestCase) - PY_TEST_FILES+=" $f" - ;; *.rb) RB_FILES+=" $f" ;; diff --git a/pyproject.toml b/pyproject.toml index 876053c5..a643fa37 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ ignore = "E123,E203,E402,E501,W503" [tool.black] skip-string-normalization = true target-version = ["py38"] -include = '(^fdroid|\.pyi?|\.TestCase)$' +include = '(^fdroid|\.pyi?)$' # These files will never be included in black runs. To run black on # one of thes files, remove it from this list. force-exclude = '''( @@ -49,10 +49,10 @@ force-exclude = '''( | tests/gradle-release-checksums\.py | tests/openssl-version-check-test\.py | tests/valid-package-names/test\.py - | tests/common\.TestCase - | tests/publish\.TestCase - | tests/signatures\.TestCase - | tests/update\.TestCase + | tests/test_common\.py + | tests/test_publish\.py + | tests/test_signatures\.py + | tests/test_update\.py )$''' diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/init.TestCase b/tests/init.TestCase deleted file mode 100755 index 7e674cb5..00000000 --- a/tests/init.TestCase +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python3 - -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - -import inspect -import logging -import os -import shutil -import sys -import unittest - - -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.init -from testcommon import mkdtemp, parse_args_for_test - - -class InitTest(unittest.TestCase): - '''fdroidserver/init.py''' - - def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = os.path.join(localmodule, 'tests') - fdroidserver.common.config = None - fdroidserver.init.config = None - self._td = mkdtemp() - self.testdir = self._td.name - - def tearDown(self): - self._td.cleanup() - os.chdir(self.basedir) - - def test_disable_in_config(self): - os.chdir(self.testdir) - with open('config.yml', 'w') as fp: - fp.write('keystore: NONE\n') - fp.write('keypass: mysupersecrets\n') - os.chmod('config.yml', 0o600) - config = fdroidserver.common.read_config() - self.assertEqual('NONE', config['keystore']) - self.assertEqual('mysupersecrets', config['keypass']) - fdroidserver.init.disable_in_config('keypass', 'comment') - with open(fp.name) as fp: - self.assertTrue('#keypass:' in fp.read()) - fdroidserver.common.config = None - config = fdroidserver.common.read_config() - self.assertIsNone(config.get('keypass')) - - @unittest.skipIf(os.name == 'nt', "calling main() like this hangs on Windows") - def test_main_in_empty_dir(self): - """Test that `fdroid init` will find apksigner and add it to the config""" - os.chdir(self.testdir) - - shutil.copy(os.path.join(self.basedir, 'keystore.jks'), self.testdir) - - bindir = os.path.join(os.getcwd(), 'bin') - os.mkdir(bindir) - apksigner = os.path.join(bindir, 'apksigner') - open(apksigner, 'w').close() - os.chmod(apksigner, 0o755) - os.environ['PATH'] = bindir - - sys.argv = ['fdroid init', '--keystore', 'keystore.jks', '--repo-keyalias=sova'] - fdroidserver.init.main() - self.assertEqual(apksigner, fdroidserver.init.config.get('apksigner')) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - fdroidserver.init.options = parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(InitTest)) - unittest.main(failfast=False) diff --git a/tests/run-tests b/tests/run-tests index 303327a5..7e3f0c13 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -170,15 +170,7 @@ test -x ./hooks/pre-commit && ./hooks/pre-commit #------------------------------------------------------------------------------# echo_header "run unit tests" -cd $WORKSPACE/tests -for testcase in $WORKSPACE/tests/*.TestCase; do - if [ $(uname) != "Linux" ] && [ $testcase == $WORKSPACE/tests/nightly.TestCase ]; then - echo "skipping nightly.TestCase, it currently only works GNU/Linux" - continue - fi - $testcase -done - +python3 -m unittest -v #------------------------------------------------------------------------------# echo_header "print fdroid version" diff --git a/tests/api.TestCase b/tests/test_api.py similarity index 82% rename from tests/api.TestCase rename to tests/test_api.py index e3e66765..a2d91926 100755 --- a/tests/api.TestCase +++ b/tests/test_api.py @@ -1,22 +1,17 @@ #!/usr/bin/env python3 -import inspect import os import shutil -import sys import unittest +from pathlib import Path from unittest import mock -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 from fdroidserver import common, signindex -from testcommon import GP_FINGERPRINT, mkdtemp +from .testcommon import GP_FINGERPRINT, mkdtemp + + +basedir = Path(__file__).parent class ApiTest(unittest.TestCase): @@ -29,8 +24,7 @@ class ApiTest(unittest.TestCase): """ def setUp(self): - self.basedir = os.path.join(localmodule, 'tests') - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name @@ -89,10 +83,10 @@ class ApiTest(unittest.TestCase): self.testdir, 'repo', os.path.basename(mirrors[0]['url']) ) os.chdir(self.testdir) - signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + signindex.config['keystore'] = os.path.join(basedir, 'keystore.jks') os.mkdir('repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo') + shutil.copy(basedir / 'repo' / 'entry.json', 'repo') + shutil.copy(basedir / 'repo' / 'index-v2.json', 'repo') signindex.sign_index('repo', 'entry.json') repo_url = 'https://fake.url/fdroid/repo' entry_url = 'https://fake.url/fdroid/repo/entry.jar' @@ -107,9 +101,3 @@ class ApiTest(unittest.TestCase): self.assertEqual( 'My First F-Droid Repo Demo', data['repo']['name']['en-US'] ) - - -if __name__ == "__main__": - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(ApiTest)) - unittest.main(failfast=False) diff --git a/tests/build.TestCase b/tests/test_build.py similarity index 97% rename from tests/build.TestCase rename to tests/test_build.py index f6607634..94596daa 100755 --- a/tests/build.TestCase +++ b/tests/test_build.py @@ -1,12 +1,7 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - -import inspect -import logging import os import shutil -import sys import tempfile import textwrap import unittest @@ -14,21 +9,10 @@ import yaml from pathlib import Path from unittest import mock -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) - -from testcommon import TmpCwd +from .testcommon import TmpCwd, mkdtemp import fdroidserver.build import fdroidserver.common -import fdroidserver.metadata -import fdroidserver.scanner -import fdroidserver.vmtools -from testcommon import mkdtemp, parse_args_for_test class FakeProcess: @@ -47,8 +31,7 @@ class BuildTest(unittest.TestCase): '''fdroidserver/build.py''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = os.path.join(localmodule, 'tests') + self.basedir = str(Path(__file__).parent) os.chdir(self.basedir) fdroidserver.common.config = None fdroidserver.build.config = None @@ -937,7 +920,7 @@ class BuildTest(unittest.TestCase): subprocess_check_output, paramiko_SSHClient, fdroidserver_vmtools_get_clean_builder, - fdroidserver_vmtools_get_build_vm, + fdroidserver_vmtools_get_build_vm, # pylint: disable=unused-argument ): """srclibs Prepare: should only be executed in the buildserver""" @@ -954,6 +937,7 @@ class BuildTest(unittest.TestCase): refresh=True, build=None, ): + # pylint: disable=unused-argument name, ref = spec.split('@') libdir = os.path.join(srclib_dir, name) os.mkdir(libdir) @@ -1098,23 +1082,3 @@ class BuildTest(unittest.TestCase): fdroidserver.build.options.keep_when_not_allowed = False fdroidserver.build.config = {'keep_when_not_allowed': False} self.assertFalse(fdroidserver.build.keep_when_not_allowed()) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(BuildTest)) - unittest.main(failfast=False) diff --git a/tests/checkupdates.TestCase b/tests/test_checkupdates.py similarity index 93% rename from tests/checkupdates.TestCase rename to tests/test_checkupdates.py index 8006dd2d..8225cdff 100755 --- a/tests/checkupdates.TestCase +++ b/tests/test_checkupdates.py @@ -1,36 +1,26 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - import git -import logging import os import shutil -import sys import tempfile import time import unittest from unittest import mock from pathlib import Path - -localmodule = Path(__file__).resolve().parent.parent -print('localmodule: ' + str(localmodule)) -if localmodule not in sys.path: - sys.path.insert(0, str(localmodule)) - +import fdroidserver import fdroidserver.checkupdates -import fdroidserver.metadata -from fdroidserver.exception import FDroidException + + +basedir = Path(__file__).parent class CheckupdatesTest(unittest.TestCase): '''fdroidserver/checkupdates.py''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = localmodule / 'tests' - os.chdir(self.basedir) + os.chdir(basedir) self.testdir = tempfile.TemporaryDirectory( str(time.time()), self._testMethodName + '_' ) @@ -70,7 +60,7 @@ class CheckupdatesTest(unittest.TestCase): ): with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()): with mock.patch('subprocess.call', lambda cmd: 0): - with self.assertRaises(FDroidException): + with self.assertRaises(fdroidserver.exception.FDroidException): fdroidserver.checkupdates.checkupdates_app(app, auto=True) build = app['Builds'][-1] @@ -165,7 +155,7 @@ class CheckupdatesTest(unittest.TestCase): with mock.patch( 'fdroidserver.checkupdates.check_http', lambda app: (None, 'bla') ): - with self.assertRaises(FDroidException): + with self.assertRaises(fdroidserver.exception.FDroidException): fdroidserver.checkupdates.checkupdates_app(app, auto=True) with mock.patch( @@ -198,7 +188,7 @@ class CheckupdatesTest(unittest.TestCase): 'fdroidserver.checkupdates.check_tags', lambda app, pattern: (None, 'bla', None), ): - with self.assertRaises(FDroidException): + with self.assertRaises(fdroidserver.exception.FDroidException): fdroidserver.checkupdates.checkupdates_app(app, auto=True) with mock.patch( @@ -236,7 +226,7 @@ class CheckupdatesTest(unittest.TestCase): faked = scheme + '://fake.url/for/testing/scheme' app.UpdateCheckData = faked + '|ignored|' + faked + '|ignored' app.metadatapath = 'metadata/' + app.id + '.yml' - with self.assertRaises(FDroidException): + with self.assertRaises(fdroidserver.exception.FDroidException): fdroidserver.checkupdates.check_http(app) def test_check_http_ignore(self): @@ -331,7 +321,7 @@ class CheckupdatesTest(unittest.TestCase): testdir = self.testdir.name os.chdir(testdir) os.mkdir('metadata') - for f in (self.basedir / 'metadata').glob('*.yml'): + for f in (basedir / 'metadata').glob('*.yml'): shutil.copy(f, 'metadata') git_repo = git.Repo.init(testdir) git_repo.git.add(all=True) @@ -434,7 +424,7 @@ class CheckupdatesTest(unittest.TestCase): @mock.patch('fdroidserver.metadata.read_metadata') def test_merge_requests_flag(self, read_metadata, sys_exit): def _sys_exit(return_code=0): - assert return_code != 0 + self.assertNotEqual(return_code, 0) raise fdroidserver.exception.FDroidException('sys.exit() ran') def _read_metadata(a=None, b=None): @@ -479,7 +469,7 @@ class CheckupdatesTest(unittest.TestCase): @mock.patch('fdroidserver.checkupdates.checkupdates_app') def test_merge_requests_branch(self, checkupdates_app, read_app_args, sys_exit): def _sys_exit(return_code=0): - assert return_code == 0 + self.assertEqual(return_code, 0) def _checkupdates_app(app, auto, commit): # pylint: disable=unused-argument os.mkdir('metadata') @@ -506,27 +496,8 @@ class CheckupdatesTest(unittest.TestCase): git_repo.create_remote('origin', os.getcwd()).fetch() git_repo.create_remote('upstream', os.getcwd()).fetch() - assert appid not in git_repo.heads + self.assertNotIn(appid, git_repo.heads) with mock.patch('sys.argv', ['fdroid checkupdates', '--merge-request', appid]): fdroidserver.checkupdates.main() sys_exit.assert_called_once() - assert appid in git_repo.heads - - -if __name__ == "__main__": - import argparse - from testcommon import parse_args_for_test - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(CheckupdatesTest)) - unittest.main(failfast=False) + self.assertIn(appid, git_repo.heads) diff --git a/tests/common.TestCase b/tests/test_common.py similarity index 96% rename from tests/common.TestCase rename to tests/test_common.py index c2e03243..5ad5a771 100755 --- a/tests/common.TestCase +++ b/tests/test_common.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - import difflib import git import glob @@ -28,25 +26,20 @@ from unittest import mock from pathlib import Path -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.index -import fdroidserver.install +import fdroidserver import fdroidserver.signindex import fdroidserver.common import fdroidserver.metadata -from testcommon import TmpCwd, mkdtemp, parse_args_for_test +from .testcommon import TmpCwd, mkdtemp from fdroidserver.common import ANTIFEATURES_CONFIG_NAME, CATEGORIES_CONFIG_NAME from fdroidserver.exception import FDroidException, VCSException,\ MetaDataException, VerificationException from fdroidserver.looseversion import LooseVersion +basedir = Path(__file__).parent + + def _mock_common_module_options_instance(): """Helper method to deal with difficult visibility of the module-level options.""" fdroidserver.common.options = mock.Mock() @@ -60,11 +53,10 @@ class CommonTest(unittest.TestCase): logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger('androguard.axml') logger.setLevel(logging.INFO) # tame the axml debug messages - self.basedir = os.path.join(localmodule, 'tests') - self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles')) + self.tmpdir = os.path.abspath(os.path.join(basedir, '..', '.testfiles')) if not os.path.exists(self.tmpdir): os.makedirs(self.tmpdir) - os.chdir(self.basedir) + os.chdir(basedir) # these are declared as None at the top of the module file fdroidserver.common.config = None @@ -77,7 +69,7 @@ class CommonTest(unittest.TestCase): def tearDown(self): fdroidserver.common.config = None fdroidserver.common.options = None - os.chdir(self.basedir) + os.chdir(basedir) self._td.cleanup() if os.path.exists(self.tmpdir): shutil.rmtree(self.tmpdir) @@ -187,11 +179,11 @@ class CommonTest(unittest.TestCase): # 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') + _dir = 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() + _dir = os.path.join(p, 'bin') + os.makedirs(_dir) + open(os.path.join(_dir, 'javac'), 'w').close() config = dict() config['java_paths'] = dict() @@ -204,21 +196,14 @@ class CommonTest(unittest.TestCase): fdroidserver.common.config = config # these are set debuggable - testfiles = [] - testfiles.append(os.path.join(self.basedir, 'urzip.apk')) - testfiles.append(os.path.join(self.basedir, 'urzip-badsig.apk')) - testfiles.append(os.path.join(self.basedir, 'urzip-badcert.apk')) - for apkfile in testfiles: + for apkfile in ('urzip.apk', 'urzip-badsig.apk', 'urzip-badcert.apk'): self.assertTrue( - fdroidserver.common.is_debuggable_or_testOnly(apkfile), + fdroidserver.common.is_debuggable_or_testOnly(str(basedir / apkfile)), "debuggable APK state was not properly parsed!", ) # these are set NOT debuggable - testfiles = [] - testfiles.append(os.path.join(self.basedir, 'urzip-release.apk')) - testfiles.append(os.path.join(self.basedir, 'urzip-release-unsigned.apk')) - testfiles.append(os.path.join(self.basedir, 'v2.only.sig_2.apk')) + testfiles = 'urzip-release.apk', 'urzip-release-unsigned.apk', 'v2.only.sig_2.apk' for apkfile in testfiles: self.assertFalse( fdroidserver.common.is_debuggable_or_testOnly(apkfile), @@ -297,7 +282,7 @@ class CommonTest(unittest.TestCase): teststr = 'FAKE_STR_FOR_TESTING' shutil.copytree( - os.path.join(self.basedir, 'source-files'), + os.path.join(basedir, 'source-files'), os.path.join(self.tmpdir, 'source-files'), ) @@ -356,7 +341,7 @@ class CommonTest(unittest.TestCase): def test_prepare_sources_with_prebuild_subdir(self): app_build_dir = os.path.join(self.testdir, 'build', 'com.example') shutil.copytree( - os.path.join(self.basedir, 'source-files', 'fdroid', 'fdroidclient'), + basedir / 'source-files' / 'fdroid' / 'fdroidclient', app_build_dir, ) @@ -418,7 +403,7 @@ class CommonTest(unittest.TestCase): os.mkdir('metadata') # use a local copy if available to avoid hitting the network - tmprepo = os.path.join(self.basedir, 'tmp', 'importer') + tmprepo = os.path.join(basedir, 'tmp', 'importer') if os.path.exists(tmprepo): git_url = tmprepo else: @@ -499,7 +484,7 @@ class CommonTest(unittest.TestCase): fdroidserver.common.config = config fdroidserver.signindex.config = config - sourcedir = os.path.join(self.basedir, 'signindex') + sourcedir = os.path.join(basedir, 'signindex') with tempfile.TemporaryDirectory( prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir ) as testsdir: @@ -561,7 +546,7 @@ class CommonTest(unittest.TestCase): """Sign entry.jar and make sure it validates""" config = fdroidserver.common.read_config() config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') - config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + config['keystore'] = os.path.join(basedir, 'keystore.jks') config['repo_keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' @@ -580,7 +565,7 @@ class CommonTest(unittest.TestCase): config = fdroidserver.common.read_config() config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') fdroidserver.common.config = config - source_dir = os.path.join(self.basedir, 'signindex') + source_dir = os.path.join(basedir, 'signindex') for f in ('unsigned.jar', 'testy.jar', 'guardianproject.jar', 'guardianproject-v1.jar'): testfile = os.path.join(source_dir, f) with self.assertRaises(fdroidserver.index.VerificationException): @@ -590,7 +575,7 @@ class CommonTest(unittest.TestCase): config = fdroidserver.common.read_config() config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') fdroidserver.common.config = config - source_dir = os.path.join(self.basedir, 'signindex') + source_dir = os.path.join(basedir, 'signindex') for f in ('testy.jar', 'guardianproject.jar'): testfile = os.path.join(source_dir, f) fdroidserver.common.verify_deprecated_jar_signature(testfile) @@ -604,7 +589,7 @@ class CommonTest(unittest.TestCase): fdroidserver.common.config = config _mock_common_module_options_instance() - sourceapk = os.path.join(self.basedir, 'urzip.apk') + sourceapk = os.path.join(basedir, 'urzip.apk') copyapk = os.path.join(self.testdir, 'urzip-copy.apk') shutil.copy(sourceapk, copyapk) @@ -624,7 +609,7 @@ class CommonTest(unittest.TestCase): ) twosigapk = os.path.join(self.testdir, 'urzip-twosig.apk') - otherapk = ZipFile(os.path.join(self.basedir, 'urzip-release.apk'), 'r') + otherapk = ZipFile(os.path.join(basedir, 'urzip-release.apk'), 'r') with ZipFile(sourceapk, 'r') as apk: with ZipFile(twosigapk, 'w') as testapk: for info in apk.infolist(): @@ -825,7 +810,7 @@ class CommonTest(unittest.TestCase): os.makedirs(os.path.dirname(do_not_use)) with open(do_not_use, 'w') as fp: fp.write('#!/bin/sh\ndate\n') - os.chmod(do_not_use, 0o0755) + os.chmod(do_not_use, 0o0755) # nosec B103 apksigner = os.path.join(self.tmpdir, 'apksigner') config = {'apksigner': apksigner} with mock.patch.dict(os.environ, clear=True): @@ -840,14 +825,14 @@ class CommonTest(unittest.TestCase): apksigner = os.path.join(self.tmpdir, 'apksigner') with open(apksigner, 'w') as fp: fp.write('#!/bin/sh\ndate\n') - os.chmod(apksigner, 0o0755) + os.chmod(apksigner, 0o0755) # nosec B103 android_home = os.path.join(self.tmpdir, 'ANDROID_HOME') do_not_use = os.path.join(android_home, 'build-tools', '30.0.3', 'apksigner') os.makedirs(os.path.dirname(do_not_use)) with open(do_not_use, 'w') as fp: fp.write('#!/bin/sh\ndate\n') - os.chmod(do_not_use, 0o0755) + os.chmod(do_not_use, 0o0755) # nosec B103 config = {'sdk_path': android_home} with mock.patch.dict(os.environ, clear=True): @@ -865,13 +850,13 @@ class CommonTest(unittest.TestCase): os.makedirs(os.path.dirname(apksigner)) with open(apksigner, 'w') as fp: fp.write('#!/bin/sh\necho 30.0.3\n') - os.chmod(apksigner, 0o0755) + os.chmod(apksigner, 0o0755) # nosec B103 do_not_use = os.path.join(android_home, 'build-tools', '29.0.3', 'apksigner') os.makedirs(os.path.dirname(do_not_use)) with open(do_not_use, 'w') as fp: fp.write('#!/bin/sh\necho 29.0.3\n') - os.chmod(do_not_use, 0o0755) + os.chmod(do_not_use, 0o0755) # nosec B103 config = {'sdk_path': android_home} with mock.patch.dict(os.environ, clear=True): @@ -917,13 +902,13 @@ class CommonTest(unittest.TestCase): config['keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' - config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + config['keystore'] = os.path.join(basedir, 'keystore.jks') fdroidserver.common.config = config fdroidserver.signindex.config = config unsigned = os.path.join(self.testdir, 'urzip-release-unsigned.apk') signed = os.path.join(self.testdir, 'urzip-release.apk') - shutil.copy(os.path.join(self.basedir, 'urzip-release-unsigned.apk'), self.testdir) + shutil.copy(os.path.join(basedir, 'urzip-release-unsigned.apk'), self.testdir) self.assertFalse(fdroidserver.common.verify_apk_signature(unsigned)) @@ -936,7 +921,7 @@ class CommonTest(unittest.TestCase): unsigned = os.path.join(self.testdir, 'duplicate.permisssions_9999999-unsigned.apk') signed = os.path.join(self.testdir, 'duplicate.permisssions_9999999.apk') shutil.copy( - os.path.join(self.basedir, 'repo', 'duplicate.permisssions_9999999.apk'), + os.path.join(basedir, 'repo', 'duplicate.permisssions_9999999.apk'), os.path.join(unsigned), ) fdroidserver.common.apk_strip_v1_signatures(unsigned, strip_manifest=True) @@ -946,7 +931,7 @@ class CommonTest(unittest.TestCase): self.assertTrue(fdroidserver.common.verify_apk_signature(signed)) self.assertEqual('18', fdroidserver.common.get_androguard_APK(signed).get_min_sdk_version()) - shutil.copy(os.path.join(self.basedir, 'minimal_targetsdk_30_unsigned.apk'), self.testdir) + shutil.copy(os.path.join(basedir, 'minimal_targetsdk_30_unsigned.apk'), self.testdir) unsigned = os.path.join(self.testdir, 'minimal_targetsdk_30_unsigned.apk') signed = os.path.join(self.testdir, 'minimal_targetsdk_30.apk') @@ -959,7 +944,7 @@ class CommonTest(unittest.TestCase): # verify it has a v2 signature self.assertTrue(fdroidserver.common.get_androguard_APK(signed).is_signed_v2()) - shutil.copy(os.path.join(self.basedir, 'no_targetsdk_minsdk30_unsigned.apk'), self.testdir) + shutil.copy(os.path.join(basedir, 'no_targetsdk_minsdk30_unsigned.apk'), self.testdir) unsigned = os.path.join(self.testdir, 'no_targetsdk_minsdk30_unsigned.apk') signed = os.path.join(self.testdir, 'no_targetsdk_minsdk30_signed.apk') @@ -967,7 +952,7 @@ class CommonTest(unittest.TestCase): self.assertTrue(fdroidserver.common.verify_apk_signature(signed)) self.assertTrue(fdroidserver.common.get_androguard_APK(signed).is_signed_v2()) - shutil.copy(os.path.join(self.basedir, 'no_targetsdk_minsdk1_unsigned.apk'), self.testdir) + shutil.copy(os.path.join(basedir, 'no_targetsdk_minsdk1_unsigned.apk'), self.testdir) unsigned = os.path.join(self.testdir, 'no_targetsdk_minsdk1_unsigned.apk') signed = os.path.join(self.testdir, 'no_targetsdk_minsdk1_signed.apk') @@ -988,18 +973,18 @@ class CommonTest(unittest.TestCase): config['keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' - config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + config['keystore'] = os.path.join(basedir, 'keystore.jks') fdroidserver.common.config = config fdroidserver.signindex.config = config unsigned = os.path.join(self.testdir, 'urzip-release-unsigned.apk') signed = os.path.join(self.testdir, 'urzip-release.apk') - shutil.copy(os.path.join(self.basedir, 'urzip-release-unsigned.apk'), self.testdir) + shutil.copy(os.path.join(basedir, 'urzip-release-unsigned.apk'), self.testdir) os.chmod(unsigned, 0o000) with self.assertRaises(fdroidserver.exception.BuildException): fdroidserver.common.sign_apk(unsigned, signed, config['keyalias']) - os.chmod(unsigned, 0o777) + os.chmod(unsigned, 0o777) # nosec B103 self.assertTrue(os.path.isfile(unsigned)) self.assertFalse(os.path.isfile(signed)) @@ -1012,7 +997,7 @@ class CommonTest(unittest.TestCase): config['keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' - config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + config['keystore'] = os.path.join(basedir, 'keystore.jks') fdroidserver.common.config = config fdroidserver.signindex.config = config @@ -1039,7 +1024,7 @@ class CommonTest(unittest.TestCase): config['keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' - config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + config['keystore'] = os.path.join(basedir, 'keystore.jks') fdroidserver.common.config = config fdroidserver.signindex.config = config @@ -1052,7 +1037,7 @@ class CommonTest(unittest.TestCase): 'v2.only.sig_2.apk', 'SystemWebView-repack.apk', ): - original = os.path.join(self.basedir, apk) + original = os.path.join(basedir, apk) unsigned = os.path.join('unsigned', apk) resign = os.path.join('repo', apk) shutil.copy(original, unsigned) @@ -1149,7 +1134,7 @@ class CommonTest(unittest.TestCase): fdroidserver.common.get_apk_id(badzip) def test_get_apk_id_aapt_regex(self): - files = glob.glob(os.path.join(self.basedir, 'build-tools', '[1-9]*.*', '*.txt')) + files = glob.glob(os.path.join(basedir, 'build-tools', '[1-9]*.*', '*.txt')) self.assertNotEqual(0, len(files)) for f in files: appid, versionCode = os.path.splitext(os.path.basename(f))[0][12:].split('_') @@ -1556,7 +1541,7 @@ class CommonTest(unittest.TestCase): def test_remove_signing_keys(self): shutil.copytree( - os.path.join(self.basedir, 'source-files'), + os.path.join(basedir, 'source-files'), os.path.join(self.tmpdir, 'source-files'), ) os.chdir(self.tmpdir) @@ -1575,7 +1560,7 @@ class CommonTest(unittest.TestCase): if not os.path.isdir(build_dir): continue fdroidserver.common.remove_signing_keys(build_dir) - fromfile = os.path.join(self.basedir, f) + fromfile = os.path.join(basedir, f) with open(f) as fp: content = fp.read() if 'signingConfig' in content: @@ -1605,7 +1590,7 @@ class CommonTest(unittest.TestCase): if not os.path.isdir(build_dir): continue fdroidserver.common.remove_signing_keys(build_dir) - fromfile = os.path.join(self.basedir, f) + fromfile = os.path.join(basedir, f) with open(fromfile) as fp: a = fp.readlines() with open(f) as fp: @@ -1947,7 +1932,7 @@ class CommonTest(unittest.TestCase): """Make sure it is possible to use config.yml alone.""" os.chdir(self.tmpdir) with mock.patch.dict(os.environ): - os.environ['SECRET'] = 'mysecretpassword' + os.environ['SECRET'] = 'mysecretpassword' # nosec B105 with open('config.yml', 'w') as fp: fp.write("""keypass: {'env': 'SECRET'}""") self.assertTrue(os.path.exists('config.yml')) @@ -1983,7 +1968,7 @@ class CommonTest(unittest.TestCase): with open('config.yml', 'w') as fp: fp.write('keystore: foo.jks') self.assertTrue(os.path.exists(fp.name)) - os.chmod(fp.name, 0o666) + os.chmod(fp.name, 0o666) # nosec B103 fdroidserver.common.read_config() os.remove(fp.name) fdroidserver.common.config = None @@ -1991,7 +1976,7 @@ class CommonTest(unittest.TestCase): with open('config.py', 'w') as fp: fp.write('keystore = "foo.jks"') self.assertTrue(os.path.exists(fp.name)) - os.chmod(fp.name, 0o666) + os.chmod(fp.name, 0o666) # nosec B103 fdroidserver.common.read_config() def test_with_both_config_yml_py(self): @@ -2119,7 +2104,7 @@ class CommonTest(unittest.TestCase): os.makedirs(os.path.dirname(apksigner)) with open(apksigner, 'w') as fp: fp.write('#!/bin/sh\ndate\n') - os.chmod(apksigner, 0o0755) + os.chmod(apksigner, 0o0755) # nosec B103 config = {'apksigner': apksigner} self.assertTrue(fdroidserver.common.test_sdk_exists(config)) @@ -2129,7 +2114,7 @@ class CommonTest(unittest.TestCase): os.makedirs(os.path.dirname(apksigner)) with open(apksigner, 'w') as fp: fp.write('#!/bin/sh\ndate\n') - os.chmod(apksigner, 0o0755) + os.chmod(apksigner, 0o0755) # nosec B103 config = {'apksigner': apksigner} self.assertFalse(fdroidserver.common.test_sdk_exists(config)) @@ -2159,7 +2144,7 @@ class CommonTest(unittest.TestCase): def test_loading_config_buildserver_yml(self): """Smoke check to make sure this file is properly parsed""" os.chdir(self.tmpdir) - shutil.copy(os.path.join(self.basedir, '..', 'buildserver', 'config.buildserver.yml'), + shutil.copy(os.path.join(basedir, '..', 'buildserver', 'config.buildserver.yml'), 'config.yml') self.assertFalse(os.path.exists('config.py')) fdroidserver.common.read_config() @@ -2238,7 +2223,7 @@ class CommonTest(unittest.TestCase): @mock.patch.dict(os.environ, {'PATH': os.getenv('PATH')}, clear=True) def test_get_android_tools_versions(self): - sdk_path = os.path.join(self.basedir, 'get_android_tools_versions/android-sdk') + sdk_path = os.path.join(basedir, 'get_android_tools_versions/android-sdk') config = { 'ndk_paths': {'r10e': os.path.join(sdk_path, '..', 'android-ndk-r10e')}, 'sdk_path': sdk_path, @@ -2264,7 +2249,7 @@ class CommonTest(unittest.TestCase): with tempfile.TemporaryDirectory() as tmpdir: sdk_path = Path(tmpdir) / 'get_android_tools_versions' shutil.copytree( - os.path.join(self.basedir, 'get_android_tools_versions'), sdk_path + os.path.join(basedir, 'get_android_tools_versions'), sdk_path ) shutil.rmtree(sdk_path / 'android-ndk-r10e') shutil.rmtree(sdk_path / 'android-sdk/ndk') @@ -2329,7 +2314,7 @@ class CommonTest(unittest.TestCase): fdroidserver.common.read_pkg_args(['org.fdroid.fdroid:foo'], allow_vercodes), def test_apk_strip_v1_signatures(self): - before = os.path.join(self.basedir, 'no_targetsdk_minsdk1_unsigned.apk') + before = os.path.join(basedir, 'no_targetsdk_minsdk1_unsigned.apk') after = os.path.join(self.testdir, 'after.apk') shutil.copy(before, after) fdroidserver.common.apk_strip_v1_signatures(after, strip_manifest=False) @@ -3156,7 +3141,7 @@ class SignerExtractionTest(unittest.TestCase): """ def setUp(self): - os.chdir(os.path.join(localmodule, 'tests')) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name @@ -3184,7 +3169,8 @@ class SignerExtractionTest(unittest.TestCase): @unittest.skip("slow and only needed when adding to APKS_WITH_JAR_SIGNATURES") def test_vs_keytool(self): - unittest.skipUnless(self.keytool, 'requires keytool to run') + if not self.keytool: + self.skipTest('requires keytool to run') pat = re.compile(r'[0-9A-F:]{95}') cmd = [self.keytool, '-printcert', '-jarfile'] for apk, fingerprint in APKS_WITH_JAR_SIGNATURES: @@ -3199,7 +3185,8 @@ class SignerExtractionTest(unittest.TestCase): @unittest.skip("slow and only needed when adding to APKS_WITH_JAR_SIGNATURES") def test_vs_apksigner(self): - unittest.skipUnless(self.apksigner, 'requires apksigner to run') + if not self.apksigner: + self.skipTest('requires apksigner to run') pat = re.compile(r'\s[0-9a-f]{64}\s') cmd = [self.apksigner, 'verify', '--print-certs'] for apk, fingerprint in APKS_WITH_JAR_SIGNATURES + APKS_WITHOUT_JAR_SIGNATURES: @@ -3353,21 +3340,3 @@ class ConfigOptionsScopeTest(unittest.TestCase): 'config' not in vars() and 'config' not in globals(), "The config should not be set in the global context, only module-level.", ) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - parser = ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(CommonTest)) - unittest.main(failfast=False) diff --git a/tests/deploy.TestCase b/tests/test_deploy.py similarity index 97% rename from tests/deploy.TestCase rename to tests/test_deploy.py index 649f8d58..d6c32d89 100755 --- a/tests/deploy.TestCase +++ b/tests/test_deploy.py @@ -1,11 +1,8 @@ #!/usr/bin/env python3 import configparser -import inspect -import logging import os import shutil -import sys import tempfile import unittest from pathlib import Path @@ -13,16 +10,10 @@ from unittest import mock import git -localmodule = os.path.realpath( - os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..') -) -if localmodule not in sys.path: - sys.path.insert(0, localmodule) +import fdroidserver +from .testcommon import TmpCwd, mkdtemp -import fdroidserver.common -import fdroidserver.deploy -from fdroidserver.exception import FDroidException -from testcommon import TmpCwd, mkdtemp, parse_args_for_test +basedir = Path(__file__).parent class Options: @@ -34,9 +25,7 @@ class DeployTest(unittest.TestCase): '''fdroidserver/deploy.py''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = os.path.join(localmodule, 'tests') - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name @@ -281,7 +270,7 @@ class DeployTest(unittest.TestCase): def test_update_serverwebroot_no_rsync_error(self): os.environ['PATH'] = self.testdir os.chdir(self.testdir) - with self.assertRaises(FDroidException): + with self.assertRaises(fdroidserver.exception.FDroidException): fdroidserver.deploy.update_serverwebroot('serverwebroot', 'repo') def test_update_serverwebroot_make_cur_version_link(self): @@ -981,7 +970,7 @@ class DeployTest(unittest.TestCase): for file in files_to_upload ] mock_driver.upload_object_via_stream.assert_has_calls(calls, any_order=True) - assert mock_driver.upload_object_via_stream.call_count == 2 + self.assertEqual(mock_driver.upload_object_via_stream.call_count, 2) def test_update_awsbucket_libcloud_in_index_only_mode(self): from libcloud.storage.base import Container @@ -1047,7 +1036,7 @@ class DeployTest(unittest.TestCase): calls, any_order=False, ) - assert mock_driver.upload_object_via_stream.call_count == 1 + self.assertEqual(mock_driver.upload_object_via_stream.call_count, 1) def test_update_servergitmirrors(self): # setup parameters for this test run @@ -1461,7 +1450,7 @@ class Test_UploadToGithubReleasesRepo(unittest.TestCase): ) def test_local_token(self): - self.repo_conf["token"] = "local_token" + self.repo_conf["token"] = "local_token" # nosec B105 with unittest.mock.patch("fdroidserver.github.GithubApi", self.api_constructor): fdroidserver.deploy.upload_to_github_releases_repo( self.repo_conf, @@ -1488,25 +1477,3 @@ class Test_UploadToGithubReleasesRepo(unittest.TestCase): ), ], ) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(DeployTest)) - newSuite.addTest(unittest.makeSuite(GitHubReleasesTest)) - newSuite.addTest(unittest.makeSuite(Test_UploadToGithubReleasesRepo)) - unittest.main(failfast=False) diff --git a/tests/exception.TestCase b/tests/test_exception.py similarity index 55% rename from tests/exception.TestCase rename to tests/test_exception.py index f3e69e69..accc6653 100755 --- a/tests/exception.TestCase +++ b/tests/test_exception.py @@ -1,21 +1,7 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - -import inspect -import os -import sys import unittest - -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.exception +import fdroidserver class ExceptionTest(unittest.TestCase): @@ -51,24 +37,3 @@ class ExceptionTest(unittest.TestCase): raise fdroidserver.exception.FDroidException(('one', 'two', 'three')) except fdroidserver.exception.FDroidException as e: str(e) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - from testcommon import parse_args_for_test - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(ExceptionTest)) - unittest.main(failfast=False) diff --git a/tests/github.TestCase b/tests/test_github.py similarity index 79% rename from tests/github.TestCase rename to tests/test_github.py index 608d7215..e1e9ac3e 100755 --- a/tests/github.TestCase +++ b/tests/test_github.py @@ -1,21 +1,10 @@ #!/usr/bin/env python3 -import inspect -import optparse -import os -import sys +import unittest import unittest.mock -import testcommon -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.github -import fdroidserver.common +from .testcommon import mock_urlopen +import fdroidserver class GithubApiTest(unittest.TestCase): @@ -40,7 +29,7 @@ class GithubApiTest(unittest.TestCase): def test_list_released_tags(self): api = fdroidserver.github.GithubApi('faketoken', 'fakerepopath') - uomock = testcommon.mock_urlopen( + uomock = mock_urlopen( body='[{"tag_name": "fake"}, {"tag_name": "double_fake"}]' ) with unittest.mock.patch("urllib.request.urlopen", uomock): @@ -59,7 +48,7 @@ class GithubApiTest(unittest.TestCase): def test_tag_exists(self): api = fdroidserver.github.GithubApi('faketoken', 'fakerepopath') - uomock = testcommon.mock_urlopen(body='[{"ref": "refs/tags/fake_tag"}]') + uomock = mock_urlopen(body='[{"ref": "refs/tags/fake_tag"}]') with unittest.mock.patch("urllib.request.urlopen", uomock): result = api.tag_exists('fake_tag') self.assertTrue(result) @@ -67,7 +56,7 @@ class GithubApiTest(unittest.TestCase): def test_tag_exists_failure(self): api = fdroidserver.github.GithubApi('faketoken', 'fakerepopath') - uomock = testcommon.mock_urlopen(body='[{"error": "failure"}]') + uomock = mock_urlopen(body='[{"error": "failure"}]') with unittest.mock.patch("urllib.request.urlopen", uomock): success = api.tag_exists('fake_tag') @@ -77,7 +66,7 @@ class GithubApiTest(unittest.TestCase): def test_list_all_tags(self): api = fdroidserver.github.GithubApi('faketoken', 'fakerepopath') - uomock = testcommon.mock_urlopen( + uomock = mock_urlopen( body='[{"ref": "refs/tags/fake"}, {"ref": "refs/tags/double_fake"}]' ) @@ -89,7 +78,7 @@ class GithubApiTest(unittest.TestCase): def test_create_release(self): api = fdroidserver.github.GithubApi('faketoken', 'fakerepopath') - uomock = testcommon.mock_urlopen(body='{"id": "fakeid"}') + uomock = mock_urlopen(body='{"id": "fakeid"}') api.tag_exists = lambda x: True api._create_release_asset = unittest.mock.Mock() @@ -116,7 +105,7 @@ class GithubApiTest(unittest.TestCase): def test__create_release_asset(self): api = fdroidserver.github.GithubApi('faketoken', 'fakerepopath') - uomock = testcommon.mock_urlopen() + uomock = mock_urlopen() with unittest.mock.patch( 'fdroidserver.github.open', @@ -144,21 +133,3 @@ class GithubApiTest(unittest.TestCase): }, ) self.assertEqual(req.data, b'fake_content') - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - 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(GithubApiTest)) - unittest.main(failfast=False) diff --git a/tests/gpgsign.TestCase b/tests/test_gpgsign.py similarity index 60% rename from tests/gpgsign.TestCase rename to tests/test_gpgsign.py index 1c013c1b..f73b217e 100755 --- a/tests/gpgsign.TestCase +++ b/tests/test_gpgsign.py @@ -1,31 +1,20 @@ #!/usr/bin/env python3 -import inspect import json -import logging import os import shutil -import sys import tempfile import unittest -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) - from fdroidserver import common, gpgsign from pathlib import Path from unittest.mock import MagicMock, patch +basedir = Path(__file__).parent + class GpgsignTest(unittest.TestCase): - basedir = Path(__file__).resolve().parent - def setUp(self): - logging.basicConfig(level=logging.DEBUG) self.tempdir = tempfile.TemporaryDirectory() os.chdir(self.tempdir.name) self.repodir = Path('repo') @@ -34,7 +23,7 @@ class GpgsignTest(unittest.TestCase): gpgsign.config = None config = common.read_config() config['verbose'] = True - config['gpghome'] = str((self.basedir / 'gnupghome').resolve()) + config['gpghome'] = str((basedir / 'gnupghome').resolve()) config['gpgkey'] = '1DBA2E89' gpgsign.config = config @@ -46,8 +35,8 @@ class GpgsignTest(unittest.TestCase): def test_sign_index(self, FDroidPopen): """This skips running gpg because its hard to setup in a test env""" index_v1_json = 'repo/index-v1.json' - shutil.copy(str(self.basedir / index_v1_json), 'repo') - shutil.copy(str(self.basedir / 'SpeedoMeterApp.main_1.apk'), 'repo') + shutil.copy(basedir / index_v1_json, 'repo') + shutil.copy(basedir / 'SpeedoMeterApp.main_1.apk', 'repo') def _side_effect(gpg): f = gpg[-1] @@ -68,24 +57,4 @@ class GpgsignTest(unittest.TestCase): # smoke check status JSON with (self.repodir / 'status/gpgsign.json').open() as fp: data = json.load(fp) - self.assertTrue('index-v1.json' in data['signed']) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(GpgsignTest)) - unittest.main(failfast=False) + self.assertIn('index-v1.json', data['signed']) diff --git a/tests/import_subcommand.TestCase b/tests/test_import_subcommand.py similarity index 83% rename from tests/import_subcommand.TestCase rename to tests/test_import_subcommand.py index 411f500d..4483841d 100755 --- a/tests/import_subcommand.TestCase +++ b/tests/test_import_subcommand.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - import logging import os import shutil @@ -15,31 +13,25 @@ import git import requests import yaml -localmodule = Path(__file__).resolve().parent.parent -print('localmodule: ' + str(localmodule)) -if localmodule not in sys.path: - sys.path.insert(0, str(localmodule)) +from .testcommon import TmpCwd, mkdtemp -from testcommon import TmpCwd, mkdtemp, parse_args_for_test - -import fdroidserver.common +import fdroidserver import fdroidserver.import_subcommand -import fdroidserver.metadata -from fdroidserver.exception import FDroidException + +basedir = Path(__file__).parent +logging.basicConfig(level=logging.DEBUG) class ImportTest(unittest.TestCase): '''fdroid import''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = localmodule / 'tests' - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name def tearDown(self): - os.chdir(self.basedir) + os.chdir(basedir) self._td.cleanup() def test_get_all_gradle_and_manifests(self): @@ -63,7 +55,7 @@ class ImportTest(unittest.TestCase): paths = [Path('source-files/cn.wildfirechat.chat') / path for path in paths] self.assertEqual(sorted(paths), sorted(a)) - abspath = Path(self.basedir) / 'source-files/realm' + abspath = basedir / 'source-files/realm' p = fdroidserver.import_subcommand.get_all_gradle_and_manifests(abspath) self.assertEqual(1, len(p)) self.assertTrue(p[0].is_relative_to(abspath)) @@ -99,6 +91,7 @@ class ImportTest(unittest.TestCase): print('Skipping ImportTest!') return + fdroidserver.common.options = type('Options', (), {'verbose': False}) app = fdroidserver.import_subcommand.get_app_from_url(url) fdroidserver.import_subcommand.clone_to_tmp_dir(app) self.assertEqual(app.RepoType, 'git') @@ -134,7 +127,7 @@ class ImportTest(unittest.TestCase): tmp_importer, onerror=fdroidserver.import_subcommand.handle_retree_error_on_windows, ) - shutil.copytree(self.basedir / 'source-files' / appid, tmp_importer) + shutil.copytree(basedir / 'source-files' / appid, tmp_importer) app = fdroidserver.import_subcommand.get_app_from_url(url) with mock.patch( @@ -185,7 +178,7 @@ class ImportTest(unittest.TestCase): the network, if it gets past the code that throws the error. """ - with self.assertRaises(FDroidException): + with self.assertRaises(fdroidserver.exception.FDroidException): fdroidserver.import_subcommand.main() @mock.patch('sys.argv', ['fdroid import', '-u', 'https://fake/git/url.git']) @@ -195,29 +188,12 @@ class ImportTest(unittest.TestCase): def test_main_local_git(self): os.chdir(self.testdir) git.Repo.init('td') - with Path('td/build.gradle').open('w') as fp: - fp.write('android { defaultConfig { applicationId "com.example" } }') + Path('td/build.gradle').write_text( + 'android { defaultConfig { applicationId "com.example" } }' + ) fdroidserver.import_subcommand.main() with open('metadata/com.example.yml') as fp: data = yaml.safe_load(fp) self.assertEqual(data['Repo'], sys.argv[2]) self.assertEqual(data['RepoType'], 'git') self.assertEqual(1, len(data['Builds'])) - - -if __name__ == "__main__": - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(ImportTest)) - unittest.main(failfast=False) diff --git a/tests/index.TestCase b/tests/test_index.py similarity index 93% rename from tests/index.TestCase rename to tests/test_index.py index facc9e77..7e315daa 100755 --- a/tests/index.TestCase +++ b/tests/test_index.py @@ -3,11 +3,9 @@ import copy import datetime import glob -import inspect -import logging import os -import sys import unittest +from pathlib import Path import yaml import zipfile from unittest.mock import patch @@ -16,17 +14,12 @@ import tempfile import json import shutil -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 from fdroidserver import common, index, publish, signindex, update -from testcommon import GP_FINGERPRINT, TmpCwd, mkdtemp, parse_args_for_test -from pathlib import Path +from .testcommon import GP_FINGERPRINT, TmpCwd, mkdtemp + + +basedir = Path(__file__).parent class Options: @@ -38,17 +31,15 @@ class Options: class IndexTest(unittest.TestCase): @classmethod def setUpClass(cls): - cls.basedir = os.path.join(localmodule, 'tests') # TODO something should remove cls.index_v1_jar, but it was # causing the tests to be flaky. There seems to be something # that is running the background somehow, maybe sign_index() # exits before jarsigner actually finishes? - cls.index_v1_jar = os.path.join(cls.basedir, 'repo', 'index-v1.jar') + cls.index_v1_jar = basedir / 'repo' / 'index-v1.jar' def setUp(self): - logging.basicConfig(level=logging.ERROR) - os.chmod(os.path.join(self.basedir, 'config.py'), 0o600) - os.chdir(self.basedir) # so read_config() can find config.py + (basedir / 'config.py').chmod(0o600) + os.chdir(basedir) # so read_config() can find config.py common.config = None common.options = Options @@ -65,11 +56,11 @@ class IndexTest(unittest.TestCase): self._td.cleanup() def _sign_test_index_v1_jar(self): - if not os.path.exists(self.index_v1_jar): - signindex.sign_index(os.path.dirname(self.index_v1_jar), 'index-v1.json') + if not self.index_v1_jar.exists(): + signindex.sign_index(self.index_v1_jar.parent, 'index-v1.json') def test_get_public_key_from_jar_succeeds(self): - source_dir = os.path.join(self.basedir, 'signindex') + source_dir = basedir / 'signindex' for f in ('testy.jar', 'guardianproject.jar'): testfile = os.path.join(source_dir, f) jar = zipfile.ZipFile(testfile) @@ -85,7 +76,7 @@ class IndexTest(unittest.TestCase): self.assertTrue(fingerprint == GP_FINGERPRINT) def test_get_public_key_from_jar_fails(self): - source_dir = os.path.join(self.basedir, 'signindex') + source_dir = basedir / 'signindex' testfile = os.path.join(source_dir, 'unsigned.jar') jar = zipfile.ZipFile(testfile) with self.assertRaises(index.VerificationException): @@ -186,10 +177,10 @@ class IndexTest(unittest.TestCase): self.testdir, 'repo', os.path.basename(mirrors[0]['url']) ) os.chdir(self.testdir) - signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + signindex.config['keystore'] = os.path.join(basedir, 'keystore.jks') os.mkdir('repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo') + shutil.copy(basedir / 'repo' / 'entry.json', 'repo') + shutil.copy(basedir / 'repo' / 'index-v2.json', 'repo') signindex.sign_index('repo', 'entry.json') repo_url = 'https://fake.url/fdroid/repo' entry_url = 'https://fake.url/fdroid/repo/entry.jar' @@ -209,10 +200,10 @@ class IndexTest(unittest.TestCase): self.testdir, 'repo', os.path.basename(mirrors[0]['url']) ) os.chdir(self.testdir) - signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + signindex.config['keystore'] = os.path.join(basedir, 'keystore.jks') os.mkdir('repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo') + shutil.copy(basedir / 'repo' / 'entry.json', 'repo') + shutil.copy(basedir / 'repo' / 'index-v2.json', 'repo') signindex.sign_index('repo', 'entry.json') bad_fp = '0123456789001234567890012345678900123456789001234567890012345678' bad_fp_url = 'https://fake.url/fdroid/repo?fingerprint=' + bad_fp @@ -240,10 +231,10 @@ class IndexTest(unittest.TestCase): mock_download_using_mirrors.side_effect = download_using_mirrors_def os.chdir(self.testdir) - signindex.config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + signindex.config['keystore'] = os.path.join(basedir, 'keystore.jks') os.mkdir('repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'entry.json'), 'repo') - shutil.copy(os.path.join(self.basedir, 'repo', 'index-v2.json'), 'repo') + shutil.copy(basedir / 'repo' / 'entry.json', 'repo') + shutil.copy(basedir / 'repo' / 'index-v2.json', 'repo') signindex.sign_index('repo', 'entry.json') url = 'https://fake.url/fdroid/repo?fingerprint=' + GP_FINGERPRINT with self.assertRaises(fdroidserver.exception.VerificationException): @@ -438,7 +429,7 @@ class IndexTest(unittest.TestCase): os.mkdir('metadata') os.mkdir('repo') metadatafile = 'metadata/info.zwanenburg.caffeinetile.yml' - shutil.copy(os.path.join(self.basedir, metadatafile), metadatafile) + shutil.copy(os.path.join(basedir, metadatafile), metadatafile) repo_icons_dir = os.path.join('repo', 'icons') self.assertFalse(os.path.isdir(repo_icons_dir)) repodict = { @@ -648,13 +639,13 @@ class IndexTest(unittest.TestCase): html = f.read() pretty_html = HTMLBeautifier.beautify(html) self.maxDiff = None - self.assertEquals(html, pretty_html) + self.assertEqual(html, pretty_html) with open(os.path.join("repo", "index.css")) as f: css = f.read() pretty_css = CSSBeautifier.beautify(css) self.maxDiff = None - self.assertEquals(css, pretty_css) + self.assertEqual(css, pretty_css) def test_v1_sort_packages_with_invalid(self): i = [ @@ -729,7 +720,6 @@ class IndexTest(unittest.TestCase): c = {'repo_url': repo_url, 'mirrors': ['http://one/fdroid']} with open('config.yml', 'w') as fp: yaml.dump(c, fp) - os.system('cat config.yml') common.config = None common.read_config() repodict = {'address': common.config['repo_url']} @@ -866,8 +856,7 @@ class AltstoreIndexTest(unittest.TestCase): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): repodir = Path(tmpdir) / 'repo' repodir.mkdir() - with open(repodir / "fake.ipa", "w") as f: - f.write("") + (repodir / "fake.ipa").touch() fdroidserver.index.make_altstore( apps, @@ -916,24 +905,3 @@ class AltstoreIndexTest(unittest.TestCase): }, json.load(f), ) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(IndexTest)) - newSuite.addTest(unittest.makeSuite(AltstoreIndexTest)) - unittest.main(failfast=False) diff --git a/tests/test_init.py b/tests/test_init.py new file mode 100755 index 00000000..fcbc83d0 --- /dev/null +++ b/tests/test_init.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 + +import os +import pathlib +import shutil +import sys +import unittest + +import fdroidserver.common +import fdroidserver.init +from . import testcommon + +basedir = pathlib.Path(__file__).parent + + +class InitTest(unittest.TestCase): + '''fdroidserver/init.py''' + + def setUp(self): + fdroidserver.common.config = None + fdroidserver.init.config = None + self._td = testcommon.mkdtemp() + self.testdir = self._td.name + os.chdir(self.testdir) + + def tearDown(self): + os.chdir(basedir) + self._td.cleanup() + + def test_disable_in_config(self): + configfile = pathlib.Path('config.yml') + configfile.write_text('keystore: NONE\nkeypass: mysupersecrets\n') + configfile.chmod(0o600) + config = fdroidserver.common.read_config() + self.assertEqual('NONE', config['keystore']) + self.assertEqual('mysupersecrets', config['keypass']) + fdroidserver.init.disable_in_config('keypass', 'comment') + self.assertIn('#keypass:', configfile.read_text()) + fdroidserver.common.config = None + config = fdroidserver.common.read_config() + self.assertIsNone(config.get('keypass')) + + @unittest.skipIf(os.name == 'nt', "calling main() like this hangs on Windows") + def test_main_in_empty_dir(self): + """Test that `fdroid init` will find apksigner and add it to the config""" + + shutil.copy(basedir / 'keystore.jks', self.testdir) + + bindir = os.path.join(os.getcwd(), 'bin') + os.mkdir(bindir) + apksigner = os.path.join(bindir, 'apksigner') + open(apksigner, 'w').close() + os.chmod(apksigner, 0o755) # nosec B103 + + sys.argv = ['fdroid init', '--keystore', 'keystore.jks', '--repo-keyalias=sova'] + with unittest.mock.patch.dict(os.environ, {'PATH': bindir}): + fdroidserver.init.main() + self.assertEqual(apksigner, fdroidserver.init.config.get('apksigner')) diff --git a/tests/install.TestCase b/tests/test_install.py similarity index 92% rename from tests/install.TestCase rename to tests/test_install.py index 351cc420..1015b4be 100755 --- a/tests/install.TestCase +++ b/tests/test_install.py @@ -1,23 +1,12 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - -import inspect import os -import sys import textwrap import unittest from pathlib import Path from unittest.mock import Mock, patch -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 from fdroidserver import common, install from fdroidserver.exception import BuildException, FDroidException @@ -265,24 +254,3 @@ class InstallTest(unittest.TestCase): def test_download_fdroid_apk_from_github(self): f = install.download_fdroid_apk_from_github() self.assertTrue(Path(f).exists()) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - from testcommon import parse_args_for_test - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - fdroidserver.install.options = parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(InstallTest)) - unittest.main(failfast=False) diff --git a/tests/lint.TestCase b/tests/test_lint.py similarity index 93% rename from tests/lint.TestCase rename to tests/test_lint.py index 409c807c..f70b03b2 100755 --- a/tests/lint.TestCase +++ b/tests/test_lint.py @@ -1,39 +1,28 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - import logging import os import shutil -import sys import tempfile import unittest from pathlib import Path import ruamel.yaml -localmodule = Path(__file__).resolve().parent.parent -print('localmodule: ' + str(localmodule)) -if localmodule not in sys.path: - sys.path.insert(0, str(localmodule)) - -from testcommon import mkdtemp, parse_args_for_test +from .testcommon import mkdtemp import fdroidserver.common import fdroidserver.lint import fdroidserver.metadata -from fdroidserver.common import CATEGORIES_CONFIG_NAME + +basedir = Path(__file__).parent class LintTest(unittest.TestCase): '''fdroidserver/lint.py''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = localmodule / 'tests' - self.tmpdir = localmodule / '.testfiles' - self.tmpdir.mkdir(exist_ok=True) - os.chdir(self.basedir) + os.chdir(basedir) fdroidserver.common.config = None fdroidserver.lint.config = None fdroidserver.lint.CATEGORIES_KEYS = None @@ -46,13 +35,13 @@ class LintTest(unittest.TestCase): def test_check_for_unsupported_metadata_files(self): self.assertTrue(fdroidserver.lint.check_for_unsupported_metadata_files()) - with tempfile.TemporaryDirectory(dir=str(self.tmpdir)) as testdir: + with tempfile.TemporaryDirectory() as testdir: testdir = Path(testdir) self.assertFalse( fdroidserver.lint.check_for_unsupported_metadata_files(testdir) ) shutil.copytree( - self.basedir / 'metadata', + basedir / 'metadata', testdir / 'metadata', ignore=shutil.ignore_patterns('apk', 'dump', '*.json'), ) @@ -326,7 +315,9 @@ class LintTest(unittest.TestCase): self.assertFalse(anywarns) def test_check_categories_in_config(self): - fdroidserver.lint.config = {CATEGORIES_CONFIG_NAME: ['InConfig']} + fdroidserver.lint.config = { + fdroidserver.common.CATEGORIES_CONFIG_NAME: ['InConfig'] + } fdroidserver.lint.load_categories_config() app = fdroidserver.metadata.App({'Categories': ['InConfig']}) self.assertEqual(0, len(list(fdroidserver.lint.check_categories(app)))) @@ -338,13 +329,15 @@ class LintTest(unittest.TestCase): self.assertEqual(1, len(list(fdroidserver.lint.check_categories(app)))) def test_check_categories_empty_is_error(self): - fdroidserver.lint.config = {CATEGORIES_CONFIG_NAME: []} + fdroidserver.lint.config = {fdroidserver.common.CATEGORIES_CONFIG_NAME: []} fdroidserver.lint.load_categories_config() app = fdroidserver.metadata.App({'Categories': ['something']}) self.assertEqual(1, len(list(fdroidserver.lint.check_categories(app)))) def test_check_categories_old_hardcoded_not_defined(self): - fdroidserver.lint.config = {CATEGORIES_CONFIG_NAME: ['foo', 'bar']} + fdroidserver.lint.config = { + fdroidserver.common.CATEGORIES_CONFIG_NAME: ['foo', 'bar'] + } fdroidserver.lint.load_categories_config() app = fdroidserver.metadata.App({'Categories': ['Writing']}) self.assertEqual(1, len(list(fdroidserver.lint.check_categories(app)))) @@ -493,8 +486,7 @@ class LintTest(unittest.TestCase): class LintAntiFeaturesTest(unittest.TestCase): def setUp(self): - self.basedir = localmodule / 'tests' - os.chdir(self.basedir) + os.chdir(basedir) fdroidserver.common.config = dict() fdroidserver.lint.ANTIFEATURES_KEYS = None fdroidserver.lint.load_antiFeatures_config() @@ -537,21 +529,3 @@ class LintAntiFeaturesTest(unittest.TestCase): app = fdroidserver.metadata.App() app['Builds'] = [{'antifeatures': ['Ads', 'Tracker']}] self.assertEqual(1, len(list(fdroidserver.lint.check_antiFeatures(app)))) - - -if __name__ == "__main__": - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - fdroidserver.lint.options = parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(LintTest)) - unittest.main(failfast=False) diff --git a/tests/main.TestCase b/tests/test_main.py similarity index 90% rename from tests/main.TestCase rename to tests/test_main.py index 691a0aca..25da93fa 100755 --- a/tests/main.TestCase +++ b/tests/test_main.py @@ -1,24 +1,14 @@ #!/usr/bin/env python3 -import inspect import os -import sys import pkgutil import textwrap import unittest import tempfile from unittest import mock -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) - -from fdroidserver import common import fdroidserver.__main__ -from testcommon import TmpCwd, TmpPyPath +from .testcommon import TmpCwd, TmpPyPath class MainTest(unittest.TestCase): @@ -27,7 +17,7 @@ class MainTest(unittest.TestCase): def test_COMMANDS_check(self): """make sure the built in sub-command defs didn't change unintentionally""" self.assertListEqual( - [x for x in fdroidserver.__main__.COMMANDS.keys()], + [x for x in fdroidserver.__main__.COMMANDS], [ 'build', 'init', @@ -206,12 +196,7 @@ class MainTest(unittest.TestCase): def test_preparse_plugin_lookup_summary_missing(self): with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): with open('fdroid_testy6.py', 'w') as f: - f.write( - textwrap.dedent( - """\ - main = lambda: print('all good')""" - ) - ) + f.write("main = lambda: print('all good')") with TmpPyPath(tmpdir): p = [x for x in pkgutil.iter_modules() if x[1].startswith('fdroid_')] module_dir = p[0][0].path @@ -259,23 +244,3 @@ class MainTest(unittest.TestCase): module_name = p[0][1] d = fdroidserver.__main__.preparse_plugin(module_name, module_path) self.assertDictEqual(d, {'name': 'fdroid_testy8', 'summary': 'ttt'}) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.options = common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(MainTest)) - unittest.main(failfast=False) diff --git a/tests/metadata.TestCase b/tests/test_metadata.py similarity index 97% rename from tests/metadata.TestCase rename to tests/test_metadata.py index 75dc3b91..cd4d12a9 100755 --- a/tests/metadata.TestCase +++ b/tests/test_metadata.py @@ -2,12 +2,10 @@ import copy import io -import logging import os import random import ruamel.yaml import shutil -import sys import unittest import tempfile import textwrap @@ -15,16 +13,14 @@ from collections import OrderedDict from pathlib import Path from unittest import mock -localmodule = Path(__file__).resolve().parent.parent -print('localmodule: ' + str(localmodule)) -if localmodule not in sys.path: - sys.path.insert(0, str(localmodule)) - import fdroidserver from fdroidserver import metadata from fdroidserver.exception import MetaDataException from fdroidserver.common import DEFAULT_LOCALE -from testcommon import TmpCwd, mkdtemp, parse_args_for_test +from .testcommon import TmpCwd, mkdtemp + + +basedir = Path(__file__).parent def _get_mock_mf(s): @@ -37,9 +33,7 @@ class MetadataTest(unittest.TestCase): '''fdroidserver/metadata.py''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = localmodule / 'tests' - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name fdroidserver.metadata.warnings_action = 'error' @@ -57,12 +51,12 @@ class MetadataTest(unittest.TestCase): pass def test_fieldtypes_key_exist(self): - for k in fdroidserver.metadata.fieldtypes.keys(): - self.assertTrue(k in fdroidserver.metadata.yaml_app_fields) + for k in fdroidserver.metadata.fieldtypes: + self.assertIn(k, fdroidserver.metadata.yaml_app_fields) def test_build_flagtypes_key_exist(self): - for k in fdroidserver.metadata.flagtypes.keys(): - self.assertTrue(k in fdroidserver.metadata.build_flags) + for k in fdroidserver.metadata.flagtypes: + self.assertIn(k, fdroidserver.metadata.build_flags) def test_FieldValidator_BitcoinAddress(self): validator = None @@ -183,7 +177,7 @@ class MetadataTest(unittest.TestCase): def test_valid_funding_yml_regex(self): """Check the regex can find all the cases""" - with (self.basedir / 'funding-usernames.yaml').open() as fp: + with (basedir / 'funding-usernames.yaml').open() as fp: yaml = ruamel.yaml.YAML(typ='safe') data = yaml.load(fp) @@ -201,9 +195,9 @@ class MetadataTest(unittest.TestCase): m, 'this is a valid %s username: {%s}' % (k, entry) ) - @mock.patch('git.Repo') + @mock.patch('git.Repo', mock.Mock()) @mock.patch('logging.error') - def test_read_metadata(self, logging_error, git_repo): + def test_read_metadata(self, logging_error): """Read specified metadata files included in tests/, compare to stored output""" self.maxDiff = None @@ -239,8 +233,8 @@ class MetadataTest(unittest.TestCase): logging_error.assert_called() self.assertEqual(3, len(logging_error.call_args_list)) - @mock.patch('git.Repo') - def test_metadata_overrides_dot_fdroid_yml(self, git_Repo): + @mock.patch('git.Repo', mock.Mock()) + def test_metadata_overrides_dot_fdroid_yml(self): """Fields in metadata files should override anything in .fdroid.yml.""" app = metadata.parse_metadata('metadata/info.guardianproject.urzip.yml') self.assertEqual(app['Summary'], '一个实用工具,获取已安装在您的设备上的应用的有关信息') @@ -258,9 +252,9 @@ class MetadataTest(unittest.TestCase): fp.write('OpenCollective: test') metadata.parse_metadata(yml) # should not throw an exception - @mock.patch('git.Repo') + @mock.patch('git.Repo', mock.Mock()) @mock.patch('logging.error') - def test_rewrite_yaml_fakeotaupdate(self, logging_error, git_Repo): + def test_rewrite_yaml_fakeotaupdate(self, logging_error): with tempfile.TemporaryDirectory() as testdir: testdir = Path(testdir) fdroidserver.common.config = {'accepted_formats': ['yml']} @@ -286,8 +280,8 @@ class MetadataTest(unittest.TestCase): logging_error.assert_called() self.assertEqual(3, len(logging_error.call_args_list)) - @mock.patch('git.Repo') - def test_rewrite_yaml_fdroidclient(self, git_Repo): + @mock.patch('git.Repo', mock.Mock()) + def test_rewrite_yaml_fdroidclient(self): with tempfile.TemporaryDirectory() as testdir: testdir = Path(testdir) fdroidserver.common.config = {'accepted_formats': ['yml']} @@ -308,14 +302,14 @@ class MetadataTest(unittest.TestCase): (Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'), ) - @mock.patch('git.Repo') - def test_rewrite_yaml_special_build_params(self, git_Repo): + @mock.patch('git.Repo', mock.Mock()) + def test_rewrite_yaml_special_build_params(self): """Test rewriting a plain YAML metadata file without localized files.""" os.chdir(self.testdir) os.mkdir('metadata') appid = 'app.with.special.build.params' file_name = Path('metadata/%s.yml' % appid) - shutil.copy(self.basedir / file_name, file_name) + shutil.copy(basedir / file_name, file_name) # rewrite metadata allapps = fdroidserver.metadata.read_metadata({appid: -1}) @@ -326,7 +320,7 @@ class MetadataTest(unittest.TestCase): self.maxDiff = None self.assertEqual( file_name.read_text(), - (self.basedir / 'metadata-rewrite-yml' / file_name.name).read_text(), + (basedir / 'metadata-rewrite-yml' / file_name.name).read_text(), ) def test_normalize_type_string(self): @@ -508,7 +502,7 @@ class MetadataTest(unittest.TestCase): metadatadir.mkdir() randomlist = [] - randomapps = list((self.basedir / 'metadata').glob('*.yml')) + randomapps = list((basedir / 'metadata').glob('*.yml')) random.shuffle(randomapps) i = 1 for f in randomapps: @@ -911,7 +905,7 @@ class MetadataTest(unittest.TestCase): { 'versionCode': 1, 'versionName': 'v0.1.0', - 'prebuild': ["a && b && " "sed -i 's,a,b,'"], + 'prebuild': ["a && b && sed -i 's,a,b,'"], } ], }, @@ -1553,7 +1547,7 @@ class MetadataTest(unittest.TestCase): ) with self.assertRaisesRegex( MetaDataException, - "Invalid srclib metadata: " "unknown key 'Evil' in " "'test.yml'", + "Invalid srclib metadata: unknown key 'Evil' in 'test.yml'", ): fdroidserver.metadata.parse_yaml_srclib(Path('test.yml')) @@ -1788,7 +1782,6 @@ class MetadataTest(unittest.TestCase): ) def test_build_ndk_path(self): - """""" with tempfile.TemporaryDirectory(prefix='android-sdk-') as sdk_path: config = {'ndk_paths': {}, 'sdk_path': sdk_path} fdroidserver.common.config = config @@ -2442,21 +2435,3 @@ class PostMetadataParseTest(unittest.TestCase): self.assertEqual(*self._post_metadata_parse_build_list(True, ['true'])) self.assertEqual(*self._post_metadata_parse_build_script(True, ['true'])) self.assertEqual(*self._post_metadata_parse_build_string(True, 'true')) - - -if __name__ == "__main__": - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(MetadataTest)) - unittest.main(failfast=False) diff --git a/tests/net.TestCase b/tests/test_net.py similarity index 85% rename from tests/net.TestCase rename to tests/test_net.py index fa4bec4f..b8c311d3 100755 --- a/tests/net.TestCase +++ b/tests/test_net.py @@ -1,26 +1,16 @@ #!/usr/bin/env python3 -import inspect -import logging import os import random import requests import socket -import sys import tempfile import threading import time import unittest from unittest.mock import MagicMock, patch -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) - -from fdroidserver import common, net +from fdroidserver import net from pathlib import Path @@ -38,7 +28,7 @@ class RetryServer: def __init__(self, port=None, failures=3): self.port = port if self.port is None: - self.port = random.randint(1024, 65535) + self.port = random.randint(1024, 65535) # nosec B311 self.failures = failures self.stop_event = threading.Event() threading.Thread(target=self.run_fake_server).start() @@ -84,10 +74,7 @@ class RetryServer: class NetTest(unittest.TestCase): - basedir = Path(__file__).resolve().parent - def setUp(self): - logging.basicConfig(level=logging.DEBUG) self.tempdir = tempfile.TemporaryDirectory() os.chdir(self.tempdir.name) Path('tmp').mkdir() @@ -155,23 +142,3 @@ class NetTest(unittest.TestCase): with self.assertRaises(requests.exceptions.ConnectionError): net.download_using_mirrors(['http://localhost:%d/' % server.port]) server.stop() - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.options = common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(NetTest)) - unittest.main(failfast=False) diff --git a/tests/nightly.TestCase b/tests/test_nightly.py similarity index 89% rename from tests/nightly.TestCase rename to tests/test_nightly.py index b1f9a8eb..09d8fbcf 100755 --- a/tests/nightly.TestCase +++ b/tests/test_nightly.py @@ -1,12 +1,10 @@ #!/usr/bin/env python3 -import inspect -import logging import os +import platform import requests import shutil import subprocess -import sys import tempfile import time import unittest @@ -15,13 +13,6 @@ import yaml from pathlib import Path from unittest.mock import patch -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) - from fdroidserver import common, exception, index, nightly @@ -35,6 +26,9 @@ AOSP_TESTKEY_DEBUG_KEYSTORE_KEY_FILE_NAME = ( 'debug_keystore_k47SVrA85+oMZAexHc62PkgvIgO8TJBYN00U82xSlxc_id_rsa' ) +basedir = Path(__file__).parent +testroot = basedir.with_name('.testfiles') + class Options: allow_disabled_algorithms = False @@ -46,20 +40,20 @@ class Options: verbose = False +@unittest.skipUnless( + platform.system() == 'Linux', + 'skipping test_nightly, it currently only works GNU/Linux', +) class NightlyTest(unittest.TestCase): - basedir = Path(__file__).resolve().parent path = os.environ['PATH'] def setUp(self): common.config = None nightly.config = None - logging.basicConfig(level=logging.WARNING) - self.basedir = Path(localmodule) / 'tests' - self.testroot = Path(localmodule) / '.testfiles' - self.testroot.mkdir(exist_ok=True) - os.chdir(self.basedir) + testroot.mkdir(exist_ok=True) + os.chdir(basedir) self.tempdir = tempfile.TemporaryDirectory( - str(time.time()), self._testMethodName + '_', self.testroot + str(time.time()), self._testMethodName + '_', testroot ) self.testdir = Path(self.tempdir.name) self.home = self.testdir / 'home' @@ -70,21 +64,21 @@ class NightlyTest(unittest.TestCase): def tearDown(self): self.tempdir.cleanup() try: - os.rmdir(self.testroot) + os.rmdir(testroot) except OSError: # other test modules might have left stuff around pass def _copy_test_debug_keystore(self): self.dot_android.mkdir() shutil.copy( - self.basedir / 'aosp_testkey_debug.keystore', + basedir / 'aosp_testkey_debug.keystore', self.dot_android / 'debug.keystore', ) def _copy_debug_apk(self): outputdir = Path('app/build/output/apk/debug') outputdir.mkdir(parents=True) - shutil.copy(self.basedir / 'urzip.apk', outputdir / 'urzip-debug.apk') + shutil.copy(basedir / 'urzip.apk', outputdir / 'urzip-debug.apk') def test_get_repo_base_url(self): for clone_url, repo_git_base, result in [ @@ -108,9 +102,7 @@ class NightlyTest(unittest.TestCase): def test_get_keystore_secret_var(self): self.assertEqual( AOSP_TESTKEY_DEBUG_KEYSTORE, - nightly._get_keystore_secret_var( - self.basedir / 'aosp_testkey_debug.keystore' - ), + nightly._get_keystore_secret_var(basedir / 'aosp_testkey_debug.keystore'), ) @patch.dict(os.environ, clear=True) @@ -118,12 +110,12 @@ class NightlyTest(unittest.TestCase): os.environ['HOME'] = str(self.home) os.environ['PATH'] = self.path ssh_private_key_file = nightly._ssh_key_from_debug_keystore( - self.basedir / 'aosp_testkey_debug.keystore' + basedir / 'aosp_testkey_debug.keystore' ) with open(ssh_private_key_file) as fp: - assert '-----BEGIN RSA PRIVATE KEY-----' in fp.read() + self.assertIn('-----BEGIN RSA PRIVATE KEY-----', fp.read()) with open(ssh_private_key_file + '.pub') as fp: - assert fp.read(8) == 'ssh-rsa ' + self.assertEqual(fp.read(8), 'ssh-rsa ') shutil.rmtree(os.path.dirname(ssh_private_key_file)) @patch.dict(os.environ, clear=True) @@ -149,9 +141,9 @@ class NightlyTest(unittest.TestCase): self._copy_test_debug_keystore() os.environ['HOME'] = str(self.home) os.environ['PATH'] = self.path - assert not dot_ssh.exists() + self.assertFalse(dot_ssh.exists()) nightly.main() - assert not dot_ssh.exists() + self.assertFalse(dot_ssh.exists()) @patch.dict(os.environ, clear=True) @patch('sys.argv', ['fdroid nightly', '--verbose']) @@ -168,8 +160,10 @@ class NightlyTest(unittest.TestCase): os.environ['HOME'] = str(self.home) os.environ['PATH'] = self.path nightly.main() - assert (dot_ssh / AOSP_TESTKEY_DEBUG_KEYSTORE_KEY_FILE_NAME).exists() - assert (dot_ssh / (AOSP_TESTKEY_DEBUG_KEYSTORE_KEY_FILE_NAME + '.pub')).exists() + self.assertTrue((dot_ssh / AOSP_TESTKEY_DEBUG_KEYSTORE_KEY_FILE_NAME).exists()) + self.assertTrue( + (dot_ssh / (AOSP_TESTKEY_DEBUG_KEYSTORE_KEY_FILE_NAME + '.pub')).exists() + ) @patch('fdroidserver.common.vcs_git.git', lambda args, e: common.PopenResult(1)) @patch('sys.argv', ['fdroid nightly', '--verbose']) @@ -200,7 +194,7 @@ class NightlyTest(unittest.TestCase): def _put_fdroid_in_args(self, args): """Find fdroid command that belongs to this source code tree""" - fdroid = os.path.join(localmodule, 'fdroid') + fdroid = os.path.join(basedir.parent, 'fdroid') if not os.path.exists(fdroid): fdroid = os.getenv('fdroid') return [fdroid] + args[1:] @@ -245,7 +239,7 @@ class NightlyTest(unittest.TestCase): }, clear=True, ): - self.assertTrue(self.testroot == Path.home().parent) + self.assertTrue(testroot == Path.home().parent) with patch('subprocess.check_call', _subprocess_check_call): try: nightly.main() @@ -319,7 +313,7 @@ class NightlyTest(unittest.TestCase): }, clear=True, ): - self.assertTrue(self.testroot == Path.home().parent) + self.assertTrue(testroot == Path.home().parent) with patch('subprocess.check_call', _subprocess_check_call): try: nightly.main() @@ -356,23 +350,3 @@ class NightlyTest(unittest.TestCase): ) del config['identity_file'] self.assertEqual(expected, config) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.options = common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(NightlyTest)) - unittest.main(failfast=False) diff --git a/tests/publish.TestCase b/tests/test_publish.py similarity index 90% rename from tests/publish.TestCase rename to tests/test_publish.py index 5ae1fd5f..df7ed72c 100755 --- a/tests/publish.TestCase +++ b/tests/test_publish.py @@ -10,45 +10,36 @@ # -keypass 123456 -dname 'CN=test, OU=F-Droid'; done # -import inspect import json -import logging import os +import pathlib import shutil import sys import unittest import tempfile -import textwrap from unittest import mock -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) - from fdroidserver import publish from fdroidserver import common from fdroidserver import metadata from fdroidserver import signatures from fdroidserver.exception import FDroidException -from testcommon import mkdtemp, parse_args_for_test +from .testcommon import mkdtemp + +basedir = pathlib.Path(__file__).parent class PublishTest(unittest.TestCase): '''fdroidserver/publish.py''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = os.path.join(localmodule, 'tests') - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name def tearDown(self): self._td.cleanup() - os.chdir(self.basedir) + os.chdir(basedir) def test_key_alias(self): publish.config = {} @@ -91,7 +82,7 @@ class PublishTest(unittest.TestCase): publish.config = common.config publish.config['keystorepass'] = '123456' publish.config['keypass'] = '123456' - publish.config['keystore'] = os.path.join(self.basedir, 'dummy-keystore.jks') + publish.config['keystore'] = os.path.join(basedir, 'dummy-keystore.jks') publish.config['repo_keyalias'] = 'repokey' appids = [ @@ -127,12 +118,7 @@ class PublishTest(unittest.TestCase): with open('config.py', 'r') as f: self.assertEqual( - textwrap.dedent( - '''\ - - repo_key_sha256 = "c58460800c7b250a619c30c13b07b7359a43e5af71a4352d86c58ae18c9f6d41" - ''' - ), + '\nrepo_key_sha256 = "c58460800c7b250a619c30c13b07b7359a43e5af71a4352d86c58ae18c9f6d41"\n', f.read(), ) @@ -142,7 +128,7 @@ class PublishTest(unittest.TestCase): publish.config = common.config publish.config['keystorepass'] = '123456' publish.config['keypass'] = '123456' - publish.config['keystore'] = os.path.join(self.basedir, 'dummy-keystore.jks') + publish.config['keystore'] = os.path.join(basedir, 'dummy-keystore.jks') publish.config['repo_keyalias'] = 'repokey' publish.config['repo_key_sha256'] = 'bad bad bad bad bad bad bad bad bad bad bad bad' @@ -273,7 +259,7 @@ class PublishTest(unittest.TestCase): config['repo_keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' - shutil.copy(os.path.join(self.basedir, 'keystore.jks'), self.testdir) + shutil.copy(basedir / 'keystore.jks', self.testdir) config['keystore'] = 'keystore.jks' config['keydname'] = 'CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US' publish.config = config @@ -293,7 +279,7 @@ class PublishTest(unittest.TestCase): metadata.write_metadata(os.path.join('metadata', '%s.yml' % app.id), app) os.mkdir('unsigned') - testapk = os.path.join(self.basedir, 'no_targetsdk_minsdk1_unsigned.apk') + testapk = basedir / 'no_targetsdk_minsdk1_unsigned.apk' unsigned = os.path.join('unsigned', common.get_release_filename(app, build)) signed = os.path.join('repo', common.get_release_filename(app, build)) shutil.copy(testapk, unsigned) @@ -348,7 +334,7 @@ class PublishTest(unittest.TestCase): config['repo_keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' - shutil.copy(os.path.join(self.basedir, 'keystore.jks'), self.testdir) + shutil.copy(basedir / 'keystore.jks', self.testdir) config['keystore'] = 'keystore.jks' config[ 'keydname' @@ -370,7 +356,7 @@ class PublishTest(unittest.TestCase): metadata.write_metadata(os.path.join('metadata', '%s.yml' % app.id), app) os.mkdir('unsigned') - testapk = os.path.join(self.basedir, 'no_targetsdk_minsdk1_unsigned.apk') + testapk = basedir / 'no_targetsdk_minsdk1_unsigned.apk' unsigned = os.path.join('unsigned', common.get_release_filename(app, build)) signed = os.path.join('repo', common.get_release_filename(app, build)) shutil.copy(testapk, unsigned) @@ -409,23 +395,3 @@ class PublishTest(unittest.TestCase): with self.assertRaises(SystemExit) as e: publish.main() self.assertEqual(e.exception.code, 1) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(PublishTest)) - unittest.main(failfast=False) diff --git a/tests/rewritemeta.TestCase b/tests/test_rewritemeta.py similarity index 89% rename from tests/rewritemeta.TestCase rename to tests/test_rewritemeta.py index e212ec84..854553e3 100755 --- a/tests/rewritemeta.TestCase +++ b/tests/test_rewritemeta.py @@ -1,29 +1,23 @@ #!/usr/bin/env python3 -import logging import os -import sys import unittest import tempfile import textwrap from pathlib import Path +from unittest import mock -localmodule = Path(__file__).resolve().parent.parent -print('localmodule: ' + str(localmodule)) -if localmodule not in sys.path: - sys.path.insert(0, str(localmodule)) +from fdroidserver import metadata, rewritemeta +from .testcommon import TmpCwd, mkdtemp -from fdroidserver import common, metadata, rewritemeta -from testcommon import TmpCwd, mkdtemp +basedir = Path(__file__).parent class RewriteMetaTest(unittest.TestCase): '''fdroidserver/publish.py''' def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = localmodule / 'tests' - os.chdir(self.basedir) + os.chdir(basedir) metadata.warnings_action = 'error' self._td = mkdtemp() self.testdir = self._td.name @@ -132,6 +126,7 @@ class RewriteMetaTest(unittest.TestCase): [{'versionCode': 0}, {'versionCode': 1}, {'versionCode': 2}], ) + @mock.patch('sys.argv', ['fdroid rewritemeta', 'a']) def test_rewrite_no_builds(self): os.chdir(self.testdir) Path('metadata').mkdir() @@ -152,6 +147,7 @@ class RewriteMetaTest(unittest.TestCase): ), ) + @mock.patch('sys.argv', ['fdroid rewritemeta', 'a']) def test_rewrite_empty_build_field(self): os.chdir(self.testdir) Path('metadata').mkdir() @@ -221,9 +217,8 @@ class RewriteMetaTest(unittest.TestCase): }, ) + @mock.patch('sys.argv', ['fdroid rewritemeta', 'a', 'b']) def test_rewrite_scenario_trivial(self): - sys.argv = ['rewritemeta', 'a', 'b'] - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): Path('metadata').mkdir() with Path('metadata/a.yml').open('w') as f: @@ -260,21 +255,3 @@ class RewriteMetaTest(unittest.TestCase): ''' ), ) - - -if __name__ == "__main__": - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.options = common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(RewriteMetaTest)) - unittest.main(failfast=False) diff --git a/tests/scanner.TestCase b/tests/test_scanner.py similarity index 93% rename from tests/scanner.TestCase rename to tests/test_scanner.py index 6c965723..8935a575 100755 --- a/tests/scanner.TestCase +++ b/tests/test_scanner.py @@ -1,8 +1,5 @@ #!/usr/bin/env python3 -import glob -import inspect -import logging import os import pathlib import re @@ -23,19 +20,13 @@ else: import tomli as tomllib import yaml -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) - -from testcommon import TmpCwd, mkdtemp, mock_open_to_str, parse_args_for_test - import fdroidserver.build import fdroidserver.common import fdroidserver.metadata import fdroidserver.scanner +from .testcommon import TmpCwd, mkdtemp, mock_open_to_str + +basedir = pathlib.Path(__file__).parent # Always use built-in default rules so changes in downloaded rules don't break tests. @@ -45,21 +36,18 @@ import fdroidserver.scanner ) class ScannerTest(unittest.TestCase): def setUp(self): - logging.basicConfig(level=logging.INFO) - self.basedir = os.path.join(localmodule, 'tests') - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name fdroidserver.scanner.ScannerTool.refresh_allowed = False def tearDown(self): - os.chdir(self.basedir) + os.chdir(basedir) self._td.cleanup() def test_scan_source_files(self): fdroidserver.common.options = mock.Mock() fdroidserver.common.options.json = False - source_files = os.path.join(self.basedir, 'source-files') projects = { 'OtakuWorld': 2, 'Zillode': 1, @@ -76,12 +64,12 @@ class ScannerTest(unittest.TestCase): 'com.lolo.io.onelist': 6, 'catalog.test': 22, } - for d in glob.glob(os.path.join(source_files, '*')): + for d in (basedir / 'source-files').iterdir(): build = fdroidserver.metadata.Build() fatal_problems = fdroidserver.scanner.scan_source(d, build) - should = projects.get(os.path.basename(d), 0) + should = projects.get(d.name, 0) self.assertEqual( - should, fatal_problems, "%s should have %d errors!" % (d, should) + should, fatal_problems, f'{d} should have {should} errors!' ) def test_get_gradle_compile_commands_without_catalog(self): @@ -225,8 +213,7 @@ class ScannerTest(unittest.TestCase): fp.write(b'\x00\x00') fp.write(uuid.uuid4().bytes) shutil.copyfile('binary.out', 'fake.png') - os.chmod('fake.png', 0o755) - os.system('ls -l binary.out') + os.chmod('fake.png', 0o755) # nosec B103 with open('snippet.png', 'wb') as fp: fp.write( b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00' @@ -234,8 +221,7 @@ class ScannerTest(unittest.TestCase): b'IT\x08\x08\x08\x08|\x08d\x88\x00\x00\x00\tpHYs\x00\x00\n' b'a\x00\x00\na\x01\xfc\xccJ%\x00\x00\x00\x19tEXtSoftware' ) - os.chmod('snippet.png', 0o755) - os.system('ls -l fake.png') + os.chmod('snippet.png', 0o755) # nosec B103 # run scanner as if from `fdroid build` os.chdir(self.testdir) @@ -365,7 +351,7 @@ class ScannerTest(unittest.TestCase): def test_gradle_maven_url_regex(self): """Check the regex can find all the cases""" - with open(os.path.join(self.basedir, 'gradle-maven-blocks.yaml')) as fp: + with open(basedir / 'gradle-maven-blocks.yaml') as fp: data = yaml.safe_load(fp) urls = [] @@ -472,7 +458,7 @@ class ScannerTest(unittest.TestCase): apk = 'urzip.apk' mapzip = 'Norway_bouvet_europe_2.obf.zip' secretfile = os.path.join( - self.basedir, 'org.bitbucket.tickytacky.mirrormirror_1.apk' + basedir, 'org.bitbucket.tickytacky.mirrormirror_1.apk' ) with tempfile.TemporaryDirectory() as tmpdir: shutil.copy(apk, tmpdir) @@ -503,7 +489,6 @@ class ScannerTest(unittest.TestCase): class Test_scan_binary(unittest.TestCase): def setUp(self): - self.basedir = os.path.join(localmodule, 'tests') config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -519,7 +504,7 @@ class Test_scan_binary(unittest.TestCase): fdroidserver.scanner._SCANNER_TOOL.regexs['warn_code_signatures'] = {} def test_code_signature_match(self): - apkfile = os.path.join(self.basedir, 'no_targetsdk_minsdk1_unsigned.apk') + apkfile = os.path.join(basedir, 'no_targetsdk_minsdk1_unsigned.apk') self.assertEqual( 1, fdroidserver.scanner.scan_binary(apkfile), @@ -538,7 +523,7 @@ class Test_scan_binary(unittest.TestCase): "https://gitlab.com/fdroid/fdroidserver/-/merge_requests/1110#note_932026766", ) def test_bottom_level_embedded_apk_code_signature(self): - apkfile = os.path.join(self.basedir, 'apk.embedded_1.apk') + apkfile = os.path.join(basedir, 'apk.embedded_1.apk') fdroidserver.scanner._SCANNER_TOOL.regexs['err_code_signatures'] = { "org/bitbucket/tickytacky/mirrormirror/MainActivity": re.compile( r'.*org/bitbucket/tickytacky/mirrormirror/MainActivity', @@ -558,7 +543,7 @@ class Test_scan_binary(unittest.TestCase): ) def test_top_level_signature_embedded_apk_present(self): - apkfile = os.path.join(self.basedir, 'apk.embedded_1.apk') + apkfile = os.path.join(basedir, 'apk.embedded_1.apk') fdroidserver.scanner._SCANNER_TOOL.regexs['err_code_signatures'] = { "org/fdroid/ci/BuildConfig": re.compile( r'.*org/fdroid/ci/BuildConfig', re.IGNORECASE | re.UNICODE @@ -577,7 +562,6 @@ class Test_scan_binary(unittest.TestCase): class Test_SignatureDataController(unittest.TestCase): - # __init__ def test_init(self): sdc = fdroidserver.scanner.SignatureDataController( 'nnn', 'fff.yml', 'https://example.com/test.json' @@ -776,8 +760,7 @@ class Test_ScannerTool(unittest.TestCase): def setUp(self): fdroidserver.common.options = None fdroidserver.common.config = None - self.basedir = os.path.join(localmodule, 'tests') - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name fdroidserver.scanner.ScannerTool.refresh_allowed = True @@ -785,7 +768,7 @@ class Test_ScannerTool(unittest.TestCase): def tearDown(self): fdroidserver.common.options = None fdroidserver.common.config = None - os.chdir(self.basedir) + os.chdir(basedir) self._td.cleanup() def test_load(self): @@ -879,30 +862,3 @@ class Test_main(unittest.TestCase): self.exit_func.assert_not_called() self.read_app_args_func.assert_not_called() self.scan_binary_func.assert_called_once_with('local.application.apk') - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTests( - [ - unittest.makeSuite(ScannerTest), - unittest.makeSuite(Test_scan_binary), - unittest.makeSuite(Test_SignatureDataController), - unittest.makeSuite(Test_main), - ] - ) - unittest.main(failfast=False) diff --git a/tests/signatures.TestCase b/tests/test_signatures.py similarity index 57% rename from tests/signatures.TestCase rename to tests/test_signatures.py index de01c5b9..5444dc23 100755 --- a/tests/signatures.TestCase +++ b/tests/test_signatures.py @@ -1,27 +1,18 @@ #!/usr/bin/env python3 -import inspect -import os -import sys -import unittest import hashlib -import logging +import os +import unittest from tempfile import TemporaryDirectory -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) - -from testcommon import TmpCwd +from .testcommon import TmpCwd from fdroidserver import common, signatures +basedir = os.path.dirname(__file__) + class SignaturesTest(unittest.TestCase): def setUp(self): - logging.basicConfig(level=logging.DEBUG) common.config = None config = common.read_config() config['jarsigner'] = common.find_sdk_tools_cmd('jarsigner') @@ -30,12 +21,11 @@ class SignaturesTest(unittest.TestCase): def test_main(self): - # option fixture class: class OptionsFixture: - APK = [os.path.abspath(os.path.join('repo', 'com.politedroid_3.apk'))] + APK = [os.path.join(basedir, 'repo', 'com.politedroid_3.apk')] with TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): - signatures.extract(OptionsFixture()) + signatures.extract(OptionsFixture) # check if extracted signatures are where they are supposed to be # also verify weather if extracted file contian what they should @@ -49,27 +39,6 @@ class SignaturesTest(unittest.TestCase): ) for path, checksum in filesAndHashes: self.assertTrue(os.path.isfile(path), - msg="check whether '{path}' was extracted " - "correctly.".format(path=path)) + f'check whether {path!r} was extracted correctly.') with open(path, 'rb') as f: self.assertEqual(hashlib.sha256(f.read()).hexdigest(), checksum) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.options = common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(SignaturesTest)) - unittest.main(failfast=False) diff --git a/tests/signindex.TestCase b/tests/test_signindex.py similarity index 89% rename from tests/signindex.TestCase rename to tests/test_signindex.py index f66e9c18..149afb24 100755 --- a/tests/signindex.TestCase +++ b/tests/test_signindex.py @@ -1,22 +1,12 @@ #!/usr/bin/env python3 -import inspect import json -import logging import os import shutil import subprocess -import sys import tempfile import unittest -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) - from fdroidserver import apksigcopier, common, exception, signindex, update from pathlib import Path from unittest.mock import patch @@ -46,7 +36,6 @@ class SignindexTest(unittest.TestCase): config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' signindex.config = config - logging.basicConfig(level=logging.DEBUG) self.tempdir = tempfile.TemporaryDirectory() os.chdir(self.tempdir.name) self.repodir = Path('repo') @@ -187,23 +176,3 @@ class SignindexTest(unittest.TestCase): ['jarsigner', '-verify', '-verbose', f], stdout=subprocess.PIPE ) self.assertFalse(b'SHA1withRSA' in cp.stdout) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.options = common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(SignindexTest)) - unittest.main(failfast=False) diff --git a/tests/update.TestCase b/tests/test_update.py similarity index 93% rename from tests/update.TestCase rename to tests/test_update.py index 2489d646..1c110343 100755 --- a/tests/update.TestCase +++ b/tests/test_update.py @@ -1,12 +1,9 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - import copy import git import glob import hashlib -import inspect import json import logging import os @@ -14,8 +11,6 @@ import random import shutil import string import subprocess -import sys -import tempfile import unittest import yaml import zipfile @@ -47,24 +42,21 @@ except ImportError: except ImportError: from yaml import Loader as FullLoader -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.exception import fdroidserver.metadata import fdroidserver.update from fdroidserver.common import CATEGORIES_CONFIG_NAME from fdroidserver.looseversion import LooseVersion -from testcommon import TmpCwd, mkdtemp, parse_args_for_test +from .testcommon import TmpCwd, mkdtemp +from PIL import PngImagePlugin DONATION_FIELDS = ('Donate', 'Liberapay', 'OpenCollective') +logging.getLogger(PngImagePlugin.__name__).setLevel(logging.INFO) +basedir = Path(__file__).parent + class Options: allow_disabled_algorithms = False @@ -80,12 +72,7 @@ class UpdateTest(unittest.TestCase): '''fdroid update''' def setUp(self): - logging.basicConfig(level=logging.INFO) - from PIL import PngImagePlugin - - logging.getLogger(PngImagePlugin.__name__).setLevel(logging.INFO) - self.basedir = os.path.join(localmodule, 'tests') - os.chdir(self.basedir) + os.chdir(basedir) self._td = mkdtemp() self.testdir = self._td.name @@ -93,7 +80,7 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.options = None def tearDown(self): - os.chdir(self.basedir) + os.chdir(basedir) self._td.cleanup() def test_insert_store_metadata(self): @@ -103,24 +90,22 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.update.config = config - repo_dir = os.path.join(self.basedir, 'repo') + repo_dir = basedir / 'repo' os.mkdir('metadata') for packageName in ( 'obb.mainpatch.current', 'org.videolan.vlc', ): shutil.copytree( - os.path.join(repo_dir, packageName), os.path.join('repo', packageName) + repo_dir / packageName, os.path.join('repo', packageName) ) for packageName in ( 'info.guardianproject.checkey', 'info.guardianproject.urzip', 'org.smssecure.smssecure', ): - if not os.path.exists('metadata'): - os.mkdir('metadata') shutil.copytree( - os.path.join(self.basedir, 'metadata', packageName), + basedir / 'metadata' / packageName, os.path.join('metadata', packageName), ) for packageName in ( @@ -129,12 +114,12 @@ class UpdateTest(unittest.TestCase): 'eu.siacs.conversations', ): shutil.copytree( - os.path.join(self.basedir, 'source-files', packageName), + basedir / 'source-files' / packageName, os.path.join(self.testdir, 'build', packageName), ) testfilename = 'icon_yAfSvPRJukZzMMfUzvbYqwaD1XmHXNtiPBtuPVHW-6s=.png' - testfile = os.path.join(repo_dir, 'org.videolan.vlc', 'en-US', 'icon.png') + testfile = repo_dir / 'org.videolan.vlc/en-US/icon.png' cpdir = os.path.join('metadata', 'org.videolan.vlc', 'en-US') cpfile = os.path.join(cpdir, testfilename) os.makedirs(cpdir, exist_ok=True) @@ -171,7 +156,7 @@ class UpdateTest(unittest.TestCase): fdroidserver.update.insert_localized_app_metadata(apps) fdroidserver.update.ingest_screenshots_from_repo_dir(apps) - appdir = os.path.join('repo', 'info.guardianproject.urzip', 'en-US') + appdir = Path('repo/info.guardianproject.urzip/en-US') self.assertTrue( os.path.isfile( os.path.join( @@ -190,8 +175,8 @@ class UpdateTest(unittest.TestCase): self.assertEqual(6, len(apps)) for packageName, app in apps.items(): - self.assertTrue('localized' in app, packageName) - self.assertTrue('en-US' in app['localized']) + self.assertIn('localized', app, packageName) + self.assertIn('en-US', app['localized']) self.assertEqual(1, len(app['localized'])) if packageName == 'info.guardianproject.urzip': self.assertEqual(7, len(app['localized']['en-US'])) @@ -267,7 +252,7 @@ class UpdateTest(unittest.TestCase): def test_name_title_scraping(self): """metadata file --> fdroiddata localized files --> fastlane/triple-t in app source --> APK""" - shutil.copytree(self.basedir, self.testdir, dirs_exist_ok=True) + shutil.copytree(basedir, self.testdir, dirs_exist_ok=True) config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -356,7 +341,7 @@ class UpdateTest(unittest.TestCase): def test_insert_missing_app_names_from_apks_from_repo(self): os.chdir(self.testdir) - shutil.copytree(self.basedir, self.testdir, dirs_exist_ok=True) + shutil.copytree(basedir, self.testdir, dirs_exist_ok=True) config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -405,10 +390,10 @@ class UpdateTest(unittest.TestCase): repoapps['info.guardianproject.urzip']['localized']['en-US']['name']) def test_insert_triple_t_metadata(self): - importer = os.path.join(self.basedir, 'tmp', 'importer') + importer = basedir / 'tmp/importer' packageName = 'org.fdroid.ci.test.app' if not os.path.isdir(importer): - logging.warning('skipping test_insert_triple_t_metadata, import.TestCase must run first!') + logging.warning('skipping test_insert_triple_t_metadata, test_import.py must run first!') return packageDir = os.path.join(self.testdir, 'build', packageName) shutil.copytree(importer, packageDir) @@ -435,7 +420,7 @@ class UpdateTest(unittest.TestCase): apps = fdroidserver.metadata.read_metadata() fdroidserver.update.copy_triple_t_store_metadata(apps) - # TODO ideally, this would compare the whole dict like in metadata.TestCase's test_read_metadata() + # TODO ideally, this would compare the whole dict like in test_metadata.test_read_metadata() correctlocales = [ 'ar', 'ast_ES', 'az', 'ca', 'ca_ES', 'cs-CZ', 'cs_CZ', 'da', 'da-DK', 'de', 'de-DE', 'el', 'en-US', 'es', 'es-ES', 'es_ES', 'et', @@ -446,12 +431,12 @@ class UpdateTest(unittest.TestCase): 'ru_RU', 'sv-SE', 'sv_SE', 'te', 'tr', 'tr-TR', 'uk', 'uk_UA', 'vi', 'vi_VN', 'zh-CN', 'zh_CN', 'zh_TW', ] - locales = sorted(list(apps['org.fdroid.ci.test.app']['localized'].keys())) + locales = sorted(apps['org.fdroid.ci.test.app']['localized']) self.assertEqual(correctlocales, locales) def test_insert_triple_t_2_metadata(self): packageName = 'org.piwigo.android' - shutil.copytree(os.path.join(self.basedir, 'triple-t-2'), self.testdir, dirs_exist_ok=True) + shutil.copytree(basedir / 'triple-t-2', self.testdir, dirs_exist_ok=True) os.chdir(self.testdir) config = dict() @@ -489,7 +474,7 @@ class UpdateTest(unittest.TestCase): packages = ('com.anysoftkeyboard.languagepack.dutch', 'com.menny.android.anysoftkeyboard') names = ('Dutch for AnySoftKeyboard', 'AnySoftKeyboard') - shutil.copytree(os.path.join(self.basedir, 'triple-t-anysoftkeyboard'), self.testdir, dirs_exist_ok=True) + shutil.copytree(basedir / 'triple-t-anysoftkeyboard', self.testdir, dirs_exist_ok=True) os.chdir(self.testdir) for packageName, name in zip(packages, names): @@ -510,7 +495,7 @@ class UpdateTest(unittest.TestCase): packages = ('verifier', 'wallet') names = dict(verifier='COVID Certificate Check', wallet='COVID Certificate') - shutil.copytree(os.path.join(self.basedir, 'triple-t-multiple'), self.testdir, dirs_exist_ok=True) + shutil.copytree(basedir / 'triple-t-multiple', self.testdir, dirs_exist_ok=True) os.chdir(self.testdir) for p in packages: @@ -530,7 +515,7 @@ class UpdateTest(unittest.TestCase): def test_insert_triple_t_flutter(self): packageName = 'fr.emersion.goguma' - shutil.copytree(os.path.join(self.basedir, 'triple-t-flutter'), self.testdir, dirs_exist_ok=True) + shutil.copytree(basedir / 'triple-t-flutter', self.testdir, dirs_exist_ok=True) os.chdir(self.testdir) config = dict() @@ -602,8 +587,8 @@ class UpdateTest(unittest.TestCase): def testScanApksAndObbs(self): os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') - shutil.copytree(os.path.join(self.basedir, 'metadata'), 'metadata') + shutil.copytree(basedir / 'repo', 'repo') + shutil.copytree(basedir / 'metadata', 'metadata') config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() @@ -657,7 +642,7 @@ class UpdateTest(unittest.TestCase): def test_apkcache_json(self): """test the migration from pickle to json""" os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(basedir / 'repo', 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() @@ -698,7 +683,7 @@ class UpdateTest(unittest.TestCase): os.chdir(self.testdir) os.mkdir('repo') filename = 'Norway_bouvet_europe_2.obf.zip' - shutil.copy(os.path.join(self.basedir, filename), 'repo') + shutil.copy(basedir / filename, 'repo') knownapks = fdroidserver.common.KnownApks() files, fcachechanged = fdroidserver.update.scan_repo_files(dict(), 'repo', knownapks, False) self.assertTrue(fcachechanged) @@ -714,7 +699,7 @@ class UpdateTest(unittest.TestCase): def test_read_added_date_from_all_apks(self): os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(basedir / 'repo', 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -727,7 +712,7 @@ class UpdateTest(unittest.TestCase): def test_apply_info_from_latest_apk(self): os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(basedir / 'repo', 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -744,7 +729,7 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.update.config = config - os.chdir(self.basedir) + os.chdir(basedir) if 'apksigner' in config: apk_info = fdroidserver.update.scan_apk('v2.only.sig_2.apk') @@ -852,7 +837,7 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.update.config = config - os.chdir(self.basedir) + os.chdir(basedir) if os.path.basename(os.getcwd()) != 'tests': raise Exception('This test must be run in the "tests/" subdir') @@ -900,10 +885,10 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.update.config = config - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with mkdtemp() as tmpdir, TmpCwd(tmpdir): os.mkdir('repo') apkfile = 'repo/SystemWebView-repack.apk' - shutil.copy(os.path.join(self.basedir, os.path.basename(apkfile)), apkfile) + shutil.copy(basedir / os.path.basename(apkfile), apkfile) fdroidserver.update.scan_apk(apkfile) def test_scan_apk_bad_namespace_in_manifest(self): @@ -923,10 +908,10 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config fdroidserver.update.config = config - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with mkdtemp() as tmpdir, TmpCwd(tmpdir): os.mkdir('repo') apkfile = 'repo/org.sajeg.fallingblocks_3.apk' - shutil.copy(os.path.join(self.basedir, os.path.basename(apkfile)), apkfile) + shutil.copy(basedir / os.path.basename(apkfile), apkfile) fdroidserver.update.scan_apk(apkfile) def test_process_apk(self): @@ -935,7 +920,7 @@ class UpdateTest(unittest.TestCase): return dumper.represent_dict(data) os.chdir(self.testdir) - shutil.copytree(self.basedir, 'tests') + shutil.copytree(basedir, 'tests') config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -989,12 +974,12 @@ class UpdateTest(unittest.TestCase): TestLoader = FullLoader try: testyaml = '- !!python/object/new:fdroidserver.update.UsesPermission\n - test\n - null' - from_yaml = yaml.load(testyaml, Loader=TestLoader) + from_yaml = yaml.load(testyaml, Loader=TestLoader) # nosec B506 except yaml.constructor.ConstructorError: from yaml import UnsafeLoader as TestLoader with open(savepath, 'r') as f: - from_yaml = yaml.load(f, Loader=TestLoader) + from_yaml = yaml.load(f, Loader=TestLoader) # nosec B506 self.maxDiff = None if not config.get('ipfs_cid'): del from_yaml['ipfsCIDv1'] # handle when ipfs_cid is not installed @@ -1017,7 +1002,7 @@ class UpdateTest(unittest.TestCase): knownapks = fdroidserver.common.KnownApks() - with tempfile.TemporaryDirectory() as tmptestsdir, TmpCwd(tmptestsdir): + with mkdtemp() as tmptestsdir, TmpCwd(tmptestsdir): os.mkdir('repo') os.mkdir('archive') # setup the repo, create icons dirs, etc. @@ -1026,7 +1011,7 @@ class UpdateTest(unittest.TestCase): disabledsigs = ['org.bitbucket.tickytacky.mirrormirror_2.apk'] for apkName in disabledsigs: - shutil.copy(os.path.join(self.basedir, apkName), + shutil.copy(basedir / apkName, os.path.join(tmptestsdir, 'repo')) skip, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'repo', @@ -1081,7 +1066,7 @@ class UpdateTest(unittest.TestCase): badsigs = ['urzip-badcert.apk', 'urzip-badsig.apk', 'urzip-release-unsigned.apk', ] for apkName in badsigs: - shutil.copy(os.path.join(self.basedir, apkName), + shutil.copy(basedir / apkName, os.path.join(self.testdir, 'repo')) skip, apk, cachechanged = fdroidserver.update.process_apk({}, apkName, 'repo', @@ -1093,7 +1078,7 @@ class UpdateTest(unittest.TestCase): self.assertFalse(cachechanged) def test_process_invalid_apk(self): - os.chdir(self.basedir) + os.chdir(basedir) if os.path.basename(os.getcwd()) != 'tests': raise Exception('This test must be run in the "tests/" subdir') @@ -1117,7 +1102,7 @@ class UpdateTest(unittest.TestCase): def test_get_apks_without_allowed_signatures(self): """Test when no AllowedAPKSigningKeys is specified""" os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(basedir / 'repo', 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -1128,6 +1113,11 @@ class UpdateTest(unittest.TestCase): knownapks = fdroidserver.common.KnownApks() apks, cachechanged = fdroidserver.update.process_apks({}, 'repo', knownapks) apkfile = 'v1.v2.sig_1020.apk' + self.assertIn( + apkfile, + os.listdir('repo'), + f'{apkfile} was archived or otherwise removed from "repo"', + ) (skip, apk, cachechanged) = fdroidserver.update.process_apk( {}, apkfile, 'repo', knownapks, False ) @@ -1138,7 +1128,7 @@ class UpdateTest(unittest.TestCase): def test_get_apks_without_allowed_signatures_allowed(self): """Test when the APK matches the specified AllowedAPKSigningKeys""" os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(basedir / 'repo', 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -1163,7 +1153,7 @@ class UpdateTest(unittest.TestCase): def test_get_apks_without_allowed_signatures_blocked(self): """Test when the APK does not match any specified AllowedAPKSigningKeys""" os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') + shutil.copytree(basedir / 'repo', 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config @@ -1190,12 +1180,12 @@ class UpdateTest(unittest.TestCase): os.chdir(self.testdir) os.mkdir('repo') testapk = os.path.join('repo', 'com.politedroid_6.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) os.mkdir('metadata') metadatafile = os.path.join('metadata', 'com.politedroid.yml') # Copy and manipulate metadata file - shutil.copy(os.path.join(self.basedir, metadatafile), metadatafile) + shutil.copy(basedir / metadatafile, metadatafile) with open(metadatafile, 'a') as fp: fp.write( '\n\nAllowedAPKSigningKeys: 32a23624c201b949f085996ba5ed53d40f703aca4989476949cae891022e0ed6\n' @@ -1209,7 +1199,7 @@ class UpdateTest(unittest.TestCase): config['repo_keyalias'] = 'sova' config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI=' - config['keystore'] = os.path.join(self.basedir, 'keystore.jks') + config['keystore'] = os.path.join(basedir, 'keystore.jks') self.assertTrue(os.path.exists(testapk)) @@ -1219,7 +1209,7 @@ class UpdateTest(unittest.TestCase): self.assertTrue(os.path.exists(testapk)) # Copy and manipulate metadata file again - shutil.copy(os.path.join(self.basedir, metadatafile), metadatafile) + shutil.copy(basedir / metadatafile, metadatafile) with open(metadatafile, 'a') as fp: fp.write( '\n\nAllowedAPKSigningKeys: fa4edeadfa4edeadfa4edeadfa4edeadfa4edeadfa4edeadfa4edeadfa4edead\n' @@ -1232,8 +1222,8 @@ class UpdateTest(unittest.TestCase): def test_translate_per_build_anti_features(self): os.chdir(self.testdir) - shutil.copytree(os.path.join(self.basedir, 'repo'), 'repo') - shutil.copytree(os.path.join(self.basedir, 'metadata'), 'metadata') + shutil.copytree(basedir / 'repo', 'repo') + shutil.copytree(basedir / 'metadata', 'metadata') config = dict() fdroidserver.common.fill_config_defaults(config) config['ndk_paths'] = dict() @@ -1263,7 +1253,7 @@ class UpdateTest(unittest.TestCase): os.chdir(self.testdir) os.mkdir('repo') os.mkdir('metadata') - shutil.copy(os.path.join(localmodule, 'tests', 'urzip.apk'), 'repo') + shutil.copy(basedir / 'urzip.apk', 'repo') config = dict() fdroidserver.common.fill_config_defaults(config) @@ -1302,7 +1292,7 @@ class UpdateTest(unittest.TestCase): # test using external template.yml os.remove(testfile) self.assertFalse(os.path.exists(testfile)) - shutil.copy(os.path.join(localmodule, 'examples', 'template.yml'), self.testdir) + shutil.copy(basedir.with_name('examples') / 'template.yml', self.testdir) fdroidserver.update.create_metadata_from_template(apk) self.assertTrue(os.path.exists(testfile)) apps = fdroidserver.metadata.read_metadata() @@ -1354,22 +1344,23 @@ class UpdateTest(unittest.TestCase): # pylint: disable=protected-access icons_src = fdroidserver.update._get_apk_icons_src('urzip-release.apk', None) - assert not icons_src + self.assertFalse(icons_src) def test_strip_and_copy_image(self): - in_file = os.path.join(self.basedir, 'metadata', 'info.guardianproject.urzip', 'en-US', 'images', 'icon.png') + in_file = basedir / 'metadata/info.guardianproject.urzip/en-US/images/icon.png' out_file = os.path.join(self.testdir, 'icon.png') fdroidserver.update._strip_and_copy_image(in_file, out_file) self.assertTrue(os.path.exists(out_file)) - in_file = os.path.join(self.basedir, 'corrupt-featureGraphic.png') + def test_strip_and_copy_image_bad_filename(self): + in_file = basedir / 'corrupt-featureGraphic.png' out_file = os.path.join(self.testdir, 'corrupt-featureGraphic.png') fdroidserver.update._strip_and_copy_image(in_file, out_file) self.assertFalse(os.path.exists(out_file)) def test_create_metadata_from_template_empty_keys(self): apk = {'packageName': 'rocks.janicerand'} - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with mkdtemp() as tmpdir, TmpCwd(tmpdir): os.mkdir('metadata') with open('template.yml', 'w') as f: f.write( @@ -1554,7 +1545,7 @@ class UpdateTest(unittest.TestCase): self.assertIsNone(app.get(field)) def test_sanitize_funding_yml(self): - with open(os.path.join(self.basedir, 'funding-usernames.yaml')) as fp: + with open(basedir / 'funding-usernames.yaml') as fp: data = yaml.load(fp, Loader=SafeLoader) for k, entries in data.items(): for entry in entries: @@ -1568,7 +1559,7 @@ class UpdateTest(unittest.TestCase): self.assertIsNotNone(m) self.assertIsNone(fdroidserver.update.sanitize_funding_yml_entry('foo\nbar')) self.assertIsNone(fdroidserver.update.sanitize_funding_yml_entry( - ''.join(chr(random.randint(65, 90)) for _ in range(2049)))) + ''.join(chr(random.randint(65, 90)) for _ in range(2049)))) # nosec B311 # not recommended but valid entries self.assertIsNotNone(fdroidserver.update.sanitize_funding_yml_entry(12345)) @@ -1593,7 +1584,7 @@ class UpdateTest(unittest.TestCase): for f, key in files.items(): limit = config['char_limits'][key] with open(f, 'w') as fp: - fp.write(''.join(random.choice(string.ascii_letters) for i in range(limit + 100))) + fp.write(''.join(random.choice(string.ascii_letters) for i in range(limit + 100))) # nosec B311 locale = 'ru_US' app = dict() fdroidserver.update._set_localized_text_entry(app, locale, key, f) @@ -1628,7 +1619,7 @@ class UpdateTest(unittest.TestCase): limit = config['char_limits']['author'] for key in ('authorEmail', 'authorPhone', 'authorWebSite'): with open(f, 'w') as fp: - fp.write(''.join(random.choice(string.ascii_letters) for i in range(limit + 100))) + fp.write(''.join(random.choice(string.ascii_letters) for i in range(limit + 100))) # nosec B311 app = dict() fdroidserver.update._set_author_entry(app, key, f) self.assertEqual(limit, len(app[key])) @@ -1643,7 +1634,7 @@ class UpdateTest(unittest.TestCase): fdroidserver.common.config = {} fdroidserver.update.config = {} fdroidserver.update.options = Options - with tempfile.TemporaryDirectory() as tmpdir: + with mkdtemp() as tmpdir: os.chdir(tmpdir) with mock.patch('sys.argv', ['fdroid update', '']): fdroidserver.update.status_update_json([], []) @@ -1737,7 +1728,7 @@ class UpdateTest(unittest.TestCase): os.mkdir('repo') testapk = os.path.join('repo', 'com.politedroid_6.apk') testapk_new = os.path.join('repo', 'Politedroid-1.5.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk_new) + shutil.copy(basedir / testapk, testapk_new) config = dict() fdroidserver.common.fill_config_defaults(config) @@ -1817,14 +1808,14 @@ class UpdateTest(unittest.TestCase): ) testapk = os.path.join('repo', 'com.politedroid_6.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) Path('metadata/com.politedroid.yml').write_text('Name: Polite') with mock.patch('sys.argv', ['fdroid update', '--delete-unknown', '--nosign']): fdroidserver.update.main() with open('repo/index-v2.json') as fp: index = json.load(fp) - self.assertFalse(CATEGORIES_CONFIG_NAME in index['repo']) + self.assertNotIn(CATEGORIES_CONFIG_NAME, index['repo']) def test_auto_defined_categories(self): """Repos that don't define categories in config/ should use auto-generated.""" @@ -1836,7 +1827,7 @@ class UpdateTest(unittest.TestCase): ) testapk = os.path.join('repo', 'com.politedroid_6.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) Path('metadata/com.politedroid.yml').write_text('Categories: [Time]') with mock.patch('sys.argv', ['fdroid update', '--delete-unknown', '--nosign']): @@ -1858,10 +1849,10 @@ class UpdateTest(unittest.TestCase): ) testapk = os.path.join('repo', 'com.politedroid_6.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) Path('metadata/com.politedroid.yml').write_text('Categories: [bar]') testapk = os.path.join('repo', 'souch.smsbypass_9.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) Path('metadata/souch.smsbypass.yml').write_text('Categories: [foo, bar]') with mock.patch('sys.argv', ['fdroid update', '--delete-unknown', '--nosign']): @@ -1885,10 +1876,10 @@ class UpdateTest(unittest.TestCase): ) testapk = os.path.join('repo', 'com.politedroid_6.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) Path('metadata/com.politedroid.yml').write_text('Categories: [Time]') testapk = os.path.join('repo', 'souch.smsbypass_9.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) Path('metadata/souch.smsbypass.yml').write_text('Categories: [System, Time]') with mock.patch('sys.argv', ['fdroid update', '--delete-unknown', '--nosign']): @@ -1915,7 +1906,7 @@ class UpdateTest(unittest.TestCase): ) testapk = os.path.join('repo', 'com.politedroid_6.apk') - shutil.copy(os.path.join(self.basedir, testapk), testapk) + shutil.copy(basedir / testapk, testapk) Path('metadata/com.politedroid.yml').write_text('Categories: [Time]') with mock.patch('sys.argv', ['fdroid update', '--delete-unknown', '--nosign']): @@ -1937,12 +1928,8 @@ class TestParseIpa(unittest.TestCase): biplist # silence the linters except ImportError as e: self.skipTest(str(e)) - ipa_path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - 'com.fake.IpaApp_1000000000001.ipa', - ) + ipa_path = os.path.join(basedir, 'com.fake.IpaApp_1000000000001.ipa') result = fdroidserver.update.parse_ipa(ipa_path, 'fake_size', 'fake_sha') - self.maxDiff = None self.assertDictEqual( result, { @@ -2007,12 +1994,10 @@ class TestUpdateVersionStringToInt(unittest.TestCase): class TestScanRepoForIpas(unittest.TestCase): - def setUp(self): - self.maxDiff = None - def test_scan_repo_for_ipas_no_cache(self): self.maxDiff = None - with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir): + with mkdtemp() as tmpdir: + os.chdir(tmpdir) os.mkdir("repo") with open('repo/abc.Def_123.ipa', 'w') as f: f.write('abc') @@ -2020,7 +2005,6 @@ class TestScanRepoForIpas(unittest.TestCase): f.write('xyz') apkcache = mock.MagicMock() - # apkcache['a'] = 1 repodir = "repo" knownapks = mock.MagicMock() @@ -2129,7 +2113,7 @@ class TestDiscoverIosScreenshots(unittest.TestCase): def test_discover_ios_screenshots(self): self.maxDiff = None - with tempfile.TemporaryDirectory() as fastlane_dir: + with mkdtemp() as fastlane_dir: fastlane_dir = Path(fastlane_dir) (fastlane_dir / "screenshots/en-US").mkdir(parents=True) with open(fastlane_dir / "screenshots/en-US/iPhone 8+ @ iOS 16-1.png", 'w') as f: @@ -2166,6 +2150,14 @@ class TestDiscoverIosScreenshots(unittest.TestCase): class TestCopyIosScreenshotsToRepo(unittest.TestCase): + def setUp(self): + self._td = mkdtemp() + os.chdir(self._td.name) + + def tearDown(self): + os.chdir(basedir) + self._td.cleanup() + def test_copy_ios_screenshots_to_repo(self): self.maxDiff = None @@ -2218,7 +2210,7 @@ class TestGetIpaIcon(unittest.TestCase): def test_get_ipa_icon(self): self.maxDiff = None - with tempfile.TemporaryDirectory() as tmpdir: + with mkdtemp() as tmpdir: tmpdir = Path(tmpdir) (tmpdir / 'OnionBrowser.xcodeproj').mkdir() with open(tmpdir / 'OnionBrowser.xcodeproj/project.pbxproj', "w") as f: @@ -2245,7 +2237,7 @@ class TestParseFromPbxproj(unittest.TestCase): def test_parse_from_pbxproj(self): self.maxDiff = None - with tempfile.TemporaryDirectory() as tmpdir: + with mkdtemp() as tmpdir: with open(Path(tmpdir) / "asdf.pbxproj", 'w', encoding="utf-8") as f: f.write(""" 230jfaod=flc' @@ -2257,29 +2249,3 @@ class TestParseFromPbxproj(unittest.TestCase): "ASSETCATALOG_COMPILER_APPICON_NAME" ) self.assertEqual(v, "MyIcon") - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(UpdateTest)) - newSuite.addTest(unittest.makeSuite(TestUpdateVersionStringToInt)) - newSuite.addTest(unittest.makeSuite(TestScanRepoForIpas)) - newSuite.addTest(unittest.makeSuite(TestParseIosScreenShotName)) - newSuite.addTest(unittest.makeSuite(TestInsertLocalizedIosAppMetadata)) - newSuite.addTest(unittest.makeSuite(TestDiscoverIosScreenshots)) - newSuite.addTest(unittest.makeSuite(TestGetIpaIcon)) - unittest.main(failfast=False) diff --git a/tests/vcs.TestCase b/tests/test_vcs.py similarity index 66% rename from tests/vcs.TestCase rename to tests/test_vcs.py index 86f67ae1..9a210d60 100755 --- a/tests/vcs.TestCase +++ b/tests/test_vcs.py @@ -1,45 +1,26 @@ #!/usr/bin/env python3 -# http://www.drdobbs.com/testing/unit-testing-with-python/240165163 - -import inspect -import logging import os -import sys import unittest from git import Repo -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.build import fdroidserver.common import fdroidserver.metadata -import fdroidserver.scanner -from testcommon import mkdtemp, parse_args_for_test +from .testcommon import mkdtemp class VCSTest(unittest.TestCase): """For some reason the VCS classes are in fdroidserver/common.py""" def setUp(self): - logging.basicConfig(level=logging.DEBUG) - self.basedir = os.path.join(localmodule, 'tests') - os.chdir(self.basedir) self._td = mkdtemp() - self.testdir = self._td.name + os.chdir(self._td.name) def tearDown(self): self._td.cleanup() - os.chdir(self.basedir) def test_remote_set_head_can_fail(self): - os.chdir(self.testdir) # First create an upstream repo with one commit upstream_repo = Repo.init("upstream_repo") with open(upstream_repo.working_dir + "/file", 'w') as f: @@ -72,6 +53,8 @@ class VCSTest(unittest.TestCase): build.androidupdate = ['no'] vcs, build_dir = fdroidserver.common.setup_vcs(app) # force an init of the repo, the remote head error only occurs on the second gotorevision call + + fdroidserver.common.options = type('Options', (), {'verbose': False}) vcs.gotorevision(build.commit) fdroidserver.common.prepare_source( vcs, @@ -82,23 +65,3 @@ class VCSTest(unittest.TestCase): extlib_dir="ignore", ) self.assertTrue(os.path.isfile("build/com.gpl.rpg.AndorsTrail/file")) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - parse_args_for_test(parser, sys.argv) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(VCSTest)) - unittest.main(failfast=False) diff --git a/tests/verify.TestCase b/tests/test_verify.py similarity index 69% rename from tests/verify.TestCase rename to tests/test_verify.py index eee8e9e8..041fc82c 100755 --- a/tests/verify.TestCase +++ b/tests/test_verify.py @@ -1,25 +1,15 @@ #!/usr/bin/env python3 -import inspect import json -import logging import os import shutil -import sys import tempfile import unittest from pathlib import Path from unittest.mock import patch -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) - -from fdroidserver import common, verify +from fdroidserver import verify TEST_APP_ENTRY = { @@ -45,12 +35,11 @@ TEST_APP_ENTRY = { } } +basedir = Path(__file__).parent + class VerifyTest(unittest.TestCase): - basedir = Path(__file__).resolve().parent - def setUp(self): - logging.basicConfig(level=logging.DEBUG) self.tempdir = tempfile.TemporaryDirectory() os.chdir(self.tempdir.name) self.repodir = Path('repo') @@ -72,8 +61,8 @@ class VerifyTest(unittest.TestCase): remote_apk = 'tmp/' + apk_name unsigned_apk = 'unsigned/' + apk_name # TODO common.use apk_strip_v1_signatures() on unsigned_apk - shutil.copy(str(self.basedir / 'repo' / apk_name), remote_apk) - shutil.copy(str(self.basedir / 'repo' / apk_name), unsigned_apk) + shutil.copy(basedir / 'repo' / apk_name, remote_apk) + shutil.copy(basedir / 'repo' / apk_name, unsigned_apk) url = TEST_APP_ENTRY['1539780240.3885746']['url'] self.assertFalse(verified_json.exists()) @@ -88,23 +77,3 @@ class VerifyTest(unittest.TestCase): secondpass = json.load(fp) self.assertEqual(firstpass, secondpass) - - -if __name__ == "__main__": - os.chdir(os.path.dirname(__file__)) - - import argparse - - parser = argparse.ArgumentParser() - parser.add_argument( - "-v", - "--verbose", - action="store_true", - default=False, - help="Spew out even more information than normal", - ) - common.options = common.parse_args(parser) - - newSuite = unittest.TestSuite() - newSuite.addTest(unittest.makeSuite(VerifyTest)) - unittest.main(failfast=False) diff --git a/tests/testcommon.py b/tests/testcommon.py index edb54fb0..e1031da6 100644 --- a/tests/testcommon.py +++ b/tests/testcommon.py @@ -78,19 +78,6 @@ def mkdir_testfiles(localmodule, test): return tempfile.mkdtemp(dir=testdir) -def parse_args_for_test(parser, args): - """Only send --flags to the ArgumentParser, not test classes, etc.""" - - from fdroidserver.common import parse_args - - flags = [] - for arg in args: - if arg[0] == '-': - flags.append(flags) - with unittest.mock.patch('sys.argv', flags): - parse_args(parser) - - def mock_urlopen(status=200, body=None): resp = unittest.mock.MagicMock() resp.getcode.return_value = status