Beispiel #1
0
    def dispatch(self, *args):
        dispatch_threads = defaultdict()
        while True:
            for k in self.testmap:
                found = False

                if k in self.dispatch_queue or k in self.running_tests:
                    found = True
                else:
                    lctx.debug("Found spot for test")

                if found:
                    continue

                try:
                    tmp_t = self.testmap[k][0]
                except Exception as e:
                    lctx.debug("No test object found in map")
                    continue

                if tmp_t is None:
                    continue

                alive = False

                h = tmp_t.testobj.TestInputData.exechostname
                test_logger = LOG.init_testlogger(tmp_t, "EXEC")
                test_logger.info("Test execution starts")
                try:
                    retsend = self.cl.send(
                        h, self.CPORT,
                        self.ev.construct("DAYTONA_HEARTBEAT", ""))

                    if retsend and len(retsend.split(",")) > 2:
                        status = retsend.split(",")[1]
                    else:
                        raise Exception(
                            "Execution host not avaliable - No Heartbeat ",
                            tmp_t.testobj.TestInputData.testid)

                    if "ALIVE" == status:
                        test_logger.info(
                            "HeartBeat received from execution host " + h)
                        ret = self.cl.send(
                            h, self.CPORT,
                            self.ev.construct(
                                "DAYTONA_HANDSHAKE", "handshake1," +
                                self.HOST + "," + str(self.PORT) + "," +
                                str(tmp_t.testobj.TestInputData.testid) + "," +
                                h))
                        if ret == "SUCCESS":
                            alive = True
                            test_logger.info(
                                "Handshake successful with execution host " +
                                h)
                            lctx.debug(
                                "Handshake successful in scheduler, adding ip/hostname to reg hosts"
                            )
                            server.serv.registered_hosts[h] = h
                            addr = socket.gethostbyname(h)
                            lctx.debug(addr)
                            server.serv.registered_hosts[addr] = addr
                        else:
                            raise Exception(
                                "Unable to handshake with agent on executuion host "
                                + h)

                except Exception as e:
                    lctx.error(e)
                    test_logger.error(e)
                    # pause the dbmon here as we dont want the same test to be picked again after we pop
                    self.dbinstance.mon_thread[0].pause()
                    self.dbinstance.lock.acquire()
                    t = self.testmap[k].pop(0)
                    t.updateStatus("waiting", "failed")
                    self.dbinstance.lock.release()
                    lctx.debug("Removed test from map : " +
                               str(t.testobj.TestInputData.testid))
                    self.dbinstance.mon_thread[0].resume()
                    LOG.removeLogger(tmp_t)
                    continue
                    # todo : add host to reg list if handshake successful

                if alive == True and found == False:
                    # for each framework pick one and move it to running, iff running has an empty slot.
                    lctx.debug(
                        "-------Found empty slot in dispatch and running Q-------"
                    )

                    # pause the dbmon here as we dont want the same test to be picked again after we pop
                    self.dbinstance.mon_thread[0].pause()
                    self.dbinstance.lock.acquire()
                    t = self.testmap[k].pop(0)
                    self.dbinstance.lock.release()

                    lctx.info("< %s" % t.testobj.TestInputData.testid)

                    self.dispatchQ__lock.acquire()
                    self.dispatch_queue[k] = t
                    self.dispatchQ__lock.release()

                    t.updateStatus("waiting", "setup")
                    self.dbinstance.mon_thread[0].resume()

                    try:
                        trigger_thread = common.FuncThread(
                            self.trigger, True, t)
                        dispatch_threads[t.testobj.TestInputData.testid] = (
                            trigger_thread, t)
                        trigger_thread.start()
                    except Exception as e:
                        lctx.error("Trigger error : " +
                                   str(t.testobj.TestInputData.testid))
                        test_logger.error("Test setup failed " +
                                          str(t.testobj.TestInputData.testid))
                        LOG.removeLogger(tmp_t)
                        self.dispatchQ__lock.acquire()
                        del self.dispatch_queue[k]
                        self.dispatchQ__lock.release()
                        lctx.debug(e)

            try:
                d = "DISPATCH [S/R] : "
                for k in self.dispatch_queue:
                    d = d + " |" + str(
                        self.dispatch_queue[k].testobj.TestInputData.testid)
            except:
                lctx.debug("ERROR : Dispatch Q empty")

            lctx.debug(d)
            d = ""

            time.sleep(2)
