示例#1
0
def test_http_lifecycle_wrapper_with_lifecycle():
  runner_mock = mock.create_autospec(ThermosTaskRunner)
  mti = MesosTaskInstance(lifecycle=LifecycleConfig(http=HttpLifecycleConfig()))

  # pass-thru if no health port has been defined -- see comment in http_lifecycle.py regarding
  # the rationalization for this behavior.
  with make_mocks(mti, {}) as (runner_mock, runner_wrapper, wrapper_init):
    assert runner_mock is runner_wrapper
    assert wrapper_init.mock_calls == []

  # wrap it once health is available and validate the constructor is called as expected
  with make_mocks(mti, {'health': 31337}) as (runner_mock, runner_wrapper, wrapper_init):
    assert isinstance(runner_wrapper, HttpLifecycleManager)
    assert wrapper_init.mock_calls == [
      mock.call(runner_mock, 31337, [('/quitquitquit', Amount(5, Time.SECONDS)),
        ('/abortabortabort', Amount(5, Time.SECONDS))])
    ]

  # Validate that we can override ports, endpoints, wait times
  mti = MesosTaskInstance(lifecycle=LifecycleConfig(http=HttpLifecycleConfig(
      port='http',
      graceful_shutdown_endpoint='/frankfrankfrank',
      shutdown_endpoint='/bobbobbob',
      graceful_shutdown_wait_secs=123,
      shutdown_wait_secs=456
  )))
  portmap = {'http': 12345, 'admin': 54321}
  with make_mocks(mti, portmap) as (runner_mock, runner_wrapper, wrapper_init):
    assert isinstance(runner_wrapper, HttpLifecycleManager)
    assert wrapper_init.mock_calls == [
      mock.call(runner_mock, 12345, [('/frankfrankfrank', Amount(123, Time.SECONDS)),
        ('/bobbobbob', Amount(456, Time.SECONDS))])
    ]
示例#2
0
def test_http_lifecycle_wrapper_without_lifecycle():
  mti_without_lifecycle = MesosTaskInstance()
  mti_without_http_lifecycle = MesosTaskInstance(lifecycle=LifecycleConfig())

  runner_mock = mock.create_autospec(ThermosTaskRunner)
  assert HttpLifecycleManager.wrap(runner_mock, mti_without_lifecycle, {}) is runner_mock
  assert HttpLifecycleManager.wrap(runner_mock, mti_without_http_lifecycle, {}) is runner_mock
示例#3
0
def task_instance_from_job(job, instance, hostname):
    instance_context = MesosContext(instance=instance, hostname=hostname)
    health_check_config = HealthCheckConfig()
    if job.has_health_check_config():
        health_check_config = job.health_check_config()
    ti = MesosTaskInstance(task=job.task(), role=job.role(), health_check_config=health_check_config, instance=instance)
    if job.has_announce():
        ti = ti(announce=job.announce())
    if job.has_environment():
        ti = ti(environment=job.environment())
    if job.has_lifecycle():
        ti = ti(lifecycle=job.lifecycle())
    return ti.bind(mesos=instance_context)
示例#4
0
def task_instance_from_job(job, instance, hostname):
    instance_context = MesosContext(instance=instance, hostname=hostname)
    health_check_config = HealthCheckConfig()
    if job.has_health_check_config():
        health_check_config = job.health_check_config()
    ti = MesosTaskInstance(task=job.task(),
                           role=job.role(),
                           health_check_config=health_check_config,
                           instance=instance)
    if job.has_announce():
        ti = ti(announce=job.announce())
    if job.has_environment():
        ti = ti(environment=job.environment())
    if job.has_lifecycle():
        ti = ti(lifecycle=job.lifecycle())
    return ti.bind(mesos=instance_context)
示例#5
0
def mesos_task_instance_from_assigned_task(assigned_task):
  """Deserialize MesosTaskInstance from an AssignedTask thrift."""
  thermos_task = assigned_task.task.executorConfig.data

  if not thermos_task:
    raise TaskInfoError('Task did not have a thermos config!')

  try:
    json_blob = json.loads(thermos_task)
  except (TypeError, ValueError) as e:
    raise TaskInfoError('Could not deserialize thermos config: %s' % e)

  # TODO(wickman) Determine if there are any serialized MesosTaskInstances in the wild;
  # kill this code if not.
  if 'instance' in json_blob:
    return MesosTaskInstance.json_loads(thermos_task)

  # This is a MesosJob
  task_instance = task_instance_from_job(
      MesosJob.json_loads(thermos_task), assigned_task.instanceId)

  try:
    ThermosTaskValidator.assert_valid_task(task_instance.task())
    ThermosTaskValidator.assert_all_refs_bound(task_instance)
  except ThermosTaskValidator.InvalidTaskError as e:
    raise UnexpectedUnboundRefsError('Got invalid task: %s' % e)

  task_instance, _ = task_instance.interpolate()
  return task_instance
