2016-01-04 21:17:58 +01:00
|
|
|
#!/usr/bin/env python3
|
2015-07-22 10:16:43 +02:00
|
|
|
|
2023-04-27 19:57:33 +02:00
|
|
|
import copy
|
2018-08-08 00:59:25 +02:00
|
|
|
import io
|
2017-11-30 10:14:38 +01:00
|
|
|
import logging
|
2015-07-22 10:16:43 +02:00
|
|
|
import optparse
|
|
|
|
import os
|
2017-11-29 22:03:26 +01:00
|
|
|
import random
|
|
|
|
import shutil
|
2015-07-22 10:16:43 +02:00
|
|
|
import sys
|
|
|
|
import unittest
|
2021-06-08 15:31:55 +02:00
|
|
|
from unittest import mock
|
2017-05-09 14:13:14 +02:00
|
|
|
import tempfile
|
2018-08-08 00:59:25 +02:00
|
|
|
import textwrap
|
2020-01-03 14:17:03 +01:00
|
|
|
from collections import OrderedDict
|
2021-06-08 15:31:55 +02:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
|
|
from testcommon import TmpCwd
|
|
|
|
|
2021-12-29 12:07:45 +01:00
|
|
|
from ruamel.yaml import YAML
|
2015-07-22 10:16:43 +02:00
|
|
|
|
2021-12-29 12:07:45 +01:00
|
|
|
yaml = YAML(typ='safe')
|
2020-09-10 02:37:05 +02:00
|
|
|
|
2021-06-08 15:31:55 +02:00
|
|
|
localmodule = Path(__file__).resolve().parent.parent
|
|
|
|
print('localmodule: ' + str(localmodule))
|
2015-07-22 10:16:43 +02:00
|
|
|
if localmodule not in sys.path:
|
2021-06-08 15:31:55 +02:00
|
|
|
sys.path.insert(0, str(localmodule))
|
2015-07-22 10:16:43 +02:00
|
|
|
|
2023-04-27 19:57:33 +02:00
|
|
|
import fdroidserver
|
|
|
|
from fdroidserver import metadata
|
2018-08-08 00:59:25 +02:00
|
|
|
from fdroidserver.exception import MetaDataException
|
2015-07-22 10:16:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
class MetadataTest(unittest.TestCase):
|
|
|
|
'''fdroidserver/metadata.py'''
|
|
|
|
|
2017-11-30 10:14:38 +01:00
|
|
|
def setUp(self):
|
|
|
|
logging.basicConfig(level=logging.DEBUG)
|
2021-06-08 15:31:55 +02:00
|
|
|
self.basedir = localmodule / 'tests'
|
2022-11-22 17:17:45 +01:00
|
|
|
os.chdir(self.basedir)
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
# auto-generated dirs by functions, not tests, so they are not always cleaned up
|
|
|
|
try:
|
|
|
|
os.rmdir("srclibs")
|
|
|
|
except OSError:
|
|
|
|
pass
|
|
|
|
try:
|
|
|
|
os.rmdir("tmp")
|
|
|
|
except OSError:
|
|
|
|
pass
|
2017-11-30 10:14:38 +01:00
|
|
|
|
2022-09-14 03:45:19 +02:00
|
|
|
def test_fieldtypes_key_exist(self):
|
|
|
|
for k in fdroidserver.metadata.fieldtypes.keys():
|
|
|
|
self.assertTrue(k in 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)
|
|
|
|
|
2019-05-10 12:02:13 +02:00
|
|
|
def test_FieldValidator_BitcoinAddress(self):
|
2019-05-07 22:43:05 +02:00
|
|
|
validator = None
|
|
|
|
for vali in fdroidserver.metadata.valuetypes:
|
|
|
|
if vali.name == 'Bitcoin address':
|
|
|
|
validator = vali
|
|
|
|
break
|
|
|
|
self.assertIsNotNone(validator, "could not find 'Bitcoin address' validator")
|
|
|
|
|
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
|
|
|
|
# some valid addresses (P2PKH, P2SH, Bech32)
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertIsNone(
|
|
|
|
validator.check('1BrrrrErsrWetrTrnrrrrm4GFg7xJaNVN2', 'fake.app.id')
|
|
|
|
)
|
|
|
|
self.assertIsNone(
|
|
|
|
validator.check('3JrrrrWrEZr3rNrrvrecrnyirrnqRhWNLy', 'fake.app.id')
|
|
|
|
)
|
|
|
|
self.assertIsNone(
|
|
|
|
validator.check('bc1qar0srrr7xrkvr5lr43lrdnwrre5rgtrzrf5rrq', 'fake.app.id')
|
|
|
|
)
|
2019-05-07 22:43:05 +02:00
|
|
|
|
2019-05-10 12:02:13 +02:00
|
|
|
# some invalid addresses
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'21BvMrSYsrWrtrrlL5A10mlGFr7rrarrN2',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'5Hrgr3ur5rGLrfKrrrrrrHSrqJrroGrrzrQrrrrrrLNrsrDrrrA',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'L1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
2019-05-10 12:02:13 +02:00
|
|
|
|
|
|
|
def test_FieldValidator_LitecoinAddress(self):
|
|
|
|
validator = None
|
|
|
|
for vali in fdroidserver.metadata.valuetypes:
|
|
|
|
if vali.name == 'Litecoin address':
|
|
|
|
validator = vali
|
|
|
|
break
|
|
|
|
self.assertIsNotNone(validator, "could not find 'Litecoin address' validator")
|
|
|
|
|
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
|
2023-05-01 11:01:08 +02:00
|
|
|
# some valid addresses (L, M, 3, segwit)
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertIsNone(
|
|
|
|
validator.check('LgeGrrrrJAxyXprrPrrBrrX5Qrrrrrrrrd', 'fake.app.id')
|
|
|
|
)
|
|
|
|
self.assertIsNone(
|
|
|
|
validator.check('MrrrrrrrJAxyXpanPtrrRAX5QHxvUJo8id', 'fake.app.id')
|
|
|
|
)
|
2019-05-10 12:02:13 +02:00
|
|
|
self.assertIsNone(validator.check('3rereVr9rAryrranrrrrrAXrrHx', 'fake.app.id'))
|
2023-05-01 11:01:08 +02:00
|
|
|
self.assertIsNone(
|
|
|
|
validator.check(
|
|
|
|
'ltc1q7euacwhn6ef99vcfa57mute92q572aqsc4c2j5', 'fake.app.id'
|
|
|
|
)
|
|
|
|
)
|
2019-05-10 12:02:13 +02:00
|
|
|
|
|
|
|
# some invalid addresses (various special use/testnet addresses, invalid chars)
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'21BvMrSYsrWrtrrrn5Au4l4GFr7rrarrN2',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'5Hrgr3ur5rGLrfKrrrrrr1SrqJrroGrrzrQrrrrrrLNrsrDrrrA',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'L0000rSYsrWrtrrrn5Au4m4GFr7rrarrN2',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
validator.check,
|
|
|
|
'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx',
|
|
|
|
'fake.app.id',
|
|
|
|
)
|
2019-05-07 22:43:05 +02:00
|
|
|
|
update: insert donation links based on FUNDING.yml
GitHub has specified FUNDING.yml, a file to include in a git repo for
pointing people to donation links. Since F-Droid also points people
to donation links, this parses them to fill out Donate:
and OpenCollective:. Specifying those in the metadata file takes
precedence over the FUNDING.yml. This follows the same pattern as how
`fdroid update` includes Fastlane/Triple-T metadata. This lets the
git repo maintain those specific donations links themselves.
https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository#about-funding-files
The test file was generated using:
```python
import os, re, yaml
found = dict()
for root, dirs, files in os.walk('.'):
for f in files:
if f == 'FUNDING.yml':
with open(os.path.join(root, f)) as fp:
data = yaml.safe_load(fp)
for k, v in data.items():
if k not in found:
found[k] = set()
if not v:
continue
if isinstance(v, list):
for i in v:
found[k].add(i)
else:
found[k].add(v)
with open('gather-funding-names.yaml', 'w') as fp:
output = dict()
for k, v in found.items():
output[k] = sorted(v)
yaml.dump(output, fp, default_flow_style=False)
```
2019-11-06 09:03:27 +01:00
|
|
|
def test_valid_funding_yml_regex(self):
|
|
|
|
"""Check the regex can find all the cases"""
|
2021-06-08 15:31:55 +02:00
|
|
|
with (self.basedir / 'funding-usernames.yaml').open() as fp:
|
2021-12-29 12:07:45 +01:00
|
|
|
data = yaml.load(fp)
|
update: insert donation links based on FUNDING.yml
GitHub has specified FUNDING.yml, a file to include in a git repo for
pointing people to donation links. Since F-Droid also points people
to donation links, this parses them to fill out Donate:
and OpenCollective:. Specifying those in the metadata file takes
precedence over the FUNDING.yml. This follows the same pattern as how
`fdroid update` includes Fastlane/Triple-T metadata. This lets the
git repo maintain those specific donations links themselves.
https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository#about-funding-files
The test file was generated using:
```python
import os, re, yaml
found = dict()
for root, dirs, files in os.walk('.'):
for f in files:
if f == 'FUNDING.yml':
with open(os.path.join(root, f)) as fp:
data = yaml.safe_load(fp)
for k, v in data.items():
if k not in found:
found[k] = set()
if not v:
continue
if isinstance(v, list):
for i in v:
found[k].add(i)
else:
found[k].add(v)
with open('gather-funding-names.yaml', 'w') as fp:
output = dict()
for k, v in found.items():
output[k] = sorted(v)
yaml.dump(output, fp, default_flow_style=False)
```
2019-11-06 09:03:27 +01:00
|
|
|
|
|
|
|
for k, entries in data.items():
|
|
|
|
for entry in entries:
|
|
|
|
m = fdroidserver.metadata.VALID_USERNAME_REGEX.match(entry)
|
|
|
|
if k == 'custom':
|
|
|
|
pass
|
|
|
|
elif k == 'bad':
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertIsNone(
|
|
|
|
m, 'this is an invalid %s username: {%s}' % (k, entry)
|
|
|
|
)
|
update: insert donation links based on FUNDING.yml
GitHub has specified FUNDING.yml, a file to include in a git repo for
pointing people to donation links. Since F-Droid also points people
to donation links, this parses them to fill out Donate:
and OpenCollective:. Specifying those in the metadata file takes
precedence over the FUNDING.yml. This follows the same pattern as how
`fdroid update` includes Fastlane/Triple-T metadata. This lets the
git repo maintain those specific donations links themselves.
https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository#about-funding-files
The test file was generated using:
```python
import os, re, yaml
found = dict()
for root, dirs, files in os.walk('.'):
for f in files:
if f == 'FUNDING.yml':
with open(os.path.join(root, f)) as fp:
data = yaml.safe_load(fp)
for k, v in data.items():
if k not in found:
found[k] = set()
if not v:
continue
if isinstance(v, list):
for i in v:
found[k].add(i)
else:
found[k].add(v)
with open('gather-funding-names.yaml', 'w') as fp:
output = dict()
for k, v in found.items():
output[k] = sorted(v)
yaml.dump(output, fp, default_flow_style=False)
```
2019-11-06 09:03:27 +01:00
|
|
|
else:
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertIsNotNone(
|
|
|
|
m, 'this is a valid %s username: {%s}' % (k, entry)
|
|
|
|
)
|
update: insert donation links based on FUNDING.yml
GitHub has specified FUNDING.yml, a file to include in a git repo for
pointing people to donation links. Since F-Droid also points people
to donation links, this parses them to fill out Donate:
and OpenCollective:. Specifying those in the metadata file takes
precedence over the FUNDING.yml. This follows the same pattern as how
`fdroid update` includes Fastlane/Triple-T metadata. This lets the
git repo maintain those specific donations links themselves.
https://help.github.com/en/articles/displaying-a-sponsor-button-in-your-repository#about-funding-files
The test file was generated using:
```python
import os, re, yaml
found = dict()
for root, dirs, files in os.walk('.'):
for f in files:
if f == 'FUNDING.yml':
with open(os.path.join(root, f)) as fp:
data = yaml.safe_load(fp)
for k, v in data.items():
if k not in found:
found[k] = set()
if not v:
continue
if isinstance(v, list):
for i in v:
found[k].add(i)
else:
found[k].add(v)
with open('gather-funding-names.yaml', 'w') as fp:
output = dict()
for k, v in found.items():
output[k] = sorted(v)
yaml.dump(output, fp, default_flow_style=False)
```
2019-11-06 09:03:27 +01:00
|
|
|
|
2015-07-22 10:16:43 +02:00
|
|
|
def test_read_metadata(self):
|
convert metadata.Build to a subclass of dict
Like with the App class in the commit before, this makes it a lot
easier to work with this data when converting between the internal
formats and external formats like YAML, JSON, MsgPack, protobuf, etc.
The one unfortunate thing here is Build.update. It becomes
dict.update(), which is a method not an attribute.
build.get('update') or build['update'] could be used, but that would
be oddly inconsistent. So instead the field is renamed to
'androidupdate', except for in the .txt v0 metadata files. This better
describes what field does anyway, since it runs `android update`.
Build.update is only referenced in two places right next to each other
for the ant builds, so this change still seems worthwhile.
2016-11-29 13:26:32 +01:00
|
|
|
def _build_yaml_representer(dumper, data):
|
|
|
|
'''Creates a YAML representation of a Build instance'''
|
|
|
|
return dumper.represent_dict(data)
|
|
|
|
|
2015-07-22 10:16:43 +02:00
|
|
|
self.maxDiff = None
|
|
|
|
|
|
|
|
config = dict()
|
2020-06-09 22:19:06 +02:00
|
|
|
fdroidserver.common.fill_config_defaults(config)
|
2015-07-22 10:16:43 +02:00
|
|
|
fdroidserver.common.config = config
|
2019-05-07 22:43:05 +02:00
|
|
|
fdroidserver.metadata.warnings_action = None
|
2015-07-22 10:16:43 +02:00
|
|
|
|
2020-11-17 14:17:08 +01:00
|
|
|
apps = fdroidserver.metadata.read_metadata()
|
2021-06-07 11:49:21 +02:00
|
|
|
for appid in (
|
|
|
|
'org.smssecure.smssecure',
|
|
|
|
'org.adaway',
|
|
|
|
'org.videolan.vlc',
|
|
|
|
'com.politedroid',
|
|
|
|
):
|
2021-06-08 15:31:55 +02:00
|
|
|
savepath = Path('metadata/dump') / (appid + '.yaml')
|
2016-11-23 17:25:59 +01:00
|
|
|
frommeta = dict(apps[appid])
|
2015-11-28 13:09:47 +01:00
|
|
|
self.assertTrue(appid in apps)
|
2021-06-08 15:31:55 +02:00
|
|
|
with savepath.open('r') as f:
|
2021-12-29 12:07:45 +01:00
|
|
|
from_yaml = yaml.load(f)
|
2020-09-10 15:56:42 +02:00
|
|
|
self.assertEqual(frommeta, from_yaml)
|
2017-06-27 23:55:38 +02:00
|
|
|
# comment above assert and uncomment below to update test
|
|
|
|
# files when new metadata fields are added
|
2021-06-08 15:31:55 +02:00
|
|
|
# with savepath.open('w') as f:
|
convert metadata.Build to a subclass of dict
Like with the App class in the commit before, this makes it a lot
easier to work with this data when converting between the internal
formats and external formats like YAML, JSON, MsgPack, protobuf, etc.
The one unfortunate thing here is Build.update. It becomes
dict.update(), which is a method not an attribute.
build.get('update') or build['update'] could be used, but that would
be oddly inconsistent. So instead the field is renamed to
'androidupdate', except for in the .txt v0 metadata files. This better
describes what field does anyway, since it runs `android update`.
Build.update is only referenced in two places right next to each other
for the ant builds, so this change still seems worthwhile.
2016-11-29 13:26:32 +01:00
|
|
|
# yaml.add_representer(fdroidserver.metadata.Build, _build_yaml_representer)
|
2016-11-23 15:14:44 +01:00
|
|
|
# yaml.dump(frommeta, f, default_flow_style=False)
|
2015-07-22 10:16:43 +02:00
|
|
|
|
2017-05-09 14:13:14 +02:00
|
|
|
def test_rewrite_yaml_fakeotaupdate(self):
|
2022-11-22 17:17:45 +01:00
|
|
|
with tempfile.TemporaryDirectory() as testdir:
|
2021-06-08 15:31:55 +02:00
|
|
|
testdir = Path(testdir)
|
|
|
|
fdroidserver.common.config = {'accepted_formats': ['yml']}
|
|
|
|
fdroidserver.metadata.warnings_action = None
|
|
|
|
|
|
|
|
# rewrite metadata
|
|
|
|
allapps = fdroidserver.metadata.read_metadata()
|
|
|
|
for appid, app in allapps.items():
|
|
|
|
if appid == 'fake.ota.update':
|
|
|
|
fdroidserver.metadata.write_metadata(
|
|
|
|
testdir / (appid + '.yml'), app
|
|
|
|
)
|
2017-05-09 14:13:14 +02:00
|
|
|
|
2021-06-08 15:31:55 +02:00
|
|
|
# assert rewrite result
|
|
|
|
self.maxDiff = None
|
|
|
|
file_name = 'fake.ota.update.yml'
|
|
|
|
self.assertEqual(
|
metadata: always open metadata files as UTF-8
Windows seems to require this, otherwise this happens:
Traceback (most recent call last):
File "tests/update.TestCase", line 737, in test_translate_per_build_anti_features
apps = fdroidserver.metadata.read_metadata(xref=True)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 813, in read_metadata
app = parse_metadata(metadatapath, appid in check_vcs, refresh)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 1023, in parse_metadata
parse_yaml_metadata(mf, app)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 1073, in parse_yaml_metadata
yamldata = yaml.safe_load(mf)
File "C:\python37\lib\site-packages\yaml\__init__.py", line 162, in safe_load
return load(stream, SafeLoader)
File "C:\python37\lib\site-packages\yaml\__init__.py", line 112, in load
loader = Loader(stream)
File "C:\python37\lib\site-packages\yaml\loader.py", line 34, in __init__
Reader.__init__(self, stream)
File "C:\python37\lib\site-packages\yaml\reader.py", line 85, in __init__
self.determine_encoding()
File "C:\python37\lib\site-packages\yaml\reader.py", line 124, in determine_encoding
self.update_raw()
File "C:\python37\lib\site-packages\yaml\reader.py", line 178, in update_raw
data = self.stream.read(size)
File "C:\python37\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 37: character maps to <undefined>
2019-09-25 13:34:11 +02:00
|
|
|
(testdir / file_name).read_text(encoding='utf-8'),
|
|
|
|
(Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'),
|
2021-06-08 15:31:55 +02:00
|
|
|
)
|
2017-05-09 14:13:14 +02:00
|
|
|
|
|
|
|
def test_rewrite_yaml_fdroidclient(self):
|
2022-11-22 17:17:45 +01:00
|
|
|
with tempfile.TemporaryDirectory() as testdir:
|
2021-06-08 15:31:55 +02:00
|
|
|
testdir = Path(testdir)
|
|
|
|
fdroidserver.common.config = {'accepted_formats': ['yml']}
|
|
|
|
|
|
|
|
# rewrite metadata
|
|
|
|
allapps = fdroidserver.metadata.read_metadata()
|
|
|
|
for appid, app in allapps.items():
|
|
|
|
if appid == 'org.fdroid.fdroid':
|
|
|
|
fdroidserver.metadata.write_metadata(
|
|
|
|
testdir / (appid + '.yml'), app
|
|
|
|
)
|
2017-05-09 14:13:14 +02:00
|
|
|
|
2021-06-08 15:31:55 +02:00
|
|
|
# assert rewrite result
|
|
|
|
self.maxDiff = None
|
|
|
|
file_name = 'org.fdroid.fdroid.yml'
|
|
|
|
self.assertEqual(
|
metadata: always open metadata files as UTF-8
Windows seems to require this, otherwise this happens:
Traceback (most recent call last):
File "tests/update.TestCase", line 737, in test_translate_per_build_anti_features
apps = fdroidserver.metadata.read_metadata(xref=True)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 813, in read_metadata
app = parse_metadata(metadatapath, appid in check_vcs, refresh)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 1023, in parse_metadata
parse_yaml_metadata(mf, app)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 1073, in parse_yaml_metadata
yamldata = yaml.safe_load(mf)
File "C:\python37\lib\site-packages\yaml\__init__.py", line 162, in safe_load
return load(stream, SafeLoader)
File "C:\python37\lib\site-packages\yaml\__init__.py", line 112, in load
loader = Loader(stream)
File "C:\python37\lib\site-packages\yaml\loader.py", line 34, in __init__
Reader.__init__(self, stream)
File "C:\python37\lib\site-packages\yaml\reader.py", line 85, in __init__
self.determine_encoding()
File "C:\python37\lib\site-packages\yaml\reader.py", line 124, in determine_encoding
self.update_raw()
File "C:\python37\lib\site-packages\yaml\reader.py", line 178, in update_raw
data = self.stream.read(size)
File "C:\python37\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 37: character maps to <undefined>
2019-09-25 13:34:11 +02:00
|
|
|
(testdir / file_name).read_text(encoding='utf-8'),
|
|
|
|
(Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'),
|
2021-06-08 15:31:55 +02:00
|
|
|
)
|
2017-05-09 14:13:14 +02:00
|
|
|
|
|
|
|
def test_rewrite_yaml_special_build_params(self):
|
2022-11-22 17:17:45 +01:00
|
|
|
with tempfile.TemporaryDirectory() as testdir:
|
2021-06-08 15:31:55 +02:00
|
|
|
testdir = Path(testdir)
|
|
|
|
|
|
|
|
# rewrite metadata
|
|
|
|
allapps = fdroidserver.metadata.read_metadata()
|
|
|
|
for appid, app in allapps.items():
|
|
|
|
if appid == 'app.with.special.build.params':
|
|
|
|
fdroidserver.metadata.write_metadata(
|
|
|
|
testdir / (appid + '.yml'), app
|
|
|
|
)
|
2017-05-09 14:13:14 +02:00
|
|
|
|
2021-06-08 15:31:55 +02:00
|
|
|
# assert rewrite result
|
|
|
|
self.maxDiff = None
|
|
|
|
file_name = 'app.with.special.build.params.yml'
|
|
|
|
self.assertEqual(
|
metadata: always open metadata files as UTF-8
Windows seems to require this, otherwise this happens:
Traceback (most recent call last):
File "tests/update.TestCase", line 737, in test_translate_per_build_anti_features
apps = fdroidserver.metadata.read_metadata(xref=True)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 813, in read_metadata
app = parse_metadata(metadatapath, appid in check_vcs, refresh)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 1023, in parse_metadata
parse_yaml_metadata(mf, app)
File "C:\Users\travis\build\fdroidtravis\fdroidserver\fdroidserver\metadata.py", line 1073, in parse_yaml_metadata
yamldata = yaml.safe_load(mf)
File "C:\python37\lib\site-packages\yaml\__init__.py", line 162, in safe_load
return load(stream, SafeLoader)
File "C:\python37\lib\site-packages\yaml\__init__.py", line 112, in load
loader = Loader(stream)
File "C:\python37\lib\site-packages\yaml\loader.py", line 34, in __init__
Reader.__init__(self, stream)
File "C:\python37\lib\site-packages\yaml\reader.py", line 85, in __init__
self.determine_encoding()
File "C:\python37\lib\site-packages\yaml\reader.py", line 124, in determine_encoding
self.update_raw()
File "C:\python37\lib\site-packages\yaml\reader.py", line 178, in update_raw
data = self.stream.read(size)
File "C:\python37\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 37: character maps to <undefined>
2019-09-25 13:34:11 +02:00
|
|
|
(testdir / file_name).read_text(encoding='utf-8'),
|
|
|
|
(Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'),
|
2021-06-08 15:31:55 +02:00
|
|
|
)
|
2017-05-09 14:13:14 +02:00
|
|
|
|
2023-04-24 14:15:45 +02:00
|
|
|
def test_normalize_type_string(self):
|
|
|
|
"""TYPE_STRING currently has some quirky behavior."""
|
|
|
|
self.assertEqual('123456', metadata._normalize_type_string(123456))
|
|
|
|
self.assertEqual('1.0', metadata._normalize_type_string(1.0))
|
|
|
|
self.assertEqual('0', metadata._normalize_type_string(0))
|
|
|
|
self.assertEqual('0.0', metadata._normalize_type_string(0.0))
|
|
|
|
self.assertEqual('0.1', metadata._normalize_type_string(0.1))
|
|
|
|
self.assertEqual('[]', metadata._normalize_type_string(list()))
|
|
|
|
self.assertEqual('{}', metadata._normalize_type_string(dict()))
|
|
|
|
self.assertEqual('false', metadata._normalize_type_string(False))
|
|
|
|
self.assertEqual('true', metadata._normalize_type_string(True))
|
|
|
|
|
2020-01-03 14:17:03 +01:00
|
|
|
def test_post_parse_yaml_metadata(self):
|
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
yamldata = OrderedDict()
|
|
|
|
builds = []
|
|
|
|
yamldata['Builds'] = builds
|
|
|
|
build = OrderedDict()
|
|
|
|
builds.append(build)
|
|
|
|
|
|
|
|
build['versionCode'] = 1.1
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
fdroidserver.metadata.post_parse_yaml_metadata,
|
|
|
|
yamldata,
|
|
|
|
)
|
2020-01-03 14:17:03 +01:00
|
|
|
|
|
|
|
build['versionCode'] = '1'
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertRaises(
|
|
|
|
fdroidserver.exception.MetaDataException,
|
|
|
|
fdroidserver.metadata.post_parse_yaml_metadata,
|
|
|
|
yamldata,
|
|
|
|
)
|
2020-01-03 14:17:03 +01:00
|
|
|
|
|
|
|
build['versionCode'] = 1
|
|
|
|
build['versionName'] = 1
|
|
|
|
fdroidserver.metadata.post_parse_yaml_metadata(yamldata)
|
|
|
|
self.assertNotEqual(1, yamldata['Builds'][0]['versionName'])
|
|
|
|
self.assertEqual('1', yamldata['Builds'][0]['versionName'])
|
|
|
|
self.assertEqual(1, yamldata['Builds'][0]['versionCode'])
|
|
|
|
|
|
|
|
build['versionName'] = 1.0
|
|
|
|
fdroidserver.metadata.post_parse_yaml_metadata(yamldata)
|
|
|
|
self.assertNotEqual(1.0, yamldata['Builds'][0]['versionName'])
|
|
|
|
self.assertEqual('1.0', yamldata['Builds'][0]['versionName'])
|
|
|
|
|
|
|
|
build['commit'] = 1.0
|
|
|
|
fdroidserver.metadata.post_parse_yaml_metadata(yamldata)
|
|
|
|
self.assertNotEqual(1.0, yamldata['Builds'][0]['commit'])
|
|
|
|
self.assertEqual('1.0', yamldata['Builds'][0]['commit'])
|
|
|
|
|
|
|
|
teststr = '98234fab134b'
|
|
|
|
build['commit'] = teststr
|
|
|
|
fdroidserver.metadata.post_parse_yaml_metadata(yamldata)
|
|
|
|
self.assertEqual(teststr, yamldata['Builds'][0]['commit'])
|
|
|
|
|
|
|
|
testcommitid = 1234567890
|
|
|
|
build['commit'] = testcommitid
|
|
|
|
fdroidserver.metadata.post_parse_yaml_metadata(yamldata)
|
|
|
|
self.assertNotEqual(testcommitid, yamldata['Builds'][0]['commit'])
|
|
|
|
self.assertEqual('1234567890', yamldata['Builds'][0]['commit'])
|
|
|
|
|
2017-11-29 22:03:26 +01:00
|
|
|
def test_read_metadata_sort_by_time(self):
|
2022-11-22 17:17:45 +01:00
|
|
|
with tempfile.TemporaryDirectory() as testdir, TmpCwd(testdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
testdir = Path(testdir)
|
|
|
|
metadatadir = testdir / 'metadata'
|
|
|
|
metadatadir.mkdir()
|
|
|
|
|
|
|
|
randomlist = []
|
|
|
|
randomapps = list((self.basedir / 'metadata').glob('*.yml'))
|
|
|
|
random.shuffle(randomapps)
|
|
|
|
i = 1
|
|
|
|
for f in randomapps:
|
2023-02-15 20:25:48 +01:00
|
|
|
shutil.copy(f, metadatadir)
|
2021-06-08 15:31:55 +02:00
|
|
|
new = metadatadir / f.name
|
|
|
|
stat = new.stat()
|
2023-02-15 20:25:48 +01:00
|
|
|
os.utime(new, (stat.st_ctime, stat.st_mtime + i))
|
2021-06-08 15:31:55 +02:00
|
|
|
# prepend new item so newest is always first
|
|
|
|
randomlist = [f.stem] + randomlist
|
|
|
|
i += 1
|
|
|
|
allapps = fdroidserver.metadata.read_metadata(sort_by_time=True)
|
|
|
|
allappids = []
|
|
|
|
for appid, app in allapps.items():
|
|
|
|
allappids.append(appid)
|
|
|
|
self.assertEqual(randomlist, allappids)
|
2017-11-29 22:03:26 +01:00
|
|
|
|
2023-04-20 17:43:56 +02:00
|
|
|
def test_parse_yaml_metadata_0size_file(self):
|
|
|
|
mf = io.StringIO('')
|
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
|
|
|
|
|
|
|
|
def test_parse_yaml_metadata_empty_dict_file(self):
|
|
|
|
mf = io.StringIO('{}')
|
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
|
|
|
|
|
|
|
|
def test_parse_yaml_metadata_empty_string_file(self):
|
|
|
|
mf = io.StringIO('""')
|
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
|
|
|
|
|
2018-08-08 00:59:25 +02:00
|
|
|
def test_parse_yaml_metadata_unknown_app_field(self):
|
2021-06-07 11:49:21 +02:00
|
|
|
mf = io.StringIO(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
AutoName: F-Droid
|
|
|
|
RepoType: git
|
|
|
|
Builds: []
|
|
|
|
bad: value"""
|
2021-06-07 11:49:21 +02:00
|
|
|
)
|
|
|
|
)
|
2018-08-08 02:18:19 +02:00
|
|
|
mf.name = 'mock_filename.yaml'
|
2018-08-08 00:59:25 +02:00
|
|
|
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
|
|
|
|
with self.assertRaises(MetaDataException):
|
2023-04-20 17:43:56 +02:00
|
|
|
fdroidserver.metadata.parse_yaml_metadata(mf)
|
2018-08-08 00:59:25 +02:00
|
|
|
|
|
|
|
def test_parse_yaml_metadata_unknown_build_flag(self):
|
2021-06-07 11:49:21 +02:00
|
|
|
mf = io.StringIO(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
AutoName: F-Droid
|
|
|
|
RepoType: git
|
|
|
|
Builds:
|
|
|
|
- bad: value"""
|
2021-06-07 11:49:21 +02:00
|
|
|
)
|
|
|
|
)
|
2018-08-08 02:18:19 +02:00
|
|
|
mf.name = 'mock_filename.yaml'
|
2018-08-08 00:59:25 +02:00
|
|
|
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
|
|
|
|
with self.assertRaises(MetaDataException):
|
2023-04-20 17:43:56 +02:00
|
|
|
fdroidserver.metadata.parse_yaml_metadata(mf)
|
2018-08-08 00:59:25 +02:00
|
|
|
|
2023-04-20 23:34:39 +02:00
|
|
|
def test_parse_yaml_metadata_continue_on_warning(self):
|
|
|
|
"""When errors are disabled, parsing should provide something that can work.
|
|
|
|
|
|
|
|
When errors are disabled, then it should try to give data that
|
|
|
|
lets something happen. A zero-length file is valid for
|
|
|
|
operation, it just declares a Application ID as "known" and
|
|
|
|
nothing else. This example gives a list as the base in the
|
|
|
|
.yml file, which is unparsable, so it gives a warning message
|
|
|
|
and carries on with a blank dict.
|
|
|
|
|
|
|
|
"""
|
|
|
|
fdroidserver.metadata.warnings_action = None
|
|
|
|
mf = io.StringIO('[AntiFeatures: Tracking]')
|
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
|
|
|
|
|
2020-05-14 15:02:19 +02:00
|
|
|
def test_parse_yaml_srclib_corrupt_file(self):
|
2022-11-22 17:17:45 +01:00
|
|
|
with tempfile.TemporaryDirectory() as testdir:
|
2021-06-08 15:31:55 +02:00
|
|
|
testdir = Path(testdir)
|
|
|
|
srclibfile = testdir / 'srclib/mock.yml'
|
|
|
|
srclibfile.parent.mkdir()
|
|
|
|
with srclibfile.open('w') as fp:
|
|
|
|
fp.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""
|
|
|
|
- RepoType: git
|
|
|
|
- Repo: https://github.com/realm/realm-js.git
|
|
|
|
"""
|
|
|
|
)
|
2021-06-07 11:49:21 +02:00
|
|
|
)
|
2021-06-08 15:31:55 +02:00
|
|
|
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
fdroidserver.metadata.parse_yaml_srclib(srclibfile)
|
2020-05-14 15:02:19 +02:00
|
|
|
|
2018-10-10 15:04:45 +02:00
|
|
|
def test_write_yaml_with_placeholder_values(self):
|
2018-08-19 14:11:16 +02:00
|
|
|
mf = io.StringIO()
|
|
|
|
|
|
|
|
app = fdroidserver.metadata.App()
|
|
|
|
app.Categories = ['None']
|
|
|
|
app.SourceCode = "https://gitlab.com/fdroid/fdroidclient.git"
|
|
|
|
app.IssueTracker = "https://gitlab.com/fdroid/fdroidclient/issues"
|
|
|
|
app.RepoType = 'git'
|
|
|
|
app.Repo = 'https://gitlab.com/fdroid/fdroidclient.git'
|
|
|
|
app.AutoUpdateMode = 'None'
|
|
|
|
app.UpdateCheckMode = 'Tags'
|
|
|
|
build = fdroidserver.metadata.Build()
|
2018-10-10 15:04:45 +02:00
|
|
|
build.versionName = 'Unknown' # taken from fdroidserver/import.py
|
|
|
|
build.versionCode = '0' # taken from fdroidserver/import.py
|
2018-08-19 14:11:16 +02:00
|
|
|
build.disable = 'Generated by import.py ...'
|
|
|
|
build.commit = 'Unknown'
|
|
|
|
build.gradle = [True]
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'] = [build]
|
2018-08-19 14:11:16 +02:00
|
|
|
|
2018-10-10 15:04:45 +02:00
|
|
|
fdroidserver.metadata.write_yaml(mf, app)
|
2018-08-19 14:11:16 +02:00
|
|
|
|
|
|
|
mf.seek(0)
|
2021-06-07 11:49:21 +02:00
|
|
|
self.assertEqual(
|
|
|
|
mf.read(),
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
Categories:
|
|
|
|
- None
|
|
|
|
License: Unknown
|
|
|
|
SourceCode: https://gitlab.com/fdroid/fdroidclient.git
|
|
|
|
IssueTracker: https://gitlab.com/fdroid/fdroidclient/issues
|
|
|
|
|
|
|
|
RepoType: git
|
|
|
|
Repo: https://gitlab.com/fdroid/fdroidclient.git
|
|
|
|
|
|
|
|
Builds:
|
|
|
|
- versionName: Unknown
|
|
|
|
versionCode: 0
|
|
|
|
disable: Generated by import.py ...
|
|
|
|
commit: Unknown
|
|
|
|
gradle:
|
|
|
|
- true
|
|
|
|
|
|
|
|
AutoUpdateMode: None
|
|
|
|
UpdateCheckMode: Tags
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
),
|
|
|
|
)
|
2018-08-19 14:11:16 +02:00
|
|
|
|
2018-08-28 10:04:05 +02:00
|
|
|
def test_parse_yaml_metadata_prebuild_list(self):
|
2021-06-07 11:49:21 +02:00
|
|
|
mf = io.StringIO(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
AutoName: F-Droid
|
|
|
|
RepoType: git
|
|
|
|
Builds:
|
|
|
|
- versionCode: 1
|
|
|
|
versionName: v0.1.0
|
|
|
|
sudo:
|
|
|
|
- apt-get update
|
|
|
|
- apt-get install -y whatever
|
|
|
|
- sed -i -e 's/<that attr="bad"/<that attr="good"/' ~/.whatever/config.xml
|
|
|
|
init:
|
|
|
|
- bash generate_some_file.sh
|
|
|
|
- sed -i -e 'g/what/ever/' /some/file
|
|
|
|
prebuild:
|
|
|
|
- npm something
|
|
|
|
- echo 'important setting' >> /a/file
|
|
|
|
build:
|
|
|
|
- ./gradlew someSpecialTask
|
|
|
|
- sed -i 'd/that wrong config/' gradle.properties
|
|
|
|
- ./gradlew compile
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
)
|
|
|
|
)
|
2018-08-28 10:16:13 +02:00
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
mf.seek(0)
|
|
|
|
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
|
2023-04-20 17:43:56 +02:00
|
|
|
result = fdroidserver.metadata.parse_yaml_metadata(mf)
|
2018-11-14 13:42:05 +01:00
|
|
|
self.maxDiff = None
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertDictEqual(
|
|
|
|
result,
|
|
|
|
{
|
|
|
|
'AutoName': 'F-Droid',
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Builds': [
|
|
|
|
{
|
|
|
|
'versionCode': 1,
|
|
|
|
'versionName': 'v0.1.0',
|
2022-09-09 12:36:54 +02:00
|
|
|
'sudo': [
|
|
|
|
"apt-get update",
|
|
|
|
"apt-get install -y whatever",
|
|
|
|
"sed -i -e 's/<that attr=\"bad\"/<that attr=\"good\"/' ~/.whatever/config.xml",
|
|
|
|
],
|
|
|
|
'init': [
|
|
|
|
"bash generate_some_file.sh",
|
|
|
|
"sed -i -e 'g/what/ever/' /some/file",
|
|
|
|
],
|
|
|
|
'prebuild': [
|
|
|
|
"npm something",
|
|
|
|
"echo 'important setting' >> /a/file",
|
|
|
|
],
|
|
|
|
'build': [
|
|
|
|
"./gradlew someSpecialTask",
|
|
|
|
"sed -i 'd/that wrong config/' gradle.properties",
|
|
|
|
"./gradlew compile",
|
|
|
|
],
|
2021-06-08 15:31:55 +02:00
|
|
|
}
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
2018-11-14 13:42:05 +01:00
|
|
|
|
|
|
|
def test_parse_yaml_metadata_prebuild_strings(self):
|
2021-06-07 11:49:21 +02:00
|
|
|
mf = io.StringIO(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
AutoName: F-Droid
|
|
|
|
RepoType: git
|
|
|
|
Builds:
|
|
|
|
- versionCode: 1
|
|
|
|
versionName: v0.1.0
|
|
|
|
sudo: |-
|
|
|
|
apt-get update && apt-get install -y whatever && sed -i -e 's/<that attr="bad"/<that attr="good"/' ~/.whatever/config.xml
|
|
|
|
init: bash generate_some_file.sh && sed -i -e 'g/what/ever/' /some/file
|
|
|
|
prebuild: npm something && echo 'important setting' >> /a/file
|
|
|
|
build: |-
|
|
|
|
./gradlew someSpecialTask && sed -i 'd/that wrong config/' gradle.properties && ./gradlew compile
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
)
|
|
|
|
)
|
2018-11-14 13:42:05 +01:00
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
mf.seek(0)
|
|
|
|
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
|
2023-04-20 17:43:56 +02:00
|
|
|
result = fdroidserver.metadata.parse_yaml_metadata(mf)
|
2018-11-14 13:42:05 +01:00
|
|
|
self.maxDiff = None
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertDictEqual(
|
|
|
|
result,
|
|
|
|
{
|
|
|
|
'AutoName': 'F-Droid',
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Builds': [
|
|
|
|
{
|
|
|
|
'versionCode': 1,
|
|
|
|
'versionName': 'v0.1.0',
|
2022-09-09 12:36:54 +02:00
|
|
|
'sudo': [
|
|
|
|
"apt-get update && "
|
|
|
|
"apt-get install -y whatever && "
|
|
|
|
"sed -i -e 's/<that attr=\"bad\"/<that attr=\"good\"/' ~/.whatever/config.xml"
|
|
|
|
],
|
|
|
|
'init': [
|
|
|
|
"bash generate_some_file.sh && "
|
|
|
|
"sed -i -e 'g/what/ever/' /some/file"
|
|
|
|
],
|
|
|
|
'prebuild': [
|
|
|
|
"npm something && echo 'important setting' >> /a/file"
|
|
|
|
],
|
|
|
|
'build': [
|
|
|
|
"./gradlew someSpecialTask && "
|
|
|
|
"sed -i 'd/that wrong config/' gradle.properties && "
|
|
|
|
"./gradlew compile"
|
|
|
|
],
|
2021-06-08 15:31:55 +02:00
|
|
|
}
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
2018-08-28 10:16:13 +02:00
|
|
|
|
2018-08-28 10:04:05 +02:00
|
|
|
def test_parse_yaml_metadata_prebuild_string(self):
|
2021-06-07 11:49:21 +02:00
|
|
|
mf = io.StringIO(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
AutoName: F-Droid
|
|
|
|
RepoType: git
|
|
|
|
Builds:
|
|
|
|
- versionCode: 1
|
|
|
|
versionName: v0.1.0
|
|
|
|
prebuild: |-
|
|
|
|
a && b && sed -i 's,a,b,'
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
)
|
|
|
|
)
|
2018-08-28 10:04:05 +02:00
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
mf.seek(0)
|
|
|
|
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
|
2023-04-20 17:43:56 +02:00
|
|
|
result = fdroidserver.metadata.parse_yaml_metadata(mf)
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertDictEqual(
|
|
|
|
result,
|
|
|
|
{
|
|
|
|
'AutoName': 'F-Droid',
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Builds': [
|
|
|
|
{
|
|
|
|
'versionCode': 1,
|
|
|
|
'versionName': 'v0.1.0',
|
2022-09-09 12:36:54 +02:00
|
|
|
'prebuild': ["a && b && " "sed -i 's,a,b,'"],
|
2021-06-08 15:31:55 +02:00
|
|
|
}
|
|
|
|
],
|
|
|
|
},
|
|
|
|
)
|
2018-08-28 10:04:05 +02:00
|
|
|
|
2019-07-15 15:45:02 +02:00
|
|
|
def test_parse_yaml_provides_should_be_ignored(self):
|
2021-06-07 11:49:21 +02:00
|
|
|
mf = io.StringIO(
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
Provides: this.is.deprecated
|
|
|
|
AutoName: F-Droid
|
|
|
|
RepoType: git
|
|
|
|
Builds:
|
|
|
|
- versionCode: 1
|
|
|
|
versionName: v0.1.0
|
|
|
|
prebuild: |-
|
|
|
|
a && b && sed -i 's,a,b,'
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
)
|
|
|
|
)
|
2019-07-11 01:46:18 +02:00
|
|
|
mf.name = 'mock_filename.yaml'
|
|
|
|
mf.seek(0)
|
|
|
|
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
|
2023-04-20 17:43:56 +02:00
|
|
|
result = fdroidserver.metadata.parse_yaml_metadata(mf)
|
2019-07-15 15:45:02 +02:00
|
|
|
self.assertNotIn('Provides', result)
|
|
|
|
self.assertNotIn('provides', result)
|
2019-07-11 01:46:18 +02:00
|
|
|
|
2018-11-13 19:53:15 +01:00
|
|
|
def test_write_yaml_1_line_scripts_as_string(self):
|
2018-08-28 10:16:13 +02:00
|
|
|
mf = io.StringIO()
|
|
|
|
app = fdroidserver.metadata.App()
|
2018-11-14 14:20:33 +01:00
|
|
|
app.Categories = ['None']
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'] = []
|
2018-08-28 10:16:13 +02:00
|
|
|
build = fdroidserver.metadata.Build()
|
|
|
|
build.versionCode = 102030
|
|
|
|
build.versionName = 'v1.2.3'
|
2022-09-09 12:36:54 +02:00
|
|
|
build.sudo = ["chmod +rwx /opt"]
|
|
|
|
build.init = ["sed -i -e 'g/what/ever/' /some/file"]
|
|
|
|
build.prebuild = ["sed -i 'd/that wrong config/' gradle.properties"]
|
|
|
|
build.build = ["./gradlew compile"]
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'].append(build)
|
2018-08-28 10:16:13 +02:00
|
|
|
fdroidserver.metadata.write_yaml(mf, app)
|
|
|
|
mf.seek(0)
|
2021-06-07 11:49:21 +02:00
|
|
|
self.assertEqual(
|
|
|
|
mf.read(),
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
Categories:
|
|
|
|
- None
|
|
|
|
License: Unknown
|
|
|
|
|
|
|
|
Builds:
|
|
|
|
- versionName: v1.2.3
|
|
|
|
versionCode: 102030
|
|
|
|
sudo: chmod +rwx /opt
|
|
|
|
init: sed -i -e 'g/what/ever/' /some/file
|
|
|
|
prebuild: sed -i 'd/that wrong config/' gradle.properties
|
|
|
|
build: ./gradlew compile
|
|
|
|
|
|
|
|
AutoUpdateMode: None
|
|
|
|
UpdateCheckMode: None
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
),
|
|
|
|
)
|
2018-11-13 19:53:15 +01:00
|
|
|
|
|
|
|
def test_write_yaml_1_line_scripts_as_list(self):
|
|
|
|
mf = io.StringIO()
|
|
|
|
app = fdroidserver.metadata.App()
|
|
|
|
app.Categories = ['None']
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'] = []
|
2018-11-13 19:53:15 +01:00
|
|
|
build = fdroidserver.metadata.Build()
|
|
|
|
build.versionCode = 102030
|
|
|
|
build.versionName = 'v1.2.3'
|
|
|
|
build.sudo = ["chmod +rwx /opt"]
|
|
|
|
build.init = ["sed -i -e 'g/what/ever/' /some/file"]
|
|
|
|
build.prebuild = ["sed -i 'd/that wrong config/' gradle.properties"]
|
|
|
|
build.build = ["./gradlew compile"]
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'].append(build)
|
2018-11-13 19:53:15 +01:00
|
|
|
fdroidserver.metadata.write_yaml(mf, app)
|
|
|
|
mf.seek(0)
|
2021-06-07 11:49:21 +02:00
|
|
|
self.assertEqual(
|
|
|
|
mf.read(),
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
Categories:
|
|
|
|
- None
|
|
|
|
License: Unknown
|
|
|
|
|
|
|
|
Builds:
|
|
|
|
- versionName: v1.2.3
|
|
|
|
versionCode: 102030
|
|
|
|
sudo: chmod +rwx /opt
|
|
|
|
init: sed -i -e 'g/what/ever/' /some/file
|
|
|
|
prebuild: sed -i 'd/that wrong config/' gradle.properties
|
|
|
|
build: ./gradlew compile
|
|
|
|
|
|
|
|
AutoUpdateMode: None
|
|
|
|
UpdateCheckMode: None
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
),
|
|
|
|
)
|
2018-11-13 19:53:15 +01:00
|
|
|
|
|
|
|
def test_write_yaml_multiline_scripts_from_list(self):
|
|
|
|
mf = io.StringIO()
|
|
|
|
app = fdroidserver.metadata.App()
|
|
|
|
app.Categories = ['None']
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'] = []
|
2018-11-13 19:53:15 +01:00
|
|
|
build = fdroidserver.metadata.Build()
|
|
|
|
build.versionCode = 102030
|
|
|
|
build.versionName = 'v1.2.3'
|
2021-06-08 15:31:55 +02:00
|
|
|
build.sudo = [
|
|
|
|
"apt-get update",
|
|
|
|
"apt-get install -y whatever",
|
|
|
|
"sed -i -e 's/<that attr=\"bad\"/<that attr=\"good\"/' ~/.whatever/config.xml",
|
|
|
|
]
|
|
|
|
build.init = [
|
|
|
|
"bash generate_some_file.sh",
|
|
|
|
"sed -i -e 'g/what/ever/' /some/file",
|
|
|
|
]
|
|
|
|
build.prebuild = ["npm something", "echo 'important setting' >> /a/file"]
|
|
|
|
build.build = [
|
|
|
|
"./gradlew someSpecialTask",
|
|
|
|
"sed -i 'd/that wrong config/' gradle.properties",
|
|
|
|
"./gradlew compile",
|
|
|
|
]
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'].append(build)
|
2018-11-13 19:53:15 +01:00
|
|
|
fdroidserver.metadata.write_yaml(mf, app)
|
|
|
|
mf.seek(0)
|
2021-06-07 11:49:21 +02:00
|
|
|
self.assertEqual(
|
|
|
|
mf.read(),
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2018-11-13 19:53:15 +01:00
|
|
|
Categories:
|
|
|
|
- None
|
|
|
|
License: Unknown
|
|
|
|
|
|
|
|
Builds:
|
|
|
|
- versionName: v1.2.3
|
|
|
|
versionCode: 102030
|
|
|
|
sudo:
|
|
|
|
- apt-get update
|
|
|
|
- apt-get install -y whatever
|
|
|
|
- sed -i -e 's/<that attr="bad"/<that attr="good"/' ~/.whatever/config.xml
|
|
|
|
init:
|
|
|
|
- bash generate_some_file.sh
|
|
|
|
- sed -i -e 'g/what/ever/' /some/file
|
|
|
|
prebuild:
|
|
|
|
- npm something
|
|
|
|
- echo 'important setting' >> /a/file
|
|
|
|
build:
|
|
|
|
- ./gradlew someSpecialTask
|
|
|
|
- sed -i 'd/that wrong config/' gradle.properties
|
|
|
|
- ./gradlew compile
|
|
|
|
|
|
|
|
AutoUpdateMode: None
|
|
|
|
UpdateCheckMode: None
|
2021-06-07 11:49:21 +02:00
|
|
|
"""
|
|
|
|
),
|
|
|
|
)
|
2018-11-13 19:53:15 +01:00
|
|
|
|
|
|
|
def test_write_yaml_multiline_scripts_from_string(self):
|
|
|
|
mf = io.StringIO()
|
|
|
|
app = fdroidserver.metadata.App()
|
|
|
|
app.Categories = ['None']
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'] = []
|
2018-11-13 19:53:15 +01:00
|
|
|
build = fdroidserver.metadata.Build()
|
|
|
|
build.versionCode = 102030
|
|
|
|
build.versionName = 'v1.2.3'
|
2022-09-09 12:36:54 +02:00
|
|
|
build.sudo = [
|
|
|
|
"apt-get update",
|
|
|
|
"apt-get install -y whatever",
|
|
|
|
"sed -i -e 's/<that attr=\"bad\"/<that attr=\"good\"/' ~/.whatever/config.xml",
|
|
|
|
]
|
|
|
|
build.init = [
|
|
|
|
"bash generate_some_file.sh",
|
|
|
|
"sed -i -e 'g/what/ever/' /some/file",
|
|
|
|
]
|
|
|
|
build.prebuild = ["npm something", "echo 'important setting' >> /a/file"]
|
|
|
|
build.build = [
|
|
|
|
"./gradlew someSpecialTask",
|
|
|
|
"sed -i 'd/that wrong config/' gradle.properties",
|
|
|
|
"./gradlew compile",
|
|
|
|
]
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'].append(build)
|
2018-11-13 19:53:15 +01:00
|
|
|
fdroidserver.metadata.write_yaml(mf, app)
|
|
|
|
mf.seek(0)
|
2021-06-07 11:49:21 +02:00
|
|
|
self.assertEqual(
|
|
|
|
mf.read(),
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2018-11-13 19:53:15 +01:00
|
|
|
Categories:
|
|
|
|
- None
|
|
|
|
License: Unknown
|
|
|
|
|
|
|
|
Builds:
|
|
|
|
- versionName: v1.2.3
|
|
|
|
versionCode: 102030
|
|
|
|
sudo:
|
|
|
|
- apt-get update
|
|
|
|
- apt-get install -y whatever
|
|
|
|
- sed -i -e 's/<that attr="bad"/<that attr="good"/' ~/.whatever/config.xml
|
|
|
|
init:
|
|
|
|
- bash generate_some_file.sh
|
|
|
|
- sed -i -e 'g/what/ever/' /some/file
|
2018-08-28 10:16:13 +02:00
|
|
|
prebuild:
|
2018-11-13 19:53:15 +01:00
|
|
|
- npm something
|
|
|
|
- echo 'important setting' >> /a/file
|
|
|
|
build:
|
|
|
|
- ./gradlew someSpecialTask
|
|
|
|
- sed -i 'd/that wrong config/' gradle.properties
|
|
|
|
- ./gradlew compile
|
2018-08-28 10:16:13 +02:00
|
|
|
|
|
|
|
AutoUpdateMode: None
|
|
|
|
UpdateCheckMode: None
|
2021-06-07 11:49:21 +02:00
|
|
|
"""
|
|
|
|
),
|
|
|
|
)
|
2018-08-28 10:16:13 +02:00
|
|
|
|
2019-07-11 03:18:30 +02:00
|
|
|
def test_write_yaml_make_sure_provides_does_not_get_written(self):
|
|
|
|
mf = io.StringIO()
|
|
|
|
app = fdroidserver.metadata.App()
|
|
|
|
app.Categories = ['None']
|
|
|
|
app.Provides = 'this.is.deprecated'
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'] = []
|
2019-07-11 03:18:30 +02:00
|
|
|
build = fdroidserver.metadata.Build()
|
|
|
|
build.versionCode = 102030
|
|
|
|
build.versionName = 'v1.2.3'
|
|
|
|
build.gradle = ['yes']
|
eliminate app.builds everywhere, it should be app['Builds']
The .txt format was the last place where the lowercase "builds" was used,
this converts references everywhere to be "Builds". This makes it possible
to load metadata YAML files with any YAML parser, then have it possible to
use fdroidserver methods on that data, like metadata.write_metadata().
The test files in tests/metadata/dump/*.yaml were manually edited by cutting
the builds: block and putting it the sort order for Builds: so the contents
should be unchanged.
```
sed -i \
-e 's/app\.builds/app.get('Builds', \[\])/g' \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\]) =/app\['Builds'] =/g" \
-e "s/app\.get(Builds, \[\])/app.get('Builds', \[\])/g" \
-e "s/app\.get('Builds', \[\])\.append/app\['Builds'\].append/g" \
-e "s/app\['builds'\]/app.get('Builds', [])/g" \
*/*.*
```
2020-12-09 16:01:21 +01:00
|
|
|
app['Builds'].append(build)
|
2019-07-11 03:18:30 +02:00
|
|
|
fdroidserver.metadata.write_yaml(mf, app)
|
|
|
|
mf.seek(0)
|
2021-06-07 11:49:21 +02:00
|
|
|
self.assertEqual(
|
|
|
|
mf.read(),
|
|
|
|
textwrap.dedent(
|
|
|
|
"""\
|
2021-06-08 15:31:55 +02:00
|
|
|
Categories:
|
|
|
|
- None
|
|
|
|
License: Unknown
|
|
|
|
|
|
|
|
Builds:
|
|
|
|
- versionName: v1.2.3
|
|
|
|
versionCode: 102030
|
|
|
|
gradle:
|
|
|
|
- yes
|
|
|
|
|
|
|
|
AutoUpdateMode: None
|
|
|
|
UpdateCheckMode: None
|
|
|
|
"""
|
2021-06-07 11:49:21 +02:00
|
|
|
),
|
|
|
|
)
|
2019-07-11 03:18:30 +02:00
|
|
|
|
2020-04-24 15:47:31 +02:00
|
|
|
def test_parse_yaml_srclib_unknown_key(self):
|
2019-12-24 00:42:29 +01:00
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
with Path('test.yml').open('w', encoding='utf-8') as f:
|
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
|
|
|
RepoType: git
|
|
|
|
Repo: https://example.com/test.git
|
|
|
|
Evil: I should not be here.
|
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
|
|
|
with self.assertRaisesRegex(
|
|
|
|
MetaDataException,
|
|
|
|
"Invalid srclib metadata: " "unknown key 'Evil' in " "'test.yml'",
|
|
|
|
):
|
|
|
|
fdroidserver.metadata.parse_yaml_srclib(Path('test.yml'))
|
2019-12-24 00:42:29 +01:00
|
|
|
|
2020-04-24 15:47:31 +02:00
|
|
|
def test_parse_yaml_srclib_does_not_exists(self):
|
2019-12-24 00:42:29 +01:00
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
2021-06-08 15:31:55 +02:00
|
|
|
with self.assertRaisesRegex(
|
|
|
|
MetaDataException,
|
|
|
|
"Invalid scrlib metadata: "
|
|
|
|
r"'non(/|\\)existent-test-srclib.yml' "
|
|
|
|
"does not exist",
|
|
|
|
):
|
|
|
|
fdroidserver.metadata.parse_yaml_srclib(
|
|
|
|
Path('non/existent-test-srclib.yml')
|
|
|
|
)
|
2019-12-24 00:42:29 +01:00
|
|
|
|
2020-04-24 15:47:31 +02:00
|
|
|
def test_parse_yaml_srclib_simple(self):
|
2019-12-24 00:42:29 +01:00
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
with Path('simple.yml').open('w', encoding='utf-8') as f:
|
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
2019-12-24 00:42:29 +01:00
|
|
|
# this should be simple
|
|
|
|
RepoType: git
|
|
|
|
Repo: https://git.host/repo.git
|
2021-06-08 15:31:55 +02:00
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
|
|
|
srclib = fdroidserver.metadata.parse_yaml_srclib(Path('simple.yml'))
|
|
|
|
self.assertDictEqual(
|
|
|
|
{
|
|
|
|
'Repo': 'https://git.host/repo.git',
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Subdir': None,
|
|
|
|
'Prepare': None,
|
|
|
|
},
|
|
|
|
srclib,
|
|
|
|
)
|
2019-12-24 00:42:29 +01:00
|
|
|
|
2020-04-24 15:47:31 +02:00
|
|
|
def test_parse_yaml_srclib_simple_with_blanks(self):
|
2019-12-24 00:42:29 +01:00
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
with Path('simple.yml').open('w', encoding='utf-8') as f:
|
2021-06-07 11:49:21 +02:00
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
2019-12-24 00:42:29 +01:00
|
|
|
# this should be simple
|
|
|
|
|
|
|
|
RepoType: git
|
|
|
|
|
|
|
|
Repo: https://git.host/repo.git
|
|
|
|
|
|
|
|
Subdir:
|
|
|
|
|
|
|
|
Prepare:
|
2021-06-07 11:49:21 +02:00
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
2021-06-08 15:31:55 +02:00
|
|
|
srclib = fdroidserver.metadata.parse_yaml_srclib(Path('simple.yml'))
|
|
|
|
self.assertDictEqual(
|
|
|
|
{
|
|
|
|
'Repo': 'https://git.host/repo.git',
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Subdir': [''],
|
2022-09-09 12:36:54 +02:00
|
|
|
'Prepare': [],
|
2021-06-08 15:31:55 +02:00
|
|
|
},
|
|
|
|
srclib,
|
|
|
|
)
|
2019-12-24 00:42:29 +01:00
|
|
|
|
2020-04-24 15:47:31 +02:00
|
|
|
def test_parse_yaml_srclib_Changelog_cketti(self):
|
2019-12-24 00:42:29 +01:00
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
with Path('Changelog-cketti.yml').open('w', encoding='utf-8') as f:
|
2021-06-07 11:49:21 +02:00
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
2019-12-24 00:42:29 +01:00
|
|
|
RepoType: git
|
|
|
|
Repo: https://github.com/cketti/ckChangeLog
|
|
|
|
|
|
|
|
Subdir: library,ckChangeLog/src/main
|
|
|
|
Prepare: "[ -f project.properties ] || echo 'source.dir=java' > ant.properties && echo -e 'android.library=true\\\\ntarget=android-19' > project.properties"
|
2021-06-07 11:49:21 +02:00
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
2021-06-08 15:31:55 +02:00
|
|
|
srclib = fdroidserver.metadata.parse_yaml_srclib(
|
|
|
|
Path('Changelog-cketti.yml')
|
|
|
|
)
|
|
|
|
self.assertDictEqual(
|
|
|
|
srclib,
|
|
|
|
{
|
|
|
|
'Repo': 'https://github.com/cketti/ckChangeLog',
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Subdir': ['library', 'ckChangeLog/src/main'],
|
2022-09-09 12:36:54 +02:00
|
|
|
'Prepare': [
|
|
|
|
"[ -f project.properties ] || echo 'source.dir=java' > "
|
|
|
|
"ant.properties && echo -e "
|
|
|
|
"'android.library=true\\ntarget=android-19' > project.properties"
|
|
|
|
],
|
2021-06-08 15:31:55 +02:00
|
|
|
},
|
|
|
|
)
|
2019-12-24 00:42:29 +01:00
|
|
|
|
2020-02-29 15:50:06 +01:00
|
|
|
def test_read_srclibs_yml_subdir_list(self):
|
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
fdroidserver.metadata.srclibs = None
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
Path('srclibs').mkdir()
|
|
|
|
with Path('srclibs/with-list.yml').open('w', encoding='utf-8') as f:
|
2021-06-07 11:49:21 +02:00
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
2020-02-29 15:50:06 +01:00
|
|
|
# this should be simple
|
|
|
|
RepoType: git
|
|
|
|
Repo: https://git.host/repo.git
|
|
|
|
|
|
|
|
Subdir:
|
|
|
|
- This is your last chance.
|
|
|
|
- After this, there is no turning back.
|
|
|
|
- You take the blue pill—the story ends,
|
|
|
|
- you wake up in your bed
|
|
|
|
- and believe whatever you want to believe.
|
|
|
|
- You take the red pill—you stay in Wonderland
|
|
|
|
- and I show you how deep the rabbit-hole goes.
|
|
|
|
Prepare:
|
|
|
|
There is a difference between knowing the path
|
|
|
|
and walking the path.
|
2021-06-07 11:49:21 +02:00
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
2020-02-29 15:50:06 +01:00
|
|
|
fdroidserver.metadata.read_srclibs()
|
|
|
|
self.maxDiff = None
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertDictEqual(
|
|
|
|
fdroidserver.metadata.srclibs,
|
|
|
|
{
|
|
|
|
'with-list': {
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Repo': 'https://git.host/repo.git',
|
|
|
|
'Subdir': [
|
|
|
|
'This is your last chance.',
|
|
|
|
'After this, there is no turning back.',
|
|
|
|
'You take the blue pill—the story ends,',
|
|
|
|
'you wake up in your bed',
|
|
|
|
'and believe whatever you want to believe.',
|
|
|
|
'You take the red pill—you stay in Wonderland',
|
|
|
|
'and I show you how deep the rabbit-hole goes.',
|
|
|
|
],
|
2022-09-09 12:36:54 +02:00
|
|
|
'Prepare': [
|
|
|
|
'There is a difference between knowing the path '
|
|
|
|
'and walking the path.'
|
|
|
|
],
|
2021-06-08 15:31:55 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
2020-02-29 15:50:06 +01:00
|
|
|
|
2020-02-29 13:42:12 +01:00
|
|
|
def test_read_srclibs_yml_prepare_list(self):
|
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
fdroidserver.metadata.srclibs = None
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
Path('srclibs').mkdir()
|
|
|
|
with Path('srclibs/with-list.yml').open('w', encoding='utf-8') as f:
|
2021-06-07 11:49:21 +02:00
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
2020-02-29 13:42:12 +01:00
|
|
|
# this should be simple
|
|
|
|
RepoType: git
|
|
|
|
Repo: https://git.host/repo.git
|
|
|
|
|
|
|
|
Subdir:
|
|
|
|
Prepare:
|
2022-09-09 12:36:54 +02:00
|
|
|
- Many
|
|
|
|
- invalid
|
|
|
|
- commands
|
|
|
|
- here.
|
2021-06-07 11:49:21 +02:00
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
2020-02-29 13:42:12 +01:00
|
|
|
fdroidserver.metadata.read_srclibs()
|
|
|
|
self.maxDiff = None
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertDictEqual(
|
|
|
|
fdroidserver.metadata.srclibs,
|
|
|
|
{
|
|
|
|
'with-list': {
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Repo': 'https://git.host/repo.git',
|
|
|
|
'Subdir': [''],
|
2022-09-09 12:36:54 +02:00
|
|
|
'Prepare': [
|
|
|
|
'Many',
|
|
|
|
'invalid',
|
|
|
|
'commands',
|
|
|
|
'here.',
|
|
|
|
],
|
2021-06-08 15:31:55 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
)
|
2020-02-29 13:42:12 +01:00
|
|
|
|
2019-12-24 00:42:29 +01:00
|
|
|
def test_read_srclibs(self):
|
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
2020-02-03 23:30:23 +01:00
|
|
|
fdroidserver.metadata.srclibs = None
|
2019-12-24 00:42:29 +01:00
|
|
|
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
|
2021-06-08 15:31:55 +02:00
|
|
|
Path('srclibs').mkdir()
|
|
|
|
with Path('srclibs/simple.yml').open('w', encoding='utf-8') as f:
|
2021-06-07 11:49:21 +02:00
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
2019-12-24 00:42:29 +01:00
|
|
|
RepoType: git
|
|
|
|
Repo: https://git.host/repo.git
|
2021-06-07 11:49:21 +02:00
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
2021-06-08 15:31:55 +02:00
|
|
|
with Path('srclibs/simple-wb.yml').open('w', encoding='utf-8') as f:
|
2021-06-07 11:49:21 +02:00
|
|
|
f.write(
|
|
|
|
textwrap.dedent(
|
|
|
|
'''\
|
2019-12-24 00:42:29 +01:00
|
|
|
# this should be simple
|
2020-07-02 00:38:09 +02:00
|
|
|
RepoType: git
|
|
|
|
Repo: https://git.host/repo.git
|
2019-12-24 00:42:29 +01:00
|
|
|
|
|
|
|
Subdir:
|
|
|
|
Prepare:
|
2021-06-07 11:49:21 +02:00
|
|
|
'''
|
|
|
|
)
|
|
|
|
)
|
2019-12-24 00:42:29 +01:00
|
|
|
fdroidserver.metadata.read_srclibs()
|
2021-06-08 15:31:55 +02:00
|
|
|
self.assertDictEqual(
|
|
|
|
fdroidserver.metadata.srclibs,
|
|
|
|
{
|
|
|
|
'simple-wb': {
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Repo': 'https://git.host/repo.git',
|
|
|
|
'Subdir': [''],
|
2022-09-09 12:36:54 +02:00
|
|
|
'Prepare': [],
|
2021-06-08 15:31:55 +02:00
|
|
|
},
|
|
|
|
'simple': {
|
|
|
|
'RepoType': 'git',
|
|
|
|
'Repo': 'https://git.host/repo.git',
|
|
|
|
'Subdir': None,
|
|
|
|
'Prepare': None,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
2019-12-24 00:42:29 +01:00
|
|
|
|
2021-06-10 15:47:33 +02:00
|
|
|
def test_build_ndk_path(self):
|
|
|
|
""""""
|
2022-11-22 17:17:45 +01:00
|
|
|
with tempfile.TemporaryDirectory(prefix='android-sdk-') as sdk_path:
|
|
|
|
config = {'ndk_paths': {}, 'sdk_path': sdk_path}
|
|
|
|
fdroidserver.common.config = config
|
|
|
|
|
|
|
|
build = fdroidserver.metadata.Build()
|
|
|
|
build.ndk = 'r10e'
|
|
|
|
self.assertEqual('', build.ndk_path())
|
|
|
|
|
|
|
|
correct = '/fake/path/ndk/r21b'
|
|
|
|
config['ndk_paths'] = {'r21b': correct}
|
|
|
|
self.assertEqual('', build.ndk_path())
|
|
|
|
config['ndk_paths'] = {'r10e': correct}
|
|
|
|
self.assertEqual(correct, build.ndk_path())
|
|
|
|
|
|
|
|
r10e = '/fake/path/ndk/r10e'
|
|
|
|
r22b = '/fake/path/ndk/r22e'
|
|
|
|
config['ndk_paths'] = {'r10e': r10e, 'r22b': r22b}
|
|
|
|
self.assertEqual(r10e, build.ndk_path())
|
|
|
|
|
|
|
|
build.ndk = ['r10e', 'r22b']
|
|
|
|
self.assertEqual(r10e, build.ndk_path())
|
|
|
|
|
|
|
|
build.ndk = ['r22b', 'r10e']
|
|
|
|
self.assertEqual(r22b, build.ndk_path())
|
2021-06-10 15:47:33 +02:00
|
|
|
|
2023-03-27 15:54:43 +02:00
|
|
|
def test_build_ndk_path_only_accepts_str(self):
|
|
|
|
"""Paths in the config must be strings, never pathlib.Path instances"""
|
|
|
|
config = {'ndk_paths': {'r24': Path('r24')}}
|
|
|
|
fdroidserver.common.config = config
|
|
|
|
build = fdroidserver.metadata.Build()
|
|
|
|
build.ndk = 'r24'
|
|
|
|
with self.assertRaises(TypeError):
|
|
|
|
build.ndk_path()
|
|
|
|
|
2015-07-22 10:16:43 +02:00
|
|
|
|
2023-04-27 19:57:33 +02:00
|
|
|
class PostMetadataParseTest(unittest.TestCase):
|
|
|
|
"""Test the functions that post process the YAML input.
|
|
|
|
|
|
|
|
The following series of "post_metadata_parse" tests map out the
|
|
|
|
current state of automatic type conversion in the YAML post
|
|
|
|
processing. They are not necessary a statement of how things
|
|
|
|
should be, but more to surface the details of it functions.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
fdroidserver.metadata.warnings_action = 'error'
|
|
|
|
|
|
|
|
def _post_metadata_parse_app_list(self, from_yaml, expected):
|
|
|
|
app = {'AntiFeatures': from_yaml}
|
|
|
|
metadata.post_parse_yaml_metadata(app)
|
|
|
|
return {'AntiFeatures': expected}, app
|
|
|
|
|
|
|
|
def _post_metadata_parse_app_string(self, from_yaml, expected):
|
|
|
|
app = {'Repo': from_yaml}
|
|
|
|
metadata.post_parse_yaml_metadata(app)
|
|
|
|
return {'Repo': expected}, app
|
|
|
|
|
|
|
|
def _post_metadata_parse_build_bool(self, from_yaml, expected):
|
|
|
|
tested_key = 'submodules'
|
|
|
|
app = {'Builds': [{'versionCode': 1, tested_key: from_yaml}]}
|
|
|
|
post = copy.deepcopy(app)
|
|
|
|
metadata.post_parse_yaml_metadata(post)
|
|
|
|
del app['Builds'][0]['versionCode']
|
|
|
|
del post['Builds'][0]['versionCode']
|
|
|
|
for build in post['Builds']:
|
|
|
|
for k in list(build):
|
|
|
|
if k != tested_key:
|
|
|
|
del build[k]
|
|
|
|
app['Builds'][0][tested_key] = expected
|
|
|
|
return app, post
|
|
|
|
|
|
|
|
def _post_metadata_parse_build_int(self, from_yaml, expected):
|
|
|
|
tested_key = 'versionCode'
|
|
|
|
app = {'Builds': [{'versionCode': from_yaml}]}
|
|
|
|
post = copy.deepcopy(app)
|
|
|
|
metadata.post_parse_yaml_metadata(post)
|
|
|
|
for build in post['Builds']:
|
|
|
|
for k in list(build):
|
|
|
|
if k != tested_key:
|
|
|
|
del build[k]
|
|
|
|
app['Builds'][0][tested_key] = expected
|
|
|
|
return app, post
|
|
|
|
|
|
|
|
def _post_metadata_parse_build_list(self, from_yaml, expected):
|
|
|
|
tested_key = 'rm'
|
|
|
|
app = {'Builds': [{'versionCode': 1, tested_key: from_yaml}]}
|
|
|
|
post = copy.deepcopy(app)
|
|
|
|
metadata.post_parse_yaml_metadata(post)
|
|
|
|
del app['Builds'][0]['versionCode']
|
|
|
|
del post['Builds'][0]['versionCode']
|
|
|
|
for build in post['Builds']:
|
|
|
|
for k in list(build):
|
|
|
|
if k != tested_key:
|
|
|
|
del build[k]
|
|
|
|
app['Builds'][0][tested_key] = expected
|
|
|
|
return app, post
|
|
|
|
|
|
|
|
def _post_metadata_parse_build_script(self, from_yaml, expected):
|
|
|
|
tested_key = 'build'
|
|
|
|
app = {'Builds': [{'versionCode': 1, tested_key: from_yaml}]}
|
|
|
|
post = copy.deepcopy(app)
|
|
|
|
metadata.post_parse_yaml_metadata(post)
|
|
|
|
del app['Builds'][0]['versionCode']
|
|
|
|
del post['Builds'][0]['versionCode']
|
|
|
|
for build in post['Builds']:
|
|
|
|
for k in list(build):
|
|
|
|
if k != tested_key:
|
|
|
|
del build[k]
|
|
|
|
app['Builds'][0][tested_key] = expected
|
|
|
|
return app, post
|
|
|
|
|
|
|
|
def _post_metadata_parse_build_string(self, from_yaml, expected):
|
|
|
|
tested_key = 'commit'
|
|
|
|
app = {'Builds': [{'versionCode': 1, tested_key: from_yaml}]}
|
|
|
|
post = copy.deepcopy(app)
|
|
|
|
metadata.post_parse_yaml_metadata(post)
|
|
|
|
del app['Builds'][0]['versionCode']
|
|
|
|
del post['Builds'][0]['versionCode']
|
|
|
|
for build in post['Builds']:
|
|
|
|
for k in list(build):
|
|
|
|
if k != tested_key:
|
|
|
|
del build[k]
|
|
|
|
app['Builds'][0][tested_key] = expected
|
|
|
|
return app, post
|
|
|
|
|
|
|
|
def test_post_metadata_parse_int(self):
|
|
|
|
"""Run the int 123456 through the various field and flag types."""
|
|
|
|
with self.assertRaises(TypeError):
|
|
|
|
self._post_metadata_parse_app_list(123456, TypeError)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(123456, '123456'))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(123456, 123456))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_int(123456, 123456))
|
2023-04-20 22:48:52 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(123456, ['123456']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(123456, ['123456']))
|
2023-04-27 19:57:33 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(123456, '123456'))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_int_0(self):
|
|
|
|
"""Run the int 0 through the various field and flag types."""
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list(0, 0))
|
2023-04-24 14:15:45 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(0, '0'))
|
2023-04-27 19:57:33 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(0, 0))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_int(0, 0))
|
2023-04-20 22:48:52 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(0, ['0']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(0, ['0']))
|
2023-04-27 19:57:33 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(0, '0'))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_float_0_0(self):
|
|
|
|
"""Run the float 0.0 through the various field and flag types."""
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list(0.0, 0.0))
|
2023-04-24 14:15:45 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(0.0, '0.0'))
|
2023-04-27 19:57:33 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(0.0, 0.0))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int(0.0, MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(0.0, 0.0))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(0.0, 0.0))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(0.0, '0.0'))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_float_0_1(self):
|
|
|
|
"""Run the float 0.1 through the various field and flag types."""
|
|
|
|
with self.assertRaises(TypeError):
|
|
|
|
self._post_metadata_parse_app_list(0.1, TypeError)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(0.1, '0.1'))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(0.1, 0.1))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int(0.1, MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(0.1, 0.1))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(0.1, 0.1))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(0.1, '0.1'))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_float_1_0(self):
|
|
|
|
"""Run the float 1.0 through the various field and flag types."""
|
|
|
|
with self.assertRaises(TypeError):
|
|
|
|
self._post_metadata_parse_app_list(1.0, TypeError)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(1.0, '1.0'))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(1.0, 1.0))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int(1.0, MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(1.0, 1.0))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(1.0, 1.0))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(1.0, '1.0'))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_empty_list(self):
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list(list(), list()))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(list(), list()))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(list(), list()))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int(list(), MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(list(), list()))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(list(), list()))
|
2023-04-24 14:15:45 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(list(), list()))
|
2023-04-27 19:57:33 +02:00
|
|
|
|
|
|
|
def test_post_metadata_parse_set_of_1(self):
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list({1}, ['1']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string({1}, '{1}'))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool({1}, {1}))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int({1}, MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list({1}, {1}))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script({1}, {1}))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string({1}, '{1}'))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_empty_dict(self):
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list(dict(), dict()))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(dict(), dict()))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(dict(), dict()))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int(dict(), MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(dict(), dict()))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(dict(), dict()))
|
2023-04-24 14:15:45 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(dict(), dict()))
|
2023-04-27 19:57:33 +02:00
|
|
|
|
|
|
|
def test_post_metadata_parse_list_int_string(self):
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list([1, 'a'], ['1', 'a']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string([1, 'a'], "[1, 'a']"))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool([1, 'a'], [1, 'a']))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int([1, 'a'], MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list([1, 'a'], [1, 'a']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script([1, 'a'], [1, 'a']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string([1, 'a'], "[1, 'a']"))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_dict_int_string(self):
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list({'k': 1}, ['k']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string({'k': 1}, "{'k': 1}"))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool({'k': 1}, {'k': 1}))
|
|
|
|
with self.assertRaises(MetaDataException):
|
|
|
|
self._post_metadata_parse_build_int({'k': 1}, MetaDataException)
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list({'k': 1}, {'k': 1}))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script({'k': 1}, {'k': 1}))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string({'k': 1}, "{'k': 1}"))
|
|
|
|
|
|
|
|
def test_post_metadata_parse_false(self):
|
|
|
|
self.assertEqual(*self._post_metadata_parse_app_list(False, False))
|
2023-04-24 14:15:45 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(False, 'false'))
|
2023-04-27 19:57:33 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(False, False))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_int(False, False))
|
2023-04-20 22:48:52 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_list(False, ['false']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_script(False, ['false']))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_string(False, 'false'))
|
2023-04-27 19:57:33 +02:00
|
|
|
|
|
|
|
def test_post_metadata_parse_true(self):
|
|
|
|
with self.assertRaises(TypeError):
|
|
|
|
self._post_metadata_parse_app_list(True, TypeError)
|
2023-04-20 14:13:50 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_app_string(True, 'true'))
|
2023-04-27 19:57:33 +02:00
|
|
|
self.assertEqual(*self._post_metadata_parse_build_bool(True, True))
|
|
|
|
self.assertEqual(*self._post_metadata_parse_build_int(True, True))
|
2023-04-20 22:48:52 +02:00
|
|
|
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'))
|
2023-04-27 19:57:33 +02:00
|
|
|
|
|
|
|
|
2015-07-22 10:16:43 +02:00
|
|
|
if __name__ == "__main__":
|
|
|
|
parser = optparse.OptionParser()
|
2021-06-07 11:49:21 +02:00
|
|
|
parser.add_option(
|
|
|
|
"-v",
|
|
|
|
"--verbose",
|
|
|
|
action="store_true",
|
|
|
|
default=False,
|
|
|
|
help="Spew out even more information than normal",
|
|
|
|
)
|
2015-07-22 10:16:43 +02:00
|
|
|
(fdroidserver.common.options, args) = parser.parse_args(['--verbose'])
|
|
|
|
|
|
|
|
newSuite = unittest.TestSuite()
|
|
|
|
newSuite.addTest(unittest.makeSuite(MetadataTest))
|
2023-04-27 15:22:01 +02:00
|
|
|
unittest.main(failfast=False)
|