# Path: lava_dispatcher/log.py
# class YAMLLogger(logging.Logger):
#     def __init__(self, name):
#         super(YAMLLogger, self).__init__(name)
#         self.handler = None
# 
#     def addZMQHandler(self, logging_url, master_cert, slave_cert, job_id, ipv6):
#         self.handler = ZMQPushHandler(logging_url, master_cert,
#                                       slave_cert, job_id, ipv6)
#         self.addHandler(self.handler)
#         return self.handler
# 
#     def close(self, linger=-1):
#         if self.handler is not None:
#             self.handler.close(linger)
#             self.removeHandler(self.handler)
#             self.handler = None
# 
#     def log_message(self, level, level_name, message, *args, **kwargs):  # pylint: disable=unused-argument
#         # Build the dictionnary
#         data = {'dt': datetime.datetime.utcnow().isoformat(),
#                 'lvl': level_name}
# 
#         if isinstance(message, str) and args:
#             data['msg'] = message % args
#         else:
#             data['msg'] = message
# 
#         # Set width to a really large value in order to always get one line.
#         # But keep this reasonable because the logs will be loaded by CLoader
#         # that is limited to around 10**7 chars
#         data_str = yaml.dump(data, default_flow_style=True,
#                              default_style='"',
#                              width=10 ** 6,
#                              Dumper=yaml.CDumper)[:-1]
#         # Test the limit and skip if the line is too long
#         if len(data_str) >= 10 ** 6:
#             if isinstance(message, str):
#                 data['msg'] = "<line way too long ...>"
#             else:
#                 data['msg'] = {"skip": "line way too long ..."}
#             data_str = yaml.dump(data, default_flow_style=True,
#                                  default_style='"',
#                                  width=10 ** 6,
#                                  Dumper=yaml.CDumper)[:-1]
#         self._log(level, data_str, ())
# 
#     def exception(self, exc, *args, **kwargs):
#         self.log_message(logging.ERROR, 'exception', exc, *args, **kwargs)
# 
#     def error(self, message, *args, **kwargs):
#         self.log_message(logging.ERROR, 'error', message, *args, **kwargs)
# 
#     def warning(self, message, *args, **kwargs):
#         self.log_message(logging.WARNING, 'warning', message, *args, **kwargs)
# 
#     def info(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'info', message, *args, **kwargs)
# 
#     def debug(self, message, *args, **kwargs):
#         self.log_message(logging.DEBUG, 'debug', message, *args, **kwargs)
# 
#     def input(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'input', message, *args, **kwargs)
# 
#     def target(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'target', message, *args, **kwargs)
# 
#     def feedback(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'feedback', message, *args, **kwargs)
# 
#     def results(self, results, *args, **kwargs):
#         if 'extra' in results and 'level' not in results:
#             raise Exception("'level' is mandatory when 'extra' is used")
#         self.log_message(logging.INFO, 'results', results, *args, **kwargs)
# 
# Path: lava_dispatcher/utils/constants.py
# ACTION_TIMEOUT = 30
# 
# OVERRIDE_CLAMP_DURATION = 300
# 
# Path: lava_dispatcher/utils/strings.py
# def seconds_to_str(time):
#     hours, remainder = divmod(int(round(time)), 3600)
#     minutes, seconds = divmod(remainder, 60)
#     return "%02d:%02d:%02d" % (hours, minutes, seconds)


import logging
import sys
import copy
import time
import types
import signal
import datetime
import traceback
import subprocess
from functools import reduce  # pylint: disable=redefined-builtin
from collections import OrderedDict
from contextlib import contextmanager
from nose.tools import nottest
from lava_dispatcher.log import YAMLLogger
from lava_dispatcher.utils.constants import (
    ACTION_TIMEOUT,
    OVERRIDE_CLAMP_DURATION
)
from lava_dispatcher.utils.strings import seconds_to_str
    def test_needs_overlay(self, parameters):  # pylint: disable=no-self-use
        if parameters['namespace'] in parameters['test_info']:
            testclasses = parameters['test_info'][parameters['namespace']]
            for testclass in testclasses:
                if testclass['class'].needs_overlay():
                    return True
        return False


class Timeout(object):
    """
    The Timeout class is a declarative base which any actions can use. If an Action has
    a timeout, that timeout name and the duration will be output as part of the action
    description and the timeout is then exposed as a modifiable value via the device_type,
    device or even job inputs. (Some timeouts may be deemed "protected" which may not be
    altered by the job. All timeouts are subject to a hardcoded maximum duration which
    cannot be exceeded by device_type, device or job input, only by the Action initialising
    the timeout.
    If a connection is set, this timeout is used per pexpect operation on that connection.
    If a connection is not set, this timeout applies for the entire run function of the action.
    """
    def __init__(self, name, duration=ACTION_TIMEOUT, exception=JobError):
        self.name = name
        self.start = 0
        self.elapsed_time = -1
        self.duration = duration  # Actions can set timeouts higher than the clamp.
        self.exception = exception

    @classmethod
    def default_duration(cls):