Beispiel #2
0
        def handle(self):
            """
            This handler is called everytime TCP server running on scheduler and agent receive any message. This
            handler perform different operation based on action received

            """
            host = self.client_address[0]
            data = self.request.recv(8192)
            cur_thread = threading.current_thread()
            ev = data.split(":")
            serv.lctx.debug("Envelope contents : " + str(ev))
            cmd = ev[1]
            msgid = ev[2]
            params = ev[3]
            serv.lctx.info(cmd)
            serv.lctx.debug(msgid)
            serv.lctx.debug(params)

            if cmd == "DAYTONA_HANDSHAKE":
                # Message received is a handshake message
                p = params.split(",")
                if p[0] == "handshake1":
                    # if payload contains handshake1 then this message came from scheduler to agent. Agent does basic
                    # env setup and send handshake2 message back to scheduler to verify connectivity from both ends
                    serv.registered_hosts[host] = host
                    addr = socket.gethostbyname(host)
                    serv.registered_hosts[addr] = addr

                    # Initialize current_test object with scheduler information and other env setup
                    current_test = activeTest(0, None, None, None)
                    current_test.stathostip = p[4]
                    current_test.stathostport = self.server.server_address[1]
                    current_test.serverip = p[1]
                    current_test.testid = int(p[3])
                    current_test.serverport = int(p[2])
                    current_test.status = "SETUP"
                    test_logger = LOG.init_testlogger(current_test, "STAT")
                    if test_logger:
                        current_test.agent_log_file = test_logger.handlers[
                            0].baseFilename

                    con = action.scheduler_handshake(current_test)
                    if con:
                        # if response received from scheduler then handshake is successfull
                        action.action_lock.acquire()
                        action.running_tests[int(p[3])] = current_test
                        action.action_lock.release()
                        response = "{}".format("SUCCESS")
                        test_logger.info(
                            "Handshake successfull with daytona host : " +
                            current_test.serverip)
                    else:
                        # else agent is not able to talk to scheduler using scheduler port, return error
                        response = "{}".format("ERROR")
                        test_logger.error(
                            "Handshake failed with daytona host : " +
                            current_test.serverip)

                    self.request.sendall(response)
                    return
                else:
                    # Payload contains handshake2, means agent sent it on scheduler and scheduler just send OK response
                    # back to agent
                    response = "{}".format("SUCCESS")
                    self.request.sendall(response)
                    return

            if host in serv.registered_hosts.keys() or cmd in (
                    "DAYTONA_HEARTBEAT", "DAYTONA_CLI"):
                # Only process daytona commands from registered daytona host which was registered after handshake
                if cmd == "DAYTONA_STREAM_END":
                    serv.lctx.debug("End stream...")
                    return

                if cmd == "DAYTONA_STREAM_START":
                    # Handler for DAYTONA_STREAM_START message received on scheduler. Scheduler will setup environment
                    # for writing logs in execution.log file for this particular test
                    filepath = params + "/execution.log"
                    d = os.path.dirname(filepath)
                    if not os.path.exists(d):
                        os.makedirs(d)

                    f = open(filepath, 'wb')
                    serv.lctx.debug(filepath)

                    serv.lctx.debug("Receiving stream..." + filepath)
                    response = "{}".format("STREAMFILEREADY")
                    self.request.send(response)

                    l = self.request.recv(8192)
                    serv.lctx.debug(len(l))
                    while l:
                        serv.lctx.debug("Receiving stream...")
                        f.write(l)
                        print l
                        serv.lctx.debug(l)
                        f.flush()
                        l = self.request.recv(8192)
                        if l == "DAYTONA_STREAM_END":
                            serv.lctx.debug("receiving term string : ")
                            break
                    f.close()
                    serv.lctx.debug("Done receiving stream into : " + filepath)
                    return

                if cmd == "DAYTONA_FILE_UPLOAD":
                    # Handler for uploading SAR data TAR file on scheduler
                    p = params.split(",")
                    serv.lctx.debug("SER SERVER : " + params)
                    fn = p[0].split("/")
                    fn.reverse()
                    loc = p[1].strip()
                    serv.lctx.debug("SER SERVER : " + loc)

                    filepath = loc + fn[0]
                    d = os.path.dirname(filepath)
                    if not os.path.exists(d):
                        os.makedirs(d)

                    serv.lctx.debug("Receiving..." + filepath)
                    response = "{}".format("FILEREADY")
                    self.request.send(response)
                    f = open(filepath, 'wb')
                    l = self.request.recv(8192)
                    serv.lctx.debug(len(l))
                    while l:
                        serv.lctx.debug("Receiving...")
                        f.write(l)
                        f.flush()
                        l = self.request.recv(8192)
                        serv.lctx.debug(len(l))
                    f.close()
                    serv.lctx.debug("Done receiving results : " + filepath)
                    return

                if cmd == "DAYTONA_STOP_SERVER":
                    # Currently not in use
                    serverInstance.shutdown()
                    serverInstance.server_close()
                    response = "{}: {}".format(cur_thread.name,
                                               "Shutting down server")
                    self.request.sendall(response)
                    if len(self.act.async_actions) > 0:
                        for pending in self.act.async_actions:
                            (t1, actionID, tst, ts) = pending
                            t1.stop()
                        serv.lctx.debug(
                            "DAYTONA_STOP_SERVER handler, Async action thread ended after stop : "
                            + cur_thread.name)
                    return

                # todo : Set server to shutdown state, reject all incomming reqs if this flag set wait for all threads
                # to shutdown (with timeout) gracefully shutdown before timeout, or force close beyond timeout

                # exResp = self.act.execute(cmd, params, msgid)
                if serv.actc is None:
                    serv.actc = ActionCaller(
                        LOG.getLogger("listenerlog", serv.role))

                # Call execute routine for mapping this daytona command with actual procedure.
                exResp = serv.actc.execute(cmd, params, msgid)

                response = "{}: {}".format(cur_thread.name, exResp)
                self.request.sendall(response)
                if len(serv.actc.async_actions) > 0:
                    serv.lctx.debug("Async action list : " +
                                    str(len(serv.actc.async_actions)))
                    for pending in self.act.async_actions:
                        (t1, actionID, tst, ts) = pending
                        t1.join()
                        serv.lctx.debug(
                            "Async action thread ended after join : " +
                            t1.name)

            else:
                serv.lctx.error(
                    "Command recieved from unknown host before handshake")
                serv.lctx.error(host)
