Tool Contract Unittesting

Due to the dynamic nature of the workflow, it’s imperative to write unittests for tasks. This can help proactively solve any problems with resolving options.

The pbsmrtpipe.pb_tasks.tests python subpackage has several tests and takes ~ second to run.

Stylistically similar to testkit, there’s a base class that has class vars that represent the task inputs and outputs.

import logging
import os

from pbcommand.models import TaskTypes
from pbsmrtpipe.schema_opt_utils import to_opt_id

from task_test_base import _TaskTestBase, TEST_DATA_DIR, get_data_file
from pbcommand.testkit import PbTestApp

log = logging.getLogger(__name__)


def _get_test_data_file(file_name):
    return os.path.join(TEST_DATA_DIR, file_name)


class TestDevSimpleTaskDefaults(PbTestApp):
    TASK_ID = "pbsmrtpipe.tasks.dev_simple_hello_world"
    DRIVER_EMIT = 'python -m pbsmrtpipe.pb_tasks.dev emit-tool-contract {i} '.format(i=TASK_ID)
    DRIVER_RESOLVE = 'python -m pbsmrtpipe.pb_tasks.dev run-rtc '

    # User Provided values
    # Abspath'ed temp files will be automatically generated
    INPUT_FILES = [get_data_file('file.txt')]
    MAX_NPROC = 24

    RESOLVED_NPROC = 1
    RESOLVED_TASK_OPTIONS = {}
    IS_DISTRIBUTED = True
    RESOLVED_IS_DISTRIBUTED = False


class TestTestDevSimpleTask(TestDevSimpleTaskDefaults):
    # Test different set of options
    TASK_OPTIONS = {to_opt_id('dev.hello_message'): "Custom Message"}

    #RESOLVED_TASK_OPTIONS = {to_opt_id('dev.hello_message'): "Custom Message"}

Running ToolContract

Individual tasks tests (or test classes) can be run using the standard nosetests interface.

(dev_pbsmrtpipe_test)pbsmrtpipe $> nosetests  --verbose --logging-config nose.cfg pbsmrtpipe/pb_tasks/tests/test_dev_simple.py
test_ncommands (test_dev_simple.TestDevSimpleTaskDefaults) ... ok
test_ncommands_type (test_dev_simple.TestDevSimpleTaskDefaults) ... ok
test_resolved_nproc (test_dev_simple.TestDevSimpleTaskDefaults) ... ok
test_resolved_options (test_dev_simple.TestDevSimpleTaskDefaults) ... ok
test_task_id (test_dev_simple.TestDevSimpleTaskDefaults) ... ok
test_task_options (test_dev_simple.TestDevSimpleTaskDefaults) ... ok
test_task_type (test_dev_simple.TestDevSimpleTaskDefaults) ... ok
test_ncommands (test_dev_simple.TestTestDevSimpleTask) ... ok
test_ncommands_type (test_dev_simple.TestTestDevSimpleTask) ... ok
test_resolved_nproc (test_dev_simple.TestTestDevSimpleTask) ... ok
test_resolved_options (test_dev_simple.TestTestDevSimpleTask) ... ok
test_task_id (test_dev_simple.TestTestDevSimpleTask) ... ok
test_task_options (test_dev_simple.TestTestDevSimpleTask) ... ok
test_task_type (test_dev_simple.TestTestDevSimpleTask) ... ok

----------------------------------------------------------------------
Ran 14 tests in 0.051s

OK

The log file will be written to report_unittests.log, which will contain details about the dependency injection resolving and will log the actual commands generated by the task.

Run all the tests by running make test-unit. Running make test-sanity will load all the defined pipelines, tool contracts, and chunk operators. Running make test-suite will run the entire test suite.

(pbsmrtpipe_test)pbsmrtpipe $> make test-unit
# snip ...
test_run_e2e (test_tools_dev_tasks.TestScatterSubreadZMWs) ... SKIP: Missing /mnt/secondary-siv/testdata/SA3-DS
test_smoke (test_tools_gather.TestCsvGather) ... ok
test_smoke (test_tools_gather.TestJsonGather) ... ok
test_01 (test_tools_runner.TestHelloRunnableTask) ... ok
test_01 (test_tools_runner.TestRunnableTask) ... ok
test_can_find_and_load_template (test_utils.TestLoadJinjaTemplate) ... ok
test_bad_which (test_utils.TestUtils) ... SKIP: Unable to find test /mnt/secondary-siv/testdata
test_which (test_utils.TestUtils) ... SKIP: Unable to find test /mnt/secondary-siv/testdata
test_version (test_version.TestVersion) ... ok

----------------------------------------------------------------------
XML: /Users/mkocher/gh_mk_projects/pbsmrtpipe/nosetests.xml
----------------------------------------------------------------------
Ran 92 tests in 58.843s

OK (SKIP=20)