toil.test

Base testing class for Toil.

Subpackages

Package Contents

Classes

concat

A literal iterable to combine sequence literals (lists, set) with generators or list comprehensions.

ExceptionalThread

A thread whose join() method re-raises exceptions raised during run(). While join() is

ToilTest

A common base class for Toil tests.

ApplianceTestSupport

A Toil test that runs a user script on a minimal cluster of appliance containers.

Functions

applianceSelf([forceDockerAppliance])

Return the fully qualified name of the Docker image to start Toil appliance containers from.

toilPackageDirPath()

Return the absolute path of the directory that corresponds to the top-level toil package.

have_working_nvidia_docker_runtime()

Return True if Docker exists and can handle an "nvidia" runtime and the "--gpus" option.

have_working_nvidia_smi()

Return True if the nvidia-smi binary, from nvidia's CUDA userspace

running_on_ec2()

Return True if we are currently running on EC2, and false otherwise.

cpu_count()

Get the rounded-up integer number of whole CPUs available.

get_temp_file([suffix, rootDir])

Return a string representing a temporary file, that must be manually deleted.

needs_env_var(var_name[, comment])

Use as a decorator before test classes or methods to run only if the given

needs_rsync3(test_item)

Decorate classes or methods that depend on any features from rsync version 3.0.0+.

needs_aws_s3(test_item)

Use as a decorator before test classes or methods to run only if AWS S3 is usable.

needs_aws_ec2(test_item)

Use as a decorator before test classes or methods to run only if AWS EC2 is usable.

needs_aws_batch(test_item)

Use as a decorator before test classes or methods to run only if AWS Batch

needs_google(test_item)

Use as a decorator before test classes or methods to run only if Google

needs_gridengine(test_item)

Use as a decorator before test classes or methods to run only if GridEngine is installed.

needs_torque(test_item)

Use as a decorator before test classes or methods to run only if PBS/Torque is installed.

needs_tes(test_item)

Use as a decorator before test classes or methods to run only if TES is available.

needs_kubernetes_installed(test_item)

Use as a decorator before test classes or methods to run only if Kubernetes is installed.

needs_kubernetes(test_item)

Use as a decorator before test classes or methods to run only if Kubernetes is installed and configured.

needs_mesos(test_item)

Use as a decorator before test classes or methods to run only if Mesos is installed.

needs_parasol(test_item)

Use as decorator so tests are only run if Parasol is installed.

needs_slurm(test_item)

Use as a decorator before test classes or methods to run only if Slurm is installed.

needs_htcondor(test_item)

Use a decorator before test classes or methods to run only if the HTCondor is installed.

needs_lsf(test_item)

Use as a decorator before test classes or methods to only run them if LSF is installed.

needs_java(test_item)

Use as a test decorator to run only if java is installed.

needs_docker(test_item)

Use as a decorator before test classes or methods to only run them if

needs_singularity(test_item)

Use as a decorator before test classes or methods to only run them if

needs_local_cuda(test_item)

Use as a decorator before test classes or methods to only run them if

needs_docker_cuda(test_item)

Use as a decorator before test classes or methods to only run them if

needs_encryption(test_item)

Use as a decorator before test classes or methods to only run them if PyNaCl is installed

needs_cwl(test_item)

Use as a decorator before test classes or methods to only run them if CWLTool is installed

needs_server(test_item)

Use as a decorator before test classes or methods to only run them if Connexion is installed.

needs_celery_broker(test_item)

Use as a decorator before test classes or methods to run only if RabbitMQ is set up to take Celery jobs.

needs_wes_server(test_item)

Use as a decorator before test classes or methods to run only if a WES

needs_local_appliance(test_item)

Use as a decorator before test classes or methods to only run them if

needs_fetchable_appliance(test_item)

Use as a decorator before test classes or methods to only run them if

integrative(test_item)

Use this to decorate integration tests so as to skip them during regular builds.

slow(test_item)

Use this decorator to identify tests that are slow and not critical.

timeLimit(seconds)

http://stackoverflow.com/a/601168

make_tests(generalMethod, targetClass, **kwargs)

This method dynamically generates test methods using the generalMethod as a template. Each

Attributes

memoize

Memoize a function result based on its parameters using this decorator.

distVersion

logger

MT

methodNamePartRegex

exception toil.test.ApplianceImageNotFound(origAppliance, url, statusCode)[source]

