mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-18 13:17:29 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
7
testing/mozbase/mozversion/mozversion/__init__.py
Normal file
7
testing/mozbase/mozversion/mozversion/__init__.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# flake8: noqa
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from .errors import *
|
||||
from .mozversion import cli, get_version
|
||||
30
testing/mozbase/mozversion/mozversion/errors.py
Normal file
30
testing/mozbase/mozversion/mozversion/errors.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
class VersionError(Exception):
|
||||
|
||||
def __init__(self, message):
|
||||
Exception.__init__(self, message)
|
||||
|
||||
|
||||
class AppNotFoundError(VersionError):
|
||||
"""Exception for the application not found"""
|
||||
|
||||
def __init__(self, message):
|
||||
VersionError.__init__(self, message)
|
||||
|
||||
|
||||
class LocalAppNotFoundError(AppNotFoundError):
|
||||
"""Exception for local application not found"""
|
||||
|
||||
def __init__(self, path):
|
||||
AppNotFoundError.__init__(self, 'Application not found at: %s' % path)
|
||||
|
||||
|
||||
class RemoteAppNotFoundError(AppNotFoundError):
|
||||
"""Exception for remote application not found"""
|
||||
|
||||
def __init__(self, message):
|
||||
AppNotFoundError.__init__(self, message)
|
||||
340
testing/mozbase/mozversion/mozversion/mozversion.py
Normal file
340
testing/mozbase/mozversion/mozversion/mozversion.py
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import argparse
|
||||
import ConfigParser
|
||||
from StringIO import StringIO
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import xml.dom.minidom
|
||||
import zipfile
|
||||
|
||||
import mozfile
|
||||
import mozlog
|
||||
|
||||
import errors
|
||||
|
||||
|
||||
INI_DATA_MAPPING = (('application', 'App'), ('platform', 'Build'))
|
||||
|
||||
|
||||
class Version(object):
|
||||
|
||||
def __init__(self):
|
||||
self._info = {}
|
||||
self._logger = mozlog.get_default_logger(component='mozversion')
|
||||
if not self._logger:
|
||||
self._logger = mozlog.unstructured.getLogger('mozversion')
|
||||
|
||||
def get_gecko_info(self, path):
|
||||
for type, section in INI_DATA_MAPPING:
|
||||
config_file = os.path.join(path, "%s.ini" % type)
|
||||
if os.path.exists(config_file):
|
||||
self._parse_ini_file(open(config_file), type, section)
|
||||
else:
|
||||
self._logger.warning('Unable to find %s' % config_file)
|
||||
|
||||
def _parse_ini_file(self, fp, type, section):
|
||||
config = ConfigParser.RawConfigParser()
|
||||
config.readfp(fp)
|
||||
name_map = {'codename': 'display_name',
|
||||
'milestone': 'version',
|
||||
'sourcerepository': 'repository',
|
||||
'sourcestamp': 'changeset'}
|
||||
for key, value in config.items(section):
|
||||
name = name_map.get(key, key).lower()
|
||||
self._info['%s_%s' % (type, name)] = config.has_option(
|
||||
section, key) and config.get(section, key) or None
|
||||
|
||||
if not self._info.get('application_display_name'):
|
||||
self._info['application_display_name'] = \
|
||||
self._info.get('application_name')
|
||||
|
||||
|
||||
class LocalFennecVersion(Version):
|
||||
|
||||
def __init__(self, path, **kwargs):
|
||||
Version.__init__(self, **kwargs)
|
||||
self.get_gecko_info(path)
|
||||
|
||||
def get_gecko_info(self, path):
|
||||
archive = zipfile.ZipFile(path, 'r')
|
||||
archive_list = archive.namelist()
|
||||
for type, section in INI_DATA_MAPPING:
|
||||
filename = "%s.ini" % type
|
||||
if filename in archive_list:
|
||||
self._parse_ini_file(archive.open(filename), type,
|
||||
section)
|
||||
else:
|
||||
self._logger.warning('Unable to find %s' % filename)
|
||||
|
||||
if "package-name.txt" in archive_list:
|
||||
self._info["package_name"] = \
|
||||
archive.open("package-name.txt").readlines()[0].strip()
|
||||
|
||||
|
||||
class LocalVersion(Version):
|
||||
|
||||
def __init__(self, binary, **kwargs):
|
||||
Version.__init__(self, **kwargs)
|
||||
|
||||
if binary:
|
||||
# on Windows, the binary may be specified with or without the
|
||||
# .exe extension
|
||||
if not os.path.exists(binary) and not os.path.exists(binary +
|
||||
'.exe'):
|
||||
raise IOError('Binary path does not exist: %s' % binary)
|
||||
path = os.path.dirname(os.path.realpath(binary))
|
||||
else:
|
||||
path = os.getcwd()
|
||||
|
||||
if not self.check_location(path):
|
||||
if sys.platform == 'darwin':
|
||||
resources_path = os.path.join(os.path.dirname(path),
|
||||
'Resources')
|
||||
if self.check_location(resources_path):
|
||||
path = resources_path
|
||||
else:
|
||||
raise errors.LocalAppNotFoundError(path)
|
||||
else:
|
||||
raise errors.LocalAppNotFoundError(path)
|
||||
|
||||
self.get_gecko_info(path)
|
||||
|
||||
def check_location(self, path):
|
||||
return (os.path.exists(os.path.join(path, 'application.ini'))
|
||||
and os.path.exists(os.path.join(path, 'platform.ini')))
|
||||
|
||||
|
||||
class B2GVersion(Version):
|
||||
|
||||
def __init__(self, sources=None, **kwargs):
|
||||
Version.__init__(self, **kwargs)
|
||||
|
||||
sources = sources or \
|
||||
os.path.exists(os.path.join(os.getcwd(), 'sources.xml')) and \
|
||||
os.path.join(os.getcwd(), 'sources.xml')
|
||||
|
||||
if sources and os.path.exists(sources):
|
||||
sources_xml = xml.dom.minidom.parse(sources)
|
||||
for element in sources_xml.getElementsByTagName('project'):
|
||||
path = element.getAttribute('path')
|
||||
changeset = element.getAttribute('revision')
|
||||
if path in ['gaia', 'gecko', 'build']:
|
||||
if path == 'gaia' and self._info.get('gaia_changeset'):
|
||||
break
|
||||
self._info['_'.join([path, 'changeset'])] = changeset
|
||||
|
||||
def get_gaia_info(self, app_zip):
|
||||
tempdir = tempfile.mkdtemp()
|
||||
try:
|
||||
gaia_commit = os.path.join(tempdir, 'gaia_commit.txt')
|
||||
try:
|
||||
zip_file = zipfile.ZipFile(app_zip.name)
|
||||
with open(gaia_commit, 'w') as f:
|
||||
f.write(zip_file.read('resources/gaia_commit.txt'))
|
||||
except zipfile.BadZipfile:
|
||||
self._logger.info('Unable to unzip application.zip, falling '
|
||||
'back to system unzip')
|
||||
from subprocess import call
|
||||
call(['unzip', '-j', app_zip.name, 'resources/gaia_commit.txt',
|
||||
'-d', tempdir])
|
||||
|
||||
with open(gaia_commit) as f:
|
||||
changeset, date = f.read().splitlines()
|
||||
self._info['gaia_changeset'] = re.match(
|
||||
'^\w{40}$', changeset) and changeset or None
|
||||
self._info['gaia_date'] = date
|
||||
except KeyError:
|
||||
self._logger.warning(
|
||||
'Unable to find resources/gaia_commit.txt in '
|
||||
'application.zip')
|
||||
finally:
|
||||
mozfile.remove(tempdir)
|
||||
|
||||
|
||||
class LocalB2GVersion(B2GVersion):
|
||||
|
||||
def __init__(self, binary, sources=None, **kwargs):
|
||||
B2GVersion.__init__(self, sources, **kwargs)
|
||||
|
||||
if binary:
|
||||
if not os.path.exists(binary):
|
||||
raise IOError('Binary path does not exist: %s' % binary)
|
||||
path = os.path.dirname(binary)
|
||||
else:
|
||||
if os.path.exists(os.path.join(os.getcwd(), 'application.ini')):
|
||||
path = os.getcwd()
|
||||
|
||||
self.get_gecko_info(path)
|
||||
|
||||
zip_path = os.path.join(
|
||||
path, 'gaia', 'profile', 'webapps',
|
||||
'settings.gaiamobile.org', 'application.zip')
|
||||
if os.path.exists(zip_path):
|
||||
with open(zip_path, 'rb') as zip_file:
|
||||
self.get_gaia_info(zip_file)
|
||||
else:
|
||||
self._logger.warning('Error pulling gaia file')
|
||||
|
||||
|
||||
class RemoteB2GVersion(B2GVersion):
|
||||
|
||||
def __init__(self, sources=None, dm_type='adb', host=None,
|
||||
device_serial=None, adb_host=None, adb_port=None,
|
||||
**kwargs):
|
||||
B2GVersion.__init__(self, sources, **kwargs)
|
||||
|
||||
try:
|
||||
import mozdevice
|
||||
except ImportError:
|
||||
self._logger.critical("mozdevice is required to get the version"
|
||||
" of a remote device")
|
||||
raise
|
||||
|
||||
if dm_type == 'adb':
|
||||
dm = mozdevice.DeviceManagerADB(deviceSerial=device_serial,
|
||||
serverHost=adb_host,
|
||||
serverPort=adb_port)
|
||||
elif dm_type == 'sut':
|
||||
if not host:
|
||||
raise errors.RemoteAppNotFoundError(
|
||||
'A host for SUT must be supplied.')
|
||||
dm = mozdevice.DeviceManagerSUT(host=host)
|
||||
else:
|
||||
raise errors.RemoteAppNotFoundError(
|
||||
'Unknown device manager type: %s' % dm_type)
|
||||
|
||||
if not sources:
|
||||
path = 'system/sources.xml'
|
||||
if dm.fileExists(path):
|
||||
sources = StringIO(dm.pullFile(path))
|
||||
else:
|
||||
self._logger.info('Unable to find %s' % path)
|
||||
|
||||
tempdir = tempfile.mkdtemp()
|
||||
for ini in ('application', 'platform'):
|
||||
with open(os.path.join(tempdir, '%s.ini' % ini), 'w') as f:
|
||||
f.write(dm.pullFile('/system/b2g/%s.ini' % ini))
|
||||
f.flush()
|
||||
self.get_gecko_info(tempdir)
|
||||
mozfile.remove(tempdir)
|
||||
|
||||
for path in ['/system/b2g', '/data/local']:
|
||||
path += '/webapps/settings.gaiamobile.org/application.zip'
|
||||
if dm.fileExists(path):
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
dm.getFile(path, f.name)
|
||||
self.get_gaia_info(f)
|
||||
break
|
||||
else:
|
||||
self._logger.warning('Error pulling gaia file')
|
||||
|
||||
build_props = dm.pullFile('/system/build.prop')
|
||||
desired_props = {
|
||||
'ro.build.version.incremental': 'device_firmware_version_incremental',
|
||||
'ro.build.version.release': 'device_firmware_version_release',
|
||||
'ro.build.date.utc': 'device_firmware_date',
|
||||
'ro.product.device': 'device_id'}
|
||||
for line in build_props.split('\n'):
|
||||
if not line.strip().startswith('#') and '=' in line:
|
||||
key, value = [s.strip() for s in line.split('=', 1)]
|
||||
if key in desired_props.keys():
|
||||
self._info[desired_props[key]] = value
|
||||
|
||||
if self._info.get('device_id', '').lower() == 'flame':
|
||||
for prop in ['ro.boot.bootloader', 't2m.sw.version']:
|
||||
value = dm.shellCheckOutput(['getprop', prop])
|
||||
if value:
|
||||
self._info['device_firmware_version_base'] = value
|
||||
break
|
||||
|
||||
|
||||
def get_version(binary=None, sources=None, dm_type=None, host=None,
|
||||
device_serial=None, adb_host=None, adb_port=None):
|
||||
"""
|
||||
Returns the application version information as a dict. You can specify
|
||||
a path to the binary of the application or an Android APK file (to get
|
||||
version information for Firefox for Android). If this is omitted then the
|
||||
current directory is checked for the existance of an application.ini
|
||||
file. If not found and that the binary path was not specified, then it is
|
||||
assumed the target application is a remote Firefox OS instance.
|
||||
|
||||
:param binary: Path to the binary for the application or Android APK file
|
||||
:param sources: Path to the sources.xml file (Firefox OS)
|
||||
:param dm_type: Device manager type. Must be 'adb' or 'sut' (Firefox OS)
|
||||
:param host: Host address of remote Firefox OS instance (SUT)
|
||||
:param device_serial: Serial identifier of Firefox OS device (ADB)
|
||||
:param adb_host: Host address of ADB server
|
||||
:param adb_port: Port of ADB server
|
||||
"""
|
||||
try:
|
||||
if binary and zipfile.is_zipfile(binary) and 'AndroidManifest.xml' in \
|
||||
zipfile.ZipFile(binary, 'r').namelist():
|
||||
version = LocalFennecVersion(binary)
|
||||
else:
|
||||
version = LocalVersion(binary)
|
||||
if version._info.get('application_name') == 'B2G':
|
||||
version = LocalB2GVersion(binary, sources=sources)
|
||||
except errors.LocalAppNotFoundError:
|
||||
if binary:
|
||||
# we had a binary argument, do not search for remote B2G
|
||||
raise
|
||||
version = RemoteB2GVersion(sources=sources,
|
||||
dm_type=dm_type,
|
||||
host=host,
|
||||
adb_host=adb_host,
|
||||
adb_port=adb_port,
|
||||
device_serial=device_serial)
|
||||
|
||||
for (key, value) in sorted(version._info.items()):
|
||||
if value:
|
||||
version._logger.info('%s: %s' % (key, value))
|
||||
|
||||
return version._info
|
||||
|
||||
|
||||
def cli(args=sys.argv[1:]):
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Display version information for Mozilla applications')
|
||||
parser.add_argument(
|
||||
'--binary',
|
||||
help='path to application binary or apk')
|
||||
fxos = parser.add_argument_group('Firefox OS')
|
||||
fxos.add_argument(
|
||||
'--sources',
|
||||
help='path to sources.xml')
|
||||
fxos.add_argument(
|
||||
'--device',
|
||||
help='serial identifier of device to target')
|
||||
fxos.add_argument(
|
||||
'--adb-host',
|
||||
help='host running adb')
|
||||
fxos.add_argument(
|
||||
'--adb-port',
|
||||
help='port running adb')
|
||||
mozlog.commandline.add_logging_group(
|
||||
parser,
|
||||
include_formatters=mozlog.commandline.TEXT_FORMATTERS
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
dm_type = os.environ.get('DM_TRANS', 'adb')
|
||||
host = os.environ.get('TEST_DEVICE')
|
||||
|
||||
mozlog.commandline.setup_logging(
|
||||
'mozversion', args, {'mach': sys.stdout})
|
||||
|
||||
get_version(binary=args.binary,
|
||||
sources=args.sources,
|
||||
dm_type=dm_type,
|
||||
host=host,
|
||||
device_serial=args.device,
|
||||
adb_host=args.adb_host,
|
||||
adb_port=args.adb_port)
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
||||
29
testing/mozbase/mozversion/setup.py
Normal file
29
testing/mozbase/mozversion/setup.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
PACKAGE_VERSION = '1.4'
|
||||
|
||||
|
||||
setup(name='mozversion',
|
||||
version=PACKAGE_VERSION,
|
||||
description='Library to get version information for applications',
|
||||
long_description='See http://mozbase.readthedocs.org',
|
||||
classifiers=[],
|
||||
keywords='mozilla',
|
||||
author='Mozilla Automation and Testing Team',
|
||||
author_email='tools@lists.mozilla.org',
|
||||
url='https://wiki.mozilla.org/Auto-tools/Projects/Mozbase',
|
||||
license='MPL',
|
||||
packages=['mozversion'],
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
install_requires=['mozfile >= 1.0', 'mozlog >= 3.0'],
|
||||
extras_require={'device': ['mozdevice >= 0.44']},
|
||||
entry_points="""
|
||||
# -*- Entry points: -*-
|
||||
[console_scripts]
|
||||
mozversion = mozversion:cli
|
||||
""")
|
||||
4
testing/mozbase/mozversion/tests/manifest.ini
Normal file
4
testing/mozbase/mozversion/tests/manifest.ini
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
[test_binary.py]
|
||||
[test_sources.py]
|
||||
[test_b2g.py]
|
||||
[test_apk.py]
|
||||
43
testing/mozbase/mozversion/tests/test_apk.py
Normal file
43
testing/mozbase/mozversion/tests/test_apk.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import mozfile
|
||||
import unittest
|
||||
import zipfile
|
||||
from mozversion import get_version
|
||||
|
||||
|
||||
class ApkTest(unittest.TestCase):
|
||||
"""test getting version information from an android .apk"""
|
||||
|
||||
application_changeset = 'a' * 40
|
||||
platform_changeset = 'b' * 40
|
||||
|
||||
def create_apk_zipfiles(self, zfile):
|
||||
zfile.writestr('application.ini',
|
||||
"""[App]\nSourceStamp=%s\n""" % self.application_changeset)
|
||||
zfile.writestr('platform.ini',
|
||||
"""[Build]\nSourceStamp=%s\n""" % self.platform_changeset)
|
||||
zfile.writestr('AndroidManifest.xml', '')
|
||||
|
||||
def test_basic(self):
|
||||
with mozfile.NamedTemporaryFile() as f:
|
||||
with zipfile.ZipFile(f.name, 'w') as z:
|
||||
self.create_apk_zipfiles(z)
|
||||
v = get_version(f.name)
|
||||
self.assertEqual(v.get('application_changeset'), self.application_changeset)
|
||||
self.assertEqual(v.get('platform_changeset'), self.platform_changeset)
|
||||
|
||||
def test_with_package_name(self):
|
||||
with mozfile.NamedTemporaryFile() as f:
|
||||
with zipfile.ZipFile(f.name, 'w') as z:
|
||||
self.create_apk_zipfiles(z)
|
||||
z.writestr('package-name.txt', "org.mozilla.fennec")
|
||||
v = get_version(f.name)
|
||||
self.assertEqual(v.get('package_name'), "org.mozilla.fennec")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
75
testing/mozbase/mozversion/tests/test_b2g.py
Normal file
75
testing/mozbase/mozversion/tests/test_b2g.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
import zipfile
|
||||
|
||||
import mozfile
|
||||
from mozversion import get_version, errors
|
||||
|
||||
|
||||
class SourcesTest(unittest.TestCase):
|
||||
"""test getting version information from a sources xml"""
|
||||
|
||||
def setUp(self):
|
||||
self.tempdir = tempfile.mkdtemp()
|
||||
|
||||
self.binary = os.path.join(self.tempdir, 'binary')
|
||||
with open(self.binary, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
|
||||
f.writelines("""[App]\nName = B2G\n""")
|
||||
|
||||
with open(os.path.join(self.tempdir, 'platform.ini'), 'w') as f:
|
||||
f.write('[Build]\nBuildID = PlatformBuildID\n')
|
||||
|
||||
def tearDown(self):
|
||||
mozfile.remove(self.tempdir)
|
||||
|
||||
def _create_zip(self, revision=None, date=None):
|
||||
zip_path = os.path.join(
|
||||
self.tempdir, 'gaia', 'profile', 'webapps',
|
||||
'settings.gaiamobile.org', 'application.zip')
|
||||
os.makedirs(os.path.dirname(zip_path))
|
||||
app_zip = zipfile.ZipFile(zip_path, 'w')
|
||||
if revision or date:
|
||||
app_zip.writestr('resources/gaia_commit.txt',
|
||||
'%s\n%s' % (revision, date))
|
||||
app_zip.close()
|
||||
|
||||
def test_gaia_commit(self):
|
||||
revision, date = ('a' * 40, 'date')
|
||||
self._create_zip(revision, date)
|
||||
v = get_version(self.binary)
|
||||
self.assertEqual(v.get('gaia_changeset'), revision)
|
||||
self.assertEqual(v.get('gaia_date'), date)
|
||||
|
||||
def test_invalid_gaia_commit(self):
|
||||
revision, date = ('a' * 41, 'date')
|
||||
self._create_zip(revision, date)
|
||||
v = get_version(self.binary)
|
||||
self.assertIsNone(v.get('gaia_changeset'))
|
||||
self.assertEqual(v.get('gaia_date'), date)
|
||||
|
||||
def test_missing_zip_file(self):
|
||||
v = get_version(self.binary)
|
||||
self.assertIsNone(v.get('gaia_changeset'))
|
||||
self.assertIsNone(v.get('gaia_date'))
|
||||
|
||||
def test_missing_gaia_commit(self):
|
||||
self._create_zip()
|
||||
v = get_version(self.binary)
|
||||
self.assertIsNone(v.get('gaia_changeset'))
|
||||
self.assertIsNone(v.get('gaia_date'))
|
||||
|
||||
def test_b2g_fallback_when_no_binary(self):
|
||||
self.assertRaises(errors.RemoteAppNotFoundError, get_version)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
177
testing/mozbase/mozversion/tests/test_binary.py
Normal file
177
testing/mozbase/mozversion/tests/test_binary.py
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
import mozfile
|
||||
|
||||
from mozversion import errors, get_version
|
||||
|
||||
|
||||
class BinaryTest(unittest.TestCase):
|
||||
"""test getting application version information from a binary path"""
|
||||
|
||||
application_ini = """[App]
|
||||
ID = AppID
|
||||
Name = AppName
|
||||
CodeName = AppCodeName
|
||||
Version = AppVersion
|
||||
BuildID = AppBuildID
|
||||
SourceRepository = AppSourceRepo
|
||||
SourceStamp = AppSourceStamp
|
||||
Vendor = AppVendor
|
||||
"""
|
||||
platform_ini = """[Build]
|
||||
BuildID = PlatformBuildID
|
||||
Milestone = PlatformMilestone
|
||||
SourceStamp = PlatformSourceStamp
|
||||
SourceRepository = PlatformSourceRepo
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.cwd = os.getcwd()
|
||||
self.tempdir = tempfile.mkdtemp()
|
||||
|
||||
self.binary = os.path.join(self.tempdir, 'binary')
|
||||
with open(self.binary, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.cwd)
|
||||
mozfile.remove(self.tempdir)
|
||||
|
||||
@unittest.skipIf(not os.environ.get('BROWSER_PATH'),
|
||||
'No binary has been specified.')
|
||||
def test_real_binary(self):
|
||||
v = get_version(os.environ.get('BROWSER_PATH'))
|
||||
self.assertTrue(isinstance(v, dict))
|
||||
|
||||
def test_binary(self):
|
||||
self._write_ini_files()
|
||||
|
||||
self._check_version(get_version(self.binary))
|
||||
|
||||
@unittest.skipIf(not hasattr(os, 'symlink'),
|
||||
'os.symlink not supported on this platform')
|
||||
def test_symlinked_binary(self):
|
||||
self._write_ini_files()
|
||||
|
||||
# create a symlink of the binary in another directory and check
|
||||
# version against this symlink
|
||||
tempdir = tempfile.mkdtemp()
|
||||
try:
|
||||
browser_link = os.path.join(tempdir,
|
||||
os.path.basename(self.binary))
|
||||
os.symlink(self.binary, browser_link)
|
||||
|
||||
self._check_version(get_version(browser_link))
|
||||
finally:
|
||||
mozfile.remove(tempdir)
|
||||
|
||||
def test_binary_in_current_path(self):
|
||||
self._write_ini_files()
|
||||
|
||||
os.chdir(self.tempdir)
|
||||
self._check_version(get_version())
|
||||
|
||||
def test_with_ini_files_on_osx(self):
|
||||
self._write_ini_files()
|
||||
|
||||
platform = sys.platform
|
||||
sys.platform = 'darwin'
|
||||
try:
|
||||
# get_version is working with ini files next to the binary
|
||||
self._check_version(get_version(binary=self.binary))
|
||||
|
||||
# or if they are in the Resources dir
|
||||
# in this case the binary must be in a Contents dir, next
|
||||
# to the Resources dir
|
||||
contents_dir = os.path.join(self.tempdir, 'Contents')
|
||||
os.mkdir(contents_dir)
|
||||
moved_binary = os.path.join(contents_dir,
|
||||
os.path.basename(self.binary))
|
||||
shutil.move(self.binary, moved_binary)
|
||||
|
||||
resources_dir = os.path.join(self.tempdir, 'Resources')
|
||||
os.mkdir(resources_dir)
|
||||
for ini_file in ('application.ini', 'platform.ini'):
|
||||
shutil.move(os.path.join(self.tempdir, ini_file), resources_dir)
|
||||
|
||||
self._check_version(get_version(binary=moved_binary))
|
||||
finally:
|
||||
sys.platform = platform
|
||||
|
||||
def test_invalid_binary_path(self):
|
||||
self.assertRaises(IOError, get_version,
|
||||
os.path.join(self.tempdir, 'invalid'))
|
||||
|
||||
def test_without_ini_files(self):
|
||||
"""With missing ini files an exception should be thrown"""
|
||||
self.assertRaises(errors.AppNotFoundError, get_version,
|
||||
self.binary)
|
||||
|
||||
def test_without_platform_ini_file(self):
|
||||
"""With a missing platform.ini file an exception should be thrown"""
|
||||
self._write_ini_files(platform=False)
|
||||
self.assertRaises(errors.AppNotFoundError, get_version,
|
||||
self.binary)
|
||||
|
||||
def test_without_application_ini_file(self):
|
||||
"""With a missing application.ini file an exception should be thrown"""
|
||||
self._write_ini_files(application=False)
|
||||
self.assertRaises(errors.AppNotFoundError, get_version,
|
||||
self.binary)
|
||||
|
||||
def test_with_exe(self):
|
||||
"""Test that we can resolve .exe files"""
|
||||
self._write_ini_files()
|
||||
|
||||
exe_name_unprefixed = self.binary + '1'
|
||||
exe_name = exe_name_unprefixed + '.exe'
|
||||
with open(exe_name, 'w') as f:
|
||||
f.write('foobar')
|
||||
self._check_version(get_version(exe_name_unprefixed))
|
||||
|
||||
def test_not_found_with_binary_specified(self):
|
||||
self.assertRaises(errors.LocalAppNotFoundError, get_version, self.binary)
|
||||
|
||||
def _write_ini_files(self, application=True, platform=True):
|
||||
if application:
|
||||
with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
|
||||
f.writelines(self.application_ini)
|
||||
if platform:
|
||||
with open(os.path.join(self.tempdir, 'platform.ini'), 'w') as f:
|
||||
f.writelines(self.platform_ini)
|
||||
|
||||
def _check_version(self, version):
|
||||
self.assertEqual(version.get('application_id'), 'AppID')
|
||||
self.assertEqual(version.get('application_name'), 'AppName')
|
||||
self.assertEqual(
|
||||
version.get('application_display_name'), 'AppCodeName')
|
||||
self.assertEqual(version.get('application_version'), 'AppVersion')
|
||||
self.assertEqual(version.get('application_buildid'), 'AppBuildID')
|
||||
self.assertEqual(
|
||||
version.get('application_repository'), 'AppSourceRepo')
|
||||
self.assertEqual(
|
||||
version.get('application_changeset'), 'AppSourceStamp')
|
||||
self.assertEqual(version.get('application_vendor'), 'AppVendor')
|
||||
self.assertIsNone(version.get('platform_name'))
|
||||
self.assertEqual(version.get('platform_buildid'), 'PlatformBuildID')
|
||||
self.assertEqual(
|
||||
version.get('platform_repository'), 'PlatformSourceRepo')
|
||||
self.assertEqual(
|
||||
version.get('platform_changeset'), 'PlatformSourceStamp')
|
||||
self.assertIsNone(version.get('invalid_key'))
|
||||
self.assertEqual(
|
||||
version.get('platform_version'), 'PlatformMilestone')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
85
testing/mozbase/mozversion/tests/test_sources.py
Normal file
85
testing/mozbase/mozversion/tests/test_sources.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import mozfile
|
||||
|
||||
from mozversion import errors, get_version
|
||||
|
||||
|
||||
class SourcesTest(unittest.TestCase):
|
||||
"""test getting version information from a sources xml"""
|
||||
|
||||
application_ini = """[App]\nName = B2G\n"""
|
||||
platform_ini = """[Build]
|
||||
BuildID = PlatformBuildID
|
||||
SourceStamp = PlatformSourceStamp
|
||||
SourceRepository = PlatformSourceRepo
|
||||
"""
|
||||
sources_xml = """<?xml version="1.0" ?><manifest>
|
||||
<project path="build" revision="build_revision" />
|
||||
<project path="gaia" revision="gaia_revision" />
|
||||
<project path="gecko" revision="gecko_revision" />
|
||||
</manifest>
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
self.cwd = os.getcwd()
|
||||
self.tempdir = tempfile.mkdtemp()
|
||||
|
||||
self.binary = os.path.join(self.tempdir, 'binary')
|
||||
with open(self.binary, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.cwd)
|
||||
mozfile.remove(self.tempdir)
|
||||
|
||||
def _write_conf_files(self, sources=True):
|
||||
with open(os.path.join(self.tempdir, 'application.ini'), 'w') as f:
|
||||
f.writelines(self.application_ini)
|
||||
with open(os.path.join(self.tempdir, 'platform.ini'), 'w') as f:
|
||||
f.writelines(self.platform_ini)
|
||||
if sources:
|
||||
with open(os.path.join(self.tempdir, 'sources.xml'), 'w') as f:
|
||||
f.writelines(self.sources_xml)
|
||||
|
||||
def test_sources(self):
|
||||
self._write_conf_files()
|
||||
|
||||
os.chdir(self.tempdir)
|
||||
self._check_version(get_version(sources=os.path.join(self.tempdir,
|
||||
'sources.xml')))
|
||||
|
||||
def test_sources_in_current_directory(self):
|
||||
self._write_conf_files()
|
||||
|
||||
os.chdir(self.tempdir)
|
||||
self._check_version(get_version())
|
||||
|
||||
def test_invalid_sources_path(self):
|
||||
"""An invalid source path should cause an exception"""
|
||||
self.assertRaises(errors.AppNotFoundError, get_version,
|
||||
self.binary, os.path.join(self.tempdir, 'invalid'))
|
||||
|
||||
def test_without_sources_file(self):
|
||||
"""With a missing sources file no exception should be thrown"""
|
||||
self._write_conf_files(sources=False)
|
||||
|
||||
get_version(self.binary)
|
||||
|
||||
def _check_version(self, version):
|
||||
self.assertEqual(version.get('build_changeset'), 'build_revision')
|
||||
self.assertEqual(version.get('gaia_changeset'), 'gaia_revision')
|
||||
self.assertEqual(version.get('gecko_changeset'), 'gecko_revision')
|
||||
self.assertIsNone(version.get('invalid_key'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue