Example #1
0
    def _shell_command_execution(self, task_id):
        dt = datetime.now()

        cmd_type = str(Command.get_by(test_id=self.test_id, id=task_id).cmd_type)
        command = str(Command.get_by(test_id=self.test_id, id=task_id).command)

        if cmd_type == 'shell':
            from AreteSlave.modules.Daemon import Daemon
            manager = Daemon.get_manager()
            test_dir = manager.workdir + os.sep + self.test_id
            if not os.path.isdir(test_dir):
                os.mkdir(test_dir)
            os.chdir(test_dir)
            try:
                command = Scheduler.subst(command, self.test_id)
                args = shlex.split(str(command))

                logging.info("[ Test %s ] Running task '%s' : %s" \
                    % (self.test_id, task_id, command))
                
                p = subprocess.Popen(args, stdout=subprocess.PIPE, \
                    stderr=subprocess.STDOUT)
                task = Task.get_by(test_id=self.test_id, id=task_id)
                self.pids[task_id] = p.pid               
                task.pid = p.pid
                session.commit()
                p.wait()
                td = datetime.now() - dt
            except (OSError, ResolvError) as e:
                logging.error(e)
                logging.error("[ Test %s ] Running task '%s' failed." \
                    % (self.test_id, task_id))

                Invocation(command=Command.get_by(test_id=self.test_id, \
                    id=task_id), start_time=dt)
                session.commit()
            else:
                Invocation(\
                    command=Command.get_by(test_id=self.test_id, \
                        id=task_id), output=p.stdout.read(), start_time=dt, \
                        duration=td, return_code=p.returncode)
                session.commit()

        elif cmd_type == 'notify':
            from AreteSlave.modules.Daemon import Daemon
            manager = Daemon.get_manager()
            manager.notify_handlers[self.test_id](self.test_id, command)

            Invocation(command=Command.get_by(test_id=self.test_id, \
                id=task_id), start_time=dt)
            session.commit()
Example #2
0
        def resolve_ref(matchobj):
            to_resolv = matchobj.group('ref')
            ref = to_resolv.split('.')
            if len(ref) is 2:
                id    = ref[0]
                param = ref[1]
                if id in cmd_ids:
                    cmd = Command.get_by(test_id=test_id, id=unicode(id))
                    param_map = {}
                    if len(cmd.invocations) > 0:
                        param_map['returncode'] = \
                            cmd.invocation[-1].return_code
                    if cmd.row_type == u'task':
                        if cmd.pid is not None:
                            param_map['pid'] = cmd.pid
                        else:
                            raise ResolvError("[ Test %s ] Task '%s' hasn't \
                                been run yet." % (test_id, cmd.id))
                    if param in param_map.keys():
                        return str(param_map[param])
                elif id in file_ids:
                    file = File.get_by(test_id=test_id, id=unicode(id))
                    param_map = {}
                    param_map['size'] = file.size
                    param_map['name'] = file.name
                    if param in param_map.keys():
                        return str(param_map[param])
            elif len(ref) is 1:
                if ref[0].startswith('poke') and len(ref[0].split(' ')) is 2:
                    from AreteSlave.modules.Daemon import Daemon
                    manager = Daemon.get_manager()
                    return '"arete-poker %s %s %s"' \
                        % (test_id, ref[0].split(' ')[1], str(manager.port))

            raise ResolvError("[ Test %s ] Cannot resolve '%s'." \
                % (test_id, to_resolv))