示例#6
0
def mesos_task_instance_from_assigned_task(assigned_task):
    """Deserialize MesosTaskInstance from an AssignedTask thrift."""
    thermos_task = assigned_task.task.executorConfig.data

    if not thermos_task:
        raise TaskInfoError('Task did not have a thermos config!')

    try:
        json_blob = json.loads(thermos_task)
    except (TypeError, ValueError) as e:
        raise TaskInfoError('Could not deserialize thermos config: %s' % e)

    # TODO(wickman) Determine if there are any serialized MesosTaskInstances in the wild;
    # kill this code if not.
    if 'instance' in json_blob:
        return MesosTaskInstance.json_loads(thermos_task)

    # This is a MesosJob
    task_instance = task_instance_from_job(MesosJob.json_loads(thermos_task),
                                           assigned_task.instanceId,
                                           assigned_task.slaveHost)

    try:
        ThermosTaskValidator.assert_valid_task(task_instance.task())
        ThermosTaskValidator.assert_all_refs_bound(task_instance)
    except ThermosTaskValidator.InvalidTaskError as e:
        raise UnexpectedUnboundRefsError('Got invalid task: %s' % e)

    task_instance, _ = task_instance.interpolate()
    return task_instance
示例#7
0
def task_instance_from_job(job, instance):
  instance_context = MesosContext(instance=instance)
  # TODO(Sathya): Remove health_check_interval_secs references after deprecation cycle is complete.
  health_check_config = HealthCheckConfig()
  if job.has_health_check_interval_secs():
    health_check_config = HealthCheckConfig(interval_secs=job.health_check_interval_secs().get())
  elif job.has_health_check_config():
    health_check_config = job.health_check_config()
  ti = MesosTaskInstance(task=job.task(),
                         role=job.role(),
                         health_check_interval_secs=health_check_config.interval_secs().get(),
                         health_check_config=health_check_config,
                         instance=instance)
  if job.has_announce():
    ti = ti(announce=job.announce())
  if job.has_environment():
    ti = ti(environment=job.environment())
  return ti.bind(mesos=instance_context).interpolate()
示例#8
0
def task_instance_from_job(job, instance):
    instance_context = MesosContext(instance=instance)
    # TODO(Sathya): Remove health_check_interval_secs references after deprecation cycle is complete.
    health_check_config = HealthCheckConfig()
    if job.has_health_check_interval_secs():
        health_check_config = HealthCheckConfig(
            interval_secs=job.health_check_interval_secs().get())
    elif job.has_health_check_config():
        health_check_config = job.health_check_config()
    ti = MesosTaskInstance(
        task=job.task(),
        role=job.role(),
        health_check_interval_secs=health_check_config.interval_secs().get(),
        health_check_config=health_check_config,
        instance=instance)
    if job.has_announce():
        ti = ti(announce=job.announce())
    if job.has_environment():
        ti = ti(environment=job.environment())
    return ti.bind(mesos=instance_context).interpolate()
示例#9
0
def test_http_lifecycle_wraps_start_and_stop():
  mti = MesosTaskInstance(lifecycle=LifecycleConfig(http=HttpLifecycleConfig()))
  runner_mock = mock.create_autospec(ThermosTaskRunner)
  with mock.patch.object(HttpLifecycleManager, '_terminate_http', return_value=None) as http_mock:
    runner_wrapper = HttpLifecycleManager.wrap(runner_mock, mti, {'health': 31337})

    # ensure that start and stop are properly wrapped
    runner_wrapper.start(23.3)
    assert runner_mock.start.mock_calls == [mock.call(timeout=23.3)]

    # ensure that http teardown called when stopped
    runner_wrapper.stop(32.2)
    assert http_mock.mock_calls == [mock.call()]
    assert runner_mock.stop.mock_calls == [mock.call(timeout=32.2)]
