mirror of
				https://github.com/f-droid/fdroidserver.git
				synced 2025-11-04 14:30:30 +03:00 
			
		
		
		
	scanner: add regression tests for signautre load logic
This commit is contained in:
		
							parent
							
								
									d815a64fdb
								
							
						
					
					
						commit
						e967fc61cf
					
				
					 1 changed files with 146 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -450,7 +450,9 @@ class Test_scan_binary(unittest.TestCase):
 | 
			
		|||
        fdroidserver.scanner._SCANNER_TOOL = mock.Mock()
 | 
			
		||||
        fdroidserver.scanner._SCANNER_TOOL.regexs = {}
 | 
			
		||||
        fdroidserver.scanner._SCANNER_TOOL.regexs['err_code_signatures'] = {
 | 
			
		||||
            "java/lang/Object": re.compile(r'.*java/lang/Object', re.IGNORECASE | re.UNICODE)
 | 
			
		||||
            "java/lang/Object": re.compile(
 | 
			
		||||
                r'.*java/lang/Object', re.IGNORECASE | re.UNICODE
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        fdroidserver.scanner._SCANNER_TOOL.regexs['warn_code_signatures'] = {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -459,7 +461,12 @@ class Test_scan_binary(unittest.TestCase):
 | 
			
		|||
        self.assertEqual(
 | 
			
		||||
            1,
 | 
			
		||||
            fdroidserver.scanner.scan_binary(apkfile),
 | 
			
		||||
            "Did not find expected code signature '{}' in binary '{}'".format(fdroidserver.scanner._SCANNER_TOOL.regexs['err_code_signatures'].values(), apkfile),
 | 
			
		||||
            "Did not find expected code signature '{}' in binary '{}'".format(
 | 
			
		||||
                fdroidserver.scanner._SCANNER_TOOL.regexs[
 | 
			
		||||
                    'err_code_signatures'
 | 
			
		||||
                ].values(),
 | 
			
		||||
                apkfile,
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @unittest.skipIf(
 | 
			
		||||
| 
						 | 
				
			
			@ -472,14 +479,20 @@ class Test_scan_binary(unittest.TestCase):
 | 
			
		|||
        apkfile = os.path.join(self.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', re.IGNORECASE | re.UNICODE
 | 
			
		||||
                r'.*org/bitbucket/tickytacky/mirrormirror/MainActivity',
 | 
			
		||||
                re.IGNORECASE | re.UNICODE,
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            1,
 | 
			
		||||
            fdroidserver.scanner.scan_binary(apkfile),
 | 
			
		||||
            "Did not find expected code signature '{}' in binary '{}'".format(fdroidserver.scanner._SCANNER_TOOL.regexs['err_code_signatures'].values(), apkfile),
 | 
			
		||||
            "Did not find expected code signature '{}' in binary '{}'".format(
 | 
			
		||||
                fdroidserver.scanner._SCANNER_TOOL.regexs[
 | 
			
		||||
                    'err_code_signatures'
 | 
			
		||||
                ].values(),
 | 
			
		||||
                apkfile,
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_top_level_signature_embedded_apk_present(self):
 | 
			
		||||
| 
						 | 
				
			
			@ -492,14 +505,21 @@ class Test_scan_binary(unittest.TestCase):
 | 
			
		|||
        self.assertEqual(
 | 
			
		||||
            1,
 | 
			
		||||
            fdroidserver.scanner.scan_binary(apkfile),
 | 
			
		||||
            "Did not find expected code signature '{}' in binary '{}'".format(fdroidserver.scanner._SCANNER_TOOL.regexs['err_code_signatures'].values(), apkfile),
 | 
			
		||||
            "Did not find expected code signature '{}' in binary '{}'".format(
 | 
			
		||||
                fdroidserver.scanner._SCANNER_TOOL.regexs[
 | 
			
		||||
                    'err_code_signatures'
 | 
			
		||||
                ].values(),
 | 
			
		||||
                apkfile,
 | 
			
		||||
            ),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Test_SignatureDataController(unittest.TestCase):
 | 
			
		||||
    # __init__
 | 
			
		||||
    def test_init(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(sdc.name, 'nnn')
 | 
			
		||||
        self.assertEqual(sdc.filename, 'fff.yml')
 | 
			
		||||
        self.assertEqual(sdc.cache_duration, timedelta(999999))
 | 
			
		||||
| 
						 | 
				
			
			@ -507,51 +527,144 @@ class Test_SignatureDataController(unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
    # check_last_updated
 | 
			
		||||
    def test_check_last_updated_ok(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        sdc.data['last_updated'] = datetime.utcnow().timestamp()
 | 
			
		||||
        sdc.check_last_updated()
 | 
			
		||||
 | 
			
		||||
    def test_check_last_updated_exception_cache_outdated(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        sdc.cache_duration = timedelta(days=7)
 | 
			
		||||
        sdc.data['last_updated'] = (datetime.utcnow() - timedelta(days=30)).timestamp()
 | 
			
		||||
        with self.assertRaises(fdroidserver.scanner.SignatureDataOutdatedException):
 | 
			
		||||
            sdc.check_last_updated()
 | 
			
		||||
 | 
			
		||||
    def test_check_last_updated_exception_not_string(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        sdc.data['last_updated'] = 'sepp'
 | 
			
		||||
        with self.assertRaises(fdroidserver.scanner.SignatureDataMalformedException):
 | 
			
		||||
            sdc.check_last_updated()
 | 
			
		||||
 | 
			
		||||
    def test_check_last_updated_exception_not_iso_formatted_string(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        sdc.data['last_updated'] = '01/09/2002 10:11'
 | 
			
		||||
        with self.assertRaises(fdroidserver.scanner.SignatureDataMalformedException):
 | 
			
		||||
            sdc.check_last_updated()
 | 
			
		||||
 | 
			
		||||
    def test_check_last_updated_no_exception_missing_when_last_updated_not_set(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        sdc.check_last_updated()
 | 
			
		||||
 | 
			
		||||
    # check_data_version
 | 
			
		||||
    def test_check_data_version_ok(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        sdc.data['version'] = fdroidserver.scanner.SCANNER_CACHE_VERSION
 | 
			
		||||
        sdc.check_data_version()
 | 
			
		||||
 | 
			
		||||
    def test_check_data_version_exception(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        with self.assertRaises(fdroidserver.scanner.SignatureDataVersionMismatchException):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        with self.assertRaises(
 | 
			
		||||
            fdroidserver.scanner.SignatureDataVersionMismatchException
 | 
			
		||||
        ):
 | 
			
		||||
            sdc.check_data_version()
 | 
			
		||||
 | 
			
		||||
    def test_load_ok(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        func_lfc = mock.Mock()
 | 
			
		||||
        func_vd = mock.Mock()
 | 
			
		||||
        func_clu = mock.Mock()
 | 
			
		||||
        with mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.load_from_cache',
 | 
			
		||||
            func_lfc,
 | 
			
		||||
        ), mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.verify_data',
 | 
			
		||||
            func_vd,
 | 
			
		||||
        ), mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.check_last_updated',
 | 
			
		||||
            func_clu,
 | 
			
		||||
        ):
 | 
			
		||||
            sdc.load()
 | 
			
		||||
        func_lfc.assert_called_once_with()
 | 
			
		||||
        func_vd.assert_called_once_with()
 | 
			
		||||
        func_clu.assert_called_once_with()
 | 
			
		||||
 | 
			
		||||
    def test_load_initial_cache_miss(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        func_lfc = mock.Mock(
 | 
			
		||||
            side_effect=fdroidserver.scanner.SignatureDataCacheMissException
 | 
			
		||||
        )
 | 
			
		||||
        func_lfd = mock.Mock()
 | 
			
		||||
        with mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.load_from_cache',
 | 
			
		||||
            func_lfc,
 | 
			
		||||
        ), mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.load_from_defaults',
 | 
			
		||||
            func_lfd,
 | 
			
		||||
        ):
 | 
			
		||||
            sdc.load()
 | 
			
		||||
        func_lfc.assert_called_once_with()
 | 
			
		||||
        func_lfd.assert_called_once_with()
 | 
			
		||||
 | 
			
		||||
    def test_load_cache_auto_refresh(self):
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        func_lfc = mock.Mock()
 | 
			
		||||
        func_vd = mock.Mock()
 | 
			
		||||
        func_clu = mock.Mock(
 | 
			
		||||
            side_effect=fdroidserver.scanner.SignatureDataOutdatedException()
 | 
			
		||||
        )
 | 
			
		||||
        func_fsfw = mock.Mock()
 | 
			
		||||
        func_wtc = mock.Mock()
 | 
			
		||||
        with mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.load_from_cache',
 | 
			
		||||
            func_lfc,
 | 
			
		||||
        ), mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.verify_data',
 | 
			
		||||
            func_vd,
 | 
			
		||||
        ), mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.check_last_updated',
 | 
			
		||||
            func_clu,
 | 
			
		||||
        ), mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.fetch_signatures_from_web',
 | 
			
		||||
            func_fsfw,
 | 
			
		||||
        ), mock.patch(
 | 
			
		||||
            'fdroidserver.scanner.SignatureDataController.write_to_cache',
 | 
			
		||||
            func_wtc,
 | 
			
		||||
        ):
 | 
			
		||||
            sdc.load()
 | 
			
		||||
        func_lfc.assert_called_once_with()
 | 
			
		||||
        func_vd.assert_called_once_with()
 | 
			
		||||
        func_clu.assert_called_once_with()
 | 
			
		||||
        func_fsfw.assert_called_once_with()
 | 
			
		||||
        func_wtc.assert_called_once_with()
 | 
			
		||||
 | 
			
		||||
    @unittest.skipIf(
 | 
			
		||||
        sys.version_info < (3, 9, 0),
 | 
			
		||||
        "mock_open doesn't allow easy access to written data in older python versions",
 | 
			
		||||
    )
 | 
			
		||||
    def test_write_to_cache(self):
 | 
			
		||||
        open_func = mock.mock_open()
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController('nnn', 'fff.yml', 'https://example.com/test.json')
 | 
			
		||||
        sdc = fdroidserver.scanner.SignatureDataController(
 | 
			
		||||
            'nnn', 'fff.yml', 'https://example.com/test.json'
 | 
			
		||||
        )
 | 
			
		||||
        sdc.data = {"mocked": "data"}
 | 
			
		||||
 | 
			
		||||
        with mock.patch("builtins.open", open_func), mock.patch(
 | 
			
		||||
| 
						 | 
				
			
			@ -561,10 +674,16 @@ class Test_SignatureDataController(unittest.TestCase):
 | 
			
		|||
            sdc.write_to_cache()
 | 
			
		||||
 | 
			
		||||
        open_func.assert_called_with(pathlib.Path('fff.yml'), 'w', encoding="utf-8")
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            mock_open_to_str(open_func),
 | 
			
		||||
            """{\n  "mocked": "data"\n}"""
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(mock_open_to_str(open_func), """{\n  "mocked": "data"\n}""")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Test_ScannerTool(unittest.TestCase):
 | 
			
		||||
    def test_load(self):
 | 
			
		||||
        st = mock.Mock()
 | 
			
		||||
        st.sdcs = [mock.Mock(), mock.Mock()]
 | 
			
		||||
        fdroidserver.scanner.ScannerTool.load(st)
 | 
			
		||||
        st.sdcs[0].load.assert_called_once_with()
 | 
			
		||||
        st.sdcs[1].load.assert_called_once_with()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Test_main(unittest.TestCase):
 | 
			
		||||
| 
						 | 
				
			
			@ -630,10 +749,12 @@ if __name__ == "__main__":
 | 
			
		|||
    (fdroidserver.common.options, args) = parser.parse_args(['--verbose'])
 | 
			
		||||
 | 
			
		||||
    newSuite = unittest.TestSuite()
 | 
			
		||||
    newSuite.addTests([
 | 
			
		||||
        unittest.makeSuite(ScannerTest),
 | 
			
		||||
        unittest.makeSuite(Test_scan_binary),
 | 
			
		||||
        unittest.makeSuite(Test_SignatureDataController),
 | 
			
		||||
        unittest.makeSuite(Test_main),
 | 
			
		||||
    ])
 | 
			
		||||
    newSuite.addTests(
 | 
			
		||||
        [
 | 
			
		||||
            unittest.makeSuite(ScannerTest),
 | 
			
		||||
            unittest.makeSuite(Test_scan_binary),
 | 
			
		||||
            unittest.makeSuite(Test_SignatureDataController),
 | 
			
		||||
            unittest.makeSuite(Test_main),
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
    unittest.main(failfast=False)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue