def test_on_subscribed(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) driver._started = True executor_info = { 'executor_id': { 'value': executor_id }, 'framework_id': { 'value': framework_id } } framework_info = {'id': {'value': framework_id}} event = { 'type': 'SUBSCRIBED', 'subscribed': { 'executor_info': executor_info, 'framework_info': framework_info, 'agent_info': {} } } driver.on_event(event) exc.registered.assert_called_once_with(driver, executor_info, framework_info, {})
def test_on_launch(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) driver._started = True task_id = str(uuid.uuid4()) framework_info = {'id': {'value': framework_id}} task_info = { "task_id": { "value": task_id }, } event = { 'type': 'LAUNCH', 'launch': { 'framework_info': framework_info, 'task': task_info } } driver.on_event(event) exc.launchTask.assert_called_once_with(driver, task_info)
def test_send_status_update(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) driver._send = mocker.Mock() status = {} driver.sendStatusUpdate(status) driver._send.assert_called_once_with({ 'type': 'UPDATE', 'framework_id': { 'value': framework_id, }, 'executor_id': { 'value': executor_id, }, 'update': { 'status': { 'timestamp': status['timestamp'], 'uuid': status['uuid'], 'source': 'SOURCE_EXECUTOR', } } })
def test_send_message(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) driver._send = mocker.Mock() message = ''.join( random.choice(string.printable) for _ in range(random.randint(1, 100))) message = encode_data(message.encode('utf8')) driver.sendFrameworkMessage(message) driver._send.assert_called_once_with({ 'type': 'MESSAGE', 'framework_id': { 'value': framework_id, }, 'executor_id': { 'value': executor_id, }, 'message': { 'data': message, } })
def test_gen_request(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) driver._master = agent_addr assert driver.framework_id == dict(value=framework_id) assert driver.executor_id == dict(value=executor_id) assert -1e-5 < driver.grace_shutdown_period < 1e-5 assert not driver.checkpoint assert driver.executor is exc req = driver.gen_request() parser = HttpParser(0) assert len(req) == parser.execute(req, len(req)) assert parser.is_headers_complete() assert parser.get_method() == 'POST' assert parser.get_url() == '/api/v1/executor' assert parser.is_partial_body() body = parser.recv_body() result = json.loads(body.decode('utf-8')) assert result == { 'type': 'SUBSCRIBE', 'framework_id': { 'value': framework_id, }, 'executor_id': { 'value': executor_id, }, 'subscribe': { 'unacknowledged_tasks': [], 'unacknowledged_updates': [], } } headers = {k.upper(): v for k, v in parser.get_headers().items()} assert headers == { 'HOST': agent_addr, 'CONTENT-TYPE': 'application/json', 'ACCEPT': 'application/json', 'CONNECTION': 'close', 'CONTENT-LENGTH': str(len(body)) } assert parser.is_message_complete()
def run(): setproctitle('Executor') if os.getuid() == 0: gid = os.environ['GID'] uid = os.environ['UID'] os.setgid(int(gid)) os.setuid(int(uid)) executor = MyExecutor() driver = MesosExecutorDriver(executor, use_addict=True) driver.run()
def test_on_shutdown(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) event = {'type': 'shutdown'} driver.on_event(event) exc.shutdown.assert_called_once_with(driver)
def test_on_kill(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) task_id = {'value': str(uuid.uuid4())} event = {'type': 'KILL', 'kill': {'task_id': task_id}} driver.on_event(event) exc.killTask.assert_called_once_with(driver, task_id)
def test_on_acknowledged(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) driver._started = True assert driver.updates == {} assert driver.tasks == {} tid = str(uuid.uuid4()) uid = uuid.uuid4() driver.updates[uid] = mocker.Mock() driver.tasks[tid] = mocker.Mock() event = { 'type': 'ACKNOWLEDGED', 'acknowledged': { 'task_id': { 'value': tid }, 'uuid': encode_data(uid.bytes) } } driver.on_event(event) assert driver.updates == {} assert driver.tasks == {}
def test_on_error(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) message = ''.join( random.choice(string.printable) for _ in range(random.randint(1, 100))) event = {'type': 'ERROR', 'error': {'message': message}} driver.on_event(event) exc.error.assert_called_once_with(driver, message)
def test_send(mocker): agent_addr = 'mock_addr:12345' framework_id = str(uuid.uuid4()) executor_id = str(uuid.uuid4()) env = { 'MESOS_LOCAL': 'true', 'MESOS_AGENT_ENDPOINT': agent_addr, 'MESOS_FRAMEWORK_ID': framework_id, 'MESOS_EXECUTOR_ID': executor_id, } mocker.patch('os.environ', env) exc = mocker.Mock() driver = MesosExecutorDriver(exc) resp = mocker.Mock(status=200, read=mocker.Mock(return_value='{}')) conn = mocker.Mock(getresponse=mocker.Mock(return_value=resp)) driver._get_conn = mocker.Mock(return_value=conn) assert driver._send({}) == {} driver._get_conn.assert_called_once_with() conn.request.assert_called_once_with( 'POST', '/api/v1/executor', body=json.dumps({}).encode('utf-8'), headers={'Content-Type': 'application/json'})
def run_mesos_driver(stop_signal, config): """Run an executor driver until the stop_signal event is set or the first task it runs completes.""" executor = CookExecutor(stop_signal, config) driver = MesosExecutorDriver(executor) driver.start() # check the status of the executor and bail if it has crashed while not executor.has_task_completed(): time.sleep(1) else: logging.info('Executor thread has completed') driver.stop()
for proc in self.procs.values(): proc.kill() self.reply_status(driver, proc_id, mesos_pb2.TASK_KILLED) self.pid_to_proc.clear() self.procs.clear() driver.join() def frameworkMessage(self, driver, msg): pid, type, data = pickle.loads(msg) logger.info('Recv framework message pid:%s, type:%s, data:%s', pid, type, data) with self.cond: if pid not in self.procs: logger.error('Cannot find pid:%s to send message', pid) return p = self.procs[pid] if type == _TYPE_SIGNAL: sig = int(data) p.send_signal(sig) if __name__ == '__main__': log_format = '%(asctime)-15s [%(levelname)s] [%(name)-9s] %(message)s' logging.basicConfig(format=log_format, level=logging.DEBUG) executor = ProcExecutor() driver = MesosExecutorDriver(executor) executor.run(driver)
class MinimalExecutor(Executor): def launchTask(self, driver, task): def run_task(task): update = Dict() update.task_id.value = task.task_id.value update.state = "TASK_RUNNING" update.timestamp = time.time() driver.sendStatusUpdate(update) print(decode_data(task.data), file=sys.stderr) time.sleep(30) update = Dict() update.task_id.value = task.task_id.value update.state = "TASK_FINISHED" update.timestamp = time.time() driver.sendStatusUpdate(update) thread = Thread(target=run_task, args=(task,)) thread.start() if __name__ == "__main__": import logging logging.basicConfig(level=logging.DEBUG) driver = MesosExecutorDriver(MinimalExecutor(), use_addict=True) driver.run()
from addict import Dict class MinimalExecutor(Executor): def launchTask(self, driver, task): def run_task(task): update = Dict() update.task_id.value = task.task_id.value update.state = 'TASK_RUNNING' update.timestamp = time.time() driver.sendStatusUpdate(update) print(decode_data(task.data), file=sys.stderr) time.sleep(30) update = Dict() update.task_id.value = task.task_id.value update.state = 'TASK_FINISHED' update.timestamp = time.time() driver.sendStatusUpdate(update) thread = Thread(target=run_task, args=(task,)) thread.start() if __name__ == '__main__': import logging logging.basicConfig(level=logging.DEBUG) driver = MesosExecutorDriver(MinimalExecutor(), use_addict=True) driver.run()
def main(): logging.basicConfig(level=logging.DEBUG) log.debug("Starting executor") if not os.environ.has_key("MESOS_AGENT_ENDPOINT"): # Some Mesos setups in our tests somehow lack this variable. Provide a # fake one to maybe convince the executor driver to work. os.environ["MESOS_AGENT_ENDPOINT"] = os.environ.get( "MESOS_SLAVE_ENDPOINT", "127.0.0.1:5051") log.warning("Had to fake MESOS_AGENT_ENDPOINT as %s" % os.environ["MESOS_AGENT_ENDPOINT"]) try: urlopen("http://%s/logging/toggle?level=1&duration=15mins" % os.environ["MESOS_AGENT_ENDPOINT"]).read() log.debug("Toggled agent log level") except Exception as e: log.debug("Failed to toggle agent log level") # Parse the agent state agent_state = json.loads( urlopen("http://%s/state" % os.environ["MESOS_AGENT_ENDPOINT"]).read()) if agent_state.has_key('completed_frameworks'): # Drop the completed frameworks whichg grow over time del agent_state['completed_frameworks'] log.debug("Agent state: %s", str(agent_state)) log.debug("Virtual memory info in executor: %s" % repr(psutil.virtual_memory())) if os.path.exists('/sys/fs/cgroup/memory'): # Mesos can limit memory with a cgroup, so we should report on that. for (dirpath, dirnames, filenames) in os.walk('/sys/fs/cgroup/memory', followlinks=True): for filename in filenames: if 'limit_in_bytes' not in filename: continue log.debug('cgroup memory info from %s:' % os.path.join(dirpath, filename)) try: for line in open(os.path.join(dirpath, filename)): log.debug(line.rstrip()) except Exception as e: log.debug("Failed to read file") # Mesos can also impose rlimit limits, including on things that really # ought to not be limited, like virtual address space size. log.debug('DATA rlimit: %s', str(resource.getrlimit(resource.RLIMIT_DATA))) log.debug('STACK rlimit: %s', str(resource.getrlimit(resource.RLIMIT_STACK))) log.debug('RSS rlimit: %s', str(resource.getrlimit(resource.RLIMIT_RSS))) log.debug('AS rlimit: %s', str(resource.getrlimit(resource.RLIMIT_AS))) executor = MesosExecutor() log.debug('Made executor') driver = MesosExecutorDriver(executor, use_addict=True) old_on_event = driver.on_event def patched_on_event(event): """ Intercept and log all pymesos events. """ log.debug("Event: %s", repr(event)) old_on_event(event) driver.on_event = patched_on_event log.debug('Made driver') driver.start() log.debug('Started driver') driver_result = driver.join() log.debug('Joined driver') # Tolerate a None in addition to the code the docs suggest we should receive from join() exit_value = 0 if (driver_result is None or driver_result == 'DRIVER_STOPPED') else 1 assert len(executor.runningTasks) == 0 sys.exit(exit_value)
# 保留以作测试用 print(decode_data(task.data), file=sys.stderr) cnt = 0 N = 2000000 for i in range(N): x = random() y = random() if (x * x + y * y) < 1: cnt += 1 vPi = 4.0 * cnt / N print(vPi) driver.sendFrameworkMessage(encode_data(str(vPi))) time.sleep(30) update = Dict() update.task_id.value = task.task_id.value update.state = 'TASK_FINISHED' update.timestamp = time.time() driver.sendStatusUpdate(update) thread = Thread(target=run_task, args=(task, )) thread.start() if __name__ == '__main__': import logging logging.basicConfig(level=logging.DEBUG) driver = MesosExecutorDriver(PiExecutor(), use_addict=True) driver.run()
t.daemon = True t.start() self.ts[task.task_id.value] = t def killTask(self, driver, task_id): try: if task_id.value in self.ps: self.ps[task_id.value].kill() reply_status(driver, task_id, 'TASK_KILLED') except: pass def shutdown(self, driver): for p in self.ps.values(): try: p.kill() except: pass for t in self.ts.values(): t.join() if __name__ == "__main__": if os.getuid() == 0: gid = os.environ['GID'] uid = os.environ['UID'] os.setgid(int(gid)) os.setuid(int(uid)) executor = MyExecutor() MesosExecutorDriver(executor, use_addict=True).run()