示例#10
0
def mesos_task_instance_from_assigned_task(assigned_task):
  """Deserialize MesosTaskInstance from an AssignedTask thrift."""
  thermos_task = assigned_task.task.executorConfig.data

  if not thermos_task:
    raise ValueError('Task did not have a thermos config!')

  try:
    json_blob = json.loads(thermos_task)
  except (TypeError, ValueError) as e:
    raise ValueError('Could not deserialize thermos config: %s' % e)

  # As part of the transition for MESOS-2133, we can send either a MesosTaskInstance
  # or we can be sending a MesosJob.  So handle both possible cases.  Once everyone
  # is using MesosJob, then we can begin to leverage additional information that
  # becomes available such as cluster.
  if 'instance' in json_blob:
    return MesosTaskInstance.json_loads(thermos_task)

  # This is a MesosJob
  mti, refs = task_instance_from_job(MesosJob.json_loads(thermos_task), assigned_task.instanceId)
  unbound_refs = []
  for ref in refs:
    # If the ref is {{thermos.task_id}} or a subscope of
    # {{thermos.ports}}, it currently gets bound by the Thermos Runner,
    # so we must leave them unbound.
    #
    # {{thermos.user}} is a legacy binding which we can safely ignore.
    #
    # TODO(wickman) These should be rewritten by the mesos client to use
    # %%style%% replacements in order to allow us to better type-check configs
    # client-side.
    if ref == Ref.from_address('thermos.task_id'):
      continue
    if Ref.subscope(Ref.from_address('thermos.ports'), ref):
      continue
    if ref == Ref.from_address('thermos.user'):
      continue
    else:
      unbound_refs.append(ref)

  if len(unbound_refs) != 0:
    raise ValueError('Unexpected unbound refs: %s' % ' '.join(map(str, unbound_refs)))

  return mti
示例#11
0
                      task=TaskConfig(executorConfig=ExecutorConfig(
                          name=AURORA_EXECUTOR_NAME,
                          data=thermos_config.json_dumps()),
                                      job=JobKey(role=role,
                                                 environment='env',
                                                 name='name')),
                      assignedPorts=assigned_ports,
                      **kw)
    td = mesos_pb2.TaskInfo()
    td.task_id.value = task_id
    td.name = thermos_config.task().name().get()
    td.data = serialize(at)
    return td


BASE_MTI = MesosTaskInstance(instance=0, role=getpass.getuser())
BASE_TASK = Task(resources=Resources(cpu=1.0, ram=16 * MB, disk=32 * MB))

HELLO_WORLD_TASK_ID = 'hello_world-001'
HELLO_WORLD = BASE_TASK(name='hello_world',
                        processes=[
                            Process(name='hello_world_{{thermos.task_id}}',
                                    cmdline='echo hello world')
                        ])
HELLO_WORLD_MTI = BASE_MTI(task=HELLO_WORLD)

SLEEP60 = BASE_TASK(processes=[Process(name='sleep60', cmdline='sleep 60')])
SLEEP2 = BASE_TASK(processes=[Process(name='sleep2', cmdline='sleep 2')])
SLEEP60_MTI = BASE_MTI(task=SLEEP60)

MESOS_JOB = MesosJob(
from twitter.common.quantity import Amount, Time

from apache.aurora.config.schema.base import MB, MesosTaskInstance, Process, Resources, Task
from apache.aurora.executor.common.sandbox import DirectorySandbox
from apache.aurora.executor.http_lifecycle import HttpLifecycleManager
from apache.aurora.executor.thermos_task_runner import ThermosTaskRunner
from apache.thermos.common.statuses import (INTERNAL_ERROR, INVALID_TASK,
                                            TERMINAL_TASK, UNKNOWN_ERROR,
                                            UNKNOWN_USER)

from gen.apache.thermos.ttypes import TaskState

TASK = MesosTaskInstance(
    instance=0,
    role=getpass.getuser(),
    task=Task(
        resources=Resources(cpu=1.0, ram=16 * MB, disk=32 * MB),
        name='hello_world',
        processes=[Process(name='hello_world', cmdline='{{command}}')],
    ))


class TestThermosTaskRunnerIntegration(object):
    PEX_PATH = None
    LOG_DIR = None

    @classmethod
    def setup_class(cls):
        cls.LOG_DIR = tempfile.mkdtemp()
        LogOptions.set_log_dir(cls.LOG_DIR)
        LogOptions.set_disk_log_level('DEBUG')
        log.init('executor_logger')
示例#13
0
文件: fixtures.py 项目: zmyer/aurora
import getpass

from apache.aurora.config.schema.base import (
    MB,
    DefaultLifecycleConfig,
    MesosJob,
    MesosTaskInstance,
    Process,
    Resources,
    Task
)

BASE_MTI = MesosTaskInstance(
    instance=0,
    lifecycle=DefaultLifecycleConfig,
    role=getpass.getuser(),
)
BASE_TASK = Task(resources=Resources(cpu=1.0, ram=16 * MB, disk=32 * MB))

HELLO_WORLD_TASK_ID = 'hello_world-001'
HELLO_WORLD = BASE_TASK(
    name='hello_world',
    processes=[Process(name='hello_world_{{thermos.task_id}}', cmdline='echo hello world')])
HELLO_WORLD_MTI = BASE_MTI(task=HELLO_WORLD)

SLEEP60 = BASE_TASK(processes=[Process(name='sleep60', cmdline='sleep 60')])
SLEEP2 = BASE_TASK(processes=[Process(name='sleep2', cmdline='sleep 2')])
SLEEP60_MTI = BASE_MTI(task=SLEEP60)

MESOS_JOB = MesosJob(