# Path: lava_dispatcher/log.py
# class YAMLLogger(logging.Logger):
#     def __init__(self, name):
#         super(YAMLLogger, self).__init__(name)
#         self.handler = None
# 
#     def addZMQHandler(self, logging_url, master_cert, slave_cert, job_id, ipv6):
#         self.handler = ZMQPushHandler(logging_url, master_cert,
#                                       slave_cert, job_id, ipv6)
#         self.addHandler(self.handler)
#         return self.handler
# 
#     def close(self, linger=-1):
#         if self.handler is not None:
#             self.handler.close(linger)
#             self.removeHandler(self.handler)
#             self.handler = None
# 
#     def log_message(self, level, level_name, message, *args, **kwargs):  # pylint: disable=unused-argument
#         # Build the dictionnary
#         data = {'dt': datetime.datetime.utcnow().isoformat(),
#                 'lvl': level_name}
# 
#         if isinstance(message, str) and args:
#             data['msg'] = message % args
#         else:
#             data['msg'] = message
# 
#         # Set width to a really large value in order to always get one line.
#         # But keep this reasonable because the logs will be loaded by CLoader
#         # that is limited to around 10**7 chars
#         data_str = yaml.dump(data, default_flow_style=True,
#                              default_style='"',
#                              width=10 ** 6,
#                              Dumper=yaml.CDumper)[:-1]
#         # Test the limit and skip if the line is too long
#         if len(data_str) >= 10 ** 6:
#             if isinstance(message, str):
#                 data['msg'] = "<line way too long ...>"
#             else:
#                 data['msg'] = {"skip": "line way too long ..."}
#             data_str = yaml.dump(data, default_flow_style=True,
#                                  default_style='"',
#                                  width=10 ** 6,
#                                  Dumper=yaml.CDumper)[:-1]
#         self._log(level, data_str, ())
# 
#     def exception(self, exc, *args, **kwargs):
#         self.log_message(logging.ERROR, 'exception', exc, *args, **kwargs)
# 
#     def error(self, message, *args, **kwargs):
#         self.log_message(logging.ERROR, 'error', message, *args, **kwargs)
# 
#     def warning(self, message, *args, **kwargs):
#         self.log_message(logging.WARNING, 'warning', message, *args, **kwargs)
# 
#     def info(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'info', message, *args, **kwargs)
# 
#     def debug(self, message, *args, **kwargs):
#         self.log_message(logging.DEBUG, 'debug', message, *args, **kwargs)
# 
#     def input(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'input', message, *args, **kwargs)
# 
#     def target(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'target', message, *args, **kwargs)
# 
#     def feedback(self, message, *args, **kwargs):
#         self.log_message(logging.INFO, 'feedback', message, *args, **kwargs)
# 
#     def results(self, results, *args, **kwargs):
#         if 'extra' in results and 'level' not in results:
#             raise Exception("'level' is mandatory when 'extra' is used")
#         self.log_message(logging.INFO, 'results', results, *args, **kwargs)
# 
# Path: lava_dispatcher/utils/constants.py
# ACTION_TIMEOUT = 30
# 
# OVERRIDE_CLAMP_DURATION = 300
# 
# Path: lava_dispatcher/utils/strings.py
# def seconds_to_str(time):
#     hours, remainder = divmod(int(round(time)), 3600)
#     minutes, seconds = divmod(remainder, 60)
#     return "%02d:%02d:%02d" % (hours, minutes, seconds)


# Path: lava_dispatcher/action.py
import logging
import sys
import copy
import time
import types
import signal
import datetime
import traceback
import subprocess
from functools import reduce  # pylint: disable=redefined-builtin
from collections import OrderedDict
from contextlib import contextmanager
from nose.tools import nottest
from lava_dispatcher.log import YAMLLogger
from lava_dispatcher.utils.constants import (
    ACTION_TIMEOUT,
    OVERRIDE_CLAMP_DURATION
)
from lava_dispatcher.utils.strings import seconds_to_str

    def test_needs_overlay(self, parameters):  # pylint: disable=no-self-use
        if parameters['namespace'] in parameters['test_info']:
            testclasses = parameters['test_info'][parameters['namespace']]
            for testclass in testclasses:
                if testclass['class'].needs_overlay():
                    return True
        return False


class Timeout(object):
    """
    The Timeout class is a declarative base which any actions can use. If an Action has
    a timeout, that timeout name and the duration will be output as part of the action
    description and the timeout is then exposed as a modifiable value via the device_type,
    device or even job inputs. (Some timeouts may be deemed "protected" which may not be
    altered by the job. All timeouts are subject to a hardcoded maximum duration which
    cannot be exceeded by device_type, device or job input, only by the Action initialising
    the timeout.
    If a connection is set, this timeout is used per pexpect operation on that connection.
    If a connection is not set, this timeout applies for the entire run function of the action.
    """
    def __init__(self, name, duration=ACTION_TIMEOUT, exception=JobError):
        self.name = name
        self.start = 0
        self.elapsed_time = -1
        self.duration = duration  # Actions can set timeouts higher than the clamp.
        self.exception = exception

    @classmethod
    def default_duration(cls):

        return ACTION_TIMEOUT