コード例 #1
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_build_with_failure(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: foo
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "Foo Retval"
              fail: True
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('foo')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert not build['success']
    assert not build['skipped']

    assert job.has_builds()
    assert not job.has_successful_builds()
    assert not job.has_running_builds()
    assert list(job.iter_builds()) == [build]
    assert list(job.iter_builds(success=True)) == []
    assert list(job.iter_builds(success=False)) == [build]

    assert isinstance(build['exception'], RuntimeError)
    assert isinstance(build['exception_tb'], TracebackInfo)
コード例 #2
0
def test_build_with_failure(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: foo
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "Foo Retval"
              fail: True
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('foo')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert not build['success']
    assert not build['skipped']

    assert job.has_builds()
    assert not job.has_successful_builds()
    assert not job.has_running_builds()
    assert list(job.iter_builds()) == [build]
    assert list(job.iter_builds(success=True)) == []
    assert list(job.iter_builds(success=False)) == [build]

    assert isinstance(build['exception'], RuntimeError)
    assert isinstance(build['exception_tb'], TracebackInfo)
コード例 #3
0
def test_build_with_skip(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-to-skip
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "Foo Retval"
              skip: True
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-to-skip')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert build['skipped']

    assert job.has_builds()
    assert not job.has_successful_builds()  # Skipped builds are ignored
    assert not job.has_running_builds()
    assert list(job.iter_builds()) == [build]
    assert list(job.iter_builds(skipped=False)) == []

    assert build['exception'] is None
    assert build['exception_tb'] is None
コード例 #4
0
def test_logging_with_context(storage):
    import logging
    from jobcontrol.core import JobExecutionContext, JobControl
    from jobcontrol.config import JobControlConfig

    logger = logging.getLogger('foo_logger')

    build_id = storage.create_build('foo')
    jc = JobControl(storage=storage, config=JobControlConfig())

    jc._install_log_handler()

    logger.debug('This will be ignored')
    logger.info('This will be ignored')
    logger.error('This will be ignored')

    with JobExecutionContext(app=jc, job_id='foo', build_id=build_id):
        logger.debug('This is a log message [D]')
        logger.info('This is a log message [I]')
        logger.warning('This is a log message [W]')
        logger.error('This is a log message [E]')
        try:
            raise ValueError('foobar')
        except:
            logger.exception('Shit happens')

    logger.info('This will get ignored as well')

    # ------------------------------------------------------------

    assert len(list(storage.iter_log_messages(build_id))) == 5
コード例 #5
0
ファイル: test_build.py プロジェクト: rshk/jobcontrol
def test_build_deletion(storage):
    func = 'jobcontrol.utils.testing:testing_job'

    config = {
        'jobs': [
            {'id': 'job-1', 'function': func},
        ]
    }

    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-1')

    build_1 = job.create_build()
    build_1.run()

    assert len(list(job.iter_builds())) == 1

    build_2 = job.create_build()
    build_2.run()

    assert len(list(job.iter_builds())) == 2

    build_1.delete()

    assert len(list(job.iter_builds())) == 1
コード例 #6
0
ファイル: test_build.py プロジェクト: rshk/jobcontrol
def test_build_configuration_pinning(storage):
    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "original-retval"
    """)
    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    # ------------------------------------------------------------
    # Create a build with old configuration
    # ------------------------------------------------------------

    job = jc.get_job('job-1')
    build = job.create_build()
    build.run()
    build.refresh()
    assert build['finished'] and build['success']
    assert build['retval'] == 'original-retval'

    build = job.create_build()
    build_id = build.id  # Then stop using this object

    # ------------------------------------------------------------
    # Update the configuration
    # ------------------------------------------------------------

    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "new-retval"
    """)
    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    # ------------------------------------------------------------
    # Running that build will return the original return value

    build = jc.get_build(build_id)
    build.run()
    build.refresh()
    assert build['finished'] and build['success']
    assert build['retval'] == 'original-retval'

    # ------------------------------------------------------------
    # A freshly created build will return the new return value

    job = jc.get_job('job-1')
    build = job.create_build()
    build.run()
    build.refresh()
    assert build['finished'] and build['success']
    assert build['retval'] == 'new-retval'

    build = job.create_build()
    build_id = build.id  # Then stop using this object
コード例 #7
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_build_failure_nonserializable_exception(storage):
    """
    It only gets worse when we cannot even serialize the exception..
    But still, we can wrap it in a serialization error exception
    and be fine with it. Hopefully, we can keep the original traceback..
    """

    config = JobControlConfig.from_string("""
    jobs:
        - id: job-nse
          function: jobcontrol.utils.testing:job_raising_nonserializable
    """)
    jc = JobControl(storage=storage, config=config)

    # Run build for RAISE nonserializable
    # It should just fail with an exception in the post-run serialization
    # todo: We might even check the traceback for that..

    job = jc.get_job('job-nse')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert not build['success']

    # WARNING! How to tell whether this job failed due to
    # the raised exception being serialized properly, or due
    # to the exception serialization failed?

    assert not isinstance(build['exception'], NonSerializableException)
    assert isinstance(build['exception'], ExceptionPlaceholder)
コード例 #8
0
ファイル: test_build.py プロジェクト: rshk/jobcontrol
def test_build_logging(storage):
    config = {
        'jobs': [
            {'id': 'job-with-logging',
             'function': 'jobcontrol.utils.testing:job_with_logging'},
        ]
    }

    jc = JobControl(storage=storage, config=config)
    job = jc.get_job('job-with-logging')

    build = job.create_build()
    build.run()
    build.refresh()

    assert build['finished'] and build['success']

    log_messages = build.iter_log_messages()
    messages_from_job = [
        msg for msg in log_messages
        if msg.name == 'jobcontrol.utils.testing.job_with_logging']

    assert len(messages_from_job) == 6

    assert messages_from_job[0].levelno == logging.DEBUG
    assert messages_from_job[0].message == 'This is a debug message'

    assert messages_from_job[0].args == ()
    assert isinstance(messages_from_job[0].created, datetime)
    assert messages_from_job[0].filename == 'testing.py'
    assert messages_from_job[0].function == 'job_with_logging'
    assert messages_from_job[0].level_name == 'DEBUG'
    assert messages_from_job[0].level == logging.DEBUG
    assert isinstance(messages_from_job[0].lineno, int)
    assert messages_from_job[0].module == 'testing'
    assert messages_from_job[0].message == 'This is a debug message'
    assert messages_from_job[0].msg == 'This is a debug message'
    assert messages_from_job[0].name == 'jobcontrol.utils.testing.job_with_logging'  # noqa
    assert isinstance(messages_from_job[0].pathname, basestring)
    assert messages_from_job[0].pathname.endswith('jobcontrol/utils/testing.py')  # noqa

    assert messages_from_job[0].exception is None
    assert messages_from_job[0].exception_tb is None

    assert messages_from_job[1].levelno == logging.INFO
    assert messages_from_job[1].message == 'This is an info message'

    assert messages_from_job[2].levelno == logging.WARNING
    assert messages_from_job[2].message == 'This is a warning message'

    assert messages_from_job[3].levelno == logging.ERROR
    assert messages_from_job[3].message == 'This is an error message'

    assert messages_from_job[4].levelno == logging.CRITICAL
    assert messages_from_job[4].message == 'This is a critical message'

    assert messages_from_job[5].levelno == logging.ERROR
    assert messages_from_job[5].message == 'This is an exception message'
    assert isinstance(messages_from_job[5].exception, ValueError)
    assert isinstance(messages_from_job[5].exception_tb, TracebackInfo)
コード例 #9
0
def test_build_deletion(storage):
    func = 'jobcontrol.utils.testing:testing_job'

    config = {
        'jobs': [
            {
                'id': 'job-1',
                'function': func
            },
        ]
    }

    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-1')

    build_1 = job.create_build()
    build_1.run()

    assert len(list(job.iter_builds())) == 1

    build_2 = job.create_build()
    build_2.run()

    assert len(list(job.iter_builds())) == 2

    build_1.delete()

    assert len(list(job.iter_builds())) == 1
コード例 #10
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_build_with_skip(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-to-skip
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "Foo Retval"
              skip: True
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-to-skip')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert build['skipped']

    assert job.has_builds()
    assert not job.has_successful_builds()  # Skipped builds are ignored
    assert not job.has_running_builds()
    assert list(job.iter_builds()) == [build]
    assert list(job.iter_builds(skipped=False)) == []

    assert build['exception'] is None
    assert build['exception_tb'] is None
コード例 #11
0
def test_build_failure_nonserializable_exception(storage):
    """
    It only gets worse when we cannot even serialize the exception..
    But still, we can wrap it in a serialization error exception
    and be fine with it. Hopefully, we can keep the original traceback..
    """

    config = JobControlConfig.from_string("""
    jobs:
        - id: job-nse
          function: jobcontrol.utils.testing:job_raising_nonserializable
    """)
    jc = JobControl(storage=storage, config=config)

    # Run build for RAISE nonserializable
    # It should just fail with an exception in the post-run serialization
    # todo: We might even check the traceback for that..

    job = jc.get_job('job-nse')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert not build['success']

    # WARNING! How to tell whether this job failed due to
    # the raised exception being serialized properly, or due
    # to the exception serialization failed?

    assert not isinstance(build['exception'], NonSerializableException)
    assert isinstance(build['exception'], ExceptionPlaceholder)
コード例 #12
0
def test_build_progress_reporting(storage):
    jc = JobControl(storage=storage, config=JobControlConfig())

    jc = JobControl(storage=storage, config={
        'jobs': [
            {'id': 'foo_job',
             'function': 'jobcontrol.utils.testing:job_with_progress',
             'kwargs': {'config': [
                 (None, 5),
                 (('foo', 'spam'), 2),
                 (('foo', 'eggs'), 4),
                 (('bar', 'bacon', 'X'), 8),
                 (('bar', 'bacon', 'Y'), 16)]}}
        ]
    })

    build = jc.create_build(job_id='foo_job')
コード例 #13
0
def test_build_configuration_pinning(storage):
    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "original-retval"
    """)
    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    # ------------------------------------------------------------
    # Create a build with old configuration
    # ------------------------------------------------------------

    job = jc.get_job('job-1')
    build = job.create_build()
    build.run()
    build.refresh()
    assert build['finished'] and build['success']
    assert build['retval'] == 'original-retval'

    build = job.create_build()
    build_id = build.id  # Then stop using this object

    # ------------------------------------------------------------
    # Update the configuration
    # ------------------------------------------------------------

    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "new-retval"
    """)
    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    # ------------------------------------------------------------
    # Running that build will return the original return value

    build = jc.get_build(build_id)
    build.run()
    build.refresh()
    assert build['finished'] and build['success']
    assert build['retval'] == 'original-retval'

    # ------------------------------------------------------------
    # A freshly created build will return the new return value

    job = jc.get_job('job-1')
    build = job.create_build()
    build.run()
    build.refresh()
    assert build['finished'] and build['success']
    assert build['retval'] == 'new-retval'

    build = job.create_build()
    build_id = build.id  # Then stop using this object
コード例 #14
0
def test_simple_build_run(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: foo
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "Foo Retval"
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('foo')

    assert job.has_builds() is False
    assert job.has_successful_builds() is False
    assert job.has_running_builds() is False
    assert job.is_outdated() is None
    assert job.can_be_built() is True

    # Create and run a build
    # ------------------------------------------------------------

    build = job.create_build()

    assert job.has_builds() is False  # "finished" builds only
    assert job.has_successful_builds() is False
    assert job.has_running_builds() is False
    assert job.is_outdated() is None
    assert job.can_be_built() is True
    assert list(job.iter_builds()) == [build]

    build.run()

    assert build['started'] is True
    assert build['finished'] is True
    assert build['success'] is True
    assert build['skipped'] is False
    assert build['retval'] == 'Foo Retval'

    assert job.has_builds() is True
    assert job.has_successful_builds() is True
    assert job.has_running_builds() is False
    assert job.is_outdated() is False
    assert job.can_be_built() is True
    assert list(job.iter_builds()) == [build]
コード例 #15
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_simple_build_run(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: foo
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "Foo Retval"
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('foo')

    assert job.has_builds() is False
    assert job.has_successful_builds() is False
    assert job.has_running_builds() is False
    assert job.is_outdated() is None
    assert job.can_be_built() is True

    # Create and run a build
    # ------------------------------------------------------------

    build = job.create_build()

    assert job.has_builds() is False  # "finished" builds only
    assert job.has_successful_builds() is False
    assert job.has_running_builds() is False
    assert job.is_outdated() is None
    assert job.can_be_built() is True
    assert list(job.iter_builds()) == [build]

    build.run()

    assert build['started'] is True
    assert build['finished'] is True
    assert build['success'] is True
    assert build['skipped'] is False
    assert build['retval'] == 'Foo Retval'

    assert job.has_builds() is True
    assert job.has_successful_builds() is True
    assert job.has_running_builds() is False
    assert job.is_outdated() is False
    assert job.can_be_built() is True
    assert list(job.iter_builds()) == [build]
コード例 #16
0
def test_build_progress_reporting(storage):
    jc = JobControl(storage=storage, config=JobControlConfig())

    jc = JobControl(storage=storage,
                    config={
                        'jobs': [{
                            'id': 'foo_job',
                            'function':
                            'jobcontrol.utils.testing:job_with_progress',
                            'kwargs': {
                                'config': [(None, 5), (('foo', 'spam'), 2),
                                           (('foo', 'eggs'), 4),
                                           (('bar', 'bacon', 'X'), 8),
                                           (('bar', 'bacon', 'Y'), 16)]
                            }
                        }]
                    })

    build = jc.create_build(job_id='foo_job')
コード例 #17
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_build_failure_due_to_nonserializable_object(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-nso
          function: jobcontrol.utils.testing:job_returning_nonserializable
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-nso')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert not build['success']

    assert isinstance(build['exception'], SerializationError)
    assert (  # The original exception message is kept..
        "TypeError('a class that defines __slots__ without defining "
        "__getstate__ cannot be pickled',)") in build['exception'].message
コード例 #18
0
def cli_main_grp(config_file, outfmt):
    # todo: use pass_context for passing context instead of global objects?

    global jc, output_fmt

    output_fmt = outfmt

    if config_file is None:
        raise ValueError('Configuration file missing')

    jc = JobControl.from_config_file(config_file)
コード例 #19
0
def test_build_failure_due_to_nonserializable_object(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-nso
          function: jobcontrol.utils.testing:job_returning_nonserializable
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-nso')
    build = job.create_build()
    build.run()

    assert build['started']
    assert build['finished']
    assert not build['success']

    assert isinstance(build['exception'], SerializationError)
    assert (  # The original exception message is kept..
        "TypeError('a class that defines __slots__ without defining "
        "__getstate__ cannot be pickled',)") in build['exception'].message
コード例 #20
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_simple_build_deletion(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-to-delete
          function: jobcontrol.utils.testing:testing_job
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-to-delete')

    build_1 = job.create_build()
    build_1.run()

    assert len(list(job.iter_builds())) == 1

    build_2 = job.create_build()
    build_2.run()

    assert len(list(job.iter_builds())) == 2

    build_1.delete()

    assert len(list(job.iter_builds())) == 1
コード例 #21
0
def test_simple_build_deletion(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-to-delete
          function: jobcontrol.utils.testing:testing_job
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-to-delete')

    build_1 = job.create_build()
    build_1.run()

    assert len(list(job.iter_builds())) == 1

    build_2 = job.create_build()
    build_2.run()

    assert len(list(job.iter_builds())) == 2

    build_1.delete()

    assert len(list(job.iter_builds())) == 1
コード例 #22
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_build_deletion_with_cleanup(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-to-delete
          function: jobcontrol.utils.testing:job_creating_temp_file
          cleanup_function: jobcontrol.utils.testing:cleanup_temp_file
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-to-delete')

    build = job.create_build()
    build.run()

    assert build['finished'] and build['success']
    assert isinstance(build.retval, str)
    assert os.path.isfile(build.retval)

    assert len(list(job.iter_builds())) == 1

    build.delete()

    assert len(list(job.iter_builds())) == 0
    assert not os.path.isfile(build.retval)
コード例 #23
0
def test_build_deletion_with_cleanup(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: job-to-delete
          function: jobcontrol.utils.testing:job_creating_temp_file
          cleanup_function: jobcontrol.utils.testing:cleanup_temp_file
    """)
    jc = JobControl(storage=storage, config=config)

    job = jc.get_job('job-to-delete')

    build = job.create_build()
    build.run()

    assert build['finished'] and build['success']
    assert isinstance(build.retval, str)
    assert os.path.isfile(build.retval)

    assert len(list(job.iter_builds())) == 1

    build.delete()

    assert len(list(job.iter_builds())) == 0
    assert not os.path.isfile(build.retval)
コード例 #24
0
def test_core_config_jobs(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: foo
          function: mymodule.foo
          dependencies: []

        - id: bar
          function: mymodule.bar
          dependencies: ['foo']

        - id: baz
          function: mymodule.baz
          dependencies: ['foo', 'bar']
    """)
    jc = JobControl(storage=storage, config=config)

    job_foo = jc.get_job('foo')
    job_bar = jc.get_job('bar')
    job_baz = jc.get_job('baz')

    # Check jobs
    # ------------------------------------------------------------

    assert isinstance(job_foo, JobInfo)
    assert job_foo.id == 'foo'
    assert job_foo.config['id'] == 'foo'
    assert job_foo.config['function'] == 'mymodule.foo'
    assert job_foo.config['args'] == ()
    assert job_foo.config['kwargs'] == {}
    assert job_foo.config['dependencies'] == []
    assert list(job_foo.get_deps()) == []
    assert list(job_foo.get_revdeps()) == [job_bar, job_baz]
    assert job_foo.get_status() == 'not_built'
    assert list(job_foo.iter_builds()) == []
    assert job_foo.get_latest_successful_build() is None
    assert job_foo.has_builds() is False
    assert job_foo.has_successful_builds() is False
    assert job_foo.has_running_builds() is False
    assert job_foo.is_outdated() is None  # no builds..
    assert job_foo.can_be_built() is True

    assert isinstance(job_bar, JobInfo)
    assert job_bar.id == 'bar'
    assert job_bar.config['id'] == 'bar'
    assert job_bar.config['function'] == 'mymodule.bar'
    assert job_bar.config['args'] == ()
    assert job_bar.config['kwargs'] == {}
    assert job_bar.config['dependencies'] == ['foo']
    assert list(job_bar.get_deps()) == [job_foo]
    assert list(job_bar.get_revdeps()) == [job_baz]
    assert job_bar.get_status() == 'not_built'
    assert list(job_bar.iter_builds()) == []
    assert job_bar.get_latest_successful_build() is None
    assert job_bar.has_builds() is False
    assert job_bar.has_successful_builds() is False
    assert job_bar.has_running_builds() is False
    assert job_bar.is_outdated() is None  # no builds..
    assert job_bar.can_be_built() is False  # "foo" has no builds

    assert isinstance(job_baz, JobInfo)
    assert job_baz.id == 'baz'
    assert job_baz.config['id'] == 'baz'
    assert job_baz.config['function'] == 'mymodule.baz'
    assert job_baz.config['args'] == ()
    assert job_baz.config['kwargs'] == {}
    assert job_baz.config['dependencies'] == ['foo', 'bar']
    assert list(job_baz.get_deps()) == [job_foo, job_bar]
    assert list(job_baz.get_revdeps()) == []
    assert job_baz.get_status() == 'not_built'
    assert list(job_baz.iter_builds()) == []
    assert job_baz.get_latest_successful_build() is None
    assert job_baz.has_builds() is False
    assert job_baz.has_successful_builds() is False
    assert job_baz.has_running_builds() is False
    assert job_baz.is_outdated() is None  # no builds..
    assert job_baz.can_be_built() is False  # "foo" and "bar" have no builds

    # Exception on non-existing job

    with pytest.raises(NotFound):
        jc.get_job('does-not-exist')

    # Iterate jobs

    assert list(jc.iter_jobs()) == [job_foo, job_bar, job_baz]
コード例 #25
0
def test_build_logging(storage):
    config = {
        'jobs': [
            {
                'id': 'job-with-logging',
                'function': 'jobcontrol.utils.testing:job_with_logging'
            },
        ]
    }

    jc = JobControl(storage=storage, config=config)
    job = jc.get_job('job-with-logging')

    build = job.create_build()
    build.run()
    build.refresh()

    assert build['finished'] and build['success']

    log_messages = build.iter_log_messages()
    messages_from_job = [
        msg for msg in log_messages
        if msg.name == 'jobcontrol.utils.testing.job_with_logging'
    ]

    assert len(messages_from_job) == 6

    assert messages_from_job[0].levelno == logging.DEBUG
    assert messages_from_job[0].message == 'This is a debug message'

    assert messages_from_job[0].args == ()
    assert isinstance(messages_from_job[0].created, datetime)
    assert messages_from_job[0].filename == 'testing.py'
    assert messages_from_job[0].function == 'job_with_logging'
    assert messages_from_job[0].level_name == 'DEBUG'
    assert messages_from_job[0].level == logging.DEBUG
    assert isinstance(messages_from_job[0].lineno, int)
    assert messages_from_job[0].module == 'testing'
    assert messages_from_job[0].message == 'This is a debug message'
    assert messages_from_job[0].msg == 'This is a debug message'
    assert messages_from_job[
        0].name == 'jobcontrol.utils.testing.job_with_logging'  # noqa
    assert isinstance(messages_from_job[0].pathname, basestring)
    assert messages_from_job[0].pathname.endswith(
        'jobcontrol/utils/testing.py')  # noqa

    assert messages_from_job[0].exception is None
    assert messages_from_job[0].exception_tb is None

    assert messages_from_job[1].levelno == logging.INFO
    assert messages_from_job[1].message == 'This is an info message'

    assert messages_from_job[2].levelno == logging.WARNING
    assert messages_from_job[2].message == 'This is a warning message'

    assert messages_from_job[3].levelno == logging.ERROR
    assert messages_from_job[3].message == 'This is an error message'

    assert messages_from_job[4].levelno == logging.CRITICAL
    assert messages_from_job[4].message == 'This is a critical message'

    assert messages_from_job[5].levelno == logging.ERROR
    assert messages_from_job[5].message == 'This is an exception message'
    assert isinstance(messages_from_job[5].exception, ValueError)
    assert isinstance(messages_from_job[5].exception_tb, TracebackInfo)
コード例 #26
0
def test_dependency_pinning(storage):
    # Test for dependency pinning
    # ---------------------------
    #
    # We want to make sure that a build uses the latest build for
    # a dependency at the time it was created; so if we run a build
    # for job-1, then create a build for job-2, then run another build
    # for job-1, the return values used when running a build for job-2
    # will be the one from the *first* build.
    # To ensure this, we are going to change the return value
    # in the configuration.

    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "original-retval"

        - id: job-2
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: !retval 'job-1'
          dependencies: ['job-1']
    """)

    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    build_1_1 = jc.create_build('job-1')
    build_1_1.run()
    build_1_1.refresh()
    assert build_1_1['finished'] and build_1_1['success']
    assert build_1_1['retval'] == 'original-retval'

    # This should have pinned dependency on build_1_1
    build_2_1 = jc.create_build('job-2')

    # Update configuration
    # --------------------

    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "new-retval"

        - id: job-2
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: !retval 'job-1'
          dependencies: ['job-1']
    """)

    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    build_1_2 = jc.create_build('job-1')
    build_1_2.run()
    build_1_2.refresh()
    assert build_1_2['finished'] and build_1_2['success']
    assert build_1_2['retval'] == 'new-retval'

    build_2_1 = jc.get_build(build_2_1.id)  # Get from *new* JC
    build_2_1.run()
    build_2_1.refresh()
    assert build_2_1['finished'] and build_2_1['success']
    assert build_2_1['retval'] == 'original-retval'

    build_2_2 = jc.create_build('job-2')
    build_2_2.run()
    build_2_2.refresh()
    assert build_2_2['finished'] and build_2_2['success']
    assert build_2_2['retval'] == 'new-retval'
コード例 #27
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_core_config_jobs(storage):
    config = JobControlConfig.from_string("""
    jobs:
        - id: foo
          function: mymodule.foo
          dependencies: []

        - id: bar
          function: mymodule.bar
          dependencies: ['foo']

        - id: baz
          function: mymodule.baz
          dependencies: ['foo', 'bar']
    """)
    jc = JobControl(storage=storage, config=config)

    job_foo = jc.get_job('foo')
    job_bar = jc.get_job('bar')
    job_baz = jc.get_job('baz')

    # Check jobs
    # ------------------------------------------------------------

    assert isinstance(job_foo, JobInfo)
    assert job_foo.id == 'foo'
    assert job_foo.config['id'] == 'foo'
    assert job_foo.config['function'] == 'mymodule.foo'
    assert job_foo.config['args'] == ()
    assert job_foo.config['kwargs'] == {}
    assert job_foo.config['dependencies'] == []
    assert list(job_foo.get_deps()) == []
    assert list(job_foo.get_revdeps()) == [job_bar, job_baz]
    assert job_foo.get_status() == 'not_built'
    assert list(job_foo.iter_builds()) == []
    assert job_foo.get_latest_successful_build() is None
    assert job_foo.has_builds() is False
    assert job_foo.has_successful_builds() is False
    assert job_foo.has_running_builds() is False
    assert job_foo.is_outdated() is None  # no builds..
    assert job_foo.can_be_built() is True

    assert isinstance(job_bar, JobInfo)
    assert job_bar.id == 'bar'
    assert job_bar.config['id'] == 'bar'
    assert job_bar.config['function'] == 'mymodule.bar'
    assert job_bar.config['args'] == ()
    assert job_bar.config['kwargs'] == {}
    assert job_bar.config['dependencies'] == ['foo']
    assert list(job_bar.get_deps()) == [job_foo]
    assert list(job_bar.get_revdeps()) == [job_baz]
    assert job_bar.get_status() == 'not_built'
    assert list(job_bar.iter_builds()) == []
    assert job_bar.get_latest_successful_build() is None
    assert job_bar.has_builds() is False
    assert job_bar.has_successful_builds() is False
    assert job_bar.has_running_builds() is False
    assert job_bar.is_outdated() is None  # no builds..
    assert job_bar.can_be_built() is False  # "foo" has no builds

    assert isinstance(job_baz, JobInfo)
    assert job_baz.id == 'baz'
    assert job_baz.config['id'] == 'baz'
    assert job_baz.config['function'] == 'mymodule.baz'
    assert job_baz.config['args'] == ()
    assert job_baz.config['kwargs'] == {}
    assert job_baz.config['dependencies'] == ['foo', 'bar']
    assert list(job_baz.get_deps()) == [job_foo, job_bar]
    assert list(job_baz.get_revdeps()) == []
    assert job_baz.get_status() == 'not_built'
    assert list(job_baz.iter_builds()) == []
    assert job_baz.get_latest_successful_build() is None
    assert job_baz.has_builds() is False
    assert job_baz.has_successful_builds() is False
    assert job_baz.has_running_builds() is False
    assert job_baz.is_outdated() is None  # no builds..
    assert job_baz.can_be_built() is False  # "foo" and "bar" have no builds

    # Exception on non-existing job

    with pytest.raises(NotFound):
        jc.get_job('does-not-exist')

    # Iterate jobs

    assert list(jc.iter_jobs()) == [job_foo, job_bar, job_baz]
コード例 #28
0
ファイル: test_core.py プロジェクト: rshk/jobcontrol
def test_job_status_reporting(storage):

    config = JobControlConfig.from_string("""
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
        - id: job-2
          function: jobcontrol.utils.testing:testing_job
        - id: job-3
          function: jobcontrol.utils.testing:testing_job
          dependencies: ['job-1', 'job-2']
        - id: job-4
          function: jobcontrol.utils.testing:testing_job
          dependencies: ['job-3']

    """)
    jc = JobControl(storage=storage, config=config)

    # Check status of unbuilt jobs
    job_1 = jc.get_job('job-1')
    job_2 = jc.get_job('job-2')
    job_3 = jc.get_job('job-3')
    job_4 = jc.get_job('job-4')

    assert job_1.get_status() == 'not_built'
    assert job_2.get_status() == 'not_built'
    assert job_3.get_status() == 'not_built'
    assert job_4.get_status() == 'not_built'

    assert list(job_1.iter_builds()) == []
    assert job_1.get_latest_successful_build() is None
    assert job_1.has_builds() is False
    assert job_1.has_successful_builds() is False
    assert job_1.has_running_builds() is False
    assert job_1.is_outdated() is None  # IDK
    assert job_1.can_be_built() is True

    assert job_2.can_be_built() is True
    assert job_3.can_be_built() is False  # deps not met
    assert job_4.can_be_built() is False  # deps not met

    # ------------------------------------------------------------
    # Manually start a build for job 1, as we want to
    # check it is running, etc..
    # ------------------------------------------------------------

    build_1_1 = job_1.create_build()
    assert build_1_1['started'] is False
    assert build_1_1['finished'] is False
    assert job_1.has_builds() is False
    assert job_1.has_running_builds() is False

    assert job_1.get_status() == 'not_built'

    jc.storage.start_build(build_1_1.id)
    build_1_1.refresh()
    assert build_1_1['started'] is True
    assert build_1_1['finished'] is False
    assert job_1.has_builds() is False  # **Completed** builds..
    assert job_1.has_running_builds() is True

    # Note: "running" is not anymore reported as a state
    assert job_1.get_status() == 'not_built'

    jc.storage.finish_build(build_1_1.id, success=False)
    build_1_1.refresh()
    assert build_1_1['started'] is True
    assert build_1_1['finished'] is True
    assert build_1_1['success'] is False
    assert job_1.has_builds() is True
    assert job_1.has_successful_builds() is False
    assert job_1.has_running_builds() is False

    assert job_1.get_status() == 'failed'

    # ------------------------------------------------------------
    # Do it again, with a new build, which should succeed this time
    # ------------------------------------------------------------

    build_1_2 = job_1.create_build()
    build_1_2.run()
    build_1_2.refresh()

    assert len(list(job_1.iter_builds())) == 2
    assert build_1_2['started'] is True
    assert build_1_2['finished'] is True
    assert build_1_2['success'] is True
    assert job_1.has_builds() is True
    assert job_1.has_successful_builds() is True
    assert job_1.has_running_builds() is False

    assert job_1.get_status() == 'success'

    # ------------------------------------------------------------
    # Now build job 2 and make sure 3 becomes buildable
    # ------------------------------------------------------------

    assert job_3.can_be_built() is False
    build_2_1 = job_2.create_build()
    build_2_1.run()
    assert job_3.can_be_built() is True

    # Job 4 is still missing a build from 3
    assert job_4.can_be_built() is False
    job_3.create_build().run()
    assert job_4.can_be_built() is True

    assert job_2.get_status() == 'success'
    assert job_3.get_status() == 'success'
    assert job_4.get_status() == 'not_built'

    # ------------------------------------------------------------
    # Rebuild #1 to get #3 to be "outdated"
    # ------------------------------------------------------------

    assert job_3.is_outdated() is False
    job_1.create_build().run()
    assert job_3.is_outdated() is True
    assert job_3.get_status() == 'outdated'
コード例 #29
0
ファイル: test_build.py プロジェクト: rshk/jobcontrol
def test_dependency_pinning(storage):
    # Test for dependency pinning
    # ---------------------------
    #
    # We want to make sure that a build uses the latest build for
    # a dependency at the time it was created; so if we run a build
    # for job-1, then create a build for job-2, then run another build
    # for job-1, the return values used when running a build for job-2
    # will be the one from the *first* build.
    # To ensure this, we are going to change the return value
    # in the configuration.

    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "original-retval"

        - id: job-2
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: !retval 'job-1'
          dependencies: ['job-1']
    """)

    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    build_1_1 = jc.create_build('job-1')
    build_1_1.run()
    build_1_1.refresh()
    assert build_1_1['finished'] and build_1_1['success']
    assert build_1_1['retval'] == 'original-retval'

    # This should have pinned dependency on build_1_1
    build_2_1 = jc.create_build('job-2')

    # Update configuration
    # --------------------

    config = dedent("""\
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: "new-retval"

        - id: job-2
          function: jobcontrol.utils.testing:testing_job
          kwargs:
              retval: !retval 'job-1'
          dependencies: ['job-1']
    """)

    config = JobControlConfig.from_string(config)
    jc = JobControl(storage=storage, config=config)

    build_1_2 = jc.create_build('job-1')
    build_1_2.run()
    build_1_2.refresh()
    assert build_1_2['finished'] and build_1_2['success']
    assert build_1_2['retval'] == 'new-retval'

    build_2_1 = jc.get_build(build_2_1.id)  # Get from *new* JC
    build_2_1.run()
    build_2_1.refresh()
    assert build_2_1['finished'] and build_2_1['success']
    assert build_2_1['retval'] == 'original-retval'

    build_2_2 = jc.create_build('job-2')
    build_2_2.run()
    build_2_2.refresh()
    assert build_2_2['finished'] and build_2_2['success']
    assert build_2_2['retval'] == 'new-retval'
コード例 #30
0
def jc(storage):
    from jobcontrol.core import JobControl
    return JobControl(storage)
コード例 #31
0
def test_job_status_reporting(storage):

    config = JobControlConfig.from_string("""
    jobs:
        - id: job-1
          function: jobcontrol.utils.testing:testing_job
        - id: job-2
          function: jobcontrol.utils.testing:testing_job
        - id: job-3
          function: jobcontrol.utils.testing:testing_job
          dependencies: ['job-1', 'job-2']
        - id: job-4
          function: jobcontrol.utils.testing:testing_job
          dependencies: ['job-3']

    """)
    jc = JobControl(storage=storage, config=config)

    # Check status of unbuilt jobs
    job_1 = jc.get_job('job-1')
    job_2 = jc.get_job('job-2')
    job_3 = jc.get_job('job-3')
    job_4 = jc.get_job('job-4')

    assert job_1.get_status() == 'not_built'
    assert job_2.get_status() == 'not_built'
    assert job_3.get_status() == 'not_built'
    assert job_4.get_status() == 'not_built'

    assert list(job_1.iter_builds()) == []
    assert job_1.get_latest_successful_build() is None
    assert job_1.has_builds() is False
    assert job_1.has_successful_builds() is False
    assert job_1.has_running_builds() is False
    assert job_1.is_outdated() is None  # IDK
    assert job_1.can_be_built() is True

    assert job_2.can_be_built() is True
    assert job_3.can_be_built() is False  # deps not met
    assert job_4.can_be_built() is False  # deps not met

    # ------------------------------------------------------------
    # Manually start a build for job 1, as we want to
    # check it is running, etc..
    # ------------------------------------------------------------

    build_1_1 = job_1.create_build()
    assert build_1_1['started'] is False
    assert build_1_1['finished'] is False
    assert job_1.has_builds() is False
    assert job_1.has_running_builds() is False

    assert job_1.get_status() == 'not_built'

    jc.storage.start_build(build_1_1.id)
    build_1_1.refresh()
    assert build_1_1['started'] is True
    assert build_1_1['finished'] is False
    assert job_1.has_builds() is False  # **Completed** builds..
    assert job_1.has_running_builds() is True

    # Note: "running" is not anymore reported as a state
    assert job_1.get_status() == 'not_built'

    jc.storage.finish_build(build_1_1.id, success=False)
    build_1_1.refresh()
    assert build_1_1['started'] is True
    assert build_1_1['finished'] is True
    assert build_1_1['success'] is False
    assert job_1.has_builds() is True
    assert job_1.has_successful_builds() is False
    assert job_1.has_running_builds() is False

    assert job_1.get_status() == 'failed'

    # ------------------------------------------------------------
    # Do it again, with a new build, which should succeed this time
    # ------------------------------------------------------------

    build_1_2 = job_1.create_build()
    build_1_2.run()
    build_1_2.refresh()

    assert len(list(job_1.iter_builds())) == 2
    assert build_1_2['started'] is True
    assert build_1_2['finished'] is True
    assert build_1_2['success'] is True
    assert job_1.has_builds() is True
    assert job_1.has_successful_builds() is True
    assert job_1.has_running_builds() is False

    assert job_1.get_status() == 'success'

    # ------------------------------------------------------------
    # Now build job 2 and make sure 3 becomes buildable
    # ------------------------------------------------------------

    assert job_3.can_be_built() is False
    build_2_1 = job_2.create_build()
    build_2_1.run()
    assert job_3.can_be_built() is True

    # Job 4 is still missing a build from 3
    assert job_4.can_be_built() is False
    job_3.create_build().run()
    assert job_4.can_be_built() is True

    assert job_2.get_status() == 'success'
    assert job_3.get_status() == 'success'
    assert job_4.get_status() == 'not_built'

    # ------------------------------------------------------------
    # Rebuild #1 to get #3 to be "outdated"
    # ------------------------------------------------------------

    assert job_3.is_outdated() is False
    job_1.create_build().run()
    assert job_3.is_outdated() is True
    assert job_3.get_status() == 'outdated'