mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-07 15:57:31 +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
4
config/tests/chrome.manifest.flat
Normal file
4
config/tests/chrome.manifest.flat
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
content test chrome/test/one
|
||||
locale ab-X-stuff chrome/test/three
|
||||
overlay chrome://one/file.xml chrome://two/otherfile.xml
|
||||
skin test classic chrome/test/one
|
||||
36
config/tests/makefiles/autodeps/Makefile.in
Normal file
36
config/tests/makefiles/autodeps/Makefile.in
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# -*- makefile -*-
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
|
||||
export STANDALONE_MAKEFILE=1
|
||||
PYTHON ?= python
|
||||
PYTEST = $(PYTHON) -E
|
||||
|
||||
# python -B not supported by older interpreters
|
||||
export PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
autotgt_tests = .deps/autotargets.mk.ts
|
||||
|
||||
tgts =\
|
||||
.deps/.mkdir.done\
|
||||
$(autotgt_tests)
|
||||
$(NULL)
|
||||
|
||||
export MAKE
|
||||
|
||||
##------------------_##
|
||||
##---] TARGETS [---##
|
||||
##------------------_##
|
||||
all::
|
||||
|
||||
check:: $(tgts)
|
||||
|
||||
# Only run unit test when autotargets.mk is modified
|
||||
$(autotgt_tests): $(topsrcdir)/config/makefiles/autotargets.mk
|
||||
$(PYTEST) $(srcdir)/check_mkdir.tpy
|
||||
@$(TOUCH) $@
|
||||
269
config/tests/makefiles/autodeps/check_mkdir.tpy
Normal file
269
config/tests/makefiles/autodeps/check_mkdir.tpy
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
#!/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
|
||||
|
||||
from subprocess import call
|
||||
from shutil import rmtree
|
||||
|
||||
import logging
|
||||
import unittest
|
||||
|
||||
|
||||
def banner():
|
||||
"""
|
||||
Display interpreter and system info for the test env
|
||||
"""
|
||||
print '*' * 75
|
||||
cmd = os.path.basename(__file__)
|
||||
print "%s: python version is %s" % (cmd, sys.version)
|
||||
print '*' * 75
|
||||
|
||||
|
||||
def myopts(vals):
|
||||
"""
|
||||
Storage for extra command line args passed.
|
||||
|
||||
Returns:
|
||||
hash - argparse::Namespace object values
|
||||
"""
|
||||
|
||||
if not hasattr(myopts, 'vals'):
|
||||
if 'argparse' in sys.modules:
|
||||
tmp = { } # key existance enables unittest module debug
|
||||
else:
|
||||
tmp = { 'debug': False, 'verbose': False }
|
||||
|
||||
for k in dir(vals):
|
||||
if k[0:1] == '_':
|
||||
continue
|
||||
tmp[k] = getattr(vals, k)
|
||||
myopts.vals = tmp
|
||||
|
||||
return myopts.vals
|
||||
|
||||
|
||||
def path2posix(src):
|
||||
"""
|
||||
Normalize directory path syntax
|
||||
|
||||
Keyword arguments:
|
||||
src - path to normalize
|
||||
|
||||
Returns:
|
||||
scalar - a file path with drive separators and windows slashes removed
|
||||
|
||||
Todo:
|
||||
move to {build,config,tools,toolkit}/python for use in a library
|
||||
"""
|
||||
|
||||
## (drive, tail) = os.path.splitdrive(src)
|
||||
## Support path testing on all platforms
|
||||
drive = ''
|
||||
winpath = src.find(':')
|
||||
if -1 != winpath and 10 > winpath:
|
||||
(drive, tail) = src.split(':', 1)
|
||||
|
||||
if drive:
|
||||
todo = [ '', drive.rstrip(':').lstrip('/').lstrip('\\') ]
|
||||
todo.extend( tail.lstrip('/').lstrip('\\').split('\\') ) # c:\a => [a]
|
||||
else: # os.name == 'posix'
|
||||
todo = src.split('\\')
|
||||
|
||||
dst = '/'.join(todo)
|
||||
return dst
|
||||
|
||||
|
||||
def checkMkdir(work, debug=False):
|
||||
"""
|
||||
Verify arg permutations for directory mutex creation.
|
||||
|
||||
Keyword arguments:
|
||||
None
|
||||
|
||||
Returns:
|
||||
Exception on error
|
||||
|
||||
Note:
|
||||
Exception() rather than self.assertTrue() is used in this test
|
||||
function to enable scatch cleanup on test exit/failure conditions.
|
||||
Not guaranteed by python closures on early exit.
|
||||
"""
|
||||
|
||||
logging.debug("Testing: checkMkdir")
|
||||
|
||||
# On Windows, don't convert paths to POSIX
|
||||
skipposix = sys.platform == "win32"
|
||||
if skipposix:
|
||||
path = os.path.abspath(__file__)
|
||||
dirname_fun = os.path.dirname
|
||||
else:
|
||||
path = path2posix(os.path.abspath(__file__))
|
||||
import posixpath
|
||||
dirname_fun = posixpath.dirname
|
||||
|
||||
src = dirname_fun(path)
|
||||
# root is 5 directories up from path
|
||||
root = reduce(lambda x, _: dirname_fun(x), xrange(5), path)
|
||||
|
||||
rootP = path2posix(root)
|
||||
srcP = path2posix(src)
|
||||
workP = path2posix(work)
|
||||
|
||||
# C:\foo -vs- /c/foo
|
||||
# [0] command paths use /c/foo
|
||||
# [1] os.path.exists() on mingw() requires C:\
|
||||
paths = [
|
||||
"mkdir_bycall", # function generated
|
||||
"mkdir_bydep", # explicit dependency
|
||||
"mkdir_bygen", # by GENERATED_DIRS macro
|
||||
]
|
||||
|
||||
## Use make from the parent "make check" call when available
|
||||
cmd = { 'make': 'make' }
|
||||
shell0 = os.environ.get('MAKE')
|
||||
if shell0:
|
||||
shell = os.path.splitext(shell0)[0] # strip: .exe, .py
|
||||
if -1 != shell.find('make'):
|
||||
print "MAKE COMMAND FOUND: %s" % (shell0)
|
||||
cmd['make'] = shell0 if skipposix else path2posix(shell0)
|
||||
|
||||
args = []
|
||||
args.append('%s' % (cmd['make']))
|
||||
args.append('-C %s' % (work if skipposix else workP))
|
||||
args.append("-f %s/testor.tmpl" % (src if skipposix else srcP))
|
||||
args.append('topsrcdir=%s' % (root if skipposix else rootP))
|
||||
args.append('deps_mkdir_bycall=%s' % paths[0])
|
||||
args.append('deps_mkdir_bydep=%s' % paths[1])
|
||||
args.append('deps_mkdir_bygen=%s' % paths[2])
|
||||
args.append('checkup') # target
|
||||
|
||||
# Call will fail on mingw with output redirected ?!?
|
||||
if debug:
|
||||
pass
|
||||
if False: # if not debug:
|
||||
args.append('>/dev/null')
|
||||
|
||||
cmd = '%s' % (' '.join(args))
|
||||
logging.debug("Running: %s" % (cmd))
|
||||
rc = call(cmd, shell=True)
|
||||
if rc:
|
||||
raise Exception("make failed ($?=%s): cmd=%s" % (rc, cmd))
|
||||
|
||||
for i in paths:
|
||||
path = os.path.join(work, i)
|
||||
logging.debug("Did testing mkdir(%s) succeed?" % (path))
|
||||
if not os.path.exists(path):
|
||||
raise Exception("Test path %s does not exist" % (path))
|
||||
|
||||
|
||||
def parseargs():
|
||||
"""
|
||||
Support additional command line arguments for testing
|
||||
|
||||
Returns:
|
||||
hash - arguments of interested parsed from the command line
|
||||
"""
|
||||
|
||||
opts = None
|
||||
try:
|
||||
import argparse2
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--debug',
|
||||
action="store_true",
|
||||
default=False,
|
||||
help='Enable debug mode')
|
||||
# Cannot overload verbose, Verbose: False enables debugging
|
||||
parser.add_argument('--verbose',
|
||||
action="store_true",
|
||||
default=False,
|
||||
help='Enable verbose mode')
|
||||
parser.add_argument('unittest_args',
|
||||
nargs='*'
|
||||
# help='Slurp/pass remaining args to unittest'
|
||||
)
|
||||
opts = parser.parse_args()
|
||||
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
return opts
|
||||
|
||||
|
||||
class TestMakeLogic(unittest.TestCase):
|
||||
"""
|
||||
Test suite used to validate makefile library rules and macros
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
opts = myopts(None) # NameSpace object not hash
|
||||
self.debug = opts['debug']
|
||||
self.verbose = opts['verbose']
|
||||
|
||||
if self.debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
if self.verbose:
|
||||
print
|
||||
print "ENVIRONMENT DUMP:"
|
||||
print '=' * 75
|
||||
for k,v in os.environ.items():
|
||||
print "env{%s} => %s" % (k, v)
|
||||
print
|
||||
|
||||
|
||||
def test_path2posix(self):
|
||||
|
||||
todo = {
|
||||
'/dev/null' : '/dev/null',
|
||||
'A:\\a\\b\\c' : '/A/a/b/c',
|
||||
'B:/x/y' : '/B/x/y',
|
||||
'C:/x\\y/z' : '/C/x/y/z',
|
||||
'//FOO/bar/tans': '//FOO/bar/tans',
|
||||
'//X\\a/b\\c/d' : '//X/a/b/c/d',
|
||||
'\\c:mozilla\\sandbox': '/c/mozilla/sandbox',
|
||||
}
|
||||
|
||||
for val,exp in todo.items():
|
||||
found = path2posix(val)
|
||||
tst = "posix2path(%s): %s != %s)" % (val, exp, found)
|
||||
self.assertEqual(exp, found, "%s: invalid path detected" % (tst))
|
||||
|
||||
|
||||
def test_mkdir(self):
|
||||
"""
|
||||
Verify directory creation rules and macros
|
||||
"""
|
||||
|
||||
failed = True
|
||||
|
||||
# Exception handling is used to cleanup scratch space on error
|
||||
try:
|
||||
work = tempfile.mkdtemp()
|
||||
checkMkdir(work, self.debug)
|
||||
failed = False
|
||||
finally:
|
||||
if os.path.exists(work):
|
||||
rmtree(work)
|
||||
|
||||
self.assertFalse(failed, "Unit test failure detected")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
banner()
|
||||
opts = parseargs()
|
||||
myopts(opts)
|
||||
|
||||
if opts:
|
||||
if hasattr(opts, 'unittest_args'):
|
||||
sys.argv[1:] = opts.unittest_args
|
||||
else:
|
||||
sys.argv[1:] = []
|
||||
|
||||
unittest.main()
|
||||
6
config/tests/makefiles/autodeps/moz.build
Normal file
6
config/tests/makefiles/autodeps/moz.build
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=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/.
|
||||
|
||||
64
config/tests/makefiles/autodeps/testor.tmpl
Normal file
64
config/tests/makefiles/autodeps/testor.tmpl
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# -*- makefile -*-
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
|
||||
###########################################################################
|
||||
## Intent: Standalone unit tests for makefile rules and target logic
|
||||
###########################################################################
|
||||
|
||||
deps =$(NULL)
|
||||
tgts =$(NULL)
|
||||
|
||||
ifdef VERBOSE
|
||||
tgts += show
|
||||
endif
|
||||
|
||||
# Define macros
|
||||
include $(topsrcdir)/config/makefiles/makeutils.mk
|
||||
include $(topsrcdir)/config/makefiles/autotargets.mk
|
||||
|
||||
##########################
|
||||
## Verify threadsafe mkdir
|
||||
##########################
|
||||
ifdef deps_mkdir_bycall
|
||||
deps += $(call mkdir_deps,deps_mkdir_bycall)
|
||||
tgts += check_mkdir
|
||||
endif
|
||||
ifdef deps_mkdir_bydep
|
||||
deps += $(foreach dir,$(deps_mkdir_bydep),$(dir)/.mkdir.done)
|
||||
tgts += check_mkdir
|
||||
endif
|
||||
ifdef deps_mkdir_bygen
|
||||
GENERATED_DIRS += $(deps_mkdir_bygen)
|
||||
tgts += check_mkdir
|
||||
endif
|
||||
|
||||
###########################
|
||||
## Minimal environment load
|
||||
###########################
|
||||
MKDIR ?= mkdir -p
|
||||
TOUCH ?= touch
|
||||
|
||||
INCLUDED_CONFIG_MK = 1
|
||||
MOZILLA_DIR := $(topsrcdir)
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
##-------------------##
|
||||
##---] TARGETS [---##
|
||||
##-------------------##
|
||||
all::
|
||||
|
||||
# Quarks:
|
||||
# o Use of 'all' would trigger export target processing
|
||||
checkup: $(tgts)
|
||||
|
||||
# AUTO_DEPS - verify GENERATED_DIRS
|
||||
check_mkdir: $(deps) $(AUTO_DEPS)
|
||||
|
||||
show:
|
||||
@echo "tgts=[$(tgts)]"
|
||||
@echo "deps=[$(deps)]"
|
||||
find $(dir $(deps)) -print
|
||||
1
config/tests/ref-simple/one/file.xml
Normal file
1
config/tests/ref-simple/one/file.xml
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0"><doc/>
|
||||
2
config/tests/ref-simple/one/preproc
Normal file
2
config/tests/ref-simple/one/preproc
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
This is ab-X-stuff.
|
||||
6
config/tests/ref-simple/one/some.css
Normal file
6
config/tests/ref-simple/one/some.css
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#div: {
|
||||
/* this is a ID rule, and should stay intact */
|
||||
}
|
||||
[lang=ab-X-stuff] {
|
||||
/* this selector should match content with lang="ab-X-stuff" */
|
||||
}
|
||||
1
config/tests/ref-simple/three/l10nfile.txt
Normal file
1
config/tests/ref-simple/three/l10nfile.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
localized content
|
||||
1
config/tests/ref-simple/two/otherfile.xml
Normal file
1
config/tests/ref-simple/two/otherfile.xml
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0"><otherdoc/>
|
||||
38
config/tests/src-simple/Makefile.in
Normal file
38
config/tests/src-simple/Makefile.in
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#
|
||||
# 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/.
|
||||
|
||||
LOCALE_SRCDIR = $(srcdir)/l10n
|
||||
|
||||
EXTERNALLY_MANAGED_MAKE_FILE := 1
|
||||
STANDALONE_MAKEFILE := 1
|
||||
JAR_MANIFEST := $(srcdir)/jar.mn
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
XPI_NAME = test_jar_mn
|
||||
|
||||
ACDEFINES += \
|
||||
-DAB_CD=ab-X-stuff \
|
||||
$(NULL)
|
||||
|
||||
MY_MANIFEST = $(if $(USE_EXTENSION_MANIFEST), $(FINAL_TARGET)/chrome.manifest, $(FINAL_TARGET)/chrome/test.manifest)
|
||||
REF_MANIFEST = $(if $(USE_EXTENSION_MANIFEST),chrome.manifest,test.manifest)
|
||||
|
||||
check-%::
|
||||
if test -d $(FINAL_TARGET); then rm -rf $(FINAL_TARGET); fi;
|
||||
$(MAKE) realchrome MOZ_JAR_MAKER_FILE_FORMAT=$*
|
||||
@echo 'Comparing manifests...'
|
||||
@if ! sort $(MY_MANIFEST) | diff --text -U 0 $(srcdir)/../$(REF_MANIFEST).$* - ; then \
|
||||
echo 'TEST-UNEXPECTED-FAIL | config/tests/$(REF_MANIFEST).$* | differing content in manifest!' ; \
|
||||
false; \
|
||||
fi
|
||||
@if [ $* = 'jar' ]; then \
|
||||
$(UNZIP) -d $(FINAL_TARGET)/chrome/test $(FINAL_TARGET)/chrome/test.jar; \
|
||||
fi
|
||||
@echo 'Comparing packages...'
|
||||
@if ! diff -ur $(srcdir)/../ref-simple $(FINAL_TARGET)/chrome/test ; then\
|
||||
echo 'TEST-UNEXPECTED-FAIL | config/tests/ref-simple | different content in jar' ; \
|
||||
false; \
|
||||
fi
|
||||
22
config/tests/src-simple/jar.mn
Normal file
22
config/tests/src-simple/jar.mn
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#filter substitution
|
||||
|
||||
test.jar:
|
||||
# test chrome with flags and path expansion
|
||||
% content test %one
|
||||
# test locale with variable substitution and path expansion
|
||||
% locale @AB_CD@ %three
|
||||
# test overlays
|
||||
% overlay chrome://one/file.xml chrome://two/otherfile.xml
|
||||
# test regular file, preprocessed file, preprocessed css
|
||||
one/file.xml (thesrcdir/file.xml)
|
||||
* one/preproc (thesrcdir/preproc.in)
|
||||
* one/some.css (thesrcdir/some.css)
|
||||
# test reference against topsrcdir
|
||||
two/otherfile.xml (/config/tests/src-simple/thetopsrcdir/otherfile.xml)
|
||||
# test reference against localesrcdir
|
||||
three/l10nfile.txt (%l10nfile.txt)
|
||||
|
||||
test.jar:
|
||||
# test manifest update the locale one was already added above, add skin
|
||||
% locale @AB_CD@ %three
|
||||
% skin test classic %one
|
||||
1
config/tests/src-simple/l10n/l10nfile.txt
Normal file
1
config/tests/src-simple/l10n/l10nfile.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
localized content
|
||||
7
config/tests/src-simple/moz.build
Normal file
7
config/tests/src-simple/moz.build
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=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/.
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
1
config/tests/src-simple/thesrcdir/file.xml
Normal file
1
config/tests/src-simple/thesrcdir/file.xml
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0"><doc/>
|
||||
6
config/tests/src-simple/thesrcdir/preproc.in
Normal file
6
config/tests/src-simple/thesrcdir/preproc.in
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# This would be an processed out
|
||||
# pretty lengthy
|
||||
# license header.
|
||||
# For example.
|
||||
|
||||
#expand This is __AB_CD__.
|
||||
6
config/tests/src-simple/thesrcdir/some.css
Normal file
6
config/tests/src-simple/thesrcdir/some.css
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#div: {
|
||||
/* this is a ID rule, and should stay intact */
|
||||
}
|
||||
%expand [lang=__AB_CD__] {
|
||||
/* this selector should match content with lang="ab-X-stuff" */
|
||||
}
|
||||
1
config/tests/src-simple/thetopsrcdir/otherfile.xml
Normal file
1
config/tests/src-simple/thetopsrcdir/otherfile.xml
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0"><otherdoc/>
|
||||
4
config/tests/test.manifest.flat
Normal file
4
config/tests/test.manifest.flat
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
content test test/one
|
||||
locale ab-X-stuff test/three
|
||||
overlay chrome://one/file.xml chrome://two/otherfile.xml
|
||||
skin test classic test/one
|
||||
4
config/tests/test.manifest.jar
Normal file
4
config/tests/test.manifest.jar
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
content test jar:test.jar!/one
|
||||
locale ab-X-stuff jar:test.jar!/three
|
||||
overlay chrome://one/file.xml chrome://two/otherfile.xml
|
||||
skin test classic jar:test.jar!/one
|
||||
4
config/tests/test.manifest.symlink
Normal file
4
config/tests/test.manifest.symlink
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
content test test/one
|
||||
locale ab-X-stuff test/three
|
||||
overlay chrome://one/file.xml chrome://two/otherfile.xml
|
||||
skin test classic test/one
|
||||
116
config/tests/test_mozbuild_reading.py
Normal file
116
config/tests/test_mozbuild_reading.py
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
# 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 __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from mozunit import main
|
||||
|
||||
from mozbuild.base import MozbuildObject
|
||||
from mozpack.files import FileFinder
|
||||
from mozbuild.frontend.context import Files
|
||||
from mozbuild.frontend.reader import (
|
||||
BuildReader,
|
||||
EmptyConfig,
|
||||
)
|
||||
|
||||
|
||||
class TestMozbuildReading(unittest.TestCase):
|
||||
# This hack is needed to appease running in automation.
|
||||
def setUp(self):
|
||||
self._old_env = dict(os.environ)
|
||||
os.environ.pop('MOZCONFIG', None)
|
||||
os.environ.pop('MOZ_OBJDIR', None)
|
||||
|
||||
def tearDown(self):
|
||||
os.environ.clear()
|
||||
os.environ.update(self._old_env)
|
||||
|
||||
def _mozbuilds(self, reader):
|
||||
if not hasattr(self, '_mozbuild_paths'):
|
||||
self._mozbuild_paths = set(reader.all_mozbuild_paths())
|
||||
|
||||
return self._mozbuild_paths
|
||||
|
||||
@unittest.skip('failing in SpiderMonkey builds')
|
||||
def test_filesystem_traversal_reading(self):
|
||||
"""Reading moz.build according to filesystem traversal works.
|
||||
|
||||
We attempt to read every known moz.build file via filesystem traversal.
|
||||
|
||||
If this test fails, it means that metadata extraction will fail.
|
||||
"""
|
||||
mb = MozbuildObject.from_environment(detect_virtualenv_mozinfo=False)
|
||||
config = mb.config_environment
|
||||
reader = BuildReader(config)
|
||||
all_paths = self._mozbuilds(reader)
|
||||
paths, contexts = reader.read_relevant_mozbuilds(all_paths)
|
||||
self.assertEqual(set(paths), all_paths)
|
||||
self.assertGreaterEqual(len(contexts), len(paths))
|
||||
|
||||
def test_filesystem_traversal_no_config(self):
|
||||
"""Reading moz.build files via filesystem traversal mode with no build config.
|
||||
|
||||
This is similar to the above test except no build config is applied.
|
||||
This will likely fail in more scenarios than the above test because a
|
||||
lot of moz.build files assumes certain variables are present.
|
||||
"""
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
root = os.path.normpath(os.path.join(here, '..', '..'))
|
||||
config = EmptyConfig(root)
|
||||
reader = BuildReader(config)
|
||||
all_paths = self._mozbuilds(reader)
|
||||
paths, contexts = reader.read_relevant_mozbuilds(all_paths)
|
||||
self.assertEqual(set(paths.keys()), all_paths)
|
||||
self.assertGreaterEqual(len(contexts), len(paths))
|
||||
|
||||
|
||||
def test_orphan_file_patterns(self):
|
||||
if sys.platform == 'win32':
|
||||
raise unittest.SkipTest('failing on windows builds')
|
||||
|
||||
mb = MozbuildObject.from_environment(detect_virtualenv_mozinfo=False)
|
||||
|
||||
try:
|
||||
config = mb.config_environment
|
||||
except Exception as e:
|
||||
if e.message == 'config.status not available. Run configure.':
|
||||
raise unittest.SkipTest('failing without config.status')
|
||||
raise
|
||||
|
||||
if config.substs['MOZ_BUILD_APP'] == 'js':
|
||||
raise unittest.SkipTest('failing in Spidermonkey builds')
|
||||
|
||||
reader = BuildReader(config)
|
||||
all_paths = self._mozbuilds(reader)
|
||||
_, contexts = reader.read_relevant_mozbuilds(all_paths)
|
||||
|
||||
finder = FileFinder(config.topsrcdir, find_executables=False,
|
||||
ignore=['obj*'])
|
||||
|
||||
def pattern_exists(pat):
|
||||
return [p for p in finder.find(pat)] != []
|
||||
|
||||
for ctx in contexts:
|
||||
if not isinstance(ctx, Files):
|
||||
continue
|
||||
relsrcdir = ctx.relsrcdir
|
||||
if not pattern_exists(os.path.join(relsrcdir, ctx.pattern)):
|
||||
self.fail("The pattern '%s' in a Files() entry in "
|
||||
"'%s' corresponds to no files in the tree.\n"
|
||||
"Please update this entry." %
|
||||
(ctx.pattern, ctx.main_path))
|
||||
test_files = ctx['IMPACTED_TESTS'].files
|
||||
for p in test_files:
|
||||
if not pattern_exists(os.path.relpath(p.full_path, config.topsrcdir)):
|
||||
self.fail("The pattern '%s' in a dependent tests entry "
|
||||
"in '%s' corresponds to no files in the tree.\n"
|
||||
"Please update this entry." %
|
||||
(p, ctx.main_path))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
431
config/tests/unit-expandlibs.py
Normal file
431
config/tests/unit-expandlibs.py
Normal file
|
|
@ -0,0 +1,431 @@
|
|||
import subprocess
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
import imp
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
import mozunit
|
||||
|
||||
from UserString import UserString
|
||||
# Create a controlled configuration for use by expandlibs
|
||||
config_win = {
|
||||
'AR': 'lib',
|
||||
'AR_EXTRACT': '',
|
||||
'DLL_PREFIX': '',
|
||||
'LIB_PREFIX': '',
|
||||
'OBJ_SUFFIX': '.obj',
|
||||
'LIB_SUFFIX': '.lib',
|
||||
'DLL_SUFFIX': '.dll',
|
||||
'IMPORT_LIB_SUFFIX': '.lib',
|
||||
'LIBS_DESC_SUFFIX': '.desc',
|
||||
'EXPAND_LIBS_LIST_STYLE': 'list',
|
||||
}
|
||||
config_unix = {
|
||||
'AR': 'ar',
|
||||
'AR_EXTRACT': 'ar -x',
|
||||
'DLL_PREFIX': 'lib',
|
||||
'LIB_PREFIX': 'lib',
|
||||
'OBJ_SUFFIX': '.o',
|
||||
'LIB_SUFFIX': '.a',
|
||||
'DLL_SUFFIX': '.so',
|
||||
'IMPORT_LIB_SUFFIX': '',
|
||||
'LIBS_DESC_SUFFIX': '.desc',
|
||||
'EXPAND_LIBS_LIST_STYLE': 'linkerscript',
|
||||
}
|
||||
|
||||
config = sys.modules['expandlibs_config'] = imp.new_module('expandlibs_config')
|
||||
|
||||
from expandlibs import LibDescriptor, ExpandArgs, relativize
|
||||
from expandlibs_gen import generate
|
||||
from expandlibs_exec import ExpandArgsMore, SectionFinder
|
||||
|
||||
def Lib(name):
|
||||
return config.LIB_PREFIX + name + config.LIB_SUFFIX
|
||||
|
||||
def Obj(name):
|
||||
return name + config.OBJ_SUFFIX
|
||||
|
||||
def Dll(name):
|
||||
return config.DLL_PREFIX + name + config.DLL_SUFFIX
|
||||
|
||||
def ImportLib(name):
|
||||
if not len(config.IMPORT_LIB_SUFFIX): return Dll(name)
|
||||
return config.LIB_PREFIX + name + config.IMPORT_LIB_SUFFIX
|
||||
|
||||
class TestRelativize(unittest.TestCase):
|
||||
def test_relativize(self):
|
||||
'''Test relativize()'''
|
||||
os_path_exists = os.path.exists
|
||||
def exists(path):
|
||||
return True
|
||||
os.path.exists = exists
|
||||
self.assertEqual(relativize(os.path.abspath(os.curdir)), os.curdir)
|
||||
self.assertEqual(relativize(os.path.abspath(os.pardir)), os.pardir)
|
||||
self.assertEqual(relativize(os.path.join(os.curdir, 'a')), 'a')
|
||||
self.assertEqual(relativize(os.path.join(os.path.abspath(os.curdir), 'a')), 'a')
|
||||
# relativize is expected to return the absolute path if it is shorter
|
||||
self.assertEqual(relativize(os.sep), os.sep)
|
||||
os.path.exists = os.path.exists
|
||||
|
||||
class TestLibDescriptor(unittest.TestCase):
|
||||
def test_serialize(self):
|
||||
'''Test LibDescriptor's serialization'''
|
||||
desc = LibDescriptor()
|
||||
desc[LibDescriptor.KEYS[0]] = ['a', 'b']
|
||||
self.assertEqual(str(desc), "{0} = a b".format(LibDescriptor.KEYS[0]))
|
||||
desc['unsupported-key'] = ['a']
|
||||
self.assertEqual(str(desc), "{0} = a b".format(LibDescriptor.KEYS[0]))
|
||||
desc[LibDescriptor.KEYS[1]] = ['c', 'd', 'e']
|
||||
self.assertEqual(str(desc),
|
||||
"{0} = a b\n{1} = c d e"
|
||||
.format(LibDescriptor.KEYS[0], LibDescriptor.KEYS[1]))
|
||||
desc[LibDescriptor.KEYS[0]] = []
|
||||
self.assertEqual(str(desc), "{0} = c d e".format(LibDescriptor.KEYS[1]))
|
||||
|
||||
def test_read(self):
|
||||
'''Test LibDescriptor's initialization'''
|
||||
desc_list = ["# Comment",
|
||||
"{0} = a b".format(LibDescriptor.KEYS[1]),
|
||||
"", # Empty line
|
||||
"foo = bar", # Should be discarded
|
||||
"{0} = c d e".format(LibDescriptor.KEYS[0])]
|
||||
desc = LibDescriptor(desc_list)
|
||||
self.assertEqual(desc[LibDescriptor.KEYS[1]], ['a', 'b'])
|
||||
self.assertEqual(desc[LibDescriptor.KEYS[0]], ['c', 'd', 'e'])
|
||||
self.assertEqual(False, 'foo' in desc)
|
||||
|
||||
def wrap_method(conf, wrapped_method):
|
||||
'''Wrapper used to call a test with a specific configuration'''
|
||||
def _method(self):
|
||||
for key in conf:
|
||||
setattr(config, key, conf[key])
|
||||
self.init()
|
||||
try:
|
||||
wrapped_method(self)
|
||||
except:
|
||||
raise
|
||||
finally:
|
||||
self.cleanup()
|
||||
return _method
|
||||
|
||||
class ReplicateTests(type):
|
||||
'''Replicates tests for unix and windows variants'''
|
||||
def __new__(cls, clsName, bases, dict):
|
||||
for name in [key for key in dict if key.startswith('test_')]:
|
||||
dict[name + '_unix'] = wrap_method(config_unix, dict[name])
|
||||
dict[name + '_unix'].__doc__ = dict[name].__doc__ + ' (unix)'
|
||||
dict[name + '_win'] = wrap_method(config_win, dict[name])
|
||||
dict[name + '_win'].__doc__ = dict[name].__doc__ + ' (win)'
|
||||
del dict[name]
|
||||
return type.__new__(cls, clsName, bases, dict)
|
||||
|
||||
class TestCaseWithTmpDir(unittest.TestCase):
|
||||
__metaclass__ = ReplicateTests
|
||||
def init(self):
|
||||
self.tmpdir = os.path.abspath(mkdtemp(dir=os.curdir))
|
||||
|
||||
def cleanup(self):
|
||||
rmtree(self.tmpdir)
|
||||
|
||||
def touch(self, files):
|
||||
for f in files:
|
||||
open(f, 'w').close()
|
||||
|
||||
def tmpfile(self, *args):
|
||||
return os.path.join(self.tmpdir, *args)
|
||||
|
||||
class TestExpandLibsGen(TestCaseWithTmpDir):
|
||||
def test_generate(self):
|
||||
'''Test library descriptor generation'''
|
||||
files = [self.tmpfile(f) for f in
|
||||
[Lib('a'), Obj('b'), Lib('c'), Obj('d'), Obj('e'), Lib('f')]]
|
||||
self.touch(files[:-1])
|
||||
self.touch([files[-1] + config.LIBS_DESC_SUFFIX])
|
||||
|
||||
desc = generate(files)
|
||||
self.assertEqual(desc['OBJS'], [self.tmpfile(Obj(s)) for s in ['b', 'd', 'e']])
|
||||
self.assertEqual(desc['LIBS'], [self.tmpfile(Lib(s)) for s in ['a', 'c', 'f']])
|
||||
|
||||
self.assertRaises(Exception, generate, files + [self.tmpfile(Obj('z'))])
|
||||
self.assertRaises(Exception, generate, files + [self.tmpfile(Lib('y'))])
|
||||
|
||||
class TestExpandInit(TestCaseWithTmpDir):
|
||||
def init(self):
|
||||
''' Initializes test environment for library expansion tests'''
|
||||
super(TestExpandInit, self).init()
|
||||
# Create 2 fake libraries, each containing 3 objects, and the second
|
||||
# including the first one and another library.
|
||||
os.mkdir(self.tmpfile('libx'))
|
||||
os.mkdir(self.tmpfile('liby'))
|
||||
self.libx_files = [self.tmpfile('libx', Obj(f)) for f in ['g', 'h', 'i']]
|
||||
self.liby_files = [self.tmpfile('liby', Obj(f)) for f in ['j', 'k', 'l']] + [self.tmpfile('liby', Lib('z'))]
|
||||
self.touch(self.libx_files + self.liby_files)
|
||||
with open(self.tmpfile('libx', Lib('x') + config.LIBS_DESC_SUFFIX), 'w') as f:
|
||||
f.write(str(generate(self.libx_files)))
|
||||
with open(self.tmpfile('liby', Lib('y') + config.LIBS_DESC_SUFFIX), 'w') as f:
|
||||
f.write(str(generate(self.liby_files + [self.tmpfile('libx', Lib('x'))])))
|
||||
|
||||
# Create various objects and libraries
|
||||
self.arg_files = [self.tmpfile(f) for f in [Lib('a'), Obj('b'), Obj('c'), Lib('d'), Obj('e')]]
|
||||
# We always give library names (LIB_PREFIX/SUFFIX), even for
|
||||
# dynamic/import libraries
|
||||
self.files = self.arg_files + [self.tmpfile(ImportLib('f'))]
|
||||
self.arg_files += [self.tmpfile(Lib('f'))]
|
||||
self.touch(self.files)
|
||||
|
||||
def assertRelEqual(self, args1, args2):
|
||||
self.assertEqual(args1, [relativize(a) for a in args2])
|
||||
|
||||
class TestExpandArgs(TestExpandInit):
|
||||
def test_expand(self):
|
||||
'''Test library expansion'''
|
||||
# Expanding arguments means libraries with a descriptor are expanded
|
||||
# with the descriptor content, and import libraries are used when
|
||||
# a library doesn't exist
|
||||
args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
|
||||
self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files)
|
||||
|
||||
# When a library exists at the same time as a descriptor, we still use
|
||||
# the descriptor.
|
||||
self.touch([self.tmpfile('libx', Lib('x'))])
|
||||
args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
|
||||
self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files)
|
||||
|
||||
self.touch([self.tmpfile('liby', Lib('y'))])
|
||||
args = ExpandArgs(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))])
|
||||
self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files)
|
||||
|
||||
class TestExpandArgsMore(TestExpandInit):
|
||||
def test_makelist(self):
|
||||
'''Test grouping object files in lists'''
|
||||
# ExpandArgsMore does the same as ExpandArgs
|
||||
with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
|
||||
self.assertRelEqual(args, ['foo', '-bar'] + self.files + self.liby_files + self.libx_files)
|
||||
|
||||
# But also has an extra method replacing object files with a list
|
||||
args.makelist()
|
||||
# self.files has objects at #1, #2, #4
|
||||
self.assertRelEqual(args[:3], ['foo', '-bar'] + self.files[:1])
|
||||
self.assertRelEqual(args[4:], [self.files[3]] + self.files[5:] + [self.tmpfile('liby', Lib('z'))])
|
||||
|
||||
# Check the list file content
|
||||
objs = [f for f in self.files + self.liby_files + self.libx_files if f.endswith(config.OBJ_SUFFIX)]
|
||||
if config.EXPAND_LIBS_LIST_STYLE == "linkerscript":
|
||||
self.assertNotEqual(args[3][0], '@')
|
||||
filename = args[3]
|
||||
content = ['INPUT("{0}")'.format(relativize(f)) for f in objs]
|
||||
with open(filename, 'r') as f:
|
||||
self.assertEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
|
||||
elif config.EXPAND_LIBS_LIST_STYLE == "list":
|
||||
self.assertEqual(args[3][0], '@')
|
||||
filename = args[3][1:]
|
||||
content = objs
|
||||
with open(filename, 'r') as f:
|
||||
self.assertRelEqual([l.strip() for l in f.readlines() if len(l.strip())], content)
|
||||
|
||||
tmp = args.tmp
|
||||
# Check that all temporary files are properly removed
|
||||
self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
|
||||
|
||||
def test_extract(self):
|
||||
'''Test library extraction'''
|
||||
# Divert subprocess.call
|
||||
subprocess_call = subprocess.call
|
||||
subprocess_check_output = subprocess.check_output
|
||||
def call(args, **kargs):
|
||||
if config.AR == 'lib':
|
||||
self.assertEqual(args[:2], [config.AR, '-NOLOGO'])
|
||||
self.assertTrue(args[2].startswith('-EXTRACT:'))
|
||||
extract = [args[2][len('-EXTRACT:'):]]
|
||||
self.assertTrue(extract)
|
||||
args = args[3:]
|
||||
else:
|
||||
# The command called is always AR_EXTRACT
|
||||
ar_extract = config.AR_EXTRACT.split()
|
||||
self.assertEqual(args[:len(ar_extract)], ar_extract)
|
||||
args = args[len(ar_extract):]
|
||||
# Remaining argument is always one library
|
||||
self.assertEqual(len(args), 1)
|
||||
arg = args[0]
|
||||
self.assertEqual(os.path.splitext(arg)[1], config.LIB_SUFFIX)
|
||||
# Simulate file extraction
|
||||
lib = os.path.splitext(os.path.basename(arg))[0]
|
||||
if config.AR != 'lib':
|
||||
extract = [lib, lib + '2']
|
||||
extract = [os.path.join(kargs['cwd'], f) for f in extract]
|
||||
if config.AR != 'lib':
|
||||
extract = [Obj(f) for f in extract]
|
||||
if not lib in extracted:
|
||||
extracted[lib] = []
|
||||
extracted[lib].extend(extract)
|
||||
self.touch(extract)
|
||||
subprocess.call = call
|
||||
|
||||
def check_output(args, **kargs):
|
||||
# The command called is always AR
|
||||
ar = config.AR
|
||||
self.assertEqual(args[0:3], [ar, '-NOLOGO', '-LIST'])
|
||||
# Remaining argument is always one library
|
||||
self.assertRelEqual([os.path.splitext(arg)[1] for arg in args[3:]],
|
||||
[config.LIB_SUFFIX])
|
||||
# Simulate LIB -NOLOGO -LIST
|
||||
lib = os.path.splitext(os.path.basename(args[3]))[0]
|
||||
return '%s\n%s\n' % (Obj(lib), Obj(lib + '2'))
|
||||
subprocess.check_output = check_output
|
||||
|
||||
# ExpandArgsMore does the same as ExpandArgs
|
||||
self.touch([self.tmpfile('liby', Lib('y'))])
|
||||
for iteration in (1, 2):
|
||||
with ExpandArgsMore(['foo', '-bar'] + self.arg_files + [self.tmpfile('liby', Lib('y'))]) as args:
|
||||
files = self.files + self.liby_files + self.libx_files
|
||||
|
||||
self.assertRelEqual(args, ['foo', '-bar'] + files)
|
||||
|
||||
extracted = {}
|
||||
# ExpandArgsMore also has an extra method extracting static libraries
|
||||
# when possible
|
||||
args.extract()
|
||||
|
||||
# With AR_EXTRACT, it uses the descriptors when there are, and
|
||||
# actually
|
||||
# extracts the remaining libraries
|
||||
extracted_args = []
|
||||
for f in files:
|
||||
if f.endswith(config.LIB_SUFFIX):
|
||||
base = os.path.splitext(os.path.basename(f))[0]
|
||||
# On the first iteration, we test the behavior of
|
||||
# extracting archives that don't have a copy of their
|
||||
# contents next to them, which is to use the file
|
||||
# extracted from the archive in a temporary directory.
|
||||
# On the second iteration, we test extracting archives
|
||||
# that do have a copy of their contents next to them,
|
||||
# in which case those contents are used instead of the
|
||||
# temporarily extracted files.
|
||||
if iteration == 1:
|
||||
extracted_args.extend(sorted(extracted[base]))
|
||||
else:
|
||||
dirname = os.path.dirname(f[len(self.tmpdir)+1:])
|
||||
if base.endswith('f'):
|
||||
dirname = os.path.join(dirname, 'foo', 'bar')
|
||||
extracted_args.extend([self.tmpfile(dirname, Obj(base)), self.tmpfile(dirname, Obj(base + '2'))])
|
||||
else:
|
||||
extracted_args.append(f)
|
||||
self.assertRelEqual(args, ['foo', '-bar'] + extracted_args)
|
||||
|
||||
tmp = args.tmp
|
||||
# Check that all temporary files are properly removed
|
||||
self.assertEqual(True, all([not os.path.exists(f) for f in tmp]))
|
||||
|
||||
# Create archives contents next to them for the second iteration.
|
||||
base = os.path.splitext(Lib('_'))[0]
|
||||
self.touch(self.tmpfile(Obj(base.replace('_', suffix))) for suffix in ('a', 'a2', 'd', 'd2'))
|
||||
try:
|
||||
os.makedirs(self.tmpfile('foo', 'bar'))
|
||||
except:
|
||||
pass
|
||||
self.touch(self.tmpfile('foo', 'bar', Obj(base.replace('_', suffix))) for suffix in ('f', 'f2'))
|
||||
self.touch(self.tmpfile('liby', Obj(base.replace('_', suffix))) for suffix in ('z', 'z2'))
|
||||
|
||||
# Restore subprocess.call and subprocess.check_output
|
||||
subprocess.call = subprocess_call
|
||||
subprocess.check_output = subprocess_check_output
|
||||
|
||||
class FakeProcess(object):
|
||||
def __init__(self, out, err = ''):
|
||||
self.out = out
|
||||
self.err = err
|
||||
|
||||
def communicate(self):
|
||||
return (self.out, self.err)
|
||||
|
||||
OBJDUMPS = {
|
||||
'foo.o': '''
|
||||
00000000 g F .text\t00000001 foo
|
||||
00000000 g F .text._Z6foobarv\t00000001 _Z6foobarv
|
||||
00000000 g F .text.hello\t00000001 hello
|
||||
00000000 g F .text._ZThn4_6foobarv\t00000001 _ZThn4_6foobarv
|
||||
''',
|
||||
'bar.o': '''
|
||||
00000000 g F .text.hi\t00000001 hi
|
||||
00000000 g F .text.hot._Z6barbazv\t00000001 .hidden _Z6barbazv
|
||||
''',
|
||||
}
|
||||
|
||||
PRINT_ICF = '''
|
||||
ld: ICF folding section '.text.hello' in file 'foo.o'into '.text.hi' in file 'bar.o'
|
||||
ld: ICF folding section '.foo' in file 'foo.o'into '.foo' in file 'bar.o'
|
||||
'''
|
||||
|
||||
class SubprocessPopen(object):
|
||||
def __init__(self, test):
|
||||
self.test = test
|
||||
|
||||
def __call__(self, args, stdout = None, stderr = None):
|
||||
self.test.assertEqual(stdout, subprocess.PIPE)
|
||||
self.test.assertEqual(stderr, subprocess.PIPE)
|
||||
if args[0] == 'objdump':
|
||||
self.test.assertEqual(args[1], '-t')
|
||||
self.test.assertTrue(args[2] in OBJDUMPS)
|
||||
return FakeProcess(OBJDUMPS[args[2]])
|
||||
else:
|
||||
return FakeProcess('', PRINT_ICF)
|
||||
|
||||
class TestSectionFinder(unittest.TestCase):
|
||||
def test_getSections(self):
|
||||
'''Test SectionFinder'''
|
||||
# Divert subprocess.Popen
|
||||
subprocess_popen = subprocess.Popen
|
||||
subprocess.Popen = SubprocessPopen(self)
|
||||
config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
|
||||
config.OBJ_SUFFIX = '.o'
|
||||
config.LIB_SUFFIX = '.a'
|
||||
finder = SectionFinder(['foo.o', 'bar.o'])
|
||||
self.assertEqual(finder.getSections('foobar'), [])
|
||||
self.assertEqual(finder.getSections('_Z6barbazv'), ['.text.hot._Z6barbazv'])
|
||||
self.assertEqual(finder.getSections('_Z6foobarv'), ['.text._Z6foobarv', '.text._ZThn4_6foobarv'])
|
||||
self.assertEqual(finder.getSections('_ZThn4_6foobarv'), ['.text._Z6foobarv', '.text._ZThn4_6foobarv'])
|
||||
subprocess.Popen = subprocess_popen
|
||||
|
||||
class TestSymbolOrder(unittest.TestCase):
|
||||
def test_getOrderedSections(self):
|
||||
'''Test ExpandMoreArgs' _getOrderedSections'''
|
||||
# Divert subprocess.Popen
|
||||
subprocess_popen = subprocess.Popen
|
||||
subprocess.Popen = SubprocessPopen(self)
|
||||
config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
|
||||
config.OBJ_SUFFIX = '.o'
|
||||
config.LIB_SUFFIX = '.a'
|
||||
config.LD_PRINT_ICF_SECTIONS = ''
|
||||
args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
|
||||
self.assertEqual(args._getOrderedSections(['_Z6foobarv', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hot._Z6barbazv'])
|
||||
self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hot._Z6barbazv'])
|
||||
subprocess.Popen = subprocess_popen
|
||||
|
||||
def test_getFoldedSections(self):
|
||||
'''Test ExpandMoreArgs' _getFoldedSections'''
|
||||
# Divert subprocess.Popen
|
||||
subprocess_popen = subprocess.Popen
|
||||
subprocess.Popen = SubprocessPopen(self)
|
||||
config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
|
||||
args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
|
||||
self.assertEqual(args._getFoldedSections(), {'.text.hello': ['.text.hi'], '.text.hi': ['.text.hello']})
|
||||
subprocess.Popen = subprocess_popen
|
||||
|
||||
def test_getOrderedSectionsWithICF(self):
|
||||
'''Test ExpandMoreArgs' _getOrderedSections, with ICF'''
|
||||
# Divert subprocess.Popen
|
||||
subprocess_popen = subprocess.Popen
|
||||
subprocess.Popen = SubprocessPopen(self)
|
||||
config.EXPAND_LIBS_ORDER_STYLE = 'linkerscript'
|
||||
config.OBJ_SUFFIX = '.o'
|
||||
config.LIB_SUFFIX = '.a'
|
||||
config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
|
||||
args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
|
||||
self.assertEqual(args._getOrderedSections(['hello', '_Z6barbazv']), ['.text.hello', '.text.hi', '.text.hot._Z6barbazv'])
|
||||
self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', 'hi', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
|
||||
subprocess.Popen = subprocess_popen
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
||||
86
config/tests/unit-mozunit.py
Normal file
86
config/tests/unit-mozunit.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# 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 sys
|
||||
import os
|
||||
from mozunit import main, MockedOpen
|
||||
import unittest
|
||||
from tempfile import mkstemp
|
||||
|
||||
class TestMozUnit(unittest.TestCase):
|
||||
def test_mocked_open(self):
|
||||
# Create a temporary file on the file system.
|
||||
(fd, path) = mkstemp()
|
||||
with os.fdopen(fd, 'w') as file:
|
||||
file.write('foobar');
|
||||
|
||||
self.assertFalse(os.path.exists('file1'))
|
||||
self.assertFalse(os.path.exists('file2'))
|
||||
|
||||
with MockedOpen({'file1': 'content1',
|
||||
'file2': 'content2'}):
|
||||
self.assertTrue(os.path.exists('file1'))
|
||||
self.assertTrue(os.path.exists('file2'))
|
||||
self.assertFalse(os.path.exists('foo/file1'))
|
||||
|
||||
# Check the contents of the files given at MockedOpen creation.
|
||||
self.assertEqual(open('file1', 'r').read(), 'content1')
|
||||
self.assertEqual(open('file2', 'r').read(), 'content2')
|
||||
|
||||
# Check that overwriting these files alters their content.
|
||||
with open('file1', 'w') as file:
|
||||
file.write('foo')
|
||||
self.assertTrue(os.path.exists('file1'))
|
||||
self.assertEqual(open('file1', 'r').read(), 'foo')
|
||||
|
||||
# ... but not until the file is closed.
|
||||
file = open('file2', 'w')
|
||||
file.write('bar')
|
||||
self.assertEqual(open('file2', 'r').read(), 'content2')
|
||||
file.close()
|
||||
self.assertEqual(open('file2', 'r').read(), 'bar')
|
||||
|
||||
# Check that appending to a file does append
|
||||
with open('file1', 'a') as file:
|
||||
file.write('bar')
|
||||
self.assertEqual(open('file1', 'r').read(), 'foobar')
|
||||
|
||||
self.assertFalse(os.path.exists('file3'))
|
||||
|
||||
# Opening a non-existing file ought to fail.
|
||||
self.assertRaises(IOError, open, 'file3', 'r')
|
||||
self.assertFalse(os.path.exists('file3'))
|
||||
|
||||
# Check that writing a new file does create the file.
|
||||
with open('file3', 'w') as file:
|
||||
file.write('baz')
|
||||
self.assertEqual(open('file3', 'r').read(), 'baz')
|
||||
self.assertTrue(os.path.exists('file3'))
|
||||
|
||||
# Check the content of the file created outside MockedOpen.
|
||||
self.assertEqual(open(path, 'r').read(), 'foobar')
|
||||
|
||||
# Check that overwriting a file existing on the file system
|
||||
# does modify its content.
|
||||
with open(path, 'w') as file:
|
||||
file.write('bazqux')
|
||||
self.assertEqual(open(path, 'r').read(), 'bazqux')
|
||||
|
||||
with MockedOpen():
|
||||
# Check that appending to a file existing on the file system
|
||||
# does modify its content.
|
||||
with open(path, 'a') as file:
|
||||
file.write('bazqux')
|
||||
self.assertEqual(open(path, 'r').read(), 'foobarbazqux')
|
||||
|
||||
# Check that the file was not actually modified on the file system.
|
||||
self.assertEqual(open(path, 'r').read(), 'foobar')
|
||||
os.remove(path)
|
||||
|
||||
# Check that the file created inside MockedOpen wasn't actually
|
||||
# created.
|
||||
self.assertRaises(IOError, open, 'file3', 'r')
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
174
config/tests/unit-nsinstall.py
Normal file
174
config/tests/unit-nsinstall.py
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
import unittest
|
||||
|
||||
import os, sys, os.path, time
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
import mozunit
|
||||
from mozprocess import processhandler
|
||||
|
||||
from nsinstall import nsinstall
|
||||
import nsinstall as nsinstall_module
|
||||
NSINSTALL_PATH = nsinstall_module.__file__
|
||||
|
||||
# Run the non-ASCII tests on (a) Windows, or (b) any platform with
|
||||
# sys.stdin.encoding set to UTF-8
|
||||
import codecs
|
||||
RUN_NON_ASCII_TESTS = (sys.platform == "win32" or
|
||||
(sys.stdin.encoding is not None and
|
||||
codecs.lookup(sys.stdin.encoding) == codecs.lookup("utf-8")))
|
||||
|
||||
class TestNsinstall(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for nsinstall.py
|
||||
"""
|
||||
def setUp(self):
|
||||
self.tmpdir = mkdtemp()
|
||||
|
||||
def tearDown(self):
|
||||
# Unicode strings means non-ASCII children can be deleted properly on
|
||||
# Windows
|
||||
if sys.stdin.encoding is None:
|
||||
tmpdir = unicode(self.tmpdir)
|
||||
else:
|
||||
tmpdir = unicode(self.tmpdir, sys.stdin.encoding)
|
||||
rmtree(tmpdir)
|
||||
|
||||
# utility methods for tests
|
||||
def touch(self, file, dir=None):
|
||||
if dir is None:
|
||||
dir = self.tmpdir
|
||||
f = os.path.join(dir, file)
|
||||
open(f, 'w').close()
|
||||
return f
|
||||
|
||||
def mkdirs(self, dir):
|
||||
d = os.path.join(self.tmpdir, dir)
|
||||
os.makedirs(d)
|
||||
return d
|
||||
|
||||
def test_nsinstall_D(self):
|
||||
"Test nsinstall -D <dir>"
|
||||
testdir = os.path.join(self.tmpdir, "test")
|
||||
self.assertEqual(nsinstall(["-D", testdir]), 0)
|
||||
self.assert_(os.path.isdir(testdir))
|
||||
|
||||
def test_nsinstall_basic(self):
|
||||
"Test nsinstall <file> <dir>"
|
||||
testfile = self.touch("testfile")
|
||||
testdir = self.mkdirs("testdir")
|
||||
self.assertEqual(nsinstall([testfile, testdir]), 0)
|
||||
self.assert_(os.path.isfile(os.path.join(testdir, "testfile")))
|
||||
|
||||
def test_nsinstall_basic_recursive(self):
|
||||
"Test nsinstall <dir> <dest dir>"
|
||||
sourcedir = self.mkdirs("sourcedir")
|
||||
self.touch("testfile", sourcedir)
|
||||
Xfile = self.touch("Xfile", sourcedir)
|
||||
copieddir = self.mkdirs("sourcedir/copieddir")
|
||||
self.touch("testfile2", copieddir)
|
||||
Xdir = self.mkdirs("sourcedir/Xdir")
|
||||
self.touch("testfile3", Xdir)
|
||||
|
||||
destdir = self.mkdirs("destdir")
|
||||
|
||||
self.assertEqual(nsinstall([sourcedir, destdir,
|
||||
'-X', Xfile,
|
||||
'-X', Xdir]), 0)
|
||||
|
||||
testdir = os.path.join(destdir, "sourcedir")
|
||||
self.assert_(os.path.isdir(testdir))
|
||||
self.assert_(os.path.isfile(os.path.join(testdir, "testfile")))
|
||||
self.assert_(not os.path.exists(os.path.join(testdir, "Xfile")))
|
||||
self.assert_(os.path.isdir(os.path.join(testdir, "copieddir")))
|
||||
self.assert_(os.path.isfile(os.path.join(testdir, "copieddir", "testfile2")))
|
||||
self.assert_(not os.path.exists(os.path.join(testdir, "Xdir")))
|
||||
|
||||
def test_nsinstall_multiple(self):
|
||||
"Test nsinstall <three files> <dest dir>"
|
||||
testfiles = [self.touch("testfile1"),
|
||||
self.touch("testfile2"),
|
||||
self.touch("testfile3")]
|
||||
testdir = self.mkdirs("testdir")
|
||||
self.assertEqual(nsinstall(testfiles + [testdir]), 0)
|
||||
for f in testfiles:
|
||||
self.assert_(os.path.isfile(os.path.join(testdir,
|
||||
os.path.basename(f))))
|
||||
|
||||
def test_nsinstall_dir_exists(self):
|
||||
"Test nsinstall <dir> <dest dir>, where <dest dir>/<dir> already exists"
|
||||
srcdir = self.mkdirs("test")
|
||||
destdir = self.mkdirs("testdir/test")
|
||||
self.assertEqual(nsinstall([srcdir, os.path.dirname(destdir)]), 0)
|
||||
self.assert_(os.path.isdir(destdir))
|
||||
|
||||
def test_nsinstall_t(self):
|
||||
"Test that nsinstall -t works (preserve timestamp)"
|
||||
testfile = self.touch("testfile")
|
||||
testdir = self.mkdirs("testdir")
|
||||
# set mtime to now - 30 seconds
|
||||
t = int(time.time()) - 30
|
||||
os.utime(testfile, (t, t))
|
||||
self.assertEqual(nsinstall(["-t", testfile, testdir]), 0)
|
||||
destfile = os.path.join(testdir, "testfile")
|
||||
self.assert_(os.path.isfile(destfile))
|
||||
self.assertEqual(os.stat(testfile).st_mtime,
|
||||
os.stat(destfile).st_mtime)
|
||||
|
||||
if sys.platform != "win32":
|
||||
# can't run this test on windows, don't have real file modes there
|
||||
def test_nsinstall_m(self):
|
||||
"Test that nsinstall -m works (set mode)"
|
||||
testfile = self.touch("testfile")
|
||||
mode = 0o600
|
||||
os.chmod(testfile, mode)
|
||||
testdir = self.mkdirs("testdir")
|
||||
self.assertEqual(nsinstall(["-m", "{0:04o}"
|
||||
.format(mode), testfile, testdir]), 0)
|
||||
destfile = os.path.join(testdir, "testfile")
|
||||
self.assert_(os.path.isfile(destfile))
|
||||
self.assertEqual(os.stat(testfile).st_mode,
|
||||
os.stat(destfile).st_mode)
|
||||
|
||||
def test_nsinstall_d(self):
|
||||
"Test that nsinstall -d works (create directories in target)"
|
||||
# -d makes no sense to me, but ok!
|
||||
testfile = self.touch("testfile")
|
||||
testdir = self.mkdirs("testdir")
|
||||
destdir = os.path.join(testdir, "subdir")
|
||||
self.assertEqual(nsinstall(["-d", testfile, destdir]), 0)
|
||||
self.assert_(os.path.isdir(os.path.join(destdir, "testfile")))
|
||||
|
||||
if RUN_NON_ASCII_TESTS:
|
||||
def test_nsinstall_non_ascii(self):
|
||||
"Test that nsinstall handles non-ASCII files"
|
||||
filename = u"\u2325\u3452\u2415\u5081"
|
||||
testfile = self.touch(filename)
|
||||
testdir = self.mkdirs(u"\u4241\u1D04\u1414")
|
||||
self.assertEqual(nsinstall([testfile.encode("utf-8"),
|
||||
testdir.encode("utf-8")]), 0)
|
||||
|
||||
destfile = os.path.join(testdir, filename)
|
||||
self.assert_(os.path.isfile(destfile))
|
||||
|
||||
def test_nsinstall_non_ascii_subprocess(self):
|
||||
"Test that nsinstall as a subprocess handles non-ASCII files"
|
||||
filename = u"\u2325\u3452\u2415\u5081"
|
||||
testfile = self.touch(filename)
|
||||
testdir = self.mkdirs(u"\u4241\u1D04\u1414")
|
||||
# We don't use subprocess because it can't handle Unicode on
|
||||
# Windows <http://bugs.python.org/issue1759845>. mozprocess calls
|
||||
# CreateProcessW directly so it's perfect.
|
||||
p = processhandler.ProcessHandlerMixin([sys.executable,
|
||||
NSINSTALL_PATH,
|
||||
testfile, testdir])
|
||||
p.run()
|
||||
rv = p.waitForFinish()
|
||||
|
||||
self.assertEqual(rv, 0)
|
||||
destfile = os.path.join(testdir, filename)
|
||||
self.assert_(os.path.isfile(destfile))
|
||||
|
||||
#TODO: implement -R, -l, -L and test them!
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
||||
80
config/tests/unit-printprereleasesuffix.py
Normal file
80
config/tests/unit-printprereleasesuffix.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import unittest
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
import mozunit
|
||||
|
||||
from printprereleasesuffix import get_prerelease_suffix
|
||||
|
||||
class TestGetPreReleaseSuffix(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for the get_prerelease_suffix function
|
||||
"""
|
||||
|
||||
def test_alpha_1(self):
|
||||
"""test 1a1 version string"""
|
||||
self.c = get_prerelease_suffix('1a1')
|
||||
self.assertEqual(self.c, ' 1 Alpha 1')
|
||||
|
||||
def test_alpha_10(self):
|
||||
"""test 1.2a10 version string"""
|
||||
self.c = get_prerelease_suffix('1.2a10')
|
||||
self.assertEqual(self.c, ' 1.2 Alpha 10')
|
||||
|
||||
def test_beta_3(self):
|
||||
"""test 1.2.3b3 version string"""
|
||||
self.c = get_prerelease_suffix('1.2.3b3')
|
||||
self.assertEqual(self.c, ' 1.2.3 Beta 3')
|
||||
|
||||
def test_beta_30(self):
|
||||
"""test 1.2.3.4b30 version string"""
|
||||
self.c = get_prerelease_suffix('1.2.3.4b30')
|
||||
self.assertEqual(self.c, ' 1.2.3.4 Beta 30')
|
||||
|
||||
def test_release_1(self):
|
||||
"""test 1.2.3.4 version string"""
|
||||
self.c = get_prerelease_suffix('1.2.3.4')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_alpha_1_pre(self):
|
||||
"""test 1.2a1pre version string"""
|
||||
self.c = get_prerelease_suffix('1.2a1pre')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_beta_10_pre(self):
|
||||
"""test 3.4b10pre version string"""
|
||||
self.c = get_prerelease_suffix('3.4b10pre')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_pre_0(self):
|
||||
"""test 1.2pre0 version string"""
|
||||
self.c = get_prerelease_suffix('1.2pre0')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_pre_1_b(self):
|
||||
"""test 1.2pre1b version string"""
|
||||
self.c = get_prerelease_suffix('1.2pre1b')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_a_a(self):
|
||||
"""test 1.2aa version string"""
|
||||
self.c = get_prerelease_suffix('1.2aa')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_b_b(self):
|
||||
"""test 1.2bb version string"""
|
||||
self.c = get_prerelease_suffix('1.2bb')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_a_b(self):
|
||||
"""test 1.2ab version string"""
|
||||
self.c = get_prerelease_suffix('1.2ab')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
def test_plus(self):
|
||||
"""test 1.2+ version string """
|
||||
self.c = get_prerelease_suffix('1.2+')
|
||||
self.assertEqual(self.c, '')
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
||||
201
config/tests/unitMozZipFile.py
Normal file
201
config/tests/unitMozZipFile.py
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
# 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 unittest
|
||||
|
||||
import shutil
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import random
|
||||
import copy
|
||||
from string import letters
|
||||
|
||||
'''
|
||||
Test case infrastructure for MozZipFile.
|
||||
|
||||
This isn't really a unit test, but a test case generator and runner.
|
||||
For a given set of files, lengths, and number of writes, we create
|
||||
a testcase for every combination of the three. There are some
|
||||
symmetries used to reduce the number of test cases, the first file
|
||||
written is always the first file, the second is either the first or
|
||||
the second, the third is one of the first three. That is, if we
|
||||
had 4 files, but only three writes, the fourth file would never even
|
||||
get tried.
|
||||
|
||||
The content written to the jars is pseudorandom with a fixed seed.
|
||||
'''
|
||||
|
||||
if not __file__:
|
||||
__file__ = sys.argv[0]
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from MozZipFile import ZipFile
|
||||
import zipfile
|
||||
|
||||
leafs = (
|
||||
'firstdir/oneleaf',
|
||||
'seconddir/twoleaf',
|
||||
'thirddir/with/sub/threeleaf')
|
||||
_lengths = map(lambda n: n * 64, [16, 64, 80])
|
||||
lengths = 3
|
||||
writes = 5
|
||||
|
||||
def givenlength(i):
|
||||
'''Return a length given in the _lengths array to allow manual
|
||||
tuning of which lengths of zip entries to use.
|
||||
'''
|
||||
return _lengths[i]
|
||||
|
||||
|
||||
def prod(*iterables):
|
||||
''''Tensor product of a list of iterables.
|
||||
|
||||
This generator returns lists of items, one of each given
|
||||
iterable. It iterates over all possible combinations.
|
||||
'''
|
||||
for item in iterables[0]:
|
||||
if len(iterables) == 1:
|
||||
yield [item]
|
||||
else:
|
||||
for others in prod(*iterables[1:]):
|
||||
yield [item] + others
|
||||
|
||||
|
||||
def getid(descs):
|
||||
'Convert a list of ints to a string.'
|
||||
return reduce(lambda x,y: x+'{0}{1}'.format(*tuple(y)), descs,'')
|
||||
|
||||
|
||||
def getContent(length):
|
||||
'Get pseudo random content of given length.'
|
||||
rv = [None] * length
|
||||
for i in xrange(length):
|
||||
rv[i] = random.choice(letters)
|
||||
return ''.join(rv)
|
||||
|
||||
|
||||
def createWriter(sizer, *items):
|
||||
'Helper method to fill in tests, one set of writes, one for each item'
|
||||
locitems = copy.deepcopy(items)
|
||||
for item in locitems:
|
||||
item['length'] = sizer(item.pop('length', 0))
|
||||
def helper(self):
|
||||
mode = 'w'
|
||||
if os.path.isfile(self.f):
|
||||
mode = 'a'
|
||||
zf = ZipFile(self.f, mode, self.compression)
|
||||
for item in locitems:
|
||||
self._write(zf, **item)
|
||||
zf = None
|
||||
pass
|
||||
return helper
|
||||
|
||||
def createTester(name, *writes):
|
||||
'''Helper method to fill in tests, calls into a list of write
|
||||
helper methods.
|
||||
'''
|
||||
_writes = copy.copy(writes)
|
||||
def tester(self):
|
||||
for w in _writes:
|
||||
getattr(self, w)()
|
||||
self._verifyZip()
|
||||
pass
|
||||
# unit tests get confused if the method name isn't test...
|
||||
tester.__name__ = name
|
||||
return tester
|
||||
|
||||
class TestExtensiveStored(unittest.TestCase):
|
||||
'''Unit tests for MozZipFile
|
||||
|
||||
The testcase are actually populated by code following the class
|
||||
definition.
|
||||
'''
|
||||
|
||||
stage = "mozzipfilestage"
|
||||
compression = zipfile.ZIP_STORED
|
||||
|
||||
def leaf(self, *leafs):
|
||||
return os.path.join(self.stage, *leafs)
|
||||
def setUp(self):
|
||||
if os.path.exists(self.stage):
|
||||
shutil.rmtree(self.stage)
|
||||
os.mkdir(self.stage)
|
||||
self.f = self.leaf('test.jar')
|
||||
self.ref = {}
|
||||
self.seed = 0
|
||||
|
||||
def tearDown(self):
|
||||
self.f = None
|
||||
self.ref = None
|
||||
|
||||
def _verifyZip(self):
|
||||
zf = zipfile.ZipFile(self.f)
|
||||
badEntry = zf.testzip()
|
||||
self.failIf(badEntry, badEntry)
|
||||
zlist = zf.namelist()
|
||||
zlist.sort()
|
||||
vlist = self.ref.keys()
|
||||
vlist.sort()
|
||||
self.assertEqual(zlist, vlist)
|
||||
for leaf, content in self.ref.iteritems():
|
||||
zcontent = zf.read(leaf)
|
||||
self.assertEqual(content, zcontent)
|
||||
|
||||
def _write(self, zf, seed=None, leaf=0, length=0):
|
||||
if seed is None:
|
||||
seed = self.seed
|
||||
self.seed += 1
|
||||
random.seed(seed)
|
||||
leaf = leafs[leaf]
|
||||
content = getContent(length)
|
||||
self.ref[leaf] = content
|
||||
zf.writestr(leaf, content)
|
||||
dir = os.path.dirname(self.leaf('stage', leaf))
|
||||
if not os.path.isdir(dir):
|
||||
os.makedirs(dir)
|
||||
open(self.leaf('stage', leaf), 'w').write(content)
|
||||
|
||||
# all leafs in all lengths
|
||||
atomics = list(prod(xrange(len(leafs)), xrange(lengths)))
|
||||
|
||||
# populate TestExtensiveStore with testcases
|
||||
for w in xrange(writes):
|
||||
# Don't iterate over all files for the the first n passes,
|
||||
# those are redundant as long as w < lengths.
|
||||
# There are symmetries in the trailing end, too, but I don't know
|
||||
# how to reduce those out right now.
|
||||
nonatomics = [list(prod(range(min(i,len(leafs))), xrange(lengths)))
|
||||
for i in xrange(1, w+1)] + [atomics]
|
||||
for descs in prod(*nonatomics):
|
||||
suffix = getid(descs)
|
||||
dicts = [dict(leaf=leaf, length=length) for leaf, length in descs]
|
||||
setattr(TestExtensiveStored, '_write' + suffix,
|
||||
createWriter(givenlength, *dicts))
|
||||
setattr(TestExtensiveStored, 'test' + suffix,
|
||||
createTester('test' + suffix, '_write' + suffix))
|
||||
|
||||
# now create another round of tests, with two writing passes
|
||||
# first, write all file combinations into the jar, close it,
|
||||
# and then write all atomics again.
|
||||
# This should catch more or less all artifacts generated
|
||||
# by the final ordering step when closing the jar.
|
||||
files = [list(prod([i], xrange(lengths))) for i in xrange(len(leafs))]
|
||||
allfiles = reduce(lambda l,r:l+r,
|
||||
[list(prod(*files[:(i+1)])) for i in xrange(len(leafs))])
|
||||
|
||||
for first in allfiles:
|
||||
testbasename = 'test{0}_'.format(getid(first))
|
||||
test = [None, '_write' + getid(first), None]
|
||||
for second in atomics:
|
||||
test[0] = testbasename + getid([second])
|
||||
test[2] = '_write' + getid([second])
|
||||
setattr(TestExtensiveStored, test[0], createTester(*test))
|
||||
|
||||
class TestExtensiveDeflated(TestExtensiveStored):
|
||||
'Test all that has been tested with ZIP_STORED with DEFLATED, too.'
|
||||
compression = zipfile.ZIP_DEFLATED
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue