<commit_before>#
# ========================================================
# Copyright (c) 2012 Whamcloud, Inc.  All rights reserved.
# ========================================================


import glob
import json
import threading
import sys
import socket
import SocketServer
import time
from cluster_sim.utils import Persisted
from cluster_sim.log import log
from chroma_agent.agent_client import ExceptionCatchingThread

ESC = [chr(27)]
# http://support.microsoft.com/kb/231866
# In reality, ctrl-c is being transformed into:
# IP (Suspend), DO TIMING_MARK
CTRL_C = [chr(255), chr(244), chr(255), chr(253), chr(6)]
# Apparently OS X telnet is different? Sends EOF.
EOF = [chr(255), chr(236)]
# ... To which we respond: NOPE, WON'T DO IT, which is sufficient to
# make the client go about its business.
# http://tools.ietf.org/html/rfc860
WONT_TIMING_MARK = [chr(255), chr(252), chr(6)]

# 23xx looks pretty clear on OS X
BASE_PDU_SERVER_PORT = 2300
PDU_SERVER_ADDRESS = '127.0.0.1'

# on a real PDU, there is a brief pause between off and on when cycled
OUTLET_CYCLE_TIME = 3


class SimulatorTcpHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        log.debug("Handling PDU request from %s:%s" % self.client_address)
        self.server.pdu_simulator.handle_client(self.request,
                                                self.client_address)


class SimulatorTcpServer(SocketServer.TCPServer):
    def __init__(self, *args, **kwargs):
        self.pdu_simulator = kwargs.pop('pdu_simulator')
        # Allow the address to be re-used, otherwise we may get stuck in
        # a TIME_WAIT timeout if there wasn't a clean connection teardown.
        SocketServer.TCPServer.allow_reuse_address = True
        # SocketServer classes are not new-style classes.
        SocketServer.TCPServer.__init__(self, *args, **kwargs)


class PDUSimulatorServer(ExceptionCatchingThread):
    def __init__(self, pdu):
        super(PDUSimulatorServer, self).__init__()

        self._pdu = pdu

    def stop(self):
        self.server.shutdown()
        self.server.server_close()

    def _run(self):
        log.info("Creating PDU server for %s on %s:%s" %
                            (self._pdu.name, self._pdu.address, self._pdu.port))
        self.server = SimulatorTcpServer((self._pdu.address, self._pdu.port),
                                         SimulatorTcpHandler,
                                         pdu_simulator = self._pdu)

        self.server.serve_forever()


class PDUSimulator(Persisted):
    default_state = {
        'outlets': {}
    }

    def __init__(self, folder, address, port, pdu_name, outlets, poweroff_hook=None, poweron_hook=None):
        self.address = address
        self.port = port
        self.name = pdu_name
        self.poweroff_hook = poweroff_hook
        self.poweron_hook = poweron_hook
        super(PDUSimulator, self).__init__(folder)

        self._lock = threading.Lock()

        self.state['klass'] = self.__class__.__name__
        self.state['name'] = pdu_name
        self.state['outlets'] = outlets
        self.state['address'] = address
        self.state['port'] = port
        self.save()

    def add_outlet(self, outlet):
        with self._lock:
            self.state['outlets'][outlet] = True
            self.save()

    def handle_client(self, sock, address):
        log.info("%s: received connection from %s:%s" % (self.__class__.__name__,
                                                         address[0], address[1]))
        fd = sock.makefile()
        fd.write("NOT IMPLEMENTED\r\n")
        fd.flush()
        sock.close()

    @property
    def filename(self):
        return "pdu_sim_%s.json" % self.name

    def outlet_is_on(self, outlet):
        with self._lock:
            return self.state['outlets'][outlet]

    def outlet_state(self, outlet):
        if not self._lock.locked():
            with self._lock:
                state = self.state['outlets'][outlet]
        else:
            state = self.state['outlets'][outlet]

        return "ON" if state else "OFF"

    @property
    def all_outlet_states(self):
        with self._lock:
            return dict([[o, self.outlet_state(o)] for o in self.state['outlets'].keys()])

    def toggle_outlet(self, outlet, state):
        with self._lock:
            self.state['outlets'][outlet] = state
            log.info("POWER: Toggled %s:%s to %s" % (self.name, outlet,
                                                     self.outlet_state(outlet)))
            self.save()

    def set_outlet_on(self, outlet):
        self.toggle_outlet(outlet, True)

        if self.poweron_hook:
            self.poweron_hook(outlet)

    def set_outlet_off(self, outlet):
        self.toggle_outlet(outlet, False)

        if self.poweroff_hook:
            self.poweroff_hook(outlet)

    def cycle_outlet(self, outlet):
        self.set_outlet_off(outlet)
        time.sleep(OUTLET_CYCLE_TIME)
        self.set_outlet_on(outlet)


class APC79xxSimulator(PDUSimulator):
    def handle_client(self, sock, address):
        log.info("%s: received connection from %s:%s" % (self.__class__.__name__,
                                                         address[0], address[1]))
        self.client_address = address
        self.socket = sock
        self.fd = sock.makefile()

        try:
            self.login()
        except socket.error:
            log.info("%s: client %s:%s disconnected" % (self.__class__.__name__,
                                                        address[0], address[1]))

    def navigation_prompt(self, prompt, forward_choices, forward, backward, banner=None):
        if hasattr(forward_choices, 'split'):
            forward_choices = forward_choices.split()

        lead_prompt = prompt
        if banner:
            lead_prompt = "%s%s" % (banner, prompt)
        self.fd.write("\r\n%s" % lead_prompt)
        self.fd.flush()
        recv_buf = []
        while True:
            response = ""
            while True:
                # This was not my first choice, but it turns out that
                # we have to interpret telnet control sequences in order
                # to accommodate real fence agents.  Sigh.
                c = self.socket.recv(1)
                if c in "\r\n":
                    response = "".join(recv_buf)
                    del(recv_buf[:])
                    # Eat the LF
                    c = self.socket.recv(1)
                    break
                recv_buf.append(c)

                if recv_buf == CTRL_C or recv_buf == EOF:
                    for c in WONT_TIMING_MARK:
                        self.socket.send(c)
                    self.control_console()<commit_msg>Fix for power control simulator on osx 10.8.<commit_after>#
# ========================================================
# Copyright (c) 2012 Whamcloud, Inc.  All rights reserved.
# ========================================================


import glob
import json
import threading
import sys
import socket
import SocketServer
import time
from cluster_sim.utils import Persisted
from cluster_sim.log import log
from chroma_agent.agent_client import ExceptionCatchingThread

ESC = [chr(27)]
# http://support.microsoft.com/kb/231866
# In reality, ctrl-c is being transformed into:
# IP (Suspend), DO TIMING_MARK
CTRL_C = [chr(255), chr(244), chr(255), chr(253), chr(6)]
# Apparently OS X telnet is different? Sends EOF.
EOF = [chr(255), chr(236)]
# ... To which we respond: NOPE, WON'T DO IT, which is sufficient to
# make the client go about its business.
# http://tools.ietf.org/html/rfc860
WONT_TIMING_MARK = [chr(255), chr(252), chr(6)]

# 23xx looks pretty clear on OS X
BASE_PDU_SERVER_PORT = 2300
PDU_SERVER_ADDRESS = '127.0.0.1'

# on a real PDU, there is a brief pause between off and on when cycled
OUTLET_CYCLE_TIME = 3


class SimulatorTcpHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        log.debug("Handling PDU request from %s:%s" % self.client_address)
        self.server.pdu_simulator.handle_client(self.request,
                                                self.client_address)


class SimulatorTcpServer(SocketServer.TCPServer):
    def __init__(self, *args, **kwargs):
        self.pdu_simulator = kwargs.pop('pdu_simulator')
        # Allow the address to be re-used, otherwise we may get stuck in
        # a TIME_WAIT timeout if there wasn't a clean connection teardown.
        SocketServer.TCPServer.allow_reuse_address = True
        # SocketServer classes are not new-style classes.
        SocketServer.TCPServer.__init__(self, *args, **kwargs)


class PDUSimulatorServer(ExceptionCatchingThread):
    def __init__(self, pdu):
        super(PDUSimulatorServer, self).__init__()

        self._pdu = pdu

    def stop(self):
        self.server.shutdown()
        self.server.server_close()

    def _run(self):
        log.info("Creating PDU server for %s on %s:%s" %
                            (self._pdu.name, self._pdu.address, self._pdu.port))
        self.server = SimulatorTcpServer((self._pdu.address, self._pdu.port),
                                         SimulatorTcpHandler,
                                         pdu_simulator = self._pdu)

        self.server.serve_forever()