Beispiel #3
0
        def handle(self):
            host = self.client_address[0]
            data = self.request.recv(8192)
            cur_thread = threading.current_thread()
            ev = data.split(":")
            serv.lctx.debug("Envelope contents : " + str(ev))
            cmd = ev[1]
            msgid = ev[2]
            params = ev[3]
            serv.lctx.info(cmd)
            serv.lctx.debug(msgid)
            serv.lctx.debug(params)

            if cmd == "DAYTONA_HANDSHAKE":
                # todo : maintain a list of daytona host that this server talks to only respond to the ones in the list

                p = params.split(",")
                if p[0] == "handshake1":
                    serv.registered_hosts[host] = host
                    addr = socket.gethostbyname(host)
                    serv.registered_hosts[addr] = addr

                    current_test = activeTest(0, None, None, None)
                    current_test.stathostip = p[4]
                    current_test.stathostport = self.server.server_address[1]
                    current_test.serverip = p[1]
                    current_test.testid = int(p[3])
                    current_test.serverport = int(p[2])
                    current_test.status = "SETUP"
		    test_logger = LOG.init_testlogger(current_test,"STAT")
                    if test_logger:
                        current_test.agent_log_file = test_logger.handlers[0].baseFilename

                    con = action.scheduler_handshake(current_test)
                    if con:
                        action.action_lock.acquire()
                        action.running_tests[int(p[3])] = current_test
                        action.action_lock.release()
                        response = "{}".format("SUCCESS")
			test_logger.info("Handshake successfull with daytona host : " + current_test.serverip)
                    else:
                        response = "{}".format("ERROR")
			test_logger.error("Handshake failed with daytona host : " + current_test.serverip)

                    self.request.sendall(response)
                    return
                else:
                    response = "{}".format("SUCCESS")
                    self.request.sendall(response)
                    return

            if host in serv.registered_hosts.keys() or cmd in ("DAYTONA_HEARTBEAT", "DAYTONA_CLI"):
                if cmd == "DAYTONA_STREAM_END":
                    serv.lctx.debug("End stream...")
                    return

                if cmd == "DAYTONA_STREAM_START":
                    filepath = params+"/execution.log"
                    d = os.path.dirname(filepath)
                    if not os.path.exists(d):
                        os.makedirs(d)

                    f = open(filepath,'wb')
                    serv.lctx.debug(filepath)

                    serv.lctx.debug("Receiving stream..." + filepath)
                    response = "{}".format("STREAMFILEREADY")
                    self.request.send(response)

                    l = self.request.recv(8192)
                    serv.lctx.debug(len(l))
                    while (l):
                        serv.lctx.debug("Receiving stream...")
                        f.write(l)
                        print l
                        serv.lctx.debug(l)
                        f.flush()
                        l = self.request.recv(8192)
                        if l == "DAYTONA_STREAM_END":
                            serv.lctx.debug("receiving term string : ")
                            break
                    f.close()
                    # response = "{}".format("SUCCESS")
                    # self.request.sendall(response)
                    serv.lctx.debug("Done receiving stream into : " + filepath)
                    return

                if cmd == "DAYTONA_FILE_UPLOAD":
                    p = params.split(",")
                    serv.lctx.debug("SER SERVER : " + params)
                    fn = p[0].split("/")
                    fn.reverse()
                    loc = p[1].strip()
                    serv.lctx.debug("SER SERVER : " + loc)

                    filepath = loc+fn[0]
                    d = os.path.dirname(filepath)
                    if not os.path.exists(d):
                        os.makedirs(d)

                    serv.lctx.debug("Receiving..." + filepath)
                    response = "{}".format("FILEREADY")
                    self.request.send(response)
                    f = open(filepath, 'wb')
                    l = self.request.recv(8192)
                    serv.lctx.debug(len(l))
                    while l:
                        serv.lctx.debug("Receiving...")
                        f.write(l)
                        f.flush()
                        l = self.request.recv(8192)
                        serv.lctx.debug(len(l))
                    f.close()
                    serv.lctx.debug("Done receiving results : " + filepath)
                    return

                if cmd == "DAYTONA_STOP_SERVER":
                    serverInstance.shutdown()
                    serverInstance.server_close()
                    response = "{}: {}".format(cur_thread.name, "Shutting down server")
                    self.request.sendall(response)
                    if len(self.act.async_actions) > 0 :
                        for pending in self.act.async_actions:
                            (t1, actionID, tst, ts) = pending
                            t1.stop()
                        serv.lctx.debug("DAYTONA_STOP_SERVER handler, Async action thread ended after stop : " + cur_thread.name)
                    return

                # todo : Set server to shutdown state, reject all incomming reqs if this flag set wait for all threads
                # to shutdown (with timeout) gracefully shutdown before timeout, or force close beyond timeout

                # exResp = self.act.execute(cmd, params, msgid)
                if serv.actc is None:
                    serv.actc = ActionCaller(LOG.getLogger("listenerlog", serv.role))

                exResp = serv.actc.execute(cmd, params, msgid)

                response = "{}: {}".format(cur_thread.name, exResp)
                self.request.sendall(response)
                if len(serv.actc.async_actions) > 0 :
                    serv.lctx.debug("Async action list : " + str(len(serv.actc.async_actions)))
                    for pending in self.act.async_actions:
                        (t1, actionID, tst, ts) = pending
                        t1.join()
                        serv.lctx.debug("Async action thread ended after join : " + t1.name)

            else:
                serv.lctx.error("Command recieved from unknown host before handshake")
                serv.lctx.error(host)