Bases: docker.errors.ImageNotFound

Inheritance diagram of toil.test.ApplianceImageNotFound

Error raised when using TOIL_APPLIANCE_SELF results in an HTTP error.

Parameters
  • origAppliance (str) – The full url of the docker image originally specified by the user (or the default). e.g. “quay.io/ucsc_cgl/toil:latest”

  • url (str) – The URL at which the image’s manifest is supposed to appear

  • statusCode (int) – the failing HTTP status code returned by the URL

toil.test.applianceSelf(forceDockerAppliance=False)[source]

Return the fully qualified name of the Docker image to start Toil appliance containers from.

The result is determined by the current version of Toil and three environment variables: TOIL_DOCKER_REGISTRY, TOIL_DOCKER_NAME and TOIL_APPLIANCE_SELF.

TOIL_DOCKER_REGISTRY specifies an account on a publicly hosted docker registry like Quay or Docker Hub. The default is UCSC’s CGL account on Quay.io where the Toil team publishes the official appliance images. TOIL_DOCKER_NAME specifies the base name of the image. The default of toil will be adequate in most cases. TOIL_APPLIANCE_SELF fully qualifies the appliance image, complete with registry, image name and version tag, overriding both TOIL_DOCKER_NAME and TOIL_DOCKER_REGISTRY` as well as the version tag of the image. Setting TOIL_APPLIANCE_SELF will not be necessary in most cases.

Parameters

forceDockerAppliance (bool) –

Return type

str

toil.test.toilPackageDirPath()[source]

Return the absolute path of the directory that corresponds to the top-level toil package.

The return value is guaranteed to end in ‘/toil’.

Return type

str

toil.test.have_working_nvidia_docker_runtime()[source]

Return True if Docker exists and can handle an “nvidia” runtime and the “–gpus” option.

Return type

bool

toil.test.have_working_nvidia_smi()[source]

Return True if the nvidia-smi binary, from nvidia’s CUDA userspace utilities, is installed and can be run successfully.

TODO: This isn’t quite the same as the check that cwltool uses to decide if it can fulfill a CUDARequirement.

Return type

bool

toil.test.running_on_ec2()[source]

Return True if we are currently running on EC2, and false otherwise.

Return type

bool

class toil.test.concat(*args)[source]

A literal iterable to combine sequence literals (lists, set) with generators or list comprehensions.

Instead of

>>> [ -1 ] + [ x * 2 for x in range( 3 ) ] + [ -1 ]
[-1, 0, 2, 4, -1]

you can write

>>> list( concat( -1, ( x * 2 for x in range( 3 ) ), -1 ) )
[-1, 0, 2, 4, -1]

This is slightly shorter (not counting the list constructor) and does not involve array construction or concatenation.

Note that concat() flattens (or chains) all iterable arguments into a single result iterable:

>>> list( concat( 1, range( 2, 4 ), 4 ) )
[1, 2, 3, 4]

It only does so one level deep. If you need to recursively flatten a data structure, check out crush().

If you want to prevent that flattening for an iterable argument, wrap it in concat():

>>> list( concat( 1, concat( range( 2, 4 ) ), 4 ) )
[1, range(2, 4), 4]

Some more example.

>>> list( concat() ) # empty concat
[]
>>> list( concat( 1 ) ) # non-iterable
[1]
>>> list( concat( concat() ) ) # empty iterable
[]
>>> list( concat( concat( 1 ) ) ) # singleton iterable
[1]
>>> list( concat( 1, concat( 2 ), 3 ) ) # flattened iterable
[1, 2, 3]
>>> list( concat( 1, [2], 3 ) ) # flattened iterable
[1, 2, 3]
>>> list( concat( 1, concat( [2] ), 3 ) ) # protecting an iterable from being flattened
[1, [2], 3]
>>> list( concat( 1, concat( [2], 3 ), 4 ) ) # protection only works with a single argument
[1, 2, 3, 4]
>>> list( concat( 1, 2, concat( 3, 4 ), 5, 6 ) )
[1, 2, 3, 4, 5, 6]
>>> list( concat( 1, 2, concat( [ 3, 4 ] ), 5, 6 ) )
[1, 2, [3, 4], 5, 6]

Note that while strings are technically iterable, concat() does not flatten them.

>>> list( concat( 'ab' ) )
['ab']
>>> list( concat( concat( 'ab' ) ) )
['ab']
Parameters

args (Any) –

__iter__()[source]
Return type

Iterator[Any]

toil.test.memoize

Memoize a function result based on its parameters using this decorator.

For example, this can be used in place of lazy initialization. If the decorating function is invoked by multiple threads, the decorated function may be called more than once with the same arguments.

class toil.test.ExceptionalThread(group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)[source]

Bases: threading.Thread

Inheritance diagram of toil.test.ExceptionalThread

A thread whose join() method re-raises exceptions raised during run(). While join() is idempotent, the exception is only during the first invocation of join() that successfully joined the thread. If join() times out, no exception will be re reraised even though an exception might already have occured in run().

When subclassing this thread, override tryRun() instead of run().

>>> def f():
...     assert 0
>>> t = ExceptionalThread(target=f)
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
>>> class MyThread(ExceptionalThread):
...     def tryRun( self ):
...         assert 0
>>> t = MyThread()
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
exc_info
run()[source]

Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

Return type

None

tryRun()[source]
Return type

None

join(*args, **kwargs)[source]

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

Parameters
  • args (Optional[float]) –

  • kwargs (Optional[float]) –

Return type

None

toil.test.cpu_count()[source]

Get the rounded-up integer number of whole CPUs available.

Counts hyperthreads as CPUs.

Uses the system’s actual CPU count, or the current v1 cgroup’s quota per period, if the quota is set.

Ignores the cgroup’s cpu shares value, because it’s extremely difficult to interpret. See https://github.com/kubernetes/kubernetes/issues/81021.

Caches result for efficiency.

Returns

Integer count of available CPUs, minimum 1.

Return type

int

toil.test.distVersion = '5.11.0'
toil.test.logger
class toil.test.ToilTest(methodName='runTest')[source]

Bases: unittest.TestCase

Inheritance diagram of toil.test.ToilTest

A common base class for Toil tests.

Please have every test case directly or indirectly inherit this one.

When running tests you may optionally set the TOIL_TEST_TEMP environment variable to the path of a directory where you want temporary test files be placed. The directory will be created if it doesn’t exist. The path may be relative in which case it will be assumed to be relative to the project root. If TOIL_TEST_TEMP is not defined, temporary files and directories will be created in the system’s default location for such files and any temporary files or directories left over from tests will be removed automatically removed during tear down. Otherwise, left-over files will not be removed.

setup_method(method)[source]
Parameters

method (Any) –

Return type

None

classmethod setUpClass()[source]

Hook method for setting up class fixture before running tests in the class.

Return type

None

classmethod tearDownClass()[source]

Hook method for deconstructing the class fixture after running all tests in the class.

Return type

None

setUp()[source]

Hook method for setting up the test fixture before exercising it.

Return type

None

tearDown()[source]

Hook method for deconstructing the test fixture after testing it.

Return type

None

classmethod awsRegion()[source]

Pick an appropriate AWS region.

Use us-west-2 unless running on EC2, in which case use the region in which the instance is located

Return type

str

toil.test.MT
toil.test.get_temp_file(suffix='', rootDir=None)[source]

Return a string representing a temporary file, that must be manually deleted.

Parameters
  • suffix (str) –

  • rootDir (Optional[str]) –

Return type

str

toil.test.needs_env_var(var_name, comment=None)[source]

Use as a decorator before test classes or methods to run only if the given environment variable is set. Can include a comment saying what the variable should be set to.

Parameters
  • var_name (str) –

  • comment (Optional[str]) –

Return type

Callable[[MT], MT]

toil.test.needs_rsync3(test_item)[source]

Decorate classes or methods that depend on any features from rsync version 3.0.0+.

Necessary because utilsTest.testAWSProvisionerUtils() uses option –protect-args which is only available in rsync 3

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_aws_s3(test_item)[source]

Use as a decorator before test classes or methods to run only if AWS S3 is usable.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_aws_ec2(test_item)[source]

Use as a decorator before test classes or methods to run only if AWS EC2 is usable.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_aws_batch(test_item)[source]

Use as a decorator before test classes or methods to run only if AWS Batch is usable.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_google(test_item)[source]

Use as a decorator before test classes or methods to run only if Google Cloud is usable.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_gridengine(test_item)[source]

Use as a decorator before test classes or methods to run only if GridEngine is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_torque(test_item)[source]

Use as a decorator before test classes or methods to run only if PBS/Torque is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_tes(test_item)[source]

Use as a decorator before test classes or methods to run only if TES is available.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_kubernetes_installed(test_item)[source]

Use as a decorator before test classes or methods to run only if Kubernetes is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_kubernetes(test_item)[source]

Use as a decorator before test classes or methods to run only if Kubernetes is installed and configured.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_mesos(test_item)[source]

Use as a decorator before test classes or methods to run only if Mesos is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_parasol(test_item)[source]

Use as decorator so tests are only run if Parasol is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_slurm(test_item)[source]

Use as a decorator before test classes or methods to run only if Slurm is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_htcondor(test_item)[source]

Use a decorator before test classes or methods to run only if the HTCondor is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_lsf(test_item)[source]

Use as a decorator before test classes or methods to only run them if LSF is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_java(test_item)[source]

Use as a test decorator to run only if java is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_docker(test_item)[source]

Use as a decorator before test classes or methods to only run them if docker is installed and docker-based tests are enabled.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_singularity(test_item)[source]

Use as a decorator before test classes or methods to only run them if singularity is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_local_cuda(test_item)[source]

Use as a decorator before test classes or methods to only run them if a CUDA setup legible to cwltool (i.e. providing userspace nvidia-smi) is present.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_docker_cuda(test_item)[source]

Use as a decorator before test classes or methods to only run them if a CUDA setup is available through Docker.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_encryption(test_item)[source]

Use as a decorator before test classes or methods to only run them if PyNaCl is installed and configured.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_cwl(test_item)[source]

Use as a decorator before test classes or methods to only run them if CWLTool is installed and configured.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_server(test_item)[source]

Use as a decorator before test classes or methods to only run them if Connexion is installed.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_celery_broker(test_item)[source]

Use as a decorator before test classes or methods to run only if RabbitMQ is set up to take Celery jobs.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_wes_server(test_item)[source]

Use as a decorator before test classes or methods to run only if a WES server is available to run against.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_local_appliance(test_item)[source]

Use as a decorator before test classes or methods to only run them if the Toil appliance Docker image is downloaded.

Parameters

test_item (MT) –

Return type

MT

toil.test.needs_fetchable_appliance(test_item)[source]

Use as a decorator before test classes or methods to only run them if the Toil appliance Docker image is able to be downloaded from the Internet.

Parameters

test_item (MT) –

Return type

MT

toil.test.integrative(test_item)[source]

Use this to decorate integration tests so as to skip them during regular builds.

We define integration tests as A) involving other, non-Toil software components that we develop and/or B) having a higher cost (time or money). Note that brittleness does not qualify a test for being integrative. Neither does involvement of external services such as AWS, since that would cover most of Toil’s test.

Parameters

test_item (MT) –

Return type

MT

toil.test.slow(test_item)[source]

Use this decorator to identify tests that are slow and not critical. Skip if TOIL_TEST_QUICK is true.

Parameters

test_item (MT) –

Return type

MT

toil.test.methodNamePartRegex
toil.test.timeLimit(seconds)[source]

http://stackoverflow.com/a/601168 Use to limit the execution time of a function. Raises an exception if the execution of the function takes more than the specified amount of time.

Parameters

seconds (int) – maximum allowable time, in seconds

Return type

Generator[None, None, None]

>>> import time
>>> with timeLimit(2):
...    time.sleep(1)
>>> import time
>>> with timeLimit(1):
...    time.sleep(2)
Traceback (most recent call last):
    ...
RuntimeError: Timed out
toil.test.make_tests(generalMethod, targetClass, **kwargs)[source]

This method dynamically generates test methods using the generalMethod as a template. Each generated function is the result of a unique combination of parameters applied to the generalMethod. Each of the parameters has a corresponding string that will be used to name the method. These generated functions are named in the scheme: test_[generalMethodName]___[ firstParamaterName]_[someValueName]__[secondParamaterName]_…

The arguments following the generalMethodName should be a series of one or more dictionaries of the form {str : type, …} where the key represents the name of the value. The names will be used to represent the permutation of values passed for each parameter in the generalMethod.

The generated method names will list the parameters in lexicographic order by parameter name.

Parameters
  • generalMethod – A method that will be parameterized with values passed as kwargs. Note that the generalMethod must be a regular method.

  • targetClass – This represents the class to which the generated test methods will be bound. If no targetClass is specified the class of the generalMethod is assumed the target.

  • kwargs – a series of dictionaries defining values, and their respective names where each keyword is the name of a parameter in generalMethod.

>>> class Foo:
...     def has(self, num, letter):
...         return num, letter
...
...     def hasOne(self, num):
...         return num
>>> class Bar(Foo):
...     pass
>>> make_tests(Foo.has, Bar, num={'one':1, 'two':2}, letter={'a':'a', 'b':'b'})
>>> b = Bar()

Note that num comes lexicographically before letter and so appears first in the generated method names.

>>> assert b.test_has__letter_a__num_one() == b.has(1, 'a')
>>> assert b.test_has__letter_b__num_one() == b.has(1, 'b')
>>> assert b.test_has__letter_a__num_two() == b.has(2, 'a')
>>> assert b.test_has__letter_b__num_two() == b.has(2, 'b')
>>> f = Foo()
>>> hasattr(f, 'test_has__num_one__letter_a')  # should be false because Foo has no test methods
False
class toil.test.ApplianceTestSupport(methodName='runTest')[source]

Bases: ToilTest

Inheritance diagram of toil.test.ApplianceTestSupport

A Toil test that runs a user script on a minimal cluster of appliance containers.

i.e. one leader container and one worker container.

class Appliance(outer, mounts, cleanMounts=False)[source]

Bases: toil.lib.threading.ExceptionalThread

Inheritance diagram of toil.test.ApplianceTestSupport.Appliance

A thread whose join() method re-raises exceptions raised during run(). While join() is idempotent, the exception is only during the first invocation of join() that successfully joined the thread. If join() times out, no exception will be re reraised even though an exception might already have occured in run().

When subclassing this thread, override tryRun() instead of run().

>>> def f():
...     assert 0
>>> t = ExceptionalThread(target=f)
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
>>> class MyThread(ExceptionalThread):
...     def tryRun( self ):
...         assert 0
>>> t = MyThread()
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
Parameters
lock
__enter__()[source]
Return type

Appliance

__exit__(exc_type, exc_val, exc_tb)[source]
Parameters
Return type

Literal[False]

tryRun()[source]
Return type

None

runOnAppliance(*args, **kwargs)[source]
Parameters
  • args (str) –

  • kwargs (Any) –

Return type

None

writeToAppliance(path, contents)[source]
Parameters
  • path (str) –

  • contents (Any) –

Return type

None

deployScript(path, packagePath, script)[source]

Deploy a Python module on the appliance.

Parameters
  • path (str) – the path (absolute or relative to the WORDIR of the appliance container) to the root of the package hierarchy where the given module should be placed. The given directory should be on the Python path.

  • packagePath (str) – the desired fully qualified module name (dotted form) of the module

  • script (str|callable) – the contents of the Python module. If a callable is given, its source code will be extracted. This is a convenience that lets you embed user scripts into test code as nested function.

Return type

None

class LeaderThread(outer, mounts, cleanMounts=False)[source]

Bases: ApplianceTestSupport.Appliance

Inheritance diagram of toil.test.ApplianceTestSupport.LeaderThread

A thread whose join() method re-raises exceptions raised during run(). While join() is idempotent, the exception is only during the first invocation of join() that successfully joined the thread. If join() times out, no exception will be re reraised even though an exception might already have occured in run().

When subclassing this thread, override tryRun() instead of run().

>>> def f():
...     assert 0
>>> t = ExceptionalThread(target=f)
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
>>> class MyThread(ExceptionalThread):
...     def tryRun( self ):
...         assert 0
>>> t = MyThread()
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
Parameters
class WorkerThread(outer, mounts, numCores)[source]

Bases: ApplianceTestSupport.Appliance

Inheritance diagram of toil.test.ApplianceTestSupport.WorkerThread

A thread whose join() method re-raises exceptions raised during run(). While join() is idempotent, the exception is only during the first invocation of join() that successfully joined the thread. If join() times out, no exception will be re reraised even though an exception might already have occured in run().

When subclassing this thread, override tryRun() instead of run().

>>> def f():
...     assert 0
>>> t = ExceptionalThread(target=f)
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
>>> class MyThread(ExceptionalThread):
...     def tryRun( self ):
...         assert 0
>>> t = MyThread()
>>> t.start()
>>> t.join()
Traceback (most recent call last):
...
AssertionError
Parameters