class PDUSimulator(Persisted):
    default_state = {
        'outlets': {}
    }

    def __init__(self, folder, address, port, pdu_name, outlets, poweroff_hook=None, poweron_hook=None):
        self.address = address
        self.port = port
        self.name = pdu_name
        self.poweroff_hook = poweroff_hook
        self.poweron_hook = poweron_hook
        super(PDUSimulator, self).__init__(folder)

        self._lock = threading.Lock()

        self.state['klass'] = self.__class__.__name__
        self.state['name'] = pdu_name
        self.state['outlets'] = outlets
        self.state['address'] = address
        self.state['port'] = port
        self.save()

    def add_outlet(self, outlet):
        with self._lock:
            self.state['outlets'][outlet] = True
            self.save()

    def handle_client(self, sock, address):
        log.info("%s: received connection from %s:%s" % (self.__class__.__name__,
                                                         address[0], address[1]))
        fd = sock.makefile()
        fd.write("NOT IMPLEMENTED\r\n")
        fd.flush()
        sock.close()

    @property
    def filename(self):
        return "pdu_sim_%s.json" % self.name

    def outlet_is_on(self, outlet):
        with self._lock:
            return self.state['outlets'][outlet]

    def outlet_state(self, outlet):
        if not self._lock.locked():
            with self._lock:
                state = self.state['outlets'][outlet]
        else:
            state = self.state['outlets'][outlet]

        return "ON" if state else "OFF"

    @property
    def all_outlet_states(self):
        with self._lock:
            return dict([[o, self.outlet_state(o)] for o in self.state['outlets'].keys()])

    def toggle_outlet(self, outlet, state):
        with self._lock:
            self.state['outlets'][outlet] = state
            log.info("POWER: Toggled %s:%s to %s" % (self.name, outlet,
                                                     self.outlet_state(outlet)))
            self.save()

    def set_outlet_on(self, outlet):
        self.toggle_outlet(outlet, True)

        if self.poweron_hook:
            self.poweron_hook(outlet)

    def set_outlet_off(self, outlet):
        self.toggle_outlet(outlet, False)

        if self.poweroff_hook:
            self.poweroff_hook(outlet)

    def cycle_outlet(self, outlet):
        self.set_outlet_off(outlet)
        time.sleep(OUTLET_CYCLE_TIME)
        self.set_outlet_on(outlet)


class APC79xxSimulator(PDUSimulator):
    def handle_client(self, sock, address):
        log.info("%s: received connection from %s:%s" % (self.__class__.__name__,
                                                         address[0], address[1]))
        self.client_address = address
        self.socket = sock
        self.fd = sock.makefile()

        try:
            self.login()
        except socket.error:
            log.info("%s: client %s:%s disconnected" % (self.__class__.__name__,
                                                        address[0], address[1]))

    def navigation_prompt(self, prompt, forward_choices, forward, backward, banner=None):
        if hasattr(forward_choices, 'split'):
            forward_choices = forward_choices.split()

        lead_prompt = prompt
        if banner:
            lead_prompt = "%s%s" % (banner, prompt)
        self.fd.write("\r\n%s" % lead_prompt)
        self.fd.flush()
        recv_buf = []
        while True:
            response = ""
            while True:
                # This was not my first choice, but it turns out that
                # we have to interpret telnet control sequences in order
                # to accommodate real fence agents.  Sigh.
                c = self.socket.recv(1)
                if c in "\r\n":
                    response = "".join(recv_buf)
                    del(recv_buf[:])
                    # Eat the LF
                    c = self.socket.recv(1)
                    break
                recv_buf.append(c)

                if recv_buf == CTRL_C:
                    for c in WONT_TIMING_MARK:
                        self.socket.send(c)
                    self.control_console()
                elif recv_buf == EOF:
                    self.logout()
{'fraction_non_alphanumeric': 0.12004730928444707, 'fraction_numerical': 0.009683619160260202, 'mean_word_length': 2.045700135074291, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5821853', 'n_tokens_mistral': 4100, 'n_tokens_neox': 3880, 'n_words': 935}