Example #3
0
    def handle(self):
        from AreteSlave.modules.Daemon import Daemon
        manager = Daemon.get_manager()

        try:
            line = self.receive()
            if line == '':
                raise socket.error
            elif line.startswith('poke'):
                line = unicode(line[5:]).split(':')
                test_id = line[0]
                poke_name = line[1]
                logging.info("[ Test %s ] Running poke: %s" % (test_id, poke_name))
                manager.run_poke(test_id, poke_name)
            else:
                logging.info("[ Connection %s ] Handling" % self.client_address[0])

                parent = None
                parent_id = None

                types_and_actions = {
                    'test'        : manager.create_test,
                    'test_check'  : manager.add_check_command,
                    'test_setup'  : manager.add_setup_command,
                    'test_task'   : manager.add_task_command,
                    'test_clean'  : manager.add_clean_command,
                    'test_file'   : manager.add_file,
                    'test_delete' : manager.delete_command_or_file,
                    'results'     : manager.open_results,
                    'results_get' : manager.get_results,
                    'delete'      : manager.delete_test,
                    'prepare'     : manager.prepare_test,
                    'start'       : manager.start_test,
                    'stop'        : manager.stop_test,
                    'trigger'     : manager.run_trigger,
                    'time'        : self.send_time
                }

                while 1:
                    if line:
                        logging.info("[ Connection %s ] [ %s ] Received: %s" % (self.client_address[0], datetime.datetime.now(), line))
                    try:
                        type, params = parse(line, parent)
                        if types_and_actions.get(type):
                            result = types_and_actions.get(type)(parent_id, **params)
                    except (DaemonError, CommandError) as e:
                        logging.error(e)
                        if isinstance(e, CommandError):
                            self.send_cmd_error(e.cmd_id)
                        elif isinstance(e, SetupTooLongError):
                            self.send_setup_too_long()
                        else:
                            self.send_bad_request()
                    else:
                        if type in ['test', 'results']:
                            parent = type
                            parent_id = params['id']
                        if type.endswith('end'):
                            parent = None
                            parent_id = None
                        if type == 'test_file':
                            name = result[0]
                            size = result[1]
                            copied = 0
                            test_dir = manager.workdir + os.sep + parent_id
                            if not os.path.isdir(test_dir):
                                os.mkdir(test_dir)
                            with open(test_dir + os.sep + name, 'wb') as f:
                                while copied < size:
                                    read = min(size - copied, 1000000)
                                    f.write(self.rfile.read(read))
                                    copied += read
                        if type == 'results_get':
                            type = result[0]
                            to_send = result[1]
                            if type == 'multi':
                                kind = result[2]
                                size_list = []
                                for output in to_send:
                                    if output != None:
                                        if kind == 'duration':
                                            output = str(float(output.seconds)+(output.microseconds/1000000.0))
                                        elif kind == 'returncode':
                                            output = str(output)
                                        elif kind == 'start_time':
                                            output = output.isoformat()
                                        output_len = len(output)
                                        size_list.append(output_len)
                                    else:
                                        size_list.append(-1)
                                self.send_ok(sizes=size_list)
                                for output in to_send:
                                    if output != None:
                                        if kind == 'duration':
                                            output = str(float(output.seconds)+(output.microseconds/1000000.0))
                                        elif kind == 'returncode':
                                            output = str(output)
                                        elif kind == 'start_time':
                                            output = output.isoformat()
                                        self.wfile.write(output)
                            elif type == 'list':
                                self.send_list(to_send)
                            else:
                                if to_send != None:
                                    self.send_ok(sizes=[len(to_send)])
                                    self.wfile.write(to_send)
                                else:
                                    self.send_ok(sizes=[-1])
                        else:
                            if type not in ['trigger', 'time']:
                                self.send_ok()
                            if type == 'start':
                                run_value = result

                                print params['id']

                                manager.setup_test(params['id'])
                                now = time.time()

                                tooLong = False

                                if run_value < now:
                                    logging.error("[ Test %s ] [ %s < %s ] Setup took too much time." % (params['id'], run_value, now))
                                    tooLong = True

                                manager.register_handler(params['id'], self.send_100)
                                if not tooLong:
                                    manager.start_tasks(parent_id, **params)

                    line = self.receive()
                    if line == '':
                        raise socket.error

        except socket.error, IOError:
            logging.info("[ Connection %s ] Dropped" % self.client_address[0])