Beispiel #4
0
    def dispatch(self, *args):
        """
        This is dispatch queue of scheduler where test from different framework wait in the waiting queue for scheduler to
        bind it with trigger thread. This procedure continuously iterate over testmap populated by DBMon with tests
        started by user from UI or CLI. This keep track of all running tests and it allows one test per framework. Once
        this procedure find an open test spot for a test from particular framework, this procedure will pop it from testmap,
        put it in dispatch queue and assign trigger thread for this test to start test setup and then execution.

        """
        dispatch_threads = defaultdict()
        while True:
            # Continuously iterate on testmap for initiating any test execution
            for k in self.testmap:
                # iterating for all frameworkid k in testmap which contains list of waiting tests for a particular framework
                found = False

                # If test for a particular framework is already in running or dispatch queue then this new test need to
                # wait until previous test gets finish, hence we do nothing and just continue
                if k in self.dispatch_queue or k in self.running_tests:
                    found = True
                else:
                    lctx.debug("Found spot for test")

                if found:
                    continue

# Proceed if spot is available for executing test for this framework
                try:
                    tmp_t = self.testmap[k][0]
                except Exception as e:
                    lctx.debug("No test object found in map")
                    continue

                if tmp_t is None:
                    continue

                alive = False

                h = tmp_t.testobj.TestInputData.exechostname

                # Initiating test logger for capturing test life cycle on scheduler, all logs are logged in file <testid>.log
                test_logger = LOG.init_testlogger(tmp_t, "EXEC")
                test_logger.info("Test execution starts")
                try:
                    # Sending heartbeat on exec host to check if it agent is up on exec host
                    retsend = self.cl.send(
                        h, self.CPORT,
                        self.ev.construct("DAYTONA_HEARTBEAT", ""))

                    if retsend and len(retsend.split(",")) > 2:
                        status = retsend.split(",")[1]
                    else:
                        raise Exception(
                            "Execution host not avaliable - No Heartbeat ",
                            tmp_t.testobj.TestInputData.testid)

                    if "ALIVE" == status:
                        test_logger.info(
                            "HeartBeat received from execution host " + h)
                        # Sending DAYTONA_HANDSHAKE for verifying connectivity between scheduler and agent on exec host
                        # using custom daytona ports
                        ret = self.cl.send(
                            h, self.CPORT,
                            self.ev.construct(
                                "DAYTONA_HANDSHAKE", "handshake1," +
                                self.HOST + "," + str(self.PORT) + "," +
                                str(tmp_t.testobj.TestInputData.testid) + "," +
                                h))
                        if ret == "SUCCESS":
                            alive = True
                            test_logger.info(
                                "Handshake successful with execution host " +
                                h)
                            lctx.debug(
                                "Handshake successful in scheduler, adding ip/hostname to reg hosts"
                            )
                            server.serv.registered_hosts[h] = h
                            addr = socket.gethostbyname(h)
                            lctx.debug(addr)
                            server.serv.registered_hosts[addr] = addr
                        else:
                            raise Exception(
                                "Unable to handshake with agent on executuion host "
                                + h)

                except Exception as e:
                    lctx.error(e)
                    test_logger.error(e)
                    # pause the dbmon here as we dont want the same test to be picked again after we pop
                    self.dbinstance.mon_thread[0].pause()
                    self.dbinstance.lock.acquire()
                    t = self.testmap[k].pop(0)
                    t.updateStatus("waiting", "failed")
                    self.dbinstance.lock.release()
                    lctx.debug("Removed test from map : " +
                               str(t.testobj.TestInputData.testid))
                    self.dbinstance.mon_thread[0].resume()
                    LOG.removeLogger(tmp_t)
                    continue

                if alive == True and found == False:
                    # for each framework pick one and move it to running, iff running has an empty slot.
                    lctx.debug(
                        "-------Found empty slot in dispatch and running Q-------"
                    )

                    # pause the dbmon here as we dont want the same test to be picked again after we pop
                    self.dbinstance.mon_thread[0].pause()
                    self.dbinstance.lock.acquire()
                    t = self.testmap[k].pop(0)
                    self.dbinstance.lock.release()

                    lctx.info("< %s" % t.testobj.TestInputData.testid)

                    # put the test in dispatch queue
                    self.dispatchQ__lock.acquire()
                    self.dispatch_queue[k] = t
                    self.dispatchQ__lock.release()

                    t.updateStatus("waiting", "setup")
                    self.dbinstance.mon_thread[0].resume()

                    try:
                        # Bind a seperate trigger thread for this test to start test execution
                        trigger_thread = common.FuncThread(
                            self.trigger, True, t)
                        dispatch_threads[t.testobj.TestInputData.testid] = (
                            trigger_thread, t)
                        trigger_thread.start()
                    except Exception as e:
                        lctx.error("Trigger error : " +
                                   str(t.testobj.TestInputData.testid))
                        test_logger.error("Test setup failed " +
                                          str(t.testobj.TestInputData.testid))
                        LOG.removeLogger(tmp_t)
                        self.dispatchQ__lock.acquire()
                        del self.dispatch_queue[k]
                        self.dispatchQ__lock.release()
                        lctx.debug(e)

            try:
                # Log list of test currently present in dispatch queue in scheduler debug file
                d = "DISPATCH [S/R] : "
                for k in self.dispatch_queue:
                    d = d + " |" + str(
                        self.dispatch_queue[k].testobj.TestInputData.testid)
            except:
                lctx.debug("ERROR : Dispatch Q empty")

            lctx.debug(d)
            d = ""

            time.sleep(2)