Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

google-apputils

Package Overview
Dependencies
Maintainers
3
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

google-apputils - npm Package Compare versions

Comparing version
0.4.1
to
0.4.2
+251
ez_setup.py
#!/usr/bin/env python
"""Bootstrap setuptools installation
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
from ez_setup import use_setuptools
use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import sys
DEFAULT_VERSION = "0.6c11"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
}
import sys, os
try: from hashlib import md5
except ImportError: from md5 import md5
def _validate_md5(egg_name, data):
if egg_name in md5_data:
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print >>sys.stderr, (
"md5 validation of %s failed! (Possible download problem?)"
% egg_name
)
sys.exit(2)
return data
def use_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
download_delay=15
):
"""Automatically find/download setuptools and make it available on sys.path
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end with
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
it is not already available. If `download_delay` is specified, it should
be the number of seconds that will be paused before initiating a download,
should one be required. If an older version of setuptools is installed,
this routine will print a message to ``sys.stderr`` and raise SystemExit in
an attempt to abort the calling script.
"""
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
def do_download():
egg = download_setuptools(version, download_base, to_dir, download_delay)
sys.path.insert(0, egg)
import setuptools; setuptools.bootstrap_install_from = egg
try:
import pkg_resources
except ImportError:
return do_download()
try:
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
if was_imported:
print >>sys.stderr, (
"The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'."
"\n\n(Currently using %r)"
) % (version, e.args[0])
sys.exit(2)
except pkg_resources.DistributionNotFound:
pass
del pkg_resources, sys.modules['pkg_resources'] # reload ok
return do_download()
def download_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
delay = 15
):
"""Download setuptools from a specified location and return its filename
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end
with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download attempt.
"""
import urllib2, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name)
src = dst = None
if not os.path.exists(saveto): # Avoid repeated downloads
try:
from distutils import log
if delay:
log.warn("""
---------------------------------------------------------------------------
This script requires setuptools version %s to run (even to display
help). I will attempt to download it for you (from
%s), but
you may need to enable firewall access for this script first.
I will start the download in %d seconds.
(Note: if this machine does not have network access, please obtain the file
%s
and place it in this directory before rerunning this script.)
---------------------------------------------------------------------------""",
version, download_base, delay, url
); from time import sleep; sleep(delay)
log.warn("Downloading %s", url)
src = urllib2.urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = _validate_md5(egg_name, src.read())
dst = open(saveto,"wb"); dst.write(data)
finally:
if src: src.close()
if dst: dst.close()
return os.path.realpath(saveto)
def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
try:
import setuptools
except ImportError:
egg = None
try:
egg = download_setuptools(version, delay=0)
sys.path.insert(0,egg)
from setuptools.command.easy_install import main
return main(list(argv)+[egg]) # we're done here
finally:
if egg and os.path.exists(egg):
os.unlink(egg)
else:
if setuptools.__version__ == '0.0.1':
print >>sys.stderr, (
"You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script."
)
sys.exit(2)
req = "setuptools>="+version
import pkg_resources
try:
pkg_resources.require(req)
except pkg_resources.VersionConflict:
try:
from setuptools.command.easy_install import main
except ImportError:
from easy_install import main
main(list(argv)+[download_setuptools(delay=0)])
sys.exit(0) # try to force an exit
else:
if argv:
from setuptools.command.easy_install import main
main(argv)
else:
print "Setuptools version",version,"or greater has been installed."
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
def update_md5(filenames):
"""Update our built-in md5 registry"""
import re
for name in filenames:
base = os.path.basename(name)
f = open(name,'rb')
md5_data[base] = md5(f.read()).hexdigest()
f.close()
data = [" %r: %r,\n" % it for it in md5_data.items()]
data.sort()
repl = "".join(data)
import inspect
srcfile = inspect.getsourcefile(sys.modules[__name__])
f = open(srcfile, 'rb'); src = f.read(); f.close()
match = re.search("\nmd5_data = {\n([^}]+)}", src)
if not match:
print >>sys.stderr, "Internal error!"
sys.exit(2)
src = src[:match.start(1)] + repl + src[match.end(1):]
f = open(srcfile,'w')
f.write(src)
f.close()
if __name__=='__main__':
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
update_md5(sys.argv[2:])
else:
main(sys.argv[1:])
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
include *.py
include LICENSE
include README
recursive-include google *.py
#!/usr/bin/env python
#!/usr/bin/env python
#
# Copyright 2005 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Helper script used by app_unittest.sh"""
import sys
import gflags as flags
from google.apputils import app
FLAGS = flags.FLAGS
flags.DEFINE_boolean("raise_exception", False, "throw MyException from main")
class MyException(Exception):
pass
def main(args):
if FLAGS.raise_exception:
raise MyException
if __name__ == '__main__':
app.run()
#!/usr/bin/env python
# Copyright 2008 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for app.py ."""
import os
import shutil
import socket
import sys
import mox
from google.apputils import basetest
from google.apputils import app
import gflags as flags
FLAGS = flags.FLAGS
class TestFunctions(basetest.TestCase):
def testInstallExceptionHandler(self):
self.assertRaises(TypeError, app.InstallExceptionHandler, 1)
if __name__ == '__main__':
basetest.main()
#! /bin/bash
# Copyright 2003 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Douglas Greiman
PYTHON=$(which python)
function die {
echo "$1"
exit 1
}
APP_PACKAGE="google.apputils"
# This should exit with error code because no main defined
$PYTHON -c "from ${APP_PACKAGE} import app; app.run()" 2>/dev/null && \
die "Test 1 failed"
# Standard use. This should exit successfully
$PYTHON -c "from ${APP_PACKAGE} import app
a = 0
def main(argv):
global a
a = 1
app.run()
assert a == 1" || \
die "Test 2 failed"
# app.run called in exec block, script read from -c string. Should succeed.
$PYTHON -c "from ${APP_PACKAGE} import app
a = 0
s='''
def main(argv):
global a
a = 1
app.run()
'''
exec s
assert a == 1" || \
die "Test 4 failed"
# app.run called in exec block, script read from file. Should succeed.
PYFILE=$TEST_TMPDIR/tmp.py
cat >$PYFILE <<EOF
from ${APP_PACKAGE} import app
a = 0
s='''
def main(argv):
global a
a = 1
app.run()
'''
exec s
assert a == 1
EOF
$PYTHON $PYFILE || \
die "Test 5 failed"
rm -f $PYFILE
# Test for usage from --help
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
pass
app.run()
" --help | grep 'USAGE:' >/dev/null || \
die "Test 11 failed"
# Test that the usage() function works
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
app.usage()
app.run()
" 2>&1 | egrep '^ --' >/dev/null || \
die "Test 12 failed"
# Test that shorthelp doesn't give flags in this case.
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
app.usage(shorthelp=1)
app.run()
" 2>&1 | grep '^ --' >/dev/null && \
die "Test 13 failed"
# Test writeto_stdout.
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
app.usage(shorthelp=1, writeto_stdout=1)
app.run()
" | grep 'USAGE' >/dev/null || \
die "Test 14 failed"
# Test detailed_error
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
app.usage(shorthelp=1, writeto_stdout=1, detailed_error='BAZBAZ')
app.run()
" 2>&1 | grep 'BAZBAZ' >/dev/null || \
die "Test 15 failed"
# Test exitcode
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
app.usage(writeto_stdout=1, exitcode=1)
app.run()
" >/dev/null
if [ "$?" -ne "1" ]; then
die "Test 16 failed"
fi
# Test --help (this could use wrapping which is tested elsewhere)
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
print 'FAIL'
app.run()
" 2>&1 --help | grep 'USAGE: -c \[flags\]' >/dev/null || \
die "Test 17 failed"
# Test --help does not wrap for __main__.__doc__
$PYTHON -c "from ${APP_PACKAGE} import app
import sys
def main(argv):
print 'FAIL'
doc = []
for i in xrange(10):
doc.append(str(i))
doc.append('12345678 ')
sys.modules['__main__'].__doc__ = ''.join(doc)
app.run()
" 2>&1 --help | grep '712345678 812345678' >/dev/null || \
die "Test 18 failed"
# Test --help with forced wrap for __main__.__doc__
$PYTHON -c "from ${APP_PACKAGE} import app
import sys
def main(argv):
print 'FAIL'
doc = []
for i in xrange(10):
doc.append(str(i))
doc.append('12345678 ')
sys.modules['__main__'].__doc__ = ''.join(doc)
app.SetEnableHelpWrapping()
app.run()
" 2>&1 --help | grep '712345678 812345678' >/dev/null && \
die "Test 19 failed"
# Test UsageError
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
raise app.UsageError('You made a usage error')
app.run()
" 2>&1 | grep "You made a usage error" >/dev/null || \
die "Test 20 failed"
# Test UsageError exit code
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
raise app.UsageError('You made a usage error', exitcode=64)
app.run()
" > /dev/null 2>&1
if [ "$?" -ne "64" ]; then
die "Test 21 failed"
fi
# Test catching top-level exceptions. We should get the exception name on
# stderr.
./app_test_helper.py \
--raise_exception 2>&1 | grep -q 'MyException' || die "Test 23 failed"
# Test exception handlers are called
have_handler_output=$TEST_TMPDIR/handler.txt
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
raise ValueError('look for me')
class TestExceptionHandler(app.ExceptionHandler):
def __init__(self, msg):
self.msg = msg
def Handle(self, exc):
print '%s %s' % (self.msg, exc)
app.InstallExceptionHandler(TestExceptionHandler('first'))
app.InstallExceptionHandler(TestExceptionHandler('second'))
app.run()
" > $have_handler_output 2>&1
grep -q "first look for me" $have_handler_output || die "Test 24 failed"
grep -q "second look for me" $have_handler_output || die "Test 25 failed"
no_handler_output=$TEST_TMPDIR/no_handler.txt
# Test exception handlers are not called for "normal" exits
for exc in "SystemExit(1)" "app.UsageError('foo')"; do
$PYTHON -c "from ${APP_PACKAGE} import app
def main(argv):
raise $exc
class TestExceptionHandler(app.ExceptionHandler):
def Handle(self, exc):
print 'handler was called'
app.InstallExceptionHandler(TestExceptionHandler())
app.run()
" > $no_handler_output 2>&1
grep -q "handler was called" $no_handler_output && die "Test 26 ($exc) failed"
done
# Test --help expands docstring.
$PYTHON -c "
'''USAGE: %s [flags]'''
from ${APP_PACKAGE} import app
def main(argv): print 'FAIL'
app.run()
" --help 2>&1 |
fgrep 'USAGE: -c [flags]' >/dev/null ||
die "Test 27 failed"
# Test --help expands docstring.
$PYTHON -c "
'''USAGE: %s --fmt=\"%%s\" --fraction=50%%'''
from ${APP_PACKAGE} import app
def main(argv): print 'FAIL'
app.run()
" --help 2>&1 |
fgrep 'USAGE: -c --fmt="%s" --fraction=50%' >/dev/null ||
die "Test 28 failed"
# Test --help expands docstring.
$PYTHON -c "
'''>%s|%%s|%%%s|%%%%s|%%%%%s<'''
from ${APP_PACKAGE} import app
def main(argv): print 'FAIL'
app.run()
" --help 2>&1 |
fgrep '>-c|%s|%-c|%%s|%%-c<' >/dev/null ||
die "Test 29 failed"
# Test bad docstring.
$PYTHON -c "
'''>%@<'''
from ${APP_PACKAGE} import app
def main(argv): print 'FAIL'
app.run()
" --help 2>&1 |
fgrep '>%@<' >/dev/null ||
die "Test 30 failed"
readonly HELP_PROG="
from ${APP_PACKAGE} import app
def main(argv): print 'HI'
app.run()
"
echo "PASS"
#!/usr/bin/env python
# Copyright 2007 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Test tool to demonstrate appcommands.py usage.
This tool shows how to use appcommands.py.
"""
from google.apputils import appcommands
import gflags as flags
FLAGS = flags.FLAGS
flags.DEFINE_string('hint', '', 'Global hint to show in commands')
# Name taken from app.py
class Test1(appcommands.Cmd):
"""Help for test1. As described by a docstring."""
def __init__(self, name, flag_values, **kargs):
"""Init and register flags specific to command."""
super(Test1, self).__init__(name, flag_values, **kargs)
# Flag --fail1 is specific to this command
flags.DEFINE_boolean('fail1', False, 'Make test1 fail',
flag_values=flag_values)
flags.DEFINE_string('foo', '', 'Param foo', flag_values=flag_values)
flags.DEFINE_string('bar', '', 'Param bar', flag_values=flag_values)
flags.DEFINE_integer('intfoo', 0, 'Integer foo', flag_values=flag_values)
flags.DEFINE_boolean('allhelp', False, 'Get _all_commands_help string',
flag_values=flag_values)
def Run(self, unused_argv):
"""Output 'Command1' and flag info.
Args:
unused_argv: Remaining arguments after parsing flags and command
Returns:
Value of flag fail1
"""
print 'Command1'
if FLAGS.hint:
print "Hint1:'%s'" % FLAGS.hint
print "Foo1:'%s'" % FLAGS.foo
print "Bar1:'%s'" % FLAGS.bar
if FLAGS.allhelp:
print "AllHelp:'%s'" % self._all_commands_help
return FLAGS.fail1 * 1
class Test2(appcommands.Cmd):
"""Help for test2."""
def __init__(self, name, flag_values, **kargs):
"""Init and register flags specific to command."""
super(Test2, self).__init__(name, flag_values, **kargs)
flags.DEFINE_boolean('fail2', False, 'Make test2 fail',
flag_values=flag_values)
flags.DEFINE_string('foo', '', 'Param foo', flag_values=flag_values)
flags.DEFINE_string('bar', '', 'Param bar', flag_values=flag_values)
def Run(self, unused_argv):
"""Output 'Command2' and flag info.
Args:
unused_argv: Remaining arguments after parsing flags and command
Returns:
Value of flag fail2
"""
print 'Command2'
if FLAGS.hint:
print "Hint2:'%s'" % FLAGS.hint
print "Foo2:'%s'" % FLAGS.foo
print "Bar2:'%s'" % FLAGS.bar
return FLAGS.fail2 * 1
def Test3(unused_argv):
"""Help for test3."""
print 'Command3'
def Test4(unused_argv):
"""Help for test4."""
print 'Command4'
def main(unused_argv):
"""Register the commands."""
appcommands.AddCmd('test1', Test1,
command_aliases=['testalias1', 'testalias2'])
appcommands.AddCmd('test1b', Test1,
command_aliases=['testalias1b', 'testalias2b'],
all_commands_help='test1b short help', help_full="""test1b
is my very favorite test
because it has verbose help messages""")
appcommands.AddCmd('test2', Test2)
appcommands.AddCmdFunc('test3', Test3)
appcommands.AddCmdFunc('test4', Test4, command_aliases=['testalias3'],
all_commands_help='replacetest4help')
if __name__ == '__main__':
appcommands.Run()
#! /bin/bash
# Copyright 2007 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: mboerger@google.com
PYTHON=$(which python)
function die {
echo "$1"
exit 1
}
IMPORTS="from google.apputils import app
from google.apputils import appcommands
import gflags as flags"
# This should exit with error code because no main defined
$PYTHON -c "${IMPORTS}
appcommands.Run()" >/dev/null 2>&1 && \
die "Test 1 failed"
# Standard use. This should exit successfully
$PYTHON -c "${IMPORTS}
import sys
def test(argv):
return 0
def main(argv):
appcommands.AddCmdFunc('test', test)
appcommands.Run()
sys.exit(1)" test || \
die "Test 2 failed"
# Even with no return from Cmds Run() does not return
$PYTHON -c "${IMPORTS}
import sys
def test(argv):
return
def main(argv):
appcommands.AddCmdFunc('test', test)
appcommands.Run()
sys.exit(1)" test || \
die "Test 3 failed"
# Standard use with returning an error code.
$PYTHON -c "${IMPORTS}
import sys
def test(argv):
return 1
def main(argv):
appcommands.AddCmdFunc('test', test)
appcommands.Run()
sys.exit(0)" test && \
die "Test 4 failed"
# Executing two commands in single mode does not work (execute only first)
$PYTHON -c "${IMPORTS}
def test1(argv):
return 0
def test2(argv):
return 1
def main(argv):
appcommands.AddCmdFunc('test1', test1)
appcommands.AddCmdFunc('test2', test2)
appcommands.Run()" test1 test2 || \
die "Test 5 failed"
# Registering a command twice does not work.
$PYTHON -c "${IMPORTS}
def test1(argv):
return 0
def main(argv):
appcommands.AddCmdFunc('test', test1)
appcommands.AddCmdFunc('test', test1)
appcommands.Run()" test >/dev/null 2>&1 && \
die "Test 6 failed"
# Executing help, returns non zero return code (1), then check result
RES=`$PYTHON -c "${IMPORTS}
def test1(argv):
'''Help1'''
return 0
def test2(argv):
'''Help2'''
return 0
def main(argv):
appcommands.AddCmdFunc('test1', test1)
appcommands.AddCmdFunc('test2', test2)
appcommands.Run()" help` && die "Test 7 failed"
echo "${RES}" | grep -q "USAGE: " || die "Test 8 failed"
echo "${RES}" | sed -ne '/following commands:/,/.*/p' | \
grep -q "help, test1, test2" || die "Test 9 failed"
echo "${RES}" | grep -q -E "(^| )test1[ \t]+Help1($| )" || die "Test 10 failed"
echo "${RES}" | grep -q -E "(^| )test2[ \t]+Help2($| )" || die "Test 11 failed"
# Executing help for command, returns non zero return code (1), then check result
RES=`$PYTHON -c "${IMPORTS}
def test1(argv):
'''Help1'''
return 0
def test2(argv):
'''Help2'''
return 0
def main(argv):
appcommands.AddCmdFunc('test1', test1)
appcommands.AddCmdFunc('test2', test2)
appcommands.Run()" help test2` && die "Test 12 failed"
echo "${RES}" | grep -q "USAGE: " || die "Test 13 failed"
echo "${RES}" | grep -q -E "(^| )Any of the following commands:" && die "Test 14 failed"
echo "${RES}" | grep -q -E "(^| )test1[ \t]+" && die "Test 15 failed"
echo "${RES}" | grep -q -E "(^| )test2[ \t]+Help2($| )" || die "Test 16 failed"
# Returning False succeeds
$PYTHON -c "${IMPORTS}
def test(argv): return False
def main(argv):
appcommands.AddCmdFunc('test', test)
appcommands.Run()" test || die "Test 17 failed"
# Returning True fails
$PYTHON -c "${IMPORTS}
def test(argv): return True
def main(argv):
appcommands.AddCmdFunc('test', test)
appcommands.Run()" test && die "Test 18 failed"
# Registering using AddCmd instead of AddCmdFunc, should be the normal case
$PYTHON -c "${IMPORTS}
class test(appcommands.Cmd):
def Run(self, argv): return 0
def main(argv):
appcommands.AddCmd('test', test)
appcommands.Run()" test || die "Test 19 failed"
# Registering using AddCmd instead of AddCmdFunc, now fail
$PYTHON -c "${IMPORTS}
class test(appcommands.Cmd):
def Run(self, argv): return 1
def main(argv):
appcommands.AddCmd('test', test)
appcommands.Run()" test && die "Test 20 failed"
TEST=./appcommands_example.py
if test -s "${TEST}.py"; then
TEST="${TEST}.py"
elif test ! -s "${TEST}"; then
die "Could not locate ${TEST}"
fi
# Success
$PYTHON $TEST test1 >/dev/null 2>&1 || die "Test 21 failed"
$PYTHON $TEST test1|grep -q 'Command1' 2>&1 || die "Test 22 failed"
$PYTHON $TEST test2|grep -q 'Command2' 2>&1 || die "Test 23 failed"
$PYTHON $TEST test3|grep -q 'Command3' 2>&1 || die "Test 24 failed"
# Success, --nofail1 belongs to test1
$PYTHON $TEST test1 --nofail1 >/dev/null 2>&1 || die "Test 25 failed"
# Failure, --fail1
$PYTHON $TEST test1 --fail1 >/dev/null 2>&1 && die "Test 26 failed"
# Failure, --nofail1 does not belong to test2
$PYTHON $TEST test2 --nofail1 >/dev/null 2>&1 && die "Test 27 failed"
# Failure, --nofail1 must appear after its command
$PYTHON $TEST --nofail1 test1 >/dev/null 2>&1 && die "Test 28 failed"
# Failure, explicit from --fail2
$PYTHON $TEST test2 --fail2 >/dev/null 2>&1 && die "Test 29 failed"
# Success, --hint before command, foo shown with test1
$PYTHON $TEST --hint 'XYZ' test1|grep -q "Hint1:'XYZ'" || die "Test 30 failed"
# Success, --hint before command, foo shown with test1
$PYTHON $TEST test1 --hint 'XYZ'|grep -q "Hint1:'XYZ'" || die "Test 31 failed"
# Success, test1b --allhelp, modified _all_commands_help shown
$PYTHON $TEST test1b --allhelp|grep -q "AllHelp:'test1b short help'" || die "Test 32 failed"
# Failure, test1 --allhelp, modified _all_commands_help not shown
$PYTHON $TEST test1 --allhelp|grep -q "AllHelp:'test1b short help'" && die "Test 33 failed"
# Test for standard --help
$PYTHON $TEST --help|grep -q "following commands:" && die "Test 34 failed"
$PYTHON $TEST help|grep -q "following commands:" || die "Test 35 failed"
# No help after command
$PYTHON $TEST test1 --help|grep -q "following commands:" && die "Test 36 failed"
$PYTHON $TEST test1 --help 'XYZ'|grep -q "Hint1:'XYZ'" && die "Test 37 failed"
# Help specific to command:
$PYTHON $TEST --help test1|grep -q "following commands:" && die "Test 38 failed"
$PYTHON $TEST --help test1|grep -q "test1 *Help for test1" && die "Test 39 failed"
$PYTHON $TEST help test1|grep -q "following commands:" && die "Test 40 failed"
$PYTHON $TEST help test1|grep -q "test1, testalias1, testalias2" || die\
"Test 41 failed"
$PYTHON $TEST help testalias1|grep -q "test1, testalias1, testalias2" || die\
"Test 42 failed"
$PYTHON $TEST help testalias1|grep -q "[-]-foo" || die\
"Test 43 failed"
$PYTHON $TEST help testalias2|grep -q "[-]-foo" || die\
"Test 44 failed"
$PYTHON $TEST help test4|grep -q "^ *Help for test4" || die "Test 45 failed"
$PYTHON $TEST help testalias3|grep -q "^ *Help for test4" || die\
"Test 46 failed"
# Help for cmds with all_command_help.
$PYTHON $TEST help|grep -q "Help for test1. As described by a docstring." || die "Test 47 failed"
$PYTHON $TEST help test1|grep -q "Help for test1. As described by a docstring." || die "Test 48 failed"
$PYTHON $TEST help|grep -q "test1b short help" || die "Test 49 failed"
$PYTHON $TEST help test1b|grep -q "test1b short help" && die "Test 50 failed"
$PYTHON $TEST help|grep -q "is my very favorite test" && die "Test 51 failed"
$PYTHON $TEST help test1b|grep -q "is my very favorite test" || die "Test 52 failed"
$PYTHON $TEST help|grep -q "Help for test4." && die "Test 53 failed"
$PYTHON $TEST help test4|grep -q "Help for test4." || die "Test 54 failed"
$PYTHON $TEST help|grep -q "replacetest4help" || die "Test 55 failed"
$PYTHON $TEST help test4|grep -q "replacetest4help" && die "Test 56 failed"
# Success, --hint before command, foo shown with test1
$PYTHON $TEST --hint 'XYZ' --help|grep -q "following commands:" && die "Test 57 failed"
$PYTHON $TEST --hint 'XYZ' --help|grep -q "XYZ" && die "Test 58 failed"
$PYTHON $TEST --hint 'XYZ' --help|grep -q "This tool shows how" || die "Test 59 failed"
$PYTHON $TEST --hint 'XYZ' help|grep -q "following commands:" || die "Test 60 failed"
$PYTHON $TEST --hint 'XYZ' help|grep -q "XYZ" && die "Test 61 failed"
$PYTHON $TEST --hint 'XYZ' help|grep -q "This tool shows how" || die "Test 62 failed"
# A command name with an letters, numbers, or an underscore is fine
$PYTHON -c "${IMPORTS}
def test(argv):
return 0
def main(argv):
appcommands.AddCmdFunc('test', test)
appcommands.AddCmdFunc('test_foo', test)
appcommands.AddCmdFunc('a123', test)
appcommands.Run()" test || die "Test 63 failed"
# A command name that starts with a non-alphanumeric characters is not ok
$PYTHON -c "${IMPORTS}
def test(argv):
return 0
def main(argv):
appcommands.AddCmdFunc('123', test)
appcommands.Run()" 123 >/dev/null 2>&1 && die "Test 64 failed"
# A command name that contains other characters is not ok
$PYTHON -c "${IMPORTS}
def test(argv):
return 0
def main(argv):
appcommands.AddCmdFunc('test+1', test)
appcommands.Run()" "test+1" >/dev/null 2>&1 && die "Test 65 failed"
# If a command raises app.UsageError, usage is printed.
RES=`$PYTHON -c "${IMPORTS}
def test(argv):
'''Help1'''
raise app.UsageError('Ha-ha')
def main(argv):
appcommands.AddCmdFunc('test', test)
appcommands.Run()" test` && die "Test 66 failed"
echo "${RES}" | grep -q "USAGE: " || die "Test 67 failed"
echo "${RES}" | grep -q -E "(^| )test[ \t]+Help1($| )" || die "Test 68 failed"
echo "${RES}" | grep -q -E "(^| )Ha-ha($| )" || die "Test 69 failed"
$PYTHON -c "${IMPORTS}
class Test(appcommands.Cmd):
def Run(self, argv): return 0
def test(*args, **kwargs):
return Test(*args, **kwargs)
def main(argv):
appcommands.AddCmd('test', test)
appcommands.Run()" test || die "Test 73 failed"
# Success, default command set and correctly run.
RES=`$PYTHON -c "${IMPORTS}
class test(appcommands.Cmd):
def Run(self, argv):
print 'test running correctly'
return 0
def main(argv):
appcommands.AddCmd('test', test)
appcommands.SetDefaultCommand('test')
appcommands.Run()"` || die "Test 74 failed"
echo "${RES}" | grep -q "test running correctly" || die "Test 75 failed"
# Failure, default command set but missing.
$PYTHON -c "${IMPORTS}
class test(appcommands.Cmd):
def Run(self, argv):
print 'test running correctly'
return 0
def main(argv):
appcommands.AddCmd('test', test)
appcommands.SetDefaultCommand('missing')
appcommands.Run()" >/dev/null 2>&1 && die "Test 76 failed"
echo "PASS"
#! /bin/bash
# Copyright 2003 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: Douglas Greiman
# Owner: unittest-team@google.com
EXE=./basetest_test.py
function die {
echo "$1"
exit $2
}
# Create directories for use
function MaybeMkdir {
for dir in $@; do
if [ ! -d "$dir" ] ; then
mkdir "$dir" || die "Unable to create $dir"
fi
done
}
# TODO(dborowitz): Clean these up if we die.
MaybeMkdir abc cba def fed ghi jkl
# Test assertListEqual, assertDictEqual, and assertSameElements
$EXE --testid=5 || die "Test 5 failed" $?
# Test assertAlmostEqual and assertNotAlmostEqual
$EXE --testid=6 || die "Test 6 failed" $?
# Test that tests marked as "expected failure" but which passes
# cause an overall failure.
$EXE --testid=7 && die "Test 7 passed unexpectedly" $?
output=$($EXE --testid=8 -- -v 2>&1) && die "Test 8 passed unexpectedly" $?
printf '%s\n' "$output"
grep '^FAILED (expected failures=1, unexpected successes=1)' <<<"$output" \
&& grep '^testDifferentExpectedFailure .* unexpected success' <<<"$output" \
&& grep '^testExpectedFailure .* expected failure' <<<"$output" \
|| die "Test 8 didn't write expected diagnostic"
# Invoke with no env vars and no flags
(
unset TEST_RANDOM_SEED
unset TEST_SRCDIR
unset TEST_TMPDIR
$EXE --testid=1
) || die "Test 1 failed" $?
# Invoke with env vars but no flags
(
export TEST_RANDOM_SEED=321
export TEST_SRCDIR=cba
export TEST_TMPDIR=fed
$EXE --testid=2
) || die "Test 2 failed" $?
# Invoke with no env vars and all flags
(
unset TEST_RANDOM_SEED
unset TEST_SRCDIR
unset TEST_TMPDIR
$EXE --testid=3 --test_random_seed=123 --test_srcdir=abc --test_tmpdir=def
) || die "Test 3 failed" $?
# Invoke with env vars and all flags
(
export TEST_RANDOM_SEED=321
export TEST_SRCDIR=cba
export TEST_TMPDIR=fed
$EXE --testid=4 --test_random_seed=123 --test_srcdir=abc --test_tmpdir=def
) || die "Test 4 failed" $?
# Cleanup
rm -r abc cba def fed ghi jkl
echo "Pass"
#!/usr/bin/env python
# Copyright 2010 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for base google test functionality."""
__author__ = 'dborowitz@google.com (Dave Borowitz)'
import os
import re
import string
import sys
import unittest
import gflags as flags
from google.apputils import basetest
PY_VERSION_2 = sys.version_info[0] == 2
FLAGS = flags.FLAGS
flags.DEFINE_integer('testid', 0, 'Which test to run')
_OUTPUT_CAPTURING_CASES = [
(basetest.CaptureTestStdout, basetest.DiffTestStdout, sys.stdout),
(basetest.CaptureTestStderr, basetest.DiffTestStderr, sys.stderr),
]
class CaptureTestStdoutStderrTest(basetest.TestCase):
def setUp(self):
self.expected_filepath = os.path.join(FLAGS.test_tmpdir, 'expected_output')
def testStdoutCapturedSuccessfully(self):
for capture_output_fn, diff_output_fn, ostream in _OUTPUT_CAPTURING_CASES:
capture_output_fn()
ostream.write('This gets captured\n')
with open(self.expected_filepath, 'wb') as expected_file:
expected_file.write(b'This gets captured\n')
diff_output_fn(self.expected_filepath) # should do nothing
def testRaisesWhenCapturedStdoutDifferentThanExpected(self):
for capture_output_fn, diff_output_fn, ostream in _OUTPUT_CAPTURING_CASES:
capture_output_fn()
ostream.write('Correct captured.out\n')
with open(self.expected_filepath, 'wb') as expected_file:
expected_file.write(b'Incorrect captured.out\n')
self.assertRaises(basetest.OutputDifferedError,
diff_output_fn, self.expected_filepath)
def testStdoutNoLongerCapturedAfterDiffTest(self):
for capture_output_fn, diff_output_fn, ostream in _OUTPUT_CAPTURING_CASES:
with open(self.expected_filepath, 'wb') as expected_file:
expected_file.write(b'This goes to captured.out\n')
capture_output_fn()
ostream.write('This goes to captured.out\n')
diff_output_fn(self.expected_filepath) # should do nothing
ostream.write('This goes to stdout screen\n')
capture_output_fn()
ostream.write('This goes to captured.out\n')
diff_output_fn(self.expected_filepath) # should do nothing
def testCapturingTestStdoutReturnsContextManager(self):
for capture_output_fn, _, ostream in _OUTPUT_CAPTURING_CASES:
with open(self.expected_filepath, 'wb') as expected_file:
expected_file.write(b'This goes to captured.out\n')
ostream.write('This goes to stdout screen\n')
with capture_output_fn(
expected_output_filepath=self.expected_filepath):
ostream.write('This goes to captured.out\n')
class GoogleTestBaseUnitTest(basetest.TestCase):
def setUp(self):
self._orig_test_diff = os.environ.pop('TEST_DIFF', None)
self.data1_file = os.path.join(FLAGS.test_tmpdir, 'provided_1.dat')
self.data2_file = os.path.join(FLAGS.test_tmpdir, 'provided_2.dat')
def tearDown(self):
if self._orig_test_diff is not None:
os.environ['TEST_DIFF'] = self._orig_test_diff
def test_Diff_SameData(self):
"""Tests for the internal _Diff method."""
basetest._WriteTestData('a\nb\n', self.data1_file)
basetest._WriteTestData('a\nb\n', self.data2_file)
# This must not raise an exception:
basetest._Diff(self.data1_file, self.data2_file)
@unittest.skipIf(not os.path.exists('/usr/bin/diff'),
'requires /usr/bin/diff')
def test_Diff_SameData_ExternalDiff(self):
"""Test the internal _Diff method when TEST_DIFF is in the env."""
os.environ['TEST_DIFF'] = '/usr/bin/diff'
basetest._WriteTestData('b\n', self.data1_file)
basetest._WriteTestData('b\n', self.data2_file)
# This must not raise an exception:
basetest._Diff(self.data1_file, self.data2_file)
@unittest.skipIf(not os.path.exists('/usr/bin/diff'),
'requires /usr/bin/diff')
def test_Diff_MissingFile_ExternalDiff(self):
"""Test the internal _Diff method on TEST_DIFF error."""
os.environ['TEST_DIFF'] = '/usr/bin/diff'
basetest._WriteTestData('a\n', self.data1_file)
if os.path.exists(self.data2_file):
os.unlink(self.data2_file) # Be 100% sure this does not exist.
# This depends on /usr/bin/diff returning an exit code greater than 1
# when an input file is missing. It has had this behavior forever.
with self.assertRaises(basetest.DiffFailureError) as error_context:
basetest._Diff(self.data1_file, self.data2_file)
def test_Diff_MissingExternalDiff(self):
"""Test the internal _Diff when TEST_DIFF program is non-existant."""
os.environ['TEST_DIFF'] = self.data1_file
if os.path.exists(self.data1_file):
os.unlink(self.data1_file) # Be 100% sure this does not exist
with self.assertRaises(basetest.DiffFailureError) as error_context:
basetest._Diff(self.data2_file, self.data2_file)
def test_Diff_Exception(self):
"""Test that _Diff includes the delta in the error msg."""
basetest._WriteTestData(b'01: text A\n02: text B\n03: C', self.data1_file)
basetest._WriteTestData(b'01: text A\n02: zzzzzz\n03: C', self.data2_file)
with self.assertRaises(basetest.OutputDifferedError) as error_context:
basetest._Diff(self.data1_file, self.data2_file)
# Check that both filenames and some semblance of a unified diff
# are present in the exception error message.
diff_error_message = str(error_context.exception)
self.assertIn('provided_1', diff_error_message)
self.assertIn('provided_2', diff_error_message)
self.assertIn('@@', diff_error_message)
self.assertIn('02: text B', diff_error_message)
@unittest.skipIf(not os.path.exists('/usr/bin/diff'),
'requires /usr/bin/diff')
def test_Diff_Exception_ExternalDiff(self):
"""Test that _Diff executes TEST_DIFF when supplied and there are diffs."""
os.environ['TEST_DIFF'] = '/usr/bin/diff'
basetest._WriteTestData(b'01: text A\n02: text B\n03: C', self.data1_file)
basetest._WriteTestData(b'01: text A\n02: zzzzzz\n03: C', self.data2_file)
with self.assertRaises(basetest.OutputDifferedError) as error_context:
basetest._Diff(self.data1_file, self.data2_file)
# Check that both filenames and the TEST_DIFF command
# are present in the exception error message.
diff_error_message = str(error_context.exception)
self.assertIn('/usr/bin/diff', diff_error_message)
self.assertIn('provided_1', diff_error_message)
self.assertIn('provided_2', diff_error_message)
def testDiffTestStrings(self):
basetest.DiffTestStrings('a', 'a')
with self.assertRaises(basetest.OutputDifferedError):
basetest.DiffTestStrings(
'-2: a message\n-2: another message\n',
'-2: a message\n-2: another message \n')
self.assertRaises(basetest.DiffFailureError, basetest.DiffTestStringFile,
'a message', 'txt.a message not existant file here')
self.assertRaises(basetest.OutputDifferedError, basetest.DiffTestStringFile,
'message', os.devnull)
def testFlags(self):
if FLAGS.testid == 1:
self.assertEqual(FLAGS.test_random_seed, 301)
self.assert_(FLAGS.test_tmpdir.startswith('/'))
self.assert_(os.access(FLAGS.test_tmpdir, os.W_OK))
elif FLAGS.testid == 2:
self.assertEqual(FLAGS.test_random_seed, 321)
self.assertEqual(FLAGS.test_srcdir, 'cba')
self.assertEqual(FLAGS.test_tmpdir, 'fed')
elif FLAGS.testid == 3:
self.assertEqual(FLAGS.test_random_seed, 123)
self.assertEqual(FLAGS.test_srcdir, 'abc')
self.assertEqual(FLAGS.test_tmpdir, 'def')
elif FLAGS.testid == 4:
self.assertEqual(FLAGS.test_random_seed, 123)
self.assertEqual(FLAGS.test_srcdir, 'abc')
self.assertEqual(FLAGS.test_tmpdir, 'def')
def testAssertIn(self):
animals = {'monkey': 'banana', 'cow': 'grass', 'seal': 'fish'}
self.assertIn('a', 'abc')
self.assertIn(2, [1, 2, 3])
self.assertIn('monkey', animals)
self.assertNotIn('d', 'abc')
self.assertNotIn(0, [1, 2, 3])
self.assertNotIn('otter', animals)
self.assertRaises(AssertionError, self.assertIn, 'x', 'abc')
self.assertRaises(AssertionError, self.assertIn, 4, [1, 2, 3])
self.assertRaises(AssertionError, self.assertIn, 'elephant', animals)
self.assertRaises(AssertionError, self.assertNotIn, 'c', 'abc')
self.assertRaises(AssertionError, self.assertNotIn, 1, [1, 2, 3])
self.assertRaises(AssertionError, self.assertNotIn, 'cow', animals)
@basetest.unittest.expectedFailure
def testExpectedFailure(self):
if FLAGS.testid == 7:
self.assertEqual(1, 1) # expected failure, got success
else:
self.assertEqual(1, 2) # the expected failure
@basetest.unittest.expectedFailure
def testDifferentExpectedFailure(self):
if FLAGS.testid == 8:
self.assertEqual(1, 1) # expected failure, got success
else:
self.assertEqual(1, 2) # the expected failure
def testAssertEqual(self):
if FLAGS.testid != 5:
return
self.assertListEqual([], [])
self.assertTupleEqual((), ())
self.assertSequenceEqual([], ())
a = [0, 'a', []]
b = []
self.assertRaises(basetest.TestCase.failureException,
self.assertListEqual, a, b)
self.assertRaises(basetest.TestCase.failureException,
self.assertListEqual, tuple(a), tuple(b))
self.assertRaises(basetest.TestCase.failureException,
self.assertSequenceEqual, a, tuple(b))
b.extend(a)
self.assertListEqual(a, b)
self.assertTupleEqual(tuple(a), tuple(b))
self.assertSequenceEqual(a, tuple(b))
self.assertSequenceEqual(tuple(a), b)
self.assertRaises(AssertionError, self.assertListEqual, a, tuple(b))
self.assertRaises(AssertionError, self.assertTupleEqual, tuple(a), b)
self.assertRaises(AssertionError, self.assertListEqual, None, b)
self.assertRaises(AssertionError, self.assertTupleEqual, None, tuple(b))
self.assertRaises(AssertionError, self.assertSequenceEqual, None, tuple(b))
self.assertRaises(AssertionError, self.assertListEqual, 1, 1)
self.assertRaises(AssertionError, self.assertTupleEqual, 1, 1)
self.assertRaises(AssertionError, self.assertSequenceEqual, 1, 1)
self.assertSameElements([1, 2, 3], [3, 2, 1])
self.assertSameElements([1, 2] + [3] * 100, [1] * 100 + [2, 3])
self.assertSameElements(['foo', 'bar', 'baz'], ['bar', 'baz', 'foo'])
self.assertRaises(AssertionError, self.assertSameElements, [10], [10, 11])
self.assertRaises(AssertionError, self.assertSameElements, [10, 11], [10])
# Test that sequences of unhashable objects can be tested for sameness:
self.assertSameElements([[1, 2], [3, 4]], [[3, 4], [1, 2]])
if PY_VERSION_2:
# dict's are no longer valid for < comparison in Python 3 making them
# unsortable (yay, sanity!). But we need to preserve this old behavior
# when running under Python 2.
self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}])
self.assertRaises(AssertionError, self.assertSameElements, [[1]], [[2]])
def testAssertItemsEqualHotfix(self):
"""Confirm that http://bugs.python.org/issue14832 - b/10038517 is gone."""
for assert_items_method in (self.assertItemsEqual, self.assertCountEqual):
with self.assertRaises(self.failureException) as error_context:
assert_items_method([4], [2])
error_message = str(error_context.exception)
# Confirm that the bug is either no longer present in Python or that our
# assertItemsEqual patching version of the method in basetest.TestCase
# doesn't get used.
self.assertIn('First has 1, Second has 0: 4', error_message)
self.assertIn('First has 0, Second has 1: 2', error_message)
def testAssertDictEqual(self):
self.assertDictEqual({}, {})
c = {'x': 1}
d = {}
self.assertRaises(basetest.TestCase.failureException,
self.assertDictEqual, c, d)
d.update(c)
self.assertDictEqual(c, d)
d['x'] = 0
self.assertRaises(basetest.TestCase.failureException,
self.assertDictEqual, c, d, 'These are unequal')
self.assertRaises(AssertionError, self.assertDictEqual, None, d)
self.assertRaises(AssertionError, self.assertDictEqual, [], d)
self.assertRaises(AssertionError, self.assertDictEqual, 1, 1)
try:
# Ensure we use equality as the sole measure of elements, not type, since
# that is consistent with dict equality.
self.assertDictEqual({1: 1.0, 2: 2}, {1: 1, 2: 3})
except AssertionError, e:
self.assertMultiLineEqual('{1: 1.0, 2: 2} != {1: 1, 2: 3}\n'
'repr() of differing entries:\n2: 2 != 3\n',
str(e))
try:
self.assertDictEqual({}, {'x': 1})
except AssertionError, e:
self.assertMultiLineEqual("{} != {'x': 1}\n"
"Unexpected, but present entries:\n'x': 1\n",
str(e))
else:
self.fail('Expecting AssertionError')
try:
self.assertDictEqual({}, {'x': 1}, 'a message')
except AssertionError, e:
self.assertIn('a message', str(e))
else:
self.fail('Expecting AssertionError')
expected = {'a': 1, 'b': 2, 'c': 3}
seen = {'a': 2, 'c': 3, 'd': 4}
try:
self.assertDictEqual(expected, seen)
except AssertionError, e:
self.assertMultiLineEqual("""\
{'a': 1, 'b': 2, 'c': 3} != {'a': 2, 'c': 3, 'd': 4}
Unexpected, but present entries:
'd': 4
repr() of differing entries:
'a': 1 != 2
Missing entries:
'b': 2
""", str(e))
else:
self.fail('Expecting AssertionError')
self.assertRaises(AssertionError, self.assertDictEqual, (1, 2), {})
self.assertRaises(AssertionError, self.assertDictEqual, {}, (1, 2))
# Ensure deterministic output of keys in dictionaries whose sort order
# doesn't match the lexical ordering of repr -- this is most Python objects,
# which are keyed by memory address.
class Obj(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
try:
self.assertDictEqual(
{'a': Obj('A'), Obj('b'): Obj('B'), Obj('c'): Obj('C')},
{'a': Obj('A'), Obj('d'): Obj('D'), Obj('e'): Obj('E')})
except AssertionError, e:
# Do as best we can not to be misleading when objects have the same repr
# but aren't equal.
err_str = str(e)
self.assertStartsWith(err_str,
"{'a': A, b: B, c: C} != {'a': A, d: D, e: E}\n")
self.assertRegexpMatches(err_str,
r'(?ms).*^Unexpected, but present entries:\s+'
r'^(d: D$\s+^e: E|e: E$\s+^d: D)$')
self.assertRegexpMatches(err_str,
r'(?ms).*^repr\(\) of differing entries:\s+'
r'^.a.: A != A$', err_str)
self.assertRegexpMatches(err_str,
r'(?ms).*^Missing entries:\s+'
r'^(b: B$\s+^c: C|c: C$\s+^b: B)$')
else:
self.fail('Expecting AssertionError')
# Confirm that safe_repr, not repr, is being used.
class RaisesOnRepr(object):
def __repr__(self):
return 1/0 # Intentionally broken __repr__ implementation.
try:
self.assertDictEqual(
{RaisesOnRepr(): RaisesOnRepr()},
{RaisesOnRepr(): RaisesOnRepr()}
)
self.fail('Expected dicts not to match')
except AssertionError as e:
# Depending on the testing environment, the object may get a __main__
# prefix or a basetest_test prefix, so strip that for comparison.
error_msg = re.sub(
r'( at 0x[^>]+)|__main__\.|basetest_test\.', '', str(e))
self.assertRegexpMatches(error_msg, """(?m)\
{<.*RaisesOnRepr object.*>: <.*RaisesOnRepr object.*>} != \
{<.*RaisesOnRepr object.*>: <.*RaisesOnRepr object.*>}
Unexpected, but present entries:
<.*RaisesOnRepr object.*>: <.*RaisesOnRepr object.*>
Missing entries:
<.*RaisesOnRepr object.*>: <.*RaisesOnRepr object.*>
""")
# Confirm that safe_repr, not repr, is being used.
class RaisesOnLt(object):
def __lt__(self):
raise TypeError('Object is unordered.')
def __repr__(self):
return '<RaisesOnLt object>'
try:
self.assertDictEqual(
{RaisesOnLt(): RaisesOnLt()},
{RaisesOnLt(): RaisesOnLt()})
except AssertionError as e:
self.assertIn('Unexpected, but present entries:\n<RaisesOnLt', str(e))
self.assertIn('Missing entries:\n<RaisesOnLt', str(e))
def testAssertSetEqual(self):
set1 = set()
set2 = set()
self.assertSetEqual(set1, set2)
self.assertRaises(AssertionError, self.assertSetEqual, None, set2)
self.assertRaises(AssertionError, self.assertSetEqual, [], set2)
self.assertRaises(AssertionError, self.assertSetEqual, set1, None)
self.assertRaises(AssertionError, self.assertSetEqual, set1, [])
set1 = set(['a'])
set2 = set()
self.assertRaises(AssertionError, self.assertSetEqual, set1, set2)
set1 = set(['a'])
set2 = set(['a'])
self.assertSetEqual(set1, set2)
set1 = set(['a'])
set2 = set(['a', 'b'])
self.assertRaises(AssertionError, self.assertSetEqual, set1, set2)
set1 = set(['a'])
set2 = frozenset(['a', 'b'])
self.assertRaises(AssertionError, self.assertSetEqual, set1, set2)
set1 = set(['a', 'b'])
set2 = frozenset(['a', 'b'])
self.assertSetEqual(set1, set2)
set1 = set()
set2 = 'foo'
self.assertRaises(AssertionError, self.assertSetEqual, set1, set2)
self.assertRaises(AssertionError, self.assertSetEqual, set2, set1)
# make sure any string formatting is tuple-safe
set1 = set([(0, 1), (2, 3)])
set2 = set([(4, 5)])
self.assertRaises(AssertionError, self.assertSetEqual, set1, set2)
def testAssertDictContainsSubset(self):
self.assertDictContainsSubset({}, {})
self.assertDictContainsSubset({}, {'a': 1})
self.assertDictContainsSubset({'a': 1}, {'a': 1})
self.assertDictContainsSubset({'a': 1}, {'a': 1, 'b': 2})
self.assertDictContainsSubset({'a': 1, 'b': 2}, {'a': 1, 'b': 2})
self.assertRaises(basetest.TestCase.failureException,
self.assertDictContainsSubset, {'a': 2}, {'a': 1},
'.*Mismatched values:.*')
self.assertRaises(basetest.TestCase.failureException,
self.assertDictContainsSubset, {'c': 1}, {'a': 1},
'.*Missing:.*')
self.assertRaises(basetest.TestCase.failureException,
self.assertDictContainsSubset, {'a': 1, 'c': 1}, {'a': 1},
'.*Missing:.*')
self.assertRaises(basetest.TestCase.failureException,
self.assertDictContainsSubset, {'a': 1, 'c': 1}, {'a': 1},
'.*Missing:.*Mismatched values:.*')
def testAssertContainsSubset(self):
# sets, lists, tuples, dicts all ok. Types of set and subset do not have to
# match.
actual = ('a', 'b', 'c')
self.assertContainsSubset({'a', 'b'}, actual)
self.assertContainsSubset(('b', 'c'), actual)
self.assertContainsSubset({'b': 1, 'c': 2}, list(actual))
self.assertContainsSubset(['c', 'a'], set(actual))
self.assertContainsSubset([], set())
self.assertContainsSubset([], {'a': 1})
self.assertRaises(AssertionError, self.assertContainsSubset, ('d',), actual)
self.assertRaises(AssertionError, self.assertContainsSubset, ['d'],
set(actual))
self.assertRaises(AssertionError, self.assertContainsSubset, {'a': 1}, [])
self.assertRaisesWithRegexpMatch(AssertionError, 'Missing elements',
self.assertContainsSubset, {1, 2, 3},
{1, 2})
self.assertRaisesWithRegexpMatch(
AssertionError, 'Custom message: Missing elements',
self.assertContainsSubset, {1, 2}, {1}, 'Custom message')
def testAssertNoCommonElements(self):
actual = ('a', 'b', 'c')
self.assertNoCommonElements((), actual)
self.assertNoCommonElements(('d', 'e'), actual)
self.assertNoCommonElements({'d', 'e'}, actual)
self.assertRaisesWithRegexpMatch(
AssertionError, 'Custom message: Common elements',
self.assertNoCommonElements, {1, 2}, {1}, 'Custom message')
with self.assertRaises(AssertionError):
self.assertNoCommonElements(['a'], actual)
with self.assertRaises(AssertionError):
self.assertNoCommonElements({'a', 'b', 'c'}, actual)
with self.assertRaises(AssertionError):
self.assertNoCommonElements({'b', 'c'}, set(actual))
def testAssertAlmostEqual(self):
if FLAGS.testid != 6:
return
self.assertAlmostEqual(1.00000001, 1.0)
self.assertNotAlmostEqual(1.0000001, 1.0)
def testAssertAlmostEqualsWithDelta(self):
self.assertAlmostEquals(3.14, 3, delta=0.2)
self.assertAlmostEquals(2.81, 3.14, delta=1)
self.assertAlmostEquals(-1, 1, delta=3)
self.assertRaises(AssertionError, self.assertAlmostEquals,
3.14, 2.81, delta=0.1)
self.assertRaises(AssertionError, self.assertAlmostEquals,
1, 2, delta=0.5)
self.assertNotAlmostEquals(3.14, 2.81, delta=0.1)
def testGetCommandString_listOfStringArgument(self):
expected = "'command' 'arg-0'"
observed = basetest.GetCommandString(['command', 'arg-0'])
self.assertEqual(expected, observed)
def testGetCommandString_listOfUnicodeStringArgument(self):
expected = "'command' 'arg-0'"
observed = basetest.GetCommandString([u'command', u'arg-0'])
self.assertEqual(expected, observed)
def testGetCommandString_stringArgument(self):
expected = 'command arg-0'
observed = basetest.GetCommandString('command arg-0')
self.assertEqual(expected, observed)
def testGetCommandString_unicodeStringArgument(self):
expected = 'command arg-0'
observed = basetest.GetCommandString(u'command arg-0')
self.assertEqual(expected, observed)
def testAssertStartsWith(self):
self.assertStartsWith('foobar', 'foo')
self.assertStartsWith('foobar', 'foobar')
self.assertRaises(AssertionError, self.assertStartsWith, 'foobar', 'bar')
self.assertRaises(AssertionError, self.assertStartsWith, 'foobar', 'blah')
def testAssertNotStartsWith(self):
self.assertNotStartsWith('foobar', 'bar')
self.assertNotStartsWith('foobar', 'blah')
self.assertRaises(AssertionError, self.assertNotStartsWith, 'foobar', 'foo')
self.assertRaises(AssertionError, self.assertNotStartsWith, 'foobar',
'foobar')
def testAssertEndsWith(self):
self.assertEndsWith('foobar', 'bar')
self.assertEndsWith('foobar', 'foobar')
self.assertRaises(AssertionError, self.assertEndsWith, 'foobar', 'foo')
self.assertRaises(AssertionError, self.assertEndsWith, 'foobar', 'blah')
def testAssertNotEndsWith(self):
self.assertNotEndsWith('foobar', 'foo')
self.assertNotEndsWith('foobar', 'blah')
self.assertRaises(AssertionError, self.assertNotEndsWith, 'foobar', 'bar')
self.assertRaises(AssertionError, self.assertNotEndsWith, 'foobar',
'foobar')
def testAssertRegexMatch_matches(self):
self.assertRegexMatch('str', ['str'])
def testAssertRegexMatch_matchesSubstring(self):
self.assertRegexMatch('pre-str-post', ['str'])
def testAssertRegexMatch_multipleRegexMatches(self):
self.assertRegexMatch('str', ['rts', 'str'])
def testAssertRegexMatch_emptyListFails(self):
expected_re = re.compile(r'No regexes specified\.', re.MULTILINE)
self.assertRaisesWithRegexpMatch(
AssertionError,
expected_re,
self.assertRegexMatch,
'str',
regexes=[])
def testAssertRegexMatch_badArguments(self):
self.assertRaisesWithRegexpMatch(
AssertionError,
'regexes is a string;.*',
self.assertRegexMatch, '1.*2', '1 2')
def testAssertRegexMatch_unicodeVsBytes(self):
"""Ensure proper utf-8 encoding or decoding happens automatically."""
self.assertRegexMatch(u'str', [b'str'])
self.assertRegexMatch(b'str', [u'str'])
def testAssertRegexMatch_unicode(self):
self.assertRegexMatch(u'foo str', [u'str'])
def testAssertRegexMatch_bytes(self):
self.assertRegexMatch(b'foo str', [b'str'])
def testAssertRegexMatch_allTheSameType(self):
self.assertRaisesWithRegexpMatch(
AssertionError, 'regexes .* same type',
self.assertRegexMatch, 'foo str', [b'str', u'foo'])
def testAssertCommandFailsStderr(self):
# TODO(user): Gross! These should use sys.executable instead of
# depending on /usr/bin/perl existing.
self.assertCommandFails(
['/usr/bin/perl', '-e', 'die "FAIL";'],
[r'(.|\n)*FAIL at -e line 1\.'])
def testAssertCommandFailsWithListOfString(self):
self.assertCommandFails(['false'], [''])
def testAssertCommandFailsWithListOfUnicodeString(self):
self.assertCommandFails([u'false'], [''])
def testAssertCommandFailsWithUnicodeString(self):
self.assertCommandFails(u'false', [u''])
def testAssertCommandFailsWithUnicodeStringBytesRegex(self):
self.assertCommandFails(u'false', [b''])
def testAssertCommandSucceedsStderr(self):
expected_re = re.compile(r'(.|\n)*FAIL at -e line 1\.', re.MULTILINE)
self.assertRaisesWithRegexpMatch(
AssertionError,
expected_re,
self.assertCommandSucceeds,
['/usr/bin/perl', '-e', 'die "FAIL";'])
def testAssertCommandSucceedsWithMatchingUnicodeRegexes(self):
self.assertCommandSucceeds(['echo', 'SUCCESS'], regexes=[u'SUCCESS'])
def testAssertCommandSucceedsWithMatchingBytesRegexes(self):
self.assertCommandSucceeds(['echo', 'SUCCESS'], regexes=[b'SUCCESS'])
def testAssertCommandSucceedsWithNonMatchingRegexes(self):
expected_re = re.compile(r'Running command', re.MULTILINE)
self.assertRaisesWithRegexpMatch(
AssertionError,
expected_re,
self.assertCommandSucceeds,
['echo', 'FAIL'],
regexes=['SUCCESS'])
def testAssertCommandSucceedsWithListOfString(self):
self.assertCommandSucceeds(['true'])
def testAssertCommandSucceedsWithListOfUnicodeString(self):
self.assertCommandSucceeds([u'true'])
def testAssertCommandSucceedsWithUnicodeString(self):
self.assertCommandSucceeds(u'true')
def testInequality(self):
# Try ints
self.assertGreater(2, 1)
self.assertGreaterEqual(2, 1)
self.assertGreaterEqual(1, 1)
self.assertLess(1, 2)
self.assertLessEqual(1, 2)
self.assertLessEqual(1, 1)
self.assertRaises(AssertionError, self.assertGreater, 1, 2)
self.assertRaises(AssertionError, self.assertGreater, 1, 1)
self.assertRaises(AssertionError, self.assertGreaterEqual, 1, 2)
self.assertRaises(AssertionError, self.assertLess, 2, 1)
self.assertRaises(AssertionError, self.assertLess, 1, 1)
self.assertRaises(AssertionError, self.assertLessEqual, 2, 1)
# Try Floats
self.assertGreater(1.1, 1.0)
self.assertGreaterEqual(1.1, 1.0)
self.assertGreaterEqual(1.0, 1.0)
self.assertLess(1.0, 1.1)
self.assertLessEqual(1.0, 1.1)
self.assertLessEqual(1.0, 1.0)
self.assertRaises(AssertionError, self.assertGreater, 1.0, 1.1)
self.assertRaises(AssertionError, self.assertGreater, 1.0, 1.0)
self.assertRaises(AssertionError, self.assertGreaterEqual, 1.0, 1.1)
self.assertRaises(AssertionError, self.assertLess, 1.1, 1.0)
self.assertRaises(AssertionError, self.assertLess, 1.0, 1.0)
self.assertRaises(AssertionError, self.assertLessEqual, 1.1, 1.0)
# Try Strings
self.assertGreater('bug', 'ant')
self.assertGreaterEqual('bug', 'ant')
self.assertGreaterEqual('ant', 'ant')
self.assertLess('ant', 'bug')
self.assertLessEqual('ant', 'bug')
self.assertLessEqual('ant', 'ant')
self.assertRaises(AssertionError, self.assertGreater, 'ant', 'bug')
self.assertRaises(AssertionError, self.assertGreater, 'ant', 'ant')
self.assertRaises(AssertionError, self.assertGreaterEqual, 'ant', 'bug')
self.assertRaises(AssertionError, self.assertLess, 'bug', 'ant')
self.assertRaises(AssertionError, self.assertLess, 'ant', 'ant')
self.assertRaises(AssertionError, self.assertLessEqual, 'bug', 'ant')
# Try Unicode
self.assertGreater(u'bug', u'ant')
self.assertGreaterEqual(u'bug', u'ant')
self.assertGreaterEqual(u'ant', u'ant')
self.assertLess(u'ant', u'bug')
self.assertLessEqual(u'ant', u'bug')
self.assertLessEqual(u'ant', u'ant')
self.assertRaises(AssertionError, self.assertGreater, u'ant', u'bug')
self.assertRaises(AssertionError, self.assertGreater, u'ant', u'ant')
self.assertRaises(AssertionError, self.assertGreaterEqual, u'ant', u'bug')
self.assertRaises(AssertionError, self.assertLess, u'bug', u'ant')
self.assertRaises(AssertionError, self.assertLess, u'ant', u'ant')
self.assertRaises(AssertionError, self.assertLessEqual, u'bug', u'ant')
# Try Mixed String/Unicode
self.assertGreater('bug', u'ant')
self.assertGreater(u'bug', 'ant')
self.assertGreaterEqual('bug', u'ant')
self.assertGreaterEqual(u'bug', 'ant')
self.assertGreaterEqual('ant', u'ant')
self.assertGreaterEqual(u'ant', 'ant')
self.assertLess('ant', u'bug')
self.assertLess(u'ant', 'bug')
self.assertLessEqual('ant', u'bug')
self.assertLessEqual(u'ant', 'bug')
self.assertLessEqual('ant', u'ant')
self.assertLessEqual(u'ant', 'ant')
self.assertRaises(AssertionError, self.assertGreater, 'ant', u'bug')
self.assertRaises(AssertionError, self.assertGreater, u'ant', 'bug')
self.assertRaises(AssertionError, self.assertGreater, 'ant', u'ant')
self.assertRaises(AssertionError, self.assertGreater, u'ant', 'ant')
self.assertRaises(AssertionError, self.assertGreaterEqual, 'ant', u'bug')
self.assertRaises(AssertionError, self.assertGreaterEqual, u'ant', 'bug')
self.assertRaises(AssertionError, self.assertLess, 'bug', u'ant')
self.assertRaises(AssertionError, self.assertLess, u'bug', 'ant')
self.assertRaises(AssertionError, self.assertLess, 'ant', u'ant')
self.assertRaises(AssertionError, self.assertLess, u'ant', 'ant')
self.assertRaises(AssertionError, self.assertLessEqual, 'bug', u'ant')
self.assertRaises(AssertionError, self.assertLessEqual, u'bug', 'ant')
def testAssertMultiLineEqual(self):
sample_text = """\
http://www.python.org/doc/2.3/lib/module-unittest.html
test case
A test case is the smallest unit of testing. [...]
"""
revised_sample_text = """\
http://www.python.org/doc/2.4.1/lib/module-unittest.html
test case
A test case is the smallest unit of testing. [...] You may provide your
own implementation that does not subclass from TestCase, of course.
"""
sample_text_error = """
- http://www.python.org/doc/2.3/lib/module-unittest.html
? ^
+ http://www.python.org/doc/2.4.1/lib/module-unittest.html
? ^^^
test case
- A test case is the smallest unit of testing. [...]
+ A test case is the smallest unit of testing. [...] You may provide your
? +++++++++++++++++++++
+ own implementation that does not subclass from TestCase, of course.
"""
for type1 in (str, unicode):
for type2 in (str, unicode):
self.assertRaisesWithLiteralMatch(AssertionError, sample_text_error,
self.assertMultiLineEqual,
type1(sample_text),
type2(revised_sample_text))
self.assertRaises(AssertionError, self.assertMultiLineEqual, (1, 2), 'str')
self.assertRaises(AssertionError, self.assertMultiLineEqual, 'str', (1, 2))
def testAssertMultiLineEqualAddsNewlinesIfNeeded(self):
self.assertRaisesWithLiteralMatch(
AssertionError,
'\n'
' line1\n'
'- line2\n'
'? ^\n'
'+ line3\n'
'? ^\n',
self.assertMultiLineEqual,
'line1\n'
'line2',
'line1\n'
'line3')
def testAssertMultiLineEqualShowsMissingNewlines(self):
self.assertRaisesWithLiteralMatch(
AssertionError,
'\n'
' line1\n'
'- line2\n'
'? -\n'
'+ line2\n',
self.assertMultiLineEqual,
'line1\n'
'line2\n',
'line1\n'
'line2')
def testAssertMultiLineEqualShowsExtraNewlines(self):
self.assertRaisesWithLiteralMatch(
AssertionError,
'\n'
' line1\n'
'- line2\n'
'+ line2\n'
'? +\n',
self.assertMultiLineEqual,
'line1\n'
'line2',
'line1\n'
'line2\n')
def testAssertIsNone(self):
self.assertIsNone(None)
self.assertRaises(AssertionError, self.assertIsNone, False)
self.assertIsNotNone('Google')
self.assertRaises(AssertionError, self.assertIsNotNone, None)
self.assertRaises(AssertionError, self.assertIsNone, (1, 2))
def testAssertIs(self):
self.assertIs(object, object)
self.assertRaises(AssertionError, self.assertIsNot, object, object)
self.assertIsNot(True, False)
self.assertRaises(AssertionError, self.assertIs, True, False)
def testAssertBetween(self):
self.assertBetween(3.14, 3.1, 3.141)
self.assertBetween(4, 4, 1e10000)
self.assertBetween(9.5, 9.4, 9.5)
self.assertBetween(-1e10, -1e10000, 0)
self.assertRaises(AssertionError, self.assertBetween, 9.4, 9.3, 9.3999)
self.assertRaises(AssertionError, self.assertBetween, -1e10000, -1e10, 0)
def testAssertRaisesWithPredicateMatch_noRaiseFails(self):
with self.assertRaisesRegexp(AssertionError, '^Exception not raised$'):
self.assertRaisesWithPredicateMatch(Exception,
lambda e: True,
lambda: 1) # don't raise
with self.assertRaisesRegexp(AssertionError, '^Exception not raised$'):
with self.assertRaisesWithPredicateMatch(Exception, lambda e: True):
pass # don't raise
def testAssertRaisesWithPredicateMatch_raisesWrongExceptionFails(self):
def _RaiseValueError():
raise ValueError
with self.assertRaises(ValueError):
self.assertRaisesWithPredicateMatch(IOError,
lambda e: True,
_RaiseValueError)
with self.assertRaises(ValueError):
with self.assertRaisesWithPredicateMatch(IOError, lambda e: True):
raise ValueError
def testAssertRaisesWithPredicateMatch_predicateFails(self):
def _RaiseValueError():
raise ValueError
with self.assertRaisesRegexp(AssertionError, ' does not match predicate '):
self.assertRaisesWithPredicateMatch(ValueError,
lambda e: False,
_RaiseValueError)
with self.assertRaisesRegexp(AssertionError, ' does not match predicate '):
with self.assertRaisesWithPredicateMatch(ValueError, lambda e: False):
raise ValueError
def testAssertRaisesWithPredicateMatch_predicatePasses(self):
def _RaiseValueError():
raise ValueError
self.assertRaisesWithPredicateMatch(ValueError,
lambda e: True,
_RaiseValueError)
with self.assertRaisesWithPredicateMatch(ValueError, lambda e: True):
raise ValueError
def testAssertRaisesWithRegexpMatch(self):
class ExceptionMock(Exception):
pass
def Stub():
raise ExceptionMock('We expect')
self.assertRaisesWithRegexpMatch(ExceptionMock, re.compile('expect$'), Stub)
self.assertRaisesWithRegexpMatch(ExceptionMock, 'expect$', Stub)
self.assertRaisesWithRegexpMatch(ExceptionMock, u'expect$', Stub)
def testAssertNotRaisesWithRegexpMatch(self):
self.assertRaisesWithRegexpMatch(
AssertionError, '^Exception not raised',
self.assertRaisesWithRegexpMatch, Exception, re.compile('x'),
lambda: None)
self.assertRaisesWithRegexpMatch(
AssertionError, '^Exception not raised',
self.assertRaisesWithRegexpMatch, Exception, 'x', lambda: None)
self.assertRaisesWithRegexpMatch(
AssertionError, '^Exception not raised',
self.assertRaisesWithRegexpMatch, Exception, u'x', lambda: None)
def testAssertRaisesWithRegexpMismatch(self):
def Stub():
raise Exception('Unexpected')
self.assertRaisesWithRegexpMatch(
AssertionError, r'"\^Expected\$" does not match "Unexpected"',
self.assertRaisesWithRegexpMatch, Exception, r'^Expected$', Stub)
self.assertRaisesWithRegexpMatch(
AssertionError, r'"\^Expected\$" does not match "Unexpected"',
self.assertRaisesWithRegexpMatch, Exception, r'^Expected$', Stub)
def testAssertContainsInOrder(self):
# Valids
self.assertContainsInOrder(
['fox', 'dog'], 'The quick brown fox jumped over the lazy dog.')
self.assertContainsInOrder(
['quick', 'fox', 'dog'],
'The quick brown fox jumped over the lazy dog.')
self.assertContainsInOrder(
['The', 'fox', 'dog.'], 'The quick brown fox jumped over the lazy dog.')
self.assertContainsInOrder(
['fox'], 'The quick brown fox jumped over the lazy dog.')
self.assertContainsInOrder(
'fox', 'The quick brown fox jumped over the lazy dog.')
self.assertContainsInOrder(
['fox', 'dog'], 'fox dog fox')
self.assertContainsInOrder(
[], 'The quick brown fox jumped over the lazy dog.')
self.assertContainsInOrder(
[], '')
# Invalids
self.assertRaises(
AssertionError, self.assertContainsInOrder,
['dog', 'fox'], 'The quick brown fox jumped over the lazy dog')
self.assertRaises(
AssertionError, self.assertContainsInOrder,
['The', 'dog', 'fox'], 'The quick brown fox jumped over the lazy dog')
self.assertRaises(
AssertionError, self.assertContainsInOrder, ['dog'], '')
def testAssertContainsSubsequenceForNumbers(self):
self.assertContainsSubsequence([1, 2, 3], [1])
self.assertContainsSubsequence([1, 2, 3], [1, 2])
self.assertContainsSubsequence([1, 2, 3], [1, 3])
with self.assertRaises(AssertionError):
self.assertContainsSubsequence([1, 2, 3], [4])
with self.assertRaises(AssertionError):
self.assertContainsSubsequence([1, 2, 3], [3, 1])
def testAssertContainsSubsequenceForStrings(self):
self.assertContainsSubsequence(['foo', 'bar', 'blorp'], ['foo', 'blorp'])
with self.assertRaises(AssertionError):
self.assertContainsSubsequence(
['foo', 'bar', 'blorp'], ['blorp', 'foo'])
def testAssertContainsSubsequenceWithEmptySubsequence(self):
self.assertContainsSubsequence([1, 2, 3], [])
self.assertContainsSubsequence(['foo', 'bar', 'blorp'], [])
self.assertContainsSubsequence([], [])
def testAssertContainsSubsequenceWithEmptyContainer(self):
with self.assertRaises(AssertionError):
self.assertContainsSubsequence([], [1])
with self.assertRaises(AssertionError):
self.assertContainsSubsequence([], ['foo'])
def testAssertTotallyOrdered(self):
# Valid.
self.assertTotallyOrdered()
self.assertTotallyOrdered([1])
self.assertTotallyOrdered([1], [2])
self.assertTotallyOrdered([1, 1, 1])
self.assertTotallyOrdered([(1, 1)], [(1, 2)], [(2, 1)])
if PY_VERSION_2:
# In Python 3 comparing different types of elements is not supported.
self.assertTotallyOrdered([None], [1], [2])
self.assertTotallyOrdered([1, 1, 1], ['a string'])
# From the docstring.
class A(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __hash__(self):
return hash(self.x)
def __repr__(self):
return 'A(%r, %r)' % (self.x, self.y)
def __eq__(self, other):
try:
return self.x == other.x
except AttributeError:
return NotImplemented
def __ne__(self, other):
try:
return self.x != other.x
except AttributeError:
return NotImplemented
def __lt__(self, other):
try:
return self.x < other.x
except AttributeError:
return NotImplemented
def __le__(self, other):
try:
return self.x <= other.x
except AttributeError:
return NotImplemented
def __gt__(self, other):
try:
return self.x > other.x
except AttributeError:
return NotImplemented
def __ge__(self, other):
try:
return self.x >= other.x
except AttributeError:
return NotImplemented
if PY_VERSION_2:
self.assertTotallyOrdered(
[None], # None should come before everything else.
[1], # Integers sort earlier.
[A(1, 'a')],
[A(2, 'b')], # 2 is after 1.
[A(3, 'c'), A(3, 'd')], # The second argument is irrelevant.
[A(4, 'z')],
['foo']) # Strings sort last.
else:
# Python 3 does not define ordering across different types.
self.assertTotallyOrdered(
[A(1, 'a')],
[A(2, 'b')], # 2 is after 1.
[A(3, 'c'), A(3, 'd')], # The second argument is irrelevant.
[A(4, 'z')])
# Invalid.
self.assertRaises(AssertionError, self.assertTotallyOrdered, [2], [1])
self.assertRaises(AssertionError, self.assertTotallyOrdered, [2], [1], [3])
self.assertRaises(AssertionError, self.assertTotallyOrdered, [1, 2])
def testShortDescriptionWithoutDocstring(self):
self.assertEquals(
self.shortDescription(),
('testShortDescriptionWithoutDocstring '
'(%s.GoogleTestBaseUnitTest)' % __name__))
def testShortDescriptionWithOneLineDocstring(self):
"""Tests shortDescription() for a method with a docstring."""
self.assertEquals(
self.shortDescription(),
('testShortDescriptionWithOneLineDocstring '
'(%s.GoogleTestBaseUnitTest)\n'
'Tests shortDescription() for a method with a docstring.' % __name__))
def testShortDescriptionWithMultiLineDocstring(self):
"""Tests shortDescription() for a method with a longer docstring.
This method ensures that only the first line of a docstring is
returned used in the short description, no matter how long the
whole thing is.
"""
self.assertEquals(
self.shortDescription(),
('testShortDescriptionWithMultiLineDocstring '
'(%s.GoogleTestBaseUnitTest)\n'
'Tests shortDescription() for a method with a longer docstring.'
% __name__))
def testRecordedProperties(self):
"""Tests that a test can record a property and then retrieve it."""
self.recordProperty('test_property', 'test_value')
self.assertEquals(self.getRecordedProperties(),
{'test_property': 'test_value'})
def testAssertUrlEqualSame(self):
self.assertUrlEqual('http://a', 'http://a')
self.assertUrlEqual('http://a/path/test', 'http://a/path/test')
self.assertUrlEqual('#fragment', '#fragment')
self.assertUrlEqual('http://a/?q=1', 'http://a/?q=1')
self.assertUrlEqual('http://a/?q=1&v=5', 'http://a/?v=5&q=1')
self.assertUrlEqual('/logs?v=1&a=2&t=labels&f=path%3A%22foo%22',
'/logs?a=2&f=path%3A%22foo%22&v=1&t=labels')
self.assertUrlEqual('http://a/path;p1', 'http://a/path;p1')
self.assertUrlEqual('http://a/path;p2;p3;p1', 'http://a/path;p1;p2;p3')
self.assertUrlEqual('sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15',
'sip:alice@atlanta.com;ttl=15;maddr=239.255.255.1')
self.assertUrlEqual('http://nyan/cat?p=1&b=', 'http://nyan/cat?b=&p=1')
def testAssertUrlEqualDifferent(self):
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a', 'http://b')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a/x', 'http://a:8080/x')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a/x', 'http://a/y')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a/?q=2', 'http://a/?q=1')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a/?q=1&v=5', 'http://a/?v=2&q=1')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a', 'sip://b')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a#g', 'sip://a#f')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://a/path;p1;p3;p1', 'http://a/path;p1;p2;p3')
self.assertRaises(AssertionError, self.assertUrlEqual,
'http://nyan/cat?p=1&b=', 'http://nyan/cat?p=1')
def testSameStructure_same(self):
self.assertSameStructure(0, 0)
self.assertSameStructure(1, 1)
self.assertSameStructure('', '')
self.assertSameStructure('hello', 'hello', msg='This Should not fail')
self.assertSameStructure(set(), set())
self.assertSameStructure(set([1, 2]), set([1, 2]))
self.assertSameStructure([], [])
self.assertSameStructure(['a'], ['a'])
self.assertSameStructure({}, {})
self.assertSameStructure({'one': 1}, {'one': 1})
# int and long should always be treated as the same type.
self.assertSameStructure({3L: 3}, {3: 3L})
def testSameStructure_different(self):
# Different type
self.assertRaisesWithRegexpMatch(
AssertionError,
r"a is a <(type|class) 'int'> but b is a <(type|class) 'str'>",
self.assertSameStructure, 0, 'hello')
self.assertRaisesWithRegexpMatch(
AssertionError,
r"a is a <(type|class) 'int'> but b is a <(type|class) 'list'>",
self.assertSameStructure, 0, [])
self.assertRaisesWithRegexpMatch(
AssertionError,
r"a is a <(type|class) 'int'> but b is a <(type|class) 'float'>",
self.assertSameStructure, 2, 2.0)
# Different scalar values
self.assertRaisesWithLiteralMatch(
AssertionError, 'a is 0 but b is 1',
self.assertSameStructure, 0, 1)
self.assertRaisesWithLiteralMatch(
AssertionError, "a is 'hello' but b is 'goodbye': This was expected",
self.assertSameStructure, 'hello', 'goodbye', msg='This was expected')
# Different sets are treated without structure
self.assertRaisesWithRegexpMatch(
AssertionError, r'AA is (set\(\[1\]\)|\{1\}) but BB is set\((\[\])?\)',
self.assertSameStructure, set([1]), set(), aname='AA', bname='BB')
# Different lists
self.assertRaisesWithLiteralMatch(
AssertionError, 'a has [2] but b does not',
self.assertSameStructure, ['x', 'y', 'z'], ['x', 'y'])
self.assertRaisesWithLiteralMatch(
AssertionError, 'a lacks [2] but b has it',
self.assertSameStructure, ['x', 'y'], ['x', 'y', 'z'])
self.assertRaisesWithLiteralMatch(
AssertionError, "a[2] is 'z' but b[2] is 'Z'",
self.assertSameStructure, ['x', 'y', 'z'], ['x', 'y', 'Z'])
# Different dicts
self.assertRaisesWithLiteralMatch(
AssertionError, "a has ['two'] but b does not",
self.assertSameStructure, {'one': 1, 'two': 2}, {'one': 1})
self.assertRaisesWithLiteralMatch(
AssertionError, "a lacks ['two'] but b has it",
self.assertSameStructure, {'one': 1}, {'one': 1, 'two': 2})
self.assertRaisesWithLiteralMatch(
AssertionError, "a['two'] is 2 but b['two'] is 3",
self.assertSameStructure, {'one': 1, 'two': 2}, {'one': 1, 'two': 3})
# Deep key generation
self.assertRaisesWithLiteralMatch(
AssertionError,
"a[0][0]['x']['y']['z'][0] is 1 but b[0][0]['x']['y']['z'][0] is 2",
self.assertSameStructure,
[[{'x': {'y': {'z': [1]}}}]], [[{'x': {'y': {'z': [2]}}}]])
# Multiple problems
self.assertRaisesWithLiteralMatch(
AssertionError,
'a[0] is 1 but b[0] is 3; a[1] is 2 but b[1] is 4',
self.assertSameStructure, [1, 2], [3, 4])
self.assertRaisesWithRegexpMatch(
AssertionError,
re.compile(r"^a\[0] is 'a' but b\[0] is 'A'; .*"
r"a\[18] is 's' but b\[18] is 'S'; \.\.\.$"),
self.assertSameStructure,
list(string.ascii_lowercase), list(string.ascii_uppercase))
def testAssertJsonEqualSame(self):
self.assertJsonEqual('{"success": true}', '{"success": true}')
self.assertJsonEqual('{"success": true}', '{"success":true}')
self.assertJsonEqual('true', 'true')
self.assertJsonEqual('null', 'null')
self.assertJsonEqual('false', 'false')
self.assertJsonEqual('34', '34')
self.assertJsonEqual('[1, 2, 3]', '[1,2,3]', msg='please PASS')
self.assertJsonEqual('{"sequence": [1, 2, 3], "float": 23.42}',
'{"float": 23.42, "sequence": [1,2,3]}')
self.assertJsonEqual('{"nest": {"spam": "eggs"}, "float": 23.42}',
'{"float": 23.42, "nest": {"spam":"eggs"}}')
def testAssertJsonEqualDifferent(self):
with self.assertRaises(AssertionError):
self.assertJsonEqual('{"success": true}', '{"success": false}')
with self.assertRaises(AssertionError):
self.assertJsonEqual('{"success": false}', '{"Success": false}')
with self.assertRaises(AssertionError):
self.assertJsonEqual('false', 'true')
with self.assertRaises(AssertionError) as error_context:
self.assertJsonEqual('null', '0', msg='I demand FAILURE')
self.assertIn('I demand FAILURE', error_context.exception.args[0])
self.assertIn('None', error_context.exception.args[0])
with self.assertRaises(AssertionError):
self.assertJsonEqual('[1, 0, 3]', '[1,2,3]')
with self.assertRaises(AssertionError):
self.assertJsonEqual('{"sequence": [1, 2, 3], "float": 23.42}',
'{"float": 23.42, "sequence": [1,0,3]}')
with self.assertRaises(AssertionError):
self.assertJsonEqual('{"nest": {"spam": "eggs"}, "float": 23.42}',
'{"float": 23.42, "nest": {"Spam":"beans"}}')
def testAssertJsonEqualBadJson(self):
with self.assertRaises(ValueError) as error_context:
self.assertJsonEqual("alhg'2;#", '{"a": true}')
self.assertIn('first', error_context.exception.args[0])
self.assertIn('alhg', error_context.exception.args[0])
with self.assertRaises(ValueError) as error_context:
self.assertJsonEqual('{"a": true}', "alhg'2;#")
self.assertIn('second', error_context.exception.args[0])
self.assertIn('alhg', error_context.exception.args[0])
with self.assertRaises(ValueError) as error_context:
self.assertJsonEqual('', '')
class GetCommandStderrTestCase(basetest.TestCase):
def setUp(self):
self.original_environ = os.environ.copy()
def tearDown(self):
os.environ = self.original_environ
def testReturnStatus(self):
expected = 255
observed = (
basetest.GetCommandStderr(
['/usr/bin/perl', '-e', 'die "FAIL";'],
None)[0])
self.assertEqual(expected, observed)
# TODO(dborowitz): Tests for more functionality that do not deal with
# PYTHON_RUNFILES.
class EqualityAssertionTest(basetest.TestCase):
"""This test verifies that basetest.failIfEqual actually tests __ne__.
If a user class implements __eq__, unittest.failUnlessEqual will call it
via first == second. However, failIfEqual also calls
first == second. This means that while the caller may believe
their __ne__ method is being tested, it is not.
"""
class NeverEqual(object):
"""Objects of this class behave like NaNs."""
def __eq__(self, unused_other):
return False
def __ne__(self, unused_other):
return False
class AllSame(object):
"""All objects of this class compare as equal."""
def __eq__(self, unused_other):
return True
def __ne__(self, unused_other):
return False
class EqualityTestsWithEq(object):
"""Performs all equality and inequality tests with __eq__."""
def __init__(self, value):
self._value = value
def __eq__(self, other):
return self._value == other._value
def __ne__(self, other):
return not self.__eq__(other)
class EqualityTestsWithNe(object):
"""Performs all equality and inequality tests with __ne__."""
def __init__(self, value):
self._value = value
def __eq__(self, other):
return not self.__ne__(other)
def __ne__(self, other):
return self._value != other._value
class EqualityTestsWithCmp(object):
def __init__(self, value):
self._value = value
def __cmp__(self, other):
return cmp(self._value, other._value)
class EqualityTestsWithLtEq(object):
def __init__(self, value):
self._value = value
def __eq__(self, other):
return self._value == other._value
def __lt__(self, other):
return self._value < other._value
def testAllComparisonsFail(self):
i1 = self.NeverEqual()
i2 = self.NeverEqual()
self.assertFalse(i1 == i2)
self.assertFalse(i1 != i2)
# Compare two distinct objects
self.assertFalse(i1 is i2)
self.assertRaises(AssertionError, self.assertEqual, i1, i2)
self.assertRaises(AssertionError, self.assertEquals, i1, i2)
self.assertRaises(AssertionError, self.failUnlessEqual, i1, i2)
self.assertRaises(AssertionError, self.assertNotEqual, i1, i2)
self.assertRaises(AssertionError, self.assertNotEquals, i1, i2)
self.assertRaises(AssertionError, self.failIfEqual, i1, i2)
# A NeverEqual object should not compare equal to itself either.
i2 = i1
self.assertTrue(i1 is i2)
self.assertFalse(i1 == i2)
self.assertFalse(i1 != i2)
self.assertRaises(AssertionError, self.assertEqual, i1, i2)
self.assertRaises(AssertionError, self.assertEquals, i1, i2)
self.assertRaises(AssertionError, self.failUnlessEqual, i1, i2)
self.assertRaises(AssertionError, self.assertNotEqual, i1, i2)
self.assertRaises(AssertionError, self.assertNotEquals, i1, i2)
self.assertRaises(AssertionError, self.failIfEqual, i1, i2)
def testAllComparisonsSucceed(self):
a = self.AllSame()
b = self.AllSame()
self.assertFalse(a is b)
self.assertTrue(a == b)
self.assertFalse(a != b)
self.assertEqual(a, b)
self.assertEquals(a, b)
self.failUnlessEqual(a, b)
self.assertRaises(AssertionError, self.assertNotEqual, a, b)
self.assertRaises(AssertionError, self.assertNotEquals, a, b)
self.assertRaises(AssertionError, self.failIfEqual, a, b)
def _PerformAppleAppleOrangeChecks(self, same_a, same_b, different):
"""Perform consistency checks with two apples and an orange.
The two apples should always compare as being the same (and inequality
checks should fail). The orange should always compare as being different
to each of the apples.
Args:
same_a: the first apple
same_b: the second apple
different: the orange
"""
self.assertTrue(same_a == same_b)
self.assertFalse(same_a != same_b)
self.assertEqual(same_a, same_b)
self.assertEquals(same_a, same_b)
self.failUnlessEqual(same_a, same_b)
if PY_VERSION_2:
# Python 3 removes the global cmp function
self.assertEqual(0, cmp(same_a, same_b))
self.assertFalse(same_a == different)
self.assertTrue(same_a != different)
self.assertNotEqual(same_a, different)
self.assertNotEquals(same_a, different)
self.failIfEqual(same_a, different)
if PY_VERSION_2:
self.assertNotEqual(0, cmp(same_a, different))
self.assertFalse(same_b == different)
self.assertTrue(same_b != different)
self.assertNotEqual(same_b, different)
self.assertNotEquals(same_b, different)
self.failIfEqual(same_b, different)
if PY_VERSION_2:
self.assertNotEqual(0, cmp(same_b, different))
def testComparisonWithEq(self):
same_a = self.EqualityTestsWithEq(42)
same_b = self.EqualityTestsWithEq(42)
different = self.EqualityTestsWithEq(1769)
self._PerformAppleAppleOrangeChecks(same_a, same_b, different)
def testComparisonWithNe(self):
same_a = self.EqualityTestsWithNe(42)
same_b = self.EqualityTestsWithNe(42)
different = self.EqualityTestsWithNe(1769)
self._PerformAppleAppleOrangeChecks(same_a, same_b, different)
def testComparisonWithCmpOrLtEq(self):
if PY_VERSION_2:
# In Python 3; the __cmp__ method is no longer special.
cmp_or_lteq_class = self.EqualityTestsWithCmp
else:
cmp_or_lteq_class = self.EqualityTestsWithLtEq
same_a = cmp_or_lteq_class(42)
same_b = cmp_or_lteq_class(42)
different = cmp_or_lteq_class(1769)
self._PerformAppleAppleOrangeChecks(same_a, same_b, different)
class AssertSequenceStartsWithTest(basetest.TestCase):
def setUp(self):
self.a = [5, 'foo', {'c': 'd'}, None]
def testEmptySequenceStartsWithEmptyPrefix(self):
self.assertSequenceStartsWith([], ())
def testSequencePrefixIsAnEmptyList(self):
self.assertSequenceStartsWith([[]], ([], 'foo'))
def testRaiseIfEmptyPrefixWithNonEmptyWhole(self):
self.assertRaisesWithRegexpMatch(
AssertionError,
'Prefix length is 0 but whole length is %d: %s' % (
len(self.a), '\[5, \'foo\', \{\'c\': \'d\'\}, None\]'),
self.assertSequenceStartsWith, [], self.a)
def testSingleElementPrefix(self):
self.assertSequenceStartsWith([5], self.a)
def testTwoElementPrefix(self):
self.assertSequenceStartsWith((5, 'foo'), self.a)
def testPrefixIsFullSequence(self):
self.assertSequenceStartsWith([5, 'foo', {'c': 'd'}, None], self.a)
def testStringPrefix(self):
self.assertSequenceStartsWith('abc', 'abc123')
def testConvertNonSequencePrefixToSequenceAndTryAgain(self):
self.assertSequenceStartsWith(5, self.a)
def testWholeNotASequence(self):
msg = ('For whole: len\(5\) is not supported, it appears to be type: '
'<(type|class) \'int\'>')
self.assertRaisesWithRegexpMatch(AssertionError, msg,
self.assertSequenceStartsWith, self.a, 5)
def testRaiseIfSequenceDoesNotStartWithPrefix(self):
msg = ('prefix: \[\'foo\', \{\'c\': \'d\'\}\] not found at start of whole: '
'\[5, \'foo\', \{\'c\': \'d\'\}, None\].')
self.assertRaisesWithRegexpMatch(
AssertionError, msg, self.assertSequenceStartsWith, ['foo', {'c': 'd'}],
self.a)
def testRaiseIfTypesArNotSupported(self):
self.assertRaisesWithRegexpMatch(
TypeError, 'unhashable type', self.assertSequenceStartsWith,
{'a': 1, 2: 'b'}, {'a': 1, 2: 'b', 'c': '3'})
class InitNotNecessaryForAssertsTest(basetest.TestCase):
"""TestCase assertions should work even if __init__ wasn't correctly called.
This is a hack, see comment in
basetest.TestCase._getAssertEqualityFunc. We know that not calling
__init__ of a superclass is a bad thing, but people keep doing them,
and this (even if a little bit dirty) saves them from shooting
themselves in the foot.
"""
def testSubclass(self):
class Subclass(basetest.TestCase):
def __init__(self): # pylint: disable=super-init-not-called
pass
Subclass().assertEquals({}, {})
def testMultipleInheritance(self):
class Foo(object):
def __init__(self, *args, **kwargs):
pass
class Subclass(Foo, basetest.TestCase):
pass
Subclass().assertEquals({}, {})
if __name__ == '__main__':
basetest.main()

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

#!/usr/bin/env python
# Copyright 2002 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unittest for datelib.py module."""
import datetime
import random
import time
import pytz
from google.apputils import basetest
from google.apputils import datelib
class TimestampUnitTest(basetest.TestCase):
seed = 1979
def testTzAwareSuccession(self):
a = datelib.Timestamp.now()
b = datelib.Timestamp.utcnow()
self.assertLessEqual(a, b)
def testTzRandomConversion(self):
random.seed(self.seed)
for unused_i in xrange(100):
stz = pytz.timezone(random.choice(pytz.all_timezones))
a = datelib.Timestamp.FromString('2008-04-12T10:00:00', stz)
b = a
for unused_j in xrange(100):
b = b.astimezone(pytz.timezone(random.choice(pytz.all_timezones)))
self.assertEqual(a, b)
random.seed()
def testMicroTimestampConversion(self):
"""Test that f1(f2(a)) == a."""
def IsEq(x):
self.assertEqual(
x, datelib.Timestamp.FromMicroTimestamp(x).AsMicroTimestamp())
IsEq(0)
IsEq(datelib.MAXIMUM_MICROSECOND_TIMESTAMP)
random.seed(self.seed)
for _ in xrange(100):
IsEq(random.randint(0, datelib.MAXIMUM_MICROSECOND_TIMESTAMP))
def testMicroTimestampKnown(self):
self.assertEqual(0, datelib.Timestamp.FromString(
'1970-01-01T00:00:00', pytz.UTC).AsMicroTimestamp())
self.assertEqual(
datelib.MAXIMUM_MICROSECOND_TIMESTAMP,
datelib.MAXIMUM_MICROSECOND_TIMESTAMP_AS_TS.AsMicroTimestamp())
def testMicroTimestampOrdering(self):
"""Test that cmp(a, b) == cmp(f1(a), f1(b))."""
def IsEq(a, b):
self.assertEqual(
cmp(a, b),
cmp(datelib.Timestamp.FromMicroTimestamp(a),
datelib.Timestamp.FromMicroTimestamp(b)))
random.seed(self.seed)
for unused_i in xrange(100):
IsEq(
random.randint(0, datelib.MAXIMUM_MICROSECOND_TIMESTAMP),
random.randint(0, datelib.MAXIMUM_MICROSECOND_TIMESTAMP))
def testCombine(self):
for tz in (datelib.UTC, datelib.US_PACIFIC):
self.assertEqual(
tz.localize(datelib.Timestamp(1970, 1, 1, 0, 0, 0, 0)),
datelib.Timestamp.combine(
datelib.datetime.date(1970, 1, 1),
datelib.datetime.time(0, 0, 0),
tz))
self.assertEqual(
tz.localize(datelib.Timestamp(9998, 12, 31, 23, 59, 59, 999999)),
datelib.Timestamp.combine(
datelib.datetime.date(9998, 12, 31),
datelib.datetime.time(23, 59, 59, 999999),
tz))
def testStrpTime(self):
time_str = '20130829 23:43:19.206'
time_fmt = '%Y%m%d %H:%M:%S.%f'
expected = datelib.Timestamp(2013, 8, 29, 23, 43, 19, 206000)
for tz in (datelib.UTC, datelib.US_PACIFIC):
if tz == datelib.LocalTimezone:
actual = datelib.Timestamp.strptime(time_str, time_fmt)
else:
actual = datelib.Timestamp.strptime(time_str, time_fmt, tz)
self.assertEqual(tz.localize(expected), actual)
def testFromString1(self):
for string_zero in (
'1970-01-01 00:00:00',
'19700101T000000',
'1970-01-01T00:00:00'
):
for testtz in (datelib.UTC, datelib.US_PACIFIC):
self.assertEqual(
datelib.Timestamp.FromString(string_zero, testtz),
testtz.localize(datelib.Timestamp(1970, 1, 1, 0, 0, 0, 0)))
self.assertEqual(
datelib.Timestamp.FromString(
'1970-01-01T00:00:00+0000', datelib.US_PACIFIC),
datelib.UTC.localize(datelib.Timestamp(1970, 1, 1, 0, 0, 0, 0)))
startdate = datelib.US_PACIFIC.localize(
datelib.Timestamp(2009, 1, 1, 3, 0, 0, 0))
for day in xrange(1, 366):
self.assertEqual(
datelib.Timestamp.FromString(startdate.isoformat()),
startdate,
'FromString works for day %d since 2009-01-01' % day)
startdate += datelib.datetime.timedelta(days=1)
def testFromString2(self):
"""Test correctness of parsing the local time in a given timezone.
The result shall always be the same as tz.localize(naive_time).
"""
baseday = datelib.datetime.date(2009, 1, 1).toordinal()
for day_offset in xrange(0, 365):
day = datelib.datetime.date.fromordinal(baseday + day_offset)
naive_day = datelib.datetime.datetime.combine(
day, datelib.datetime.time(0, 45, 9))
naive_day_str = naive_day.strftime('%Y-%m-%dT%H:%M:%S')
self.assertEqual(
datelib.US_PACIFIC.localize(naive_day),
datelib.Timestamp.FromString(naive_day_str, tz=datelib.US_PACIFIC),
'FromString localizes time incorrectly')
def testFromStringInterval(self):
expected_date = datetime.datetime.utcnow() - datetime.timedelta(days=1)
expected_s = time.mktime(expected_date.utctimetuple())
actual_date = datelib.Timestamp.FromString('1d')
actual_s = time.mktime(actual_date.timetuple())
diff_seconds = actual_s - expected_s
self.assertBetween(diff_seconds, 0, 1)
self.assertRaises(
datelib.TimeParseError, datelib.Timestamp.FromString, 'wat')
def _EpochToDatetime(t, tz=None):
if tz is not None:
return datelib.datetime.datetime.fromtimestamp(t, tz)
else:
return datelib.datetime.datetime.utcfromtimestamp(t)
class DatetimeConversionUnitTest(basetest.TestCase):
def setUp(self):
self.pst = pytz.timezone('US/Pacific')
self.utc = pytz.utc
self.now = time.time()
def testDatetimeToUTCMicros(self):
self.assertEqual(
0, datelib.DatetimeToUTCMicros(_EpochToDatetime(0)))
self.assertEqual(
1001 * long(datelib._MICROSECONDS_PER_SECOND),
datelib.DatetimeToUTCMicros(_EpochToDatetime(1001)))
self.assertEqual(long(self.now * datelib._MICROSECONDS_PER_SECOND),
datelib.DatetimeToUTCMicros(_EpochToDatetime(self.now)))
# tzinfo shouldn't change the result
self.assertEqual(
0, datelib.DatetimeToUTCMicros(_EpochToDatetime(0, tz=self.pst)))
def testDatetimeToUTCMillis(self):
self.assertEqual(
0, datelib.DatetimeToUTCMillis(_EpochToDatetime(0)))
self.assertEqual(
1001 * 1000L, datelib.DatetimeToUTCMillis(_EpochToDatetime(1001)))
self.assertEqual(long(self.now * 1000),
datelib.DatetimeToUTCMillis(_EpochToDatetime(self.now)))
# tzinfo shouldn't change the result
self.assertEqual(
0, datelib.DatetimeToUTCMillis(_EpochToDatetime(0, tz=self.pst)))
def testUTCMicrosToDatetime(self):
self.assertEqual(_EpochToDatetime(0), datelib.UTCMicrosToDatetime(0))
self.assertEqual(_EpochToDatetime(1.000001),
datelib.UTCMicrosToDatetime(1000001))
self.assertEqual(_EpochToDatetime(self.now), datelib.UTCMicrosToDatetime(
long(self.now * datelib._MICROSECONDS_PER_SECOND)))
# Check timezone-aware comparisons
self.assertEqual(_EpochToDatetime(0, self.pst),
datelib.UTCMicrosToDatetime(0, tz=self.pst))
self.assertEqual(_EpochToDatetime(0, self.pst),
datelib.UTCMicrosToDatetime(0, tz=self.utc))
def testUTCMillisToDatetime(self):
self.assertEqual(_EpochToDatetime(0), datelib.UTCMillisToDatetime(0))
self.assertEqual(_EpochToDatetime(1.001), datelib.UTCMillisToDatetime(1001))
t = time.time()
dt = _EpochToDatetime(t)
# truncate sub-milli time
dt -= datelib.datetime.timedelta(microseconds=dt.microsecond % 1000)
self.assertEqual(dt, datelib.UTCMillisToDatetime(long(t * 1000)))
# Check timezone-aware comparisons
self.assertEqual(_EpochToDatetime(0, self.pst),
datelib.UTCMillisToDatetime(0, tz=self.pst))
self.assertEqual(_EpochToDatetime(0, self.pst),
datelib.UTCMillisToDatetime(0, tz=self.utc))
class MicrosecondsToSecondsUnitTest(basetest.TestCase):
def testConversionFromMicrosecondsToSeconds(self):
self.assertEqual(0.0, datelib.MicrosecondsToSeconds(0))
self.assertEqual(7.0, datelib.MicrosecondsToSeconds(7000000))
self.assertEqual(1.234567, datelib.MicrosecondsToSeconds(1234567))
self.assertEqual(12345654321.123456,
datelib.MicrosecondsToSeconds(12345654321123456))
if __name__ == '__main__':
basetest.main()
#!/usr/bin/env python
# Copyright 2007 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unittest for common file utilities."""
import __builtin__
import errno
import os
import posix
import pwd
import shutil
import stat
import tempfile
import mox
from google.apputils import basetest
from google.apputils import file_util
import gflags as flags
FLAGS = flags.FLAGS
# pylint is dumb about mox:
# pylint: disable=no-member
class FileUtilTest(basetest.TestCase):
def testHomeDir(self):
self.assertEqual(file_util.HomeDir(), pwd.getpwuid(os.geteuid()).pw_dir)
self.assertEqual(file_util.HomeDir(0), pwd.getpwuid(0).pw_dir)
self.assertEqual(file_util.HomeDir('root'), pwd.getpwnam('root').pw_dir)
class FileUtilTempdirTest(basetest.TestCase):
def setUp(self):
self.temp_dir = tempfile.mkdtemp()
self.file_path = self.temp_dir + 'sample.txt'
self.sample_contents = 'Random text: aldmkfhjwoem103u74.'
# To avoid confusion in the mode tests.
self.prev_umask = posix.umask(0)
def tearDown(self):
shutil.rmtree(self.temp_dir)
posix.umask(self.prev_umask)
def testWriteOverwrite(self):
file_util.Write(self.file_path, 'original contents')
file_util.Write(self.file_path, self.sample_contents)
with open(self.file_path) as fp:
self.assertEquals(fp.read(), self.sample_contents)
def testWriteExclusive(self):
file_util.Write(self.file_path, 'original contents')
self.assertRaises(OSError, file_util.Write, self.file_path,
self.sample_contents, overwrite_existing=False)
def testWriteMode(self):
mode = 0744
file_util.Write(self.file_path, self.sample_contents, mode=mode)
s = os.stat(self.file_path)
self.assertEqual(stat.S_IMODE(s.st_mode), mode)
def testAtomicWriteSuccessful(self):
file_util.AtomicWrite(self.file_path, self.sample_contents)
with open(self.file_path) as fp:
self.assertEquals(fp.read(), self.sample_contents)
def testAtomicWriteMode(self):
mode = 0745
file_util.AtomicWrite(self.file_path, self.sample_contents, mode=mode)
s = os.stat(self.file_path)
self.assertEqual(stat.S_IMODE(s.st_mode), mode)
class FileUtilMoxTestBase(basetest.TestCase):
def setUp(self):
self.mox = mox.Mox()
self.sample_contents = 'Contents of the file'
self.file_path = '/path/to/some/file'
self.fd = 'a file descriptor'
def tearDown(self):
# In case a test fails before it gets to the unset line.
self.mox.UnsetStubs()
class FileUtilMoxTest(FileUtilMoxTestBase):
def testListDirPath(self):
self.mox.StubOutWithMock(os, 'listdir')
dir_contents = ['file1', 'file2', 'file3', 'directory1', 'file4',
'directory2']
os.listdir('/path/to/some/directory').AndReturn(dir_contents)
self.mox.ReplayAll()
self.assertListEqual(file_util.ListDirPath('/path/to/some/directory'),
['%s/%s' % ('/path/to/some/directory', entry)
for entry in dir_contents])
self.mox.VerifyAll()
def testSuccessfulRead(self):
file_handle = self.mox.CreateMockAnything()
self.mox.StubOutWithMock(__builtin__, 'open', use_mock_anything=True)
open(self.file_path).AndReturn(file_handle)
file_handle.__enter__().AndReturn(file_handle)
file_handle.read().AndReturn(self.sample_contents)
file_handle.__exit__(None, None, None)
self.mox.ReplayAll()
try:
self.assertEquals(file_util.Read(self.file_path), self.sample_contents)
self.mox.VerifyAll()
finally:
# Because we mock out the built-in open() function, which the unittest
# library depends on, we need to make sure we revert it before leaving the
# test, otherwise any test failures will cause further internal failures
# and yield no meaningful error output.
self.mox.ResetAll()
self.mox.UnsetStubs()
def testWriteGroup(self):
self.mox.StubOutWithMock(os, 'open')
self.mox.StubOutWithMock(os, 'write')
self.mox.StubOutWithMock(os, 'close')
self.mox.StubOutWithMock(os, 'chown')
gid = 'new gid'
os.open(self.file_path, os.O_WRONLY | os.O_TRUNC | os.O_CREAT,
0666).AndReturn(self.fd)
os.write(self.fd, self.sample_contents)
os.close(self.fd)
os.chown(self.file_path, -1, gid)
self.mox.ReplayAll()
file_util.Write(self.file_path, self.sample_contents, gid=gid)
self.mox.VerifyAll()
class AtomicWriteMoxTest(FileUtilMoxTestBase):
def setUp(self):
super(AtomicWriteMoxTest, self).setUp()
self.mox.StubOutWithMock(tempfile, 'mkstemp')
self.mox.StubOutWithMock(os, 'write')
self.mox.StubOutWithMock(os, 'close')
self.mox.StubOutWithMock(os, 'chmod')
self.mox.StubOutWithMock(os, 'rename')
self.mox.StubOutWithMock(os, 'remove')
self.mode = 'new permissions'
self.gid = 'new gid'
self.temp_filename = '/some/temp/file'
self.os_error = OSError('A problem renaming!')
tempfile.mkstemp(dir='/path/to/some').AndReturn(
(self.fd, self.temp_filename))
os.write(self.fd, self.sample_contents)
os.close(self.fd)
os.chmod(self.temp_filename, self.mode)
def tearDown(self):
self.mox.UnsetStubs()
def testAtomicWriteGroup(self):
self.mox.StubOutWithMock(os, 'chown')
os.chown(self.temp_filename, -1, self.gid)
os.rename(self.temp_filename, self.file_path)
self.mox.ReplayAll()
file_util.AtomicWrite(self.file_path, self.sample_contents,
mode=self.mode, gid=self.gid)
self.mox.VerifyAll()
def testAtomicWriteGroupError(self):
self.mox.StubOutWithMock(os, 'chown')
os.chown(self.temp_filename, -1, self.gid).AndRaise(self.os_error)
os.remove(self.temp_filename)
self.mox.ReplayAll()
self.assertRaises(OSError, file_util.AtomicWrite, self.file_path,
self.sample_contents, mode=self.mode, gid=self.gid)
self.mox.VerifyAll()
def testRenamingError(self):
os.rename(self.temp_filename, self.file_path).AndRaise(self.os_error)
os.remove(self.temp_filename)
self.mox.ReplayAll()
self.assertRaises(OSError, file_util.AtomicWrite, self.file_path,
self.sample_contents, mode=self.mode)
self.mox.VerifyAll()
def testRenamingErrorWithRemoveError(self):
extra_error = OSError('A problem removing!')
os.rename(self.temp_filename, self.file_path).AndRaise(self.os_error)
os.remove(self.temp_filename).AndRaise(extra_error)
self.mox.ReplayAll()
try:
file_util.AtomicWrite(self.file_path, self.sample_contents,
mode=self.mode)
except OSError as e:
self.assertEquals(str(e),
'A problem renaming!. Additional errors cleaning up: '
'A problem removing!')
else:
raise self.failureException('OSError not raised by AtomicWrite')
self.mox.VerifyAll()
class TemporaryFilesMoxTest(FileUtilMoxTestBase):
def testTemporaryFileWithContents(self):
contents = 'Inspiration!'
with file_util.TemporaryFileWithContents(contents) as temporary_file:
filename = temporary_file.name
contents_read = open(temporary_file.name).read()
self.assertEqual(contents_read, contents)
# Ensure that the file does not exist.
self.assertFalse(os.path.exists(filename))
class TemporaryDirsMoxTest(FileUtilMoxTestBase):
def testTemporaryDirectoryWithException(self):
def Inner(accumulator):
with file_util.TemporaryDirectory(base_path=FLAGS.test_tmpdir) as tmpdir:
self.assertTrue(os.path.isdir(tmpdir))
accumulator.append(tmpdir)
raise Exception('meh')
temp_dirs = []
self.assertRaises(Exception, Inner, temp_dirs)
# Ensure that the directory is removed on exit even when exceptions happen.
self.assertEquals(len(temp_dirs), 1)
self.assertFalse(os.path.isdir(temp_dirs[0]))
def testTemporaryDirectory(self):
with file_util.TemporaryDirectory(base_path=FLAGS.test_tmpdir) as temp_dir:
self.assertTrue(os.path.isdir(temp_dir))
# Ensure that the directory is removed on exit.
self.assertFalse(os.path.isdir(temp_dir))
class MkDirsMoxTest(FileUtilMoxTestBase):
# pylint is dumb about mox:
# pylint: disable=maybe-no-member
def setUp(self):
super(MkDirsMoxTest, self).setUp()
self.mox.StubOutWithMock(os, 'mkdir')
self.mox.StubOutWithMock(os, 'chmod')
self.mox.StubOutWithMock(os.path, 'isdir')
self.dir_tree = ['/path', 'to', 'some', 'directory']
def tearDown(self):
self.mox.UnsetStubs()
def testNoErrorsAbsoluteOneDir(self):
# record, replay
os.mkdir('/foo')
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('/foo')
self.mox.VerifyAll()
def testNoErrorsAbsoluteOneDirWithForceMode(self):
# record, replay
os.mkdir('/foo')
os.chmod('/foo', 0707)
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('/foo', force_mode=0707)
self.mox.VerifyAll()
def testNoErrorsExistingDirWithForceMode(self):
exist_error = OSError(errno.EEXIST, 'This string not used')
# record, replay
os.mkdir('/foo').AndRaise(exist_error)
# no chmod is called since the dir exists
os.path.isdir('/foo').AndReturn(True)
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('/foo', force_mode=0707)
self.mox.VerifyAll()
def testNoErrorsAbsoluteSlashDot(self):
# record, replay
os.mkdir('/foo')
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('/foo/.')
self.mox.VerifyAll()
def testNoErrorsAbsoluteExcessiveSlashDot(self):
"""See that normpath removes irrelevant .'s in the path."""
# record, replay
os.mkdir('/foo')
os.mkdir('/foo/bar')
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('/./foo/./././bar/.')
self.mox.VerifyAll()
def testNoErrorsAbsoluteTwoDirs(self):
# record, replay
os.mkdir('/foo')
os.mkdir('/foo/bar')
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('/foo/bar')
self.mox.VerifyAll()
def testNoErrorsPartialTwoDirsWithForceMode(self):
exist_error = OSError(errno.EEXIST, 'This string not used')
# record, replay
os.mkdir('/foo').AndRaise(exist_error) # /foo exists
os.path.isdir('/foo').AndReturn(True)
os.mkdir('/foo/bar') # bar does not
os.chmod('/foo/bar', 0707)
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('/foo/bar', force_mode=0707)
self.mox.VerifyAll()
def testNoErrorsRelativeOneDir(self):
# record, replay
os.mkdir('foo')
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('foo')
self.mox.VerifyAll()
def testNoErrorsRelativeTwoDirs(self):
# record, replay
os.mkdir('foo')
os.mkdir('foo/bar')
self.mox.ReplayAll()
# test, verify
file_util.MkDirs('foo/bar')
self.mox.VerifyAll()
def testDirectoriesExist(self):
exist_error = OSError(errno.EEXIST, 'This string not used')
# record, replay
for i in range(len(self.dir_tree)):
path = os.path.join(*self.dir_tree[:i+1])
os.mkdir(path).AndRaise(exist_error)
os.path.isdir(path).AndReturn(True)
self.mox.ReplayAll()
# test, verify
file_util.MkDirs(os.path.join(*self.dir_tree))
self.mox.VerifyAll()
def testFileInsteadOfDirectory(self):
exist_error = OSError(errno.EEXIST, 'This string not used')
path = self.dir_tree[0]
# record, replay
os.mkdir(path).AndRaise(exist_error)
os.path.isdir(path).AndReturn(False)
self.mox.ReplayAll()
# test, verify
self.assertRaises(OSError, file_util.MkDirs, os.path.join(*self.dir_tree))
self.mox.VerifyAll()
def testNonExistsError(self):
non_exist_error = OSError(errno.ETIMEDOUT, 'This string not used')
path = self.dir_tree[0]
# record, replay
os.mkdir(path).AndRaise(non_exist_error)
self.mox.ReplayAll()
# test, verify
self.assertRaises(OSError, file_util.MkDirs, os.path.join(*self.dir_tree))
self.mox.VerifyAll()
class RmDirsTestCase(mox.MoxTestBase):
def testRmDirs(self):
test_sandbox = os.path.join(FLAGS.test_tmpdir, 'test-rm-dirs')
test_dir = os.path.join(test_sandbox, 'test', 'dir')
os.makedirs(test_sandbox)
with open(os.path.join(test_sandbox, 'file'), 'w'):
pass
os.makedirs(test_dir)
with open(os.path.join(test_dir, 'file'), 'w'):
pass
file_util.RmDirs(test_dir)
self.assertFalse(os.path.exists(os.path.join(test_sandbox, 'test')))
self.assertTrue(os.path.exists(os.path.join(test_sandbox, 'file')))
shutil.rmtree(test_sandbox)
def testRmDirsForNonExistingDirectory(self):
self.mox.StubOutWithMock(os, 'rmdir')
os.rmdir('path/to')
os.rmdir('path')
self.mox.StubOutWithMock(shutil, 'rmtree')
shutil.rmtree('path/to/directory').AndRaise(
OSError(errno.ENOENT, "No such file or directory 'path/to/directory'"))
self.mox.ReplayAll()
file_util.RmDirs('path/to/directory')
self.mox.VerifyAll()
def testRmDirsForNonExistingParentDirectory(self):
self.mox.StubOutWithMock(os, 'rmdir')
os.rmdir('path/to').AndRaise(
OSError(errno.ENOENT, "No such file or directory 'path/to'"))
os.rmdir('path')
self.mox.StubOutWithMock(shutil, 'rmtree')
shutil.rmtree('path/to/directory').AndRaise(
OSError(errno.ENOENT, "No such file or directory 'path/to/directory'"))
self.mox.ReplayAll()
file_util.RmDirs('path/to/directory')
self.mox.VerifyAll()
def testRmDirsForNotEmptyDirectory(self):
self.mox.StubOutWithMock(os, 'rmdir')
os.rmdir('path/to').AndRaise(
OSError(errno.ENOTEMPTY, 'Directory not empty', 'path/to'))
self.mox.StubOutWithMock(shutil, 'rmtree')
shutil.rmtree('path/to/directory')
self.mox.ReplayAll()
file_util.RmDirs('path/to/directory')
self.mox.VerifyAll()
def testRmDirsForPermissionDeniedOnParentDirectory(self):
self.mox.StubOutWithMock(os, 'rmdir')
os.rmdir('path/to').AndRaise(
OSError(errno.EACCES, 'Permission denied', 'path/to'))
self.mox.StubOutWithMock(shutil, 'rmtree')
shutil.rmtree('path/to/directory')
self.mox.ReplayAll()
file_util.RmDirs('path/to/directory')
self.mox.VerifyAll()
def testRmDirsWithSimplePath(self):
self.mox.StubOutWithMock(shutil, 'rmtree')
shutil.rmtree('directory')
self.mox.ReplayAll()
file_util.RmDirs('directory')
self.mox.VerifyAll()
if __name__ == '__main__':
basetest.main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Test for google.apputils.humanize."""
import datetime
from google.apputils import basetest
from google.apputils import datelib
from google.apputils import humanize
class HumanizeTest(basetest.TestCase):
def testCommas(self):
self.assertEqual('0', humanize.Commas(0))
self.assertEqual('100', humanize.Commas(100))
self.assertEqual('1,000', humanize.Commas(1000))
self.assertEqual('10,000', humanize.Commas(10000))
self.assertEqual('1,000,000', humanize.Commas(1e6))
self.assertEqual('-1,000,000', humanize.Commas(-1e6))
def testPlural(self):
self.assertEqual('0 objects', humanize.Plural(0, 'object'))
self.assertEqual('1 object', humanize.Plural(1, 'object'))
self.assertEqual('-1 objects', humanize.Plural(-1, 'object'))
self.assertEqual('42 objects', humanize.Plural(42, 'object'))
self.assertEqual('42 cats', humanize.Plural(42, 'cat'))
self.assertEqual('42 glasses', humanize.Plural(42, 'glass'))
self.assertEqual('42 potatoes', humanize.Plural(42, 'potato'))
self.assertEqual('42 cherries', humanize.Plural(42, 'cherry'))
self.assertEqual('42 monkeys', humanize.Plural(42, 'monkey'))
self.assertEqual('42 oxen', humanize.Plural(42, 'ox', 'oxen'))
self.assertEqual('42 indices', humanize.Plural(42, 'index'))
self.assertEqual(
'42 attorneys general',
humanize.Plural(42, 'attorney general', 'attorneys general'))
def testPluralWord(self):
self.assertEqual('vaxen', humanize.PluralWord(2, 'vax', plural='vaxen'))
self.assertEqual('cores', humanize.PluralWord(2, 'core'))
self.assertEqual('group', humanize.PluralWord(1, 'group'))
self.assertEqual('cells', humanize.PluralWord(0, 'cell'))
self.assertEqual('degree', humanize.PluralWord(1.0, 'degree'))
self.assertEqual('helloes', humanize.PluralWord(3.14, 'hello'))
def testWordSeries(self):
self.assertEqual('', humanize.WordSeries([]))
self.assertEqual('foo', humanize.WordSeries(['foo']))
self.assertEqual('foo and bar', humanize.WordSeries(['foo', 'bar']))
self.assertEqual(
'foo, bar, and baz', humanize.WordSeries(['foo', 'bar', 'baz']))
self.assertEqual(
'foo, bar, or baz', humanize.WordSeries(['foo', 'bar', 'baz'],
conjunction='or'))
def testAddIndefiniteArticle(self):
self.assertEqual('a thing', humanize.AddIndefiniteArticle('thing'))
self.assertEqual('an object', humanize.AddIndefiniteArticle('object'))
self.assertEqual('a Porsche', humanize.AddIndefiniteArticle('Porsche'))
self.assertEqual('an Audi', humanize.AddIndefiniteArticle('Audi'))
def testDecimalPrefix(self):
self.assertEqual('0 m', humanize.DecimalPrefix(0, 'm'))
self.assertEqual('1 km', humanize.DecimalPrefix(1000, 'm'))
self.assertEqual('-1 km', humanize.DecimalPrefix(-1000, 'm'))
self.assertEqual('10 Gbps', humanize.DecimalPrefix(10e9, 'bps'))
self.assertEqual('6000 Yg', humanize.DecimalPrefix(6e27, 'g'))
self.assertEqual('12.1 km', humanize.DecimalPrefix(12100, 'm', precision=3))
self.assertEqual('12 km', humanize.DecimalPrefix(12100, 'm', precision=2))
self.assertEqual('1.15 km', humanize.DecimalPrefix(1150, 'm', precision=3))
self.assertEqual('-1.15 km', humanize.DecimalPrefix(-1150, 'm',
precision=3))
self.assertEqual('1 k', humanize.DecimalPrefix(1000, ''))
self.assertEqual('-10 G', humanize.DecimalPrefix(-10e9, ''))
self.assertEqual('12', humanize.DecimalPrefix(12, ''))
self.assertEqual('-115', humanize.DecimalPrefix(-115, ''))
self.assertEqual('0', humanize.DecimalPrefix(0, ''))
self.assertEqual('1.1 s', humanize.DecimalPrefix(1.12, 's', precision=2))
self.assertEqual('-1.1 s', humanize.DecimalPrefix(-1.12, 's', precision=2))
self.assertEqual('nan bps', humanize.DecimalPrefix(float('nan'), 'bps'))
self.assertEqual('nan', humanize.DecimalPrefix(float('nan'), ''))
self.assertEqual('inf bps', humanize.DecimalPrefix(float('inf'), 'bps'))
self.assertEqual('-inf bps', humanize.DecimalPrefix(float('-inf'), 'bps'))
self.assertEqual('-inf', humanize.DecimalPrefix(float('-inf'), ''))
self.assertEqual('-4 mm',
humanize.DecimalPrefix(-0.004, 'm', min_scale=None))
self.assertEqual('0 m', humanize.DecimalPrefix(0, 'm', min_scale=None))
self.assertEqual(
u'1 µs',
humanize.DecimalPrefix(0.0000013, 's', min_scale=None))
self.assertEqual('3 km', humanize.DecimalPrefix(3000, 'm', min_scale=None))
self.assertEqual(
'5000 TB',
humanize.DecimalPrefix(5e15, 'B', max_scale=4))
self.assertEqual(
'5 mSWE',
humanize.DecimalPrefix(0.005, 'SWE', min_scale=None))
self.assertEqual(
'0.0005 ms',
humanize.DecimalPrefix(5e-7, 's', min_scale=-1, precision=2))
def testBinaryPrefix(self):
self.assertEqual('0 B', humanize.BinaryPrefix(0, 'B'))
self.assertEqual('1000 B', humanize.BinaryPrefix(1000, 'B'))
self.assertEqual('1 KiB', humanize.BinaryPrefix(1024, 'B'))
self.assertEqual('64 GiB', humanize.BinaryPrefix(2**36, 'B'))
self.assertEqual('65536 Yibit', humanize.BinaryPrefix(2**96, 'bit'))
self.assertEqual('1.25 KiB', humanize.BinaryPrefix(1280, 'B', precision=3))
self.assertEqual('1.2 KiB', humanize.BinaryPrefix(1280, 'B', precision=2))
self.assertEqual('1.2 Ki', humanize.BinaryPrefix(1280, '', precision=2))
self.assertEqual('12', humanize.BinaryPrefix(12, '', precision=2))
# Test both int and long versions of the same quantity to make sure they are
# printed in the same way.
self.assertEqual('10.0 QPS', humanize.BinaryPrefix(10, 'QPS', precision=3))
self.assertEqual('10.0 QPS', humanize.BinaryPrefix(10L, 'QPS', precision=3))
def testDecimalScale(self):
self.assertIsInstance(humanize.DecimalScale(0, '')[0], float)
self.assertIsInstance(humanize.DecimalScale(1, '')[0], float)
self.assertEqual((12.1, 'km'), humanize.DecimalScale(12100, 'm'))
self.assertEqual((12.1, 'k'), humanize.DecimalScale(12100, ''))
self.assertEqual((0, ''), humanize.DecimalScale(0, ''))
self.assertEqual(
(12.1, 'km'),
humanize.DecimalScale(12100, 'm', min_scale=0, max_scale=None))
self.assertEqual(
(12100, 'm'),
humanize.DecimalScale(12100, 'm', min_scale=0, max_scale=0))
self.assertEqual((1.15, 'Mm'), humanize.DecimalScale(1150000, 'm'))
self.assertEqual((1, 'm'),
humanize.DecimalScale(1, 'm', min_scale=None))
self.assertEqual((450, 'mSWE'),
humanize.DecimalScale(0.45, 'SWE', min_scale=None))
self.assertEqual(
(250, u'µm'),
humanize.DecimalScale(1.0 / (4 * 1000), 'm', min_scale=None))
self.assertEqual(
(0.250, 'km'),
humanize.DecimalScale(250, 'm', min_scale=1))
self.assertEqual(
(12000, 'mm'),
humanize.DecimalScale(12, 'm', min_scale=None, max_scale=-1))
def testBinaryScale(self):
self.assertIsInstance(humanize.BinaryScale(0, '')[0], float)
self.assertIsInstance(humanize.BinaryScale(1, '')[0], float)
value, unit = humanize.BinaryScale(200000000000, 'B')
self.assertAlmostEqual(value, 186.26, 2)
self.assertEqual(unit, 'GiB')
value, unit = humanize.BinaryScale(3000000000000, 'B')
self.assertAlmostEqual(value, 2.728, 3)
self.assertEqual(unit, 'TiB')
def testPrettyFraction(self):
# No rounded integer part
self.assertEqual(u'½', humanize.PrettyFraction(0.5))
# Roundeded integer + fraction
self.assertEqual(u'6⅔', humanize.PrettyFraction(20.0 / 3.0))
# Rounded integer, no fraction
self.assertEqual(u'2', humanize.PrettyFraction(2.00001))
# No rounded integer, no fraction
self.assertEqual(u'0', humanize.PrettyFraction(0.001))
# Round up
self.assertEqual(u'1', humanize.PrettyFraction(0.99))
# No round up, edge case
self.assertEqual(u'⅞', humanize.PrettyFraction(0.9))
# Negative fraction
self.assertEqual(u'-⅕', humanize.PrettyFraction(-0.2))
# Negative close to zero (should not be -0)
self.assertEqual(u'0', humanize.PrettyFraction(-0.001))
# Smallest fraction that should round down.
self.assertEqual(u'0', humanize.PrettyFraction(1.0 / 16.0))
# Largest fraction should round up.
self.assertEqual(u'1', humanize.PrettyFraction(15.0 / 16.0))
# Integer zero.
self.assertEqual(u'0', humanize.PrettyFraction(0))
# Check that division yields fraction
self.assertEqual(u'⅘', humanize.PrettyFraction(4.0 / 5.0))
# Custom spacer.
self.assertEqual(u'2 ½', humanize.PrettyFraction(2.5, spacer=' '))
def testDuration(self):
self.assertEqual('2h', humanize.Duration(7200))
self.assertEqual('5d 13h 47m 12s', humanize.Duration(481632))
self.assertEqual('0s', humanize.Duration(0))
self.assertEqual('59s', humanize.Duration(59))
self.assertEqual('1m', humanize.Duration(60))
self.assertEqual('1m 1s', humanize.Duration(61))
self.assertEqual('1h 1s', humanize.Duration(3601))
self.assertEqual('2h-2s', humanize.Duration(7202, separator='-'))
def testLargeDuration(self):
# The maximum seconds and days that can be stored in a datetime.timedelta
# object, as seconds. max_days is equal to MAX_DELTA_DAYS in Python's
# Modules/datetimemodule.c, converted to seconds.
max_seconds = 3600 * 24 - 1
max_days = 999999999 * 24 * 60 * 60
self.assertEqual('999999999d', humanize.Duration(max_days))
self.assertEqual('999999999d 23h 59m 59s',
humanize.Duration(max_days + max_seconds))
self.assertEqual('>=999999999d 23h 59m 60s',
humanize.Duration(max_days + max_seconds + 1))
def testTimeDelta(self):
self.assertEqual('0s', humanize.TimeDelta(datetime.timedelta()))
self.assertEqual('2h', humanize.TimeDelta(datetime.timedelta(hours=2)))
self.assertEqual('1m', humanize.TimeDelta(datetime.timedelta(minutes=1)))
self.assertEqual('5d', humanize.TimeDelta(datetime.timedelta(days=5)))
self.assertEqual('1.25s', humanize.TimeDelta(
datetime.timedelta(seconds=1, microseconds=250000)))
self.assertEqual('1.5s',
humanize.TimeDelta(datetime.timedelta(seconds=1.5)))
self.assertEqual('4d 10h 5m 12.25s', humanize.TimeDelta(
datetime.timedelta(days=4, hours=10, minutes=5, seconds=12,
microseconds=250000)))
def testUnixTimestamp(self):
self.assertEqual('2013-11-17 11:08:27.723524 PST',
humanize.UnixTimestamp(1384715307.723524,
datelib.US_PACIFIC))
self.assertEqual('2013-11-17 19:08:27.723524 UTC',
humanize.UnixTimestamp(1384715307.723524,
datelib.UTC))
# DST part of the timezone should not depend on the current local time,
# so this should be in PDT (and different from the PST in the first test).
self.assertEqual('2013-05-17 15:47:21.723524 PDT',
humanize.UnixTimestamp(1368830841.723524,
datelib.US_PACIFIC))
self.assertEqual('1970-01-01 00:00:00.000000 UTC',
humanize.UnixTimestamp(0, datelib.UTC))
def testAddOrdinalSuffix(self):
self.assertEqual('0th', humanize.AddOrdinalSuffix(0))
self.assertEqual('1st', humanize.AddOrdinalSuffix(1))
self.assertEqual('2nd', humanize.AddOrdinalSuffix(2))
self.assertEqual('3rd', humanize.AddOrdinalSuffix(3))
self.assertEqual('4th', humanize.AddOrdinalSuffix(4))
self.assertEqual('5th', humanize.AddOrdinalSuffix(5))
self.assertEqual('10th', humanize.AddOrdinalSuffix(10))
self.assertEqual('11th', humanize.AddOrdinalSuffix(11))
self.assertEqual('12th', humanize.AddOrdinalSuffix(12))
self.assertEqual('13th', humanize.AddOrdinalSuffix(13))
self.assertEqual('14th', humanize.AddOrdinalSuffix(14))
self.assertEqual('20th', humanize.AddOrdinalSuffix(20))
self.assertEqual('21st', humanize.AddOrdinalSuffix(21))
self.assertEqual('22nd', humanize.AddOrdinalSuffix(22))
self.assertEqual('23rd', humanize.AddOrdinalSuffix(23))
self.assertEqual('24th', humanize.AddOrdinalSuffix(24))
self.assertEqual('63rd', humanize.AddOrdinalSuffix(63))
self.assertEqual('100000th', humanize.AddOrdinalSuffix(100000))
self.assertEqual('100001st', humanize.AddOrdinalSuffix(100001))
self.assertEqual('100011th', humanize.AddOrdinalSuffix(100011))
self.assertRaises(ValueError, humanize.AddOrdinalSuffix, -1)
self.assertRaises(ValueError, humanize.AddOrdinalSuffix, 0.5)
self.assertRaises(ValueError, humanize.AddOrdinalSuffix, 123.001)
class NaturalSortKeyChunkingTest(basetest.TestCase):
def testChunkifySingleChars(self):
self.assertListEqual(
humanize.NaturalSortKey('a1b2c3'),
['a', 1, 'b', 2, 'c', 3])
def testChunkifyMultiChars(self):
self.assertListEqual(
humanize.NaturalSortKey('aa11bb22cc33'),
['aa', 11, 'bb', 22, 'cc', 33])
def testChunkifyComplex(self):
self.assertListEqual(
humanize.NaturalSortKey('one 11 -- two 44'),
['one ', 11, ' -- two ', 44])
class NaturalSortKeysortTest(basetest.TestCase):
def testNaturalSortKeySimpleWords(self):
self.test = ['pair', 'banana', 'apple']
self.good = ['apple', 'banana', 'pair']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
def testNaturalSortKeySimpleNums(self):
self.test = ['3333', '2222', '9999', '0000']
self.good = ['0000', '2222', '3333', '9999']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
def testNaturalSortKeySimpleDigits(self):
self.test = ['8', '3', '2']
self.good = ['2', '3', '8']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
def testVersionStrings(self):
self.test = ['1.2', '0.9', '1.1a2', '1.1a', '1', '1.2.1', '0.9.1']
self.good = ['0.9', '0.9.1', '1', '1.1a', '1.1a2', '1.2', '1.2.1']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
def testNaturalSortKeySimpleNumLong(self):
self.test = ['11', '9', '1', '200', '19', '20', '900']
self.good = ['1', '9', '11', '19', '20', '200', '900']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
def testNaturalSortKeyAlNum(self):
self.test = ['x10', 'x9', 'x1', 'x11']
self.good = ['x1', 'x9', 'x10', 'x11']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
def testNaturalSortKeyNumAlNum(self):
self.test = ['4x10', '4x9', '4x11', '5yy4', '3x1', '2x11']
self.good = ['2x11', '3x1', '4x9', '4x10', '4x11', '5yy4']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
def testNaturalSortKeyAlNumAl(self):
self.test = ['a9c', 'a4b', 'a10c', 'a1c', 'c10c', 'c10a', 'c9a']
self.good = ['a1c', 'a4b', 'a9c', 'a10c', 'c9a', 'c10a', 'c10c']
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
class NaturalSortKeyBigTest(basetest.TestCase):
def testBig(self):
self.test = [
'1000X Radonius Maximus', '10X Radonius', '200X Radonius',
'20X Radonius', '20X Radonius Prime', '30X Radonius',
'40X Radonius', 'Allegia 50 Clasteron', 'Allegia 500 Clasteron',
'Allegia 51 Clasteron', 'Allegia 51B Clasteron',
'Allegia 52 Clasteron', 'Allegia 60 Clasteron', 'Alpha 100',
'Alpha 2', 'Alpha 200', 'Alpha 2A', 'Alpha 2A-8000', 'Alpha 2A-900',
'Callisto Morphamax', 'Callisto Morphamax 500',
'Callisto Morphamax 5000', 'Callisto Morphamax 600',
'Callisto Morphamax 700', 'Callisto Morphamax 7000',
'Callisto Morphamax 7000 SE', 'Callisto Morphamax 7000 SE2',
'QRS-60 Intrinsia Machine', 'QRS-60F Intrinsia Machine',
'QRS-62 Intrinsia Machine', 'QRS-62F Intrinsia Machine',
'Xiph Xlater 10000', 'Xiph Xlater 2000', 'Xiph Xlater 300',
'Xiph Xlater 40', 'Xiph Xlater 5', 'Xiph Xlater 50',
'Xiph Xlater 500', 'Xiph Xlater 5000', 'Xiph Xlater 58']
self.good = [
'10X Radonius',
'20X Radonius',
'20X Radonius Prime',
'30X Radonius',
'40X Radonius',
'200X Radonius',
'1000X Radonius Maximus',
'Allegia 50 Clasteron',
'Allegia 51 Clasteron',
'Allegia 51B Clasteron',
'Allegia 52 Clasteron',
'Allegia 60 Clasteron',
'Allegia 500 Clasteron',
'Alpha 2',
'Alpha 2A',
'Alpha 2A-900',
'Alpha 2A-8000',
'Alpha 100',
'Alpha 200',
'Callisto Morphamax',
'Callisto Morphamax 500',
'Callisto Morphamax 600',
'Callisto Morphamax 700',
'Callisto Morphamax 5000',
'Callisto Morphamax 7000',
'Callisto Morphamax 7000 SE',
'Callisto Morphamax 7000 SE2',
'QRS-60 Intrinsia Machine',
'QRS-60F Intrinsia Machine',
'QRS-62 Intrinsia Machine',
'QRS-62F Intrinsia Machine',
'Xiph Xlater 5',
'Xiph Xlater 40',
'Xiph Xlater 50',
'Xiph Xlater 58',
'Xiph Xlater 300',
'Xiph Xlater 500',
'Xiph Xlater 2000',
'Xiph Xlater 5000',
'Xiph Xlater 10000',
]
self.test.sort(key=humanize.NaturalSortKey)
self.assertListEqual(self.test, self.good)
if __name__ == '__main__':
basetest.main()
#!/usr/bin/env python
# Copyright 2010 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the resources module."""
__author__ = 'dborowitz@google.com (Dave Borowitz)'
from google.apputils import basetest
from google.apputils import file_util
from google.apputils import resources
PREFIX = __name__ + ':data/'
class ResourcesTest(basetest.TestCase):
def _CheckTestData(self, func):
self.assertEqual('test file a contents\n', func(PREFIX + 'a'))
self.assertEqual('test file b contents\n', func(PREFIX + 'b'))
def testGetResource(self):
self._CheckTestData(resources.GetResource)
def testGetResourceAsFile(self):
self._CheckTestData(lambda n: resources.GetResourceAsFile(n).read())
def testGetResourceFilename(self):
self._CheckTestData(
lambda n: file_util.Read(resources.GetResourceFilename(n)))
if __name__ == '__main__':
basetest.main()
#!/usr/bin/env python
# Copyright 2010 Google Inc. All Rights Reserved.
"""Tests for google.apputils.
In addition to the test modules under this package, we have a special TestCase
that runs the tests that are shell scripts.
"""
# TODO(dborowitz): It may be useful to generalize this and provide it to users
# who want to run their own sh_tests.
import os
import subprocess
import sys
from google.apputils import basetest
import gflags
FLAGS = gflags.FLAGS
class ShellScriptTests(basetest.TestCase):
"""TestCase that runs the various *test.sh scripts."""
def RunTestScript(self, script_name):
tests_path = os.path.dirname(__file__)
sh_test_path = os.path.realpath(os.path.join(tests_path, script_name))
path_with_python = ':'.join((
os.path.dirname(sys.executable), os.environ.get('PATH')))
env = {
'PATH': path_with_python,
# Setuptools puts dependency eggs in our path, so propagate that.
'PYTHONPATH': os.pathsep.join(sys.path),
'TEST_TMPDIR': FLAGS.test_tmpdir,
}
p = subprocess.Popen(sh_test_path, cwd=tests_path, env=env)
self.assertEqual(0, p.wait())
def testBaseTest(self):
self.RunTestScript('basetest_sh_test.sh')
def testApp(self):
self.RunTestScript('app_unittest.sh')
def testAppCommands(self):
self.RunTestScript('appcommands_unittest.sh')
if __name__ == '__main__':
basetest.main()
#!/usr/bin/env python
# This code must be source compatible with Python 2.4 through 3.3.
#
# Copyright 2003 Google Inc. All Rights Reserved.
"""Unittest for shellutil module."""
import os
# Use unittest instead of basetest to avoid bootstrap issues / circular deps.
import unittest
from google.apputils import shellutil
# Running windows?
win32 = (os.name == 'nt')
class ShellUtilUnitTest(unittest.TestCase):
def testShellEscapeList(self):
# TODO(user): Actually run some shell commands and test the
# shell escaping works properly.
# Empty list
words = []
self.assertEqual(shellutil.ShellEscapeList(words), '')
# Empty string
words = ['']
self.assertEqual(shellutil.ShellEscapeList(words), "''")
# Single word
words = ['foo']
self.assertEqual(shellutil.ShellEscapeList(words), "'foo'")
# Single word with single quote
words = ["foo'bar"]
expected = """ 'foo'"'"'bar' """.strip()
self.assertEqual(shellutil.ShellEscapeList(words), expected)
# .. double quote
words = ['foo"bar']
expected = """ 'foo"bar' """.strip()
self.assertEqual(shellutil.ShellEscapeList(words), expected)
# Multiple words
words = ['foo', 'bar']
self.assertEqual(shellutil.ShellEscapeList(words), "'foo' 'bar'")
# Words with spaces
words = ['foo', 'bar', "foo'' ''bar"]
expected = """ 'foo' 'bar' 'foo'"'"''"'"' '"'"''"'"'bar' """.strip()
self.assertEqual(shellutil.ShellEscapeList(words), expected)
# Now I'm just being mean
words = ['foo', 'bar', """ ""'"'" """.strip()]
expected = """ 'foo' 'bar' '""'"'"'"'"'"'"' """.strip()
self.assertEqual(shellutil.ShellEscapeList(words), expected)
def testShellifyStatus(self):
if not win32:
self.assertEqual(shellutil.ShellifyStatus(0), 0)
self.assertEqual(shellutil.ShellifyStatus(1), 129)
self.assertEqual(shellutil.ShellifyStatus(1 * 256), 1)
if __name__ == '__main__':
unittest.main()
#!/usr/bin/env python
# Copyright 2006 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the stopwatch module."""
__author__ = 'dbentley@google.com (Dan Bentley)'
from google.apputils import basetest
import gflags as flags
from google.apputils import stopwatch
FLAGS = flags.FLAGS
class StubTime(object):
"""Simple stub replacement for the time module.
Only useful for relative calculations, since it always starts at 0.
"""
# These method names match the standard library time module.
def __init__(self):
self._counter = 0
def time(self):
"""Get the time for this time object.
A call is always guaranteed to be greater than the previous one.
Returns:
A monotonically increasing time.
"""
self._counter += 0.0001
return self._counter
def sleep(self, time):
"""Simulate sleeping for the specified number of seconds."""
self._counter += time
class StopwatchUnitTest(basetest.TestCase):
"""Stopwatch tests.
These tests are tricky because timing is difficult.
Therefore, we test the structure of the results but not the results
themselves for fear it would lead to intermittent but persistent
failures.
"""
def setUp(self):
self.time = StubTime()
stopwatch.time = self.time
def testResults(self):
sw = stopwatch.StopWatch()
sw.start()
sw.stop()
results = sw.results()
self.assertListEqual([r[0] for r in results], ['total'])
results = sw.results(verbose=1)
self.assertListEqual([r[0] for r in results], ['overhead', 'total'])
# test tally part of results.
sw.start('ron')
sw.stop('ron')
sw.start('ron')
sw.stop('ron')
results = sw.results()
results = sw.results(verbose=1)
for r in results:
if r[0] == 'ron':
assert r[2] == 2
def testSeveralTimes(self):
sw = stopwatch.StopWatch()
sw.start()
sw.start('a')
sw.start('b')
self.time.sleep(1)
sw.stop('b')
sw.stop('a')
sw.stop()
results = sw.results(verbose=1)
self.assertListEqual([r[0] for r in results],
['a', 'b', 'overhead', 'total'])
# Make sure overhead is positive
self.assertEqual(results[2][1] > 0, 1)
def testNoStopOthers(self):
sw = stopwatch.StopWatch()
sw.start()
sw.start('a')
sw.start('b', stop_others=0)
self.time.sleep(1)
sw.stop('b')
sw.stop('a')
sw.stop()
#overhead should be negative, because we ran two timers simultaneously
#It is possible that this could fail in outlandish circumstances.
#If this is a problem in practice, increase the value of the call to
#time.sleep until it passes consistently.
#Or, consider finding a platform where the two calls sw.start() and
#sw.start('a') happen within 1 second.
results = sw.results(verbose=1)
self.assertEqual(results[2][1] < 0, 1)
def testStopNonExistentTimer(self):
sw = stopwatch.StopWatch()
self.assertRaises(RuntimeError, sw.stop)
self.assertRaises(RuntimeError, sw.stop, 'foo')
def testResultsDoesntCrashWhenUnstarted(self):
sw = stopwatch.StopWatch()
sw.results()
def testResultsDoesntCrashWhenUnstopped(self):
sw = stopwatch.StopWatch()
sw.start()
sw.results()
def testTimerValue(self):
sw = stopwatch.StopWatch()
self.assertAlmostEqual(0, sw.timervalue('a'), 2)
sw.start('a')
self.assertAlmostEqual(0, sw.timervalue('a'), 2)
self.time.sleep(1)
self.assertAlmostEqual(1, sw.timervalue('a'), 2)
sw.stop('a')
self.assertAlmostEqual(1, sw.timervalue('a'), 2)
sw.start('a')
self.time.sleep(1)
self.assertAlmostEqual(2, sw.timervalue('a'), 2)
sw.stop('a')
self.assertAlmostEqual(2, sw.timervalue('a'), 2)
def testResultsDoesntReset(self):
sw = stopwatch.StopWatch()
sw.start()
self.time.sleep(1)
sw.start('a')
self.time.sleep(1)
sw.stop('a')
sw.stop()
res1 = sw.results(verbose=True)
res2 = sw.results(verbose=True)
self.assertListEqual(res1, res2)
if __name__ == '__main__':
basetest.main()
[tox]
envlist = py27
[testenv]
deps = ez-setup
commands = python setup.py google_test
+1
-1
Metadata-Version: 1.0
Name: google-apputils
Version: 0.4.1
Version: 0.4.2
Summary: UNKNOWN

@@ -5,0 +5,0 @@ Home-page: http://code.google.com/p/google-apputils-python

@@ -0,3 +1,7 @@

LICENSE
MANIFEST.in
README
ez_setup.py
setup.py
tox.ini
google/__init__.py

@@ -23,2 +27,19 @@ google/apputils/__init__.py

google_apputils.egg-info/requires.txt
google_apputils.egg-info/top_level.txt
google_apputils.egg-info/top_level.txt
tests/__init__.py
tests/app_test.py
tests/app_test_helper.py
tests/app_unittest.sh
tests/appcommands_example.py
tests/appcommands_unittest.sh
tests/basetest_sh_test.sh
tests/basetest_test.py
tests/datelib_unittest.py
tests/file_util_test.py
tests/humanize_test.py
tests/resources_test.py
tests/sh_test.py
tests/shellutil_unittest.py
tests/stopwatch_unittest.py
tests/data/a
tests/data/b
Metadata-Version: 1.0
Name: google-apputils
Version: 0.4.1
Version: 0.4.2
Summary: UNKNOWN

@@ -5,0 +5,0 @@ Home-page: http://code.google.com/p/google-apputils-python

@@ -18,4 +18,8 @@ #!/usr/bin/env python

import ez_setup
ez_setup.use_setuptools()
try:
import setuptools
except ImportError:
import ez_setup
ez_setup.use_setuptools()
import setuptools

@@ -54,3 +58,3 @@ from setuptools import setup, find_packages

name="google-apputils",
version="0.4.1",
version="0.4.2",
packages=find_packages(exclude=["tests"]),

@@ -57,0 +61,0 @@ namespace_packages=["google"],