<commit_before>#!/usr/bin/env python2.7
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Dictionaries used for client matrix testing.

def get_github_repo(lang):
    return {
        'dart': 'https://github.com/grpc/grpc-dart.git',
        'go': 'https://github.com/grpc/grpc-go.git',
        'java': 'https://github.com/grpc/grpc-java.git',
        'node': 'https://github.com/grpc/grpc-node.git',
        # all other languages use the grpc.git repo.
    }.get(lang, 'https://github.com/grpc/grpc.git')

def get_release_tags(lang):
    return map(lambda r: get_release_tag_name(r), LANG_RELEASE_MATRIX[lang])

def get_release_tag_name(release_info):
    assert len(release_info.keys()) == 1
    return release_info.keys()[0]

def should_build_docker_interop_image_from_release_tag(lang):
    if lang in ['go', 'java', 'node']:
        return False
    return True

# Dictionary of runtimes per language
LANG_RUNTIME_MATRIX = {
    'cxx': ['cxx'],  # This is actually debian8.
    'go': ['go1.7', 'go1.8'],
    'java': ['java_oracle8'],
    'python': ['python'],
    'node': ['node'],
    'ruby': ['ruby'],
    'php': ['php', 'php7'],
    'csharp': ['csharp', 'csharpcoreclr'],
}

# Dictionary of releases per language.  For each language, we need to provide
# a release tag pointing to the latest build of the branch.
LANG_RELEASE_MATRIX = {
    'cxx': [
        {
            'v1.0.1': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'go': [
        {
            'v1.0.5': None
        },
        {
            'v1.2.1': None
        },
        {
            'v1.3.0': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.5.2': None
        },
        {
            'v1.6.0': None
        },
        {
            'v1.7.4': None
        },
        {
            'v1.8.2': None
        },
        {
            'v1.9.2': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.3': None
        },
        {
            'v1.12.0': None
        },
    ],
    'java': [
        {
            'v1.0.3': None
        },
        {
            'v1.1.2': None
        },
        {
            'v1.2.0': None
        },
        {
            'v1.3.1': None
        },
        {
            'v1.4.0': None
        },
        {
            'v1.5.0': None
        },
        {
            'v1.6.1': None
        },
        {
            'v1.7.0': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.0': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.1': None
        },
        {
            'v1.14.0': None
        },
    ],
    'python': [
        {
            'v1.0.x': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.1': None  # first python 1.8 release is 1.8.1
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'node': [
        {
            'v1.0.1': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        # TODO: https://github.com/grpc/grpc-node/issues/235.
        #{
        #    'v1.7.2': None
        #},
        {
            'v1.8.4': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.0': None
        },
        {
            'v1.11.3': None
        },
        {
            'v1.12.4': None
        },
    ],
    'ruby': [
        {
            'v1.0.1': {
                'patch': [
                    'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile',
                    'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh',
                ]
            }
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'php': [
        {
            'v1.0.1': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'csharp': [
        {
            'v1.0.1': {
                'patch': [
                    'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile',
                    'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile',
                ]
            }
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
}

# This matrix lists the version of testcases to use for a release. As new
# releases come out, some older docker commands for running tests need to be
# changed, hence the need for specifying which commands to use for a
# particular version in some cases. If not specified, xxx__master file will be
# used. For example, all java versions will run the commands in java__master.
# The testcases files exist under the testcases directory.
TESTCASES_VERSION_MATRIX = {
    'node_v1.0.1': 'node__v1.0.1',
    'node_v1.1.4': 'node__v1.1.4',
    'node_v1.2.5': 'node__v1.1.4',
    'node_v1.3.9': 'node__v1.1.4',
    'node_v1.4.2': 'node__v1.1.4',
    'node_v1.6.6': 'node__v1.1.4',
    'ruby_v1.0.1': 'ruby__v1.0.1',
    'csharp_v1.0.1': 'csharp__v1.1.4',
    'csharp_v1.1.4': 'csharp__v1.1.4',
    'csharp_v1.2.5': 'csharp__v1.1.4',
    'python_v1.0.x': 'python__v1.0.x',
    'python_v1.1.4': 'python__v1.0.x',
    'python_v1.2.5': 'python__v1.0.x',
    'python_v1.3.9': 'python__v1.0.x',
    'python_v1.4.2': 'python__v1.0.x',
    'python_v1.6.6': 'python__v1.0.x',
    'python_v1.7.2': 'python__v1.0.x',
    'python_v1.8.1': 'python__v1.0.x',
    'python_v1.9.1': 'python__v1.0.x',
    'python_v1.10.1': 'python__v1.0.x',
}
<commit_msg>Add v1.15.0 release of grpc-java<commit_after>#!/usr/bin/env python2.7
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Dictionaries used for client matrix testing.

def get_github_repo(lang):
    return {
        'dart': 'https://github.com/grpc/grpc-dart.git',
        'go': 'https://github.com/grpc/grpc-go.git',
        'java': 'https://github.com/grpc/grpc-java.git',
        'node': 'https://github.com/grpc/grpc-node.git',
        # all other languages use the grpc.git repo.
    }.get(lang, 'https://github.com/grpc/grpc.git')

def get_release_tags(lang):
    return map(lambda r: get_release_tag_name(r), LANG_RELEASE_MATRIX[lang])

def get_release_tag_name(release_info):
    assert len(release_info.keys()) == 1
    return release_info.keys()[0]

def should_build_docker_interop_image_from_release_tag(lang):
    if lang in ['go', 'java', 'node']:
        return False
    return True

# Dictionary of runtimes per language
LANG_RUNTIME_MATRIX = {
    'cxx': ['cxx'],  # This is actually debian8.
    'go': ['go1.7', 'go1.8'],
    'java': ['java_oracle8'],
    'python': ['python'],
    'node': ['node'],
    'ruby': ['ruby'],
    'php': ['php', 'php7'],
    'csharp': ['csharp', 'csharpcoreclr'],
}

# Dictionary of releases per language.  For each language, we need to provide
# a release tag pointing to the latest build of the branch.
LANG_RELEASE_MATRIX = {
    'cxx': [
        {
            'v1.0.1': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'go': [
        {
            'v1.0.5': None
        },
        {
            'v1.2.1': None
        },
        {
            'v1.3.0': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.5.2': None
        },
        {
            'v1.6.0': None
        },
        {
            'v1.7.4': None
        },
        {
            'v1.8.2': None
        },
        {
            'v1.9.2': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.3': None
        },
        {
            'v1.12.0': None
        },
    ],
    'java': [
        {
            'v1.0.3': None
        },
        {
            'v1.1.2': None
        },
        {
            'v1.2.0': None
        },
        {
            'v1.3.1': None
        },
        {
            'v1.4.0': None
        },
        {
            'v1.5.0': None
        },
        {
            'v1.6.1': None
        },
        {
            'v1.7.0': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.0': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.1': None
        },
        {
            'v1.14.0': None
        },
        {
            'v1.15.0': None
        },
    ],
    'python': [
        {
            'v1.0.x': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.1': None  # first python 1.8 release is 1.8.1
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'node': [
        {
            'v1.0.1': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        # TODO: https://github.com/grpc/grpc-node/issues/235.
        #{
        #    'v1.7.2': None
        #},
        {
            'v1.8.4': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.0': None
        },
        {
            'v1.11.3': None
        },
        {
            'v1.12.4': None
        },
    ],
    'ruby': [
        {
            'v1.0.1': {
                'patch': [
                    'tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile',
                    'tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh',
                ]
            }
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'php': [
        {
            'v1.0.1': None
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
    'csharp': [
        {
            'v1.0.1': {
                'patch': [
                    'tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile',
                    'tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile',
                ]
            }
        },
        {
            'v1.1.4': None
        },
        {
            'v1.2.5': None
        },
        {
            'v1.3.9': None
        },
        {
            'v1.4.2': None
        },
        {
            'v1.6.6': None
        },
        {
            'v1.7.2': None
        },
        {
            'v1.8.0': None
        },
        {
            'v1.9.1': None
        },
        {
            'v1.10.1': None
        },
        {
            'v1.11.1': None
        },
        {
            'v1.12.0': None
        },
        {
            'v1.13.0': None
        },
        {
            'v1.14.1': None
        },
    ],
}

# This matrix lists the version of testcases to use for a release. As new
# releases come out, some older docker commands for running tests need to be
# changed, hence the need for specifying which commands to use for a
# particular version in some cases. If not specified, xxx__master file will be
# used. For example, all java versions will run the commands in java__master.
# The testcases files exist under the testcases directory.
TESTCASES_VERSION_MATRIX = {
    'node_v1.0.1': 'node__v1.0.1',
    'node_v1.1.4': 'node__v1.1.4',
    'node_v1.2.5': 'node__v1.1.4',
    'node_v1.3.9': 'node__v1.1.4',
    'node_v1.4.2': 'node__v1.1.4',
    'node_v1.6.6': 'node__v1.1.4',
    'ruby_v1.0.1': 'ruby__v1.0.1',
    'csharp_v1.0.1': 'csharp__v1.1.4',
    'csharp_v1.1.4': 'csharp__v1.1.4',
    'csharp_v1.2.5': 'csharp__v1.1.4',
    'python_v1.0.x': 'python__v1.0.x',
    'python_v1.1.4': 'python__v1.0.x',
    'python_v1.2.5': 'python__v1.0.x',
    'python_v1.3.9': 'python__v1.0.x',
    'python_v1.4.2': 'python__v1.0.x',
    'python_v1.6.6': 'python__v1.0.x',
    'python_v1.7.2': 'python__v1.0.x',
    'python_v1.8.1': 'python__v1.0.x',
    'python_v1.9.1': 'python__v1.0.x',
    'python_v1.10.1': 'python__v1.0.x',
}
<|endoftext|>


<commit_before>#pylint: disable=C0301, C0103, W0212

"""
.. module:: radical.pilot.compute_pilot
   :platform: Unix
   :synopsis: Provides the interface for the ComputePilot class.

.. moduleauthor:: Ole Weidner <ole.weidner@rutgers.edu>
"""

__copyright__ = "Copyright 2013-2014, http://radical.rutgers.edu"
__license__ = "MIT"

import os
import time
import saga

from radical.pilot.states import *
from radical.pilot.logentry import *
from radical.pilot.exceptions import *

from radical.pilot.utils.logger import logger

from radical.pilot.staging_directives import TRANSFER, COPY, LINK, MOVE, \
    STAGING_AREA, expand_staging_directive

# -----------------------------------------------------------------------------
#
class ComputePilot (object):
    """A ComputePilot represent a resource overlay on a local or remote
       resource.

    .. note:: A ComputePilot cannot be created directly. The factory method
              :meth:`radical.pilot.PilotManager.submit_pilots` has to be used instead.

                **Example**::

                      pm = radical.pilot.PilotManager(session=s)

                      pd = radical.pilot.ComputePilotDescription()
                      pd.resource = "local.localhost"
                      pd.cores    = 2
                      pd.runtime  = 5 # minutes

                      pilot = pm.submit_pilots(pd)
    """
    # -------------------------------------------------------------------------
    #
    def __init__(self):
        """Le constructeur. Not meant to be called directly.
        """
        # 'static' members
        self._uid = None
        self._description = None
        self._manager = None

        # Registered callback functions
        self._calback_wrappers = dict()

        # handle to the manager's worker
        self._worker = None

        # list of callback functions
        self._callback_list = []

    # -------------------------------------------------------------------------
    #
    @staticmethod
    def create(pilot_manager_obj, pilot_description):
        """ PRIVATE: Create a new pilot.
        """
        # Create and return pilot object.
        pilot = ComputePilot()

        #pilot._uid = pilot_uid
        pilot._description = pilot_description
        pilot._manager = pilot_manager_obj

        # Pilots use the worker of their parent manager.
        pilot._worker = pilot._manager._worker

        #logger.info("Created new ComputePilot %s" % str(pilot))
        return pilot

    # -------------------------------------------------------------------------
    #
    @staticmethod
    def _get(pilot_manager_obj, pilot_ids):
        """ PRIVATE: Get one or more pilot via their UIDs.
        """
        pilots_json = pilot_manager_obj._worker.get_compute_pilot_data(
            pilot_ids=pilot_ids)

        # create and return pilot objects
        pilots = []

        for p in pilots_json:
            pilot = ComputePilot()
            pilot._uid = str(p['_id'])
            pilot._description = p['description']
            pilot._manager = pilot_manager_obj

            pilot._worker = pilot._manager._worker

            logger.debug("Reconnected to existing ComputePilot %s" % str(pilot))
            pilots.append(pilot)

        return pilots

    # -------------------------------------------------------------------------
    #
    def as_dict(self):
        """Returns a Python dictionary representation of the
           ComputePilot object.
        """
        obj_dict = {
            'uid':             self.uid,
            'state':           self.state,
            'stdout':          self.stdout,
            'stderr':          self.stderr,
            'logfile':         self.logfile,
            'log':             self.log,
            'sandbox':         self.sandbox,
            'resource':        self.resource,
            'submission_time': self.submission_time,
            'start_time':      self.start_time,
            'stop_time':       self.stop_time,
            'resource_detail': self.resource_detail
        }
        return obj_dict

    # -------------------------------------------------------------------------
    #
    def __str__(self):
        """Returns a string representation of the ComputePilot object.
        """
        return str(self.as_dict())

    # -------------------------------------------------------------------------
    #
    @property
    def uid(self):
        """Returns the Pilot's unique identifier.

        The uid identifies the Pilot within the :class:`PilotManager` and
        can be used to retrieve an existing Pilot.

        **Returns:**
            * A unique identifier (string).
        """
        return self._uid

    # -------------------------------------------------------------------------
    #
    @property
    def description(self):
        """Returns the pilot description the pilot was started with.
        """
        return self._description

    # -------------------------------------------------------------------------
    #
    @property
    def sandbox(self):
        """Returns the Pilot's 'sandbox' / working directory url.

        **Returns:**
            * A URL string.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['sandbox']

    # -------------------------------------------------------------------------
    #
    @property
    def state(self):
        """Returns the current state of the pilot.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['state']

    # -------------------------------------------------------------------------
    #
    @property
    def state_history(self):
        """Returns the complete state history of the pilot.
        """
        if not self._uid:
            return None

        states = []

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        for state in pilot_json['statehistory']:
            states.append(State(state=state["state"], timestamp=state["timestamp"]))

        return states

    # -------------------------------------------------------------------------
    #
    @property
    def callback_history(self):
        """Returns the complete callback history of the pilot.
        """
        if not self._uid:
            return None

        callbacks = []

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        if 'callbackhostory' in pilot_json :
            for callback in pilot_json['callbackhistory']:
                callbacks.append(State(state=callback["state"], timestamp=callback["timestamp"]))

        return callbacks

    # -------------------------------------------------------------------------
    #
    @property
    def stdout(self):
        """Returns the stdout of the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json.get ('stdout')

    # -------------------------------------------------------------------------
    #
    @property
    def stderr(self):
        """Returns the stderr of the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json.get ('stderr')

    # -------------------------------------------------------------------------
    #
    @property
    def logfile(self):
        """Returns the logfile of the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json.get ('logfile')

    # -------------------------------------------------------------------------
    #
    @property
    def log(self):
        """Returns the log of the pilot.
        """
        if not self._uid:
            return None

        logs = []

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        for log in pilot_json['log']:
            logs.append (Logentry.from_dict (log))

        return logs

    # -------------------------------------------------------------------------
    #
    @property
    def resource_detail(self):
        """Returns the names of the nodes managed by the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        resource_details = {
            'nodes':          pilot_json['nodes'],
            'cores_per_node': pilot_json['cores_per_node']
        }
        return resource_details

    # -------------------------------------------------------------------------
    #
    @property
    def pilot_manager(self):
        """ Returns the pilot manager object for this pilot.
        """
        return self._manager

    # -------------------------------------------------------------------------
    #
    @property
    def unit_managers(self):
        """ Returns the unit manager object UIDs for this pilot.
        """
        if not self._uid:
            return None

        raise NotImplementedError("Not Implemented")

    # -------------------------------------------------------------------------
    #
    @property
    def units(self):
        """ Returns the units scheduled for this pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            return None

        raise NotImplementedError("Not Implemented")

    # -------------------------------------------------------------------------
    #
    @property
    def submission_time(self):
        """ Returns the time the pilot was submitted.
        """
        # Check if this instance is valid
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['submitted']

    # -------------------------------------------------------------------------
    #
    @property
    def start_time(self):
        """ Returns the time the pilot was started on the backend.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['started']

    # -------------------------------------------------------------------------
    #
    @property
    def stop_time(self):
        """ Returns the time the pilot was stopped.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['finished']

    # -------------------------------------------------------------------------
    #
    @property
    def resource(self):
        """ Returns the resource.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['description']['resource']

    # -------------------------------------------------------------------------
    #
    def register_callback(self, callback_func, callback_data=None):
        """Registers a callback function that is triggered every time the
        ComputePilot's state changes.

        All callback functions need to have the same signature::

            def callback_func(obj, state, data)

        where ``object`` is a handle to the object that triggered the callback,
        ``state`` is the new state of that object, and ``data`` is the data
        passed on callback registration.
        """
        self._worker.register_pilot_callback(self, callback_func, callback_data)

    # -------------------------------------------------------------------------
    #
    def wait(self, state=None, timeout=None):
        """Returns when the pilot reaches a specific state or
        when an optional timeout is reached.

        **Arguments:**

            * **state** [`list of strings`]
              The state(s) that Pilot has to reach in order for the
              call to return.

              By default `wait` waits for the Pilot to reach
              a **terminal** state, which can be one of the following:

              * :data:`radical.pilot.states.DONE`
              * :data:`radical.pilot.states.FAILED`
              * :data:`radical.pilot.states.CANCELED`

            * **timeout** [`float`]
              Optional timeout in seconds before the call returns regardless
              whether the Pilot has reached the desired state or not.
              The default value **None** never times out.

        **Raises:**

            * :class:`radical.pilot.exceptions.radical.pilotException` if the state of
              the pilot cannot be determined.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        if not state:
            state = [DONE, FAILED, CANCELED]

        elif not isinstance(state, list):
            state = [state]

        start_wait = time.time()
        # the self.state property pulls the state from the back end.
        new_state = self.state

        while new_state not in state:
            time.sleep(0.1)
            new_state = self.state

            if (timeout is not None) and (timeout <= (time.time() - start_wait)):
                break

        # done waiting -- return the state
        return new_state

    # -------------------------------------------------------------------------
    #
    def cancel(self):
        """Sends sends a termination request to the pilot.

        **Raises:**

            * :class:`radical.pilot.radical.pilotException` if the termination
              request cannot be fulfilled.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState(msg="Invalid instance.")

        if self.state in [DONE, FAILED, CANCELED]:
            # nothing to do as we are already in a terminal state
            return

        # now we can send a 'cancel' command to the pilot.
        self._manager.cancel_pilots(self.uid)

    # -------------------------------------------------------------------------
    #
    def stage_in(self, directives):
        """Stages the content of the staging directive into the pilot's
        staging area"""

        # Wait until we can assume the pilot directory to be created
        if self.state == NEW:
            self.wait(state=[PENDING_LAUNCH, LAUNCHING, PENDING_ACTIVE, ACTIVE])
        elif self.state in [DONE, FAILED, CANCELED]:
            raise Exception("Pilot already finished, no need to stage anymore!")

        # Iterate over all directives
        for directive in expand_staging_directive(directives, logger):

            # TODO: respect flags in directive

            src_url = saga.Url(directive['source'])
            action = directive['action']

            # Convert the target url into a SAGA Url object
            tgt_url = saga.Url(directive['target'])

            if tgt_url.path.endswith('/'):
                # If the original target was a directory (ends with /),
                # we assume that the user wants the same filename as the source.
                tgt_filename = os.path.basename(src_url.path)
            else:
                # Otherwise, extract the filename and the directory components
                tgt_filename = os.path.basename(tgt_url.path)
                tgt_url.path = os.path.dirname(tgt_url.path)

            # Handle special 'staging' scheme
            if tgt_url.scheme == 'staging':

                # Remove the leading slash to get a relative path from the staging area
                rel_path = tgt_url.path.split('/', 1)[1]
                rel_dir = os.path.dirname(rel_path)

                # Now base the target directory relative of the sandbox and staging prefix
                tgt_url = saga.Url(os.path.join(self.sandbox, STAGING_AREA, rel_dir))

            # Define and open the staging directory for the pilot
            # We use the target dir construct here, so that we can create
            # the directory if it does not yet exist.
            target_dir = saga.filesystem.Directory(tgt_url, flags=saga.filesystem.CREATE_PARENTS)

            if action == LINK:
                # TODO: Does this make sense?
                #log_message = 'Linking %s to %s' % (source, abs_target)
                #os.symlink(source, abs_target)
                pass
            elif action == COPY:
                # TODO: Does this make sense?
                #log_message = 'Copying %s to %s' % (source, abs_target)
                #shutil.copyfile(source, abs_target)
                pass
            elif action == MOVE:
                # TODO: Does this make sense?
                #log_message = 'Moving %s to %s' % (source, abs_target)
                #shutil.move(source, abs_target)
                pass
            elif action == TRANSFER:
                log_message = 'Transferring %s to %s' % (src_url, os.path.join(str(tgt_dir_url), tgt_filename))
                logger.info(log_message)
                # Transfer the source file to the target staging area
                target_dir.copy(src_url, tgt_filename)
            else:
                raise Exception('Action %s not supported' % action)
<commit_msg>Fix for #489.<commit_after>#pylint: disable=C0301, C0103, W0212

"""
.. module:: radical.pilot.compute_pilot
   :platform: Unix
   :synopsis: Provides the interface for the ComputePilot class.

.. moduleauthor:: Ole Weidner <ole.weidner@rutgers.edu>
"""

__copyright__ = "Copyright 2013-2014, http://radical.rutgers.edu"
__license__ = "MIT"

import os
import time
import saga

from radical.pilot.states import *
from radical.pilot.logentry import *
from radical.pilot.exceptions import *

from radical.pilot.utils.logger import logger

from radical.pilot.staging_directives import TRANSFER, COPY, LINK, MOVE, \
    STAGING_AREA, expand_staging_directive

# -----------------------------------------------------------------------------
#
class ComputePilot (object):
    """A ComputePilot represent a resource overlay on a local or remote
       resource.

    .. note:: A ComputePilot cannot be created directly. The factory method
              :meth:`radical.pilot.PilotManager.submit_pilots` has to be used instead.

                **Example**::

                      pm = radical.pilot.PilotManager(session=s)

                      pd = radical.pilot.ComputePilotDescription()
                      pd.resource = "local.localhost"
                      pd.cores    = 2
                      pd.runtime  = 5 # minutes

                      pilot = pm.submit_pilots(pd)
    """
    # -------------------------------------------------------------------------
    #
    def __init__(self):
        """Le constructeur. Not meant to be called directly.
        """
        # 'static' members
        self._uid = None
        self._description = None
        self._manager = None

        # Registered callback functions
        self._calback_wrappers = dict()

        # handle to the manager's worker
        self._worker = None

        # list of callback functions
        self._callback_list = []

    # -------------------------------------------------------------------------
    #
    @staticmethod
    def create(pilot_manager_obj, pilot_description):
        """ PRIVATE: Create a new pilot.
        """
        # Create and return pilot object.
        pilot = ComputePilot()

        #pilot._uid = pilot_uid
        pilot._description = pilot_description
        pilot._manager = pilot_manager_obj

        # Pilots use the worker of their parent manager.
        pilot._worker = pilot._manager._worker

        #logger.info("Created new ComputePilot %s" % str(pilot))
        return pilot

    # -------------------------------------------------------------------------
    #
    @staticmethod
    def _get(pilot_manager_obj, pilot_ids):
        """ PRIVATE: Get one or more pilot via their UIDs.
        """
        pilots_json = pilot_manager_obj._worker.get_compute_pilot_data(
            pilot_ids=pilot_ids)

        # create and return pilot objects
        pilots = []

        for p in pilots_json:
            pilot = ComputePilot()
            pilot._uid = str(p['_id'])
            pilot._description = p['description']
            pilot._manager = pilot_manager_obj

            pilot._worker = pilot._manager._worker

            logger.debug("Reconnected to existing ComputePilot %s" % str(pilot))
            pilots.append(pilot)

        return pilots

    # -------------------------------------------------------------------------
    #
    def as_dict(self):
        """Returns a Python dictionary representation of the
           ComputePilot object.
        """
        obj_dict = {
            'uid':             self.uid,
            'state':           self.state,
            'stdout':          self.stdout,
            'stderr':          self.stderr,
            'logfile':         self.logfile,
            'log':             self.log,
            'sandbox':         self.sandbox,
            'resource':        self.resource,
            'submission_time': self.submission_time,
            'start_time':      self.start_time,
            'stop_time':       self.stop_time,
            'resource_detail': self.resource_detail
        }
        return obj_dict

    # -------------------------------------------------------------------------
    #
    def __str__(self):
        """Returns a string representation of the ComputePilot object.
        """
        return str(self.as_dict())

    # -------------------------------------------------------------------------
    #
    @property
    def uid(self):
        """Returns the Pilot's unique identifier.

        The uid identifies the Pilot within the :class:`PilotManager` and
        can be used to retrieve an existing Pilot.

        **Returns:**
            * A unique identifier (string).
        """
        return self._uid

    # -------------------------------------------------------------------------
    #
    @property
    def description(self):
        """Returns the pilot description the pilot was started with.
        """
        return self._description

    # -------------------------------------------------------------------------
    #
    @property
    def sandbox(self):
        """Returns the Pilot's 'sandbox' / working directory url.

        **Returns:**
            * A URL string.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['sandbox']

    # -------------------------------------------------------------------------
    #
    @property
    def state(self):
        """Returns the current state of the pilot.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['state']

    # -------------------------------------------------------------------------
    #
    @property
    def state_history(self):
        """Returns the complete state history of the pilot.
        """
        if not self._uid:
            return None

        states = []

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        for state in pilot_json['statehistory']:
            states.append(State(state=state["state"], timestamp=state["timestamp"]))

        return states

    # -------------------------------------------------------------------------
    #
    @property
    def callback_history(self):
        """Returns the complete callback history of the pilot.
        """
        if not self._uid:
            return None

        callbacks = []

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        if 'callbackhostory' in pilot_json :
            for callback in pilot_json['callbackhistory']:
                callbacks.append(State(state=callback["state"], timestamp=callback["timestamp"]))

        return callbacks

    # -------------------------------------------------------------------------
    #
    @property
    def stdout(self):
        """Returns the stdout of the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json.get ('stdout')

    # -------------------------------------------------------------------------
    #
    @property
    def stderr(self):
        """Returns the stderr of the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json.get ('stderr')

    # -------------------------------------------------------------------------
    #
    @property
    def logfile(self):
        """Returns the logfile of the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json.get ('logfile')

    # -------------------------------------------------------------------------
    #
    @property
    def log(self):
        """Returns the log of the pilot.
        """
        if not self._uid:
            return None

        logs = []

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        for log in pilot_json['log']:
            logs.append (Logentry.from_dict (log))

        return logs

    # -------------------------------------------------------------------------
    #
    @property
    def resource_detail(self):
        """Returns the names of the nodes managed by the pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        resource_details = {
            'nodes':          pilot_json['nodes'],
            'cores_per_node': pilot_json['cores_per_node']
        }
        return resource_details

    # -------------------------------------------------------------------------
    #
    @property
    def pilot_manager(self):
        """ Returns the pilot manager object for this pilot.
        """
        return self._manager

    # -------------------------------------------------------------------------
    #
    @property
    def unit_managers(self):
        """ Returns the unit manager object UIDs for this pilot.
        """
        if not self._uid:
            return None

        raise NotImplementedError("Not Implemented")

    # -------------------------------------------------------------------------
    #
    @property
    def units(self):
        """ Returns the units scheduled for this pilot.
        """
        # Check if this instance is valid
        if not self._uid:
            return None

        raise NotImplementedError("Not Implemented")

    # -------------------------------------------------------------------------
    #
    @property
    def submission_time(self):
        """ Returns the time the pilot was submitted.
        """
        # Check if this instance is valid
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['submitted']

    # -------------------------------------------------------------------------
    #
    @property
    def start_time(self):
        """ Returns the time the pilot was started on the backend.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['started']

    # -------------------------------------------------------------------------
    #
    @property
    def stop_time(self):
        """ Returns the time the pilot was stopped.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['finished']

    # -------------------------------------------------------------------------
    #
    @property
    def resource(self):
        """ Returns the resource.
        """
        if not self._uid:
            return None

        pilot_json = self._worker.get_compute_pilot_data(pilot_ids=self.uid)
        return pilot_json['description']['resource']

    # -------------------------------------------------------------------------
    #
    def register_callback(self, callback_func, callback_data=None):
        """Registers a callback function that is triggered every time the
        ComputePilot's state changes.

        All callback functions need to have the same signature::

            def callback_func(obj, state, data)

        where ``object`` is a handle to the object that triggered the callback,
        ``state`` is the new state of that object, and ``data`` is the data
        passed on callback registration.
        """
        self._worker.register_pilot_callback(self, callback_func, callback_data)

    # -------------------------------------------------------------------------
    #
    def wait(self, state=None, timeout=None):
        """Returns when the pilot reaches a specific state or
        when an optional timeout is reached.

        **Arguments:**

            * **state** [`list of strings`]
              The state(s) that Pilot has to reach in order for the
              call to return.

              By default `wait` waits for the Pilot to reach
              a **terminal** state, which can be one of the following:

              * :data:`radical.pilot.states.DONE`
              * :data:`radical.pilot.states.FAILED`
              * :data:`radical.pilot.states.CANCELED`

            * **timeout** [`float`]
              Optional timeout in seconds before the call returns regardless
              whether the Pilot has reached the desired state or not.
              The default value **None** never times out.

        **Raises:**

            * :class:`radical.pilot.exceptions.radical.pilotException` if the state of
              the pilot cannot be determined.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState("Invalid instance.")

        if not state:
            state = [DONE, FAILED, CANCELED]

        elif not isinstance(state, list):
            state = [state]

        start_wait = time.time()
        # the self.state property pulls the state from the back end.
        new_state = self.state

        while new_state not in state:
            time.sleep(0.1)
            new_state = self.state

            if (timeout is not None) and (timeout <= (time.time() - start_wait)):
                break

        # done waiting -- return the state
        return new_state

    # -------------------------------------------------------------------------
    #
    def cancel(self):
        """Sends sends a termination request to the pilot.

        **Raises:**

            * :class:`radical.pilot.radical.pilotException` if the termination
              request cannot be fulfilled.
        """
        # Check if this instance is valid
        if not self._uid:
            raise IncorrectState(msg="Invalid instance.")

        if self.state in [DONE, FAILED, CANCELED]:
            # nothing to do as we are already in a terminal state
            return

        # now we can send a 'cancel' command to the pilot.
        self._manager.cancel_pilots(self.uid)

    # -------------------------------------------------------------------------
    #
    def stage_in(self, directives):
        """Stages the content of the staging directive into the pilot's
        staging area"""

        # Wait until we can assume the pilot directory to be created
        if self.state == NEW:
            self.wait(state=[PENDING_LAUNCH, LAUNCHING, PENDING_ACTIVE, ACTIVE])
        elif self.state in [DONE, FAILED, CANCELED]:
            raise Exception("Pilot already finished, no need to stage anymore!")

        # Iterate over all directives
        for directive in expand_staging_directive(directives, logger):

            # TODO: respect flags in directive

            src_url = saga.Url(directive['source'])
            action = directive['action']

            # Convert the target url into a SAGA Url object
            tgt_url = saga.Url(directive['target'])
            # Create a pointer to the directory object that we will use
            tgt_dir_url = tgt_url

            if tgt_url.path.endswith('/'):
                # If the original target was a directory (ends with /),
                # we assume that the user wants the same filename as the source.
                tgt_filename = os.path.basename(src_url.path)
            else:
                # Otherwise, extract the filename and update the directory
                tgt_filename = os.path.basename(tgt_dir_url.path)
                tgt_dir_url.path = os.path.dirname(tgt_dir_url.path)

            # Handle special 'staging' scheme
            if tgt_dir_url.scheme == 'staging':

                # We expect a staging:///relative/path/file.txt URI,
                # as hostname would have unclear semantics currently.
                if tgt_dir_url.host:
                    raise Exception("hostname not supported with staging:// scheme")

                # Remove the leading slash to get a relative path from the staging area
                rel_path = os.path.relpath(tgt_dir_url.path, '/')

                # Now base the target directory relative of the sandbox and staging prefix
                tgt_dir_url = saga.Url(os.path.join(self.sandbox, STAGING_AREA, rel_path))

            # Define and open the staging directory for the pilot
            # We use the target dir construct here, so that we can create
            # the directory if it does not yet exist.
            target_dir = saga.filesystem.Directory(tgt_dir_url, flags=saga.filesystem.CREATE_PARENTS)

            if action == LINK:
                # TODO: Does this make sense?
                #log_message = 'Linking %s to %s' % (source, abs_target)
                #os.symlink(source, abs_target)
                pass
            elif action == COPY:
                # TODO: Does this make sense?
                #log_message = 'Copying %s to %s' % (source, abs_target)
                #shutil.copyfile(source, abs_target)
                pass
            elif action == MOVE:
                # TODO: Does this make sense?
                #log_message = 'Moving %s to %s' % (source, abs_target)
                #shutil.move(source, abs_target)
                pass
            elif action == TRANSFER:
                log_message = 'Transferring %s to %s' % (src_url, os.path.join(str(tgt_dir_url), tgt_filename))
                logger.info(log_message)
                # Transfer the source file to the target staging area
                target_dir.copy(src_url, tgt_filename)
            else:
                raise Exception('Action %s not supported' % action)
<|endoftext|>


<commit_before>from django.contrib.auth.models import User
from datetime import datetime
from datetime import timedelta

from devilry.apps.core.models import Node
from devilry.apps.core.models import Subject
from devilry.apps.core.models import Period
from devilry.apps.core.models import Assignment
from devilry.apps.core.models import AssignmentGroup
from devilry.apps.core.models import Deadline
from devilry.apps.core.models import Delivery
from devilry.apps.core.models import StaticFeedback
from devilry.apps.core.models import FileMeta
from devilry.apps.core.deliverystore import MemoryDeliveryStore
from .datebuilder import DateTimeBuilder

class ReloadableDbBuilderInterface(object):
    def update(self, **attributes):
        raise NotImplementedError()

    def reload_from_db(self):
        raise NotImplementedError()

class UserBuilder(ReloadableDbBuilderInterface):
    def __init__(self, username, full_name=None, email=None):
        email = email or u'{}@example.com'.format(username)
        self.user = User(username=username, email=email)
        self.user.set_password('test')
        self.user.full_clean()
        self.user.save()
        profile = self.user.get_profile()
        if full_name:
            profile.full_name = full_name
        profile.save()

    def update(self, **attributes):
        for attrname, value in attributes.iteritems():
            setattr(self.user, attrname, value)
        self.user.save()
        self.reload_from_db()

    def update_profile(self, **attributes):
        profile = self.user.get_profile()
        for attrname, value in attributes.iteritems():
            setattr(profile, attrname, value)
        profile.save()
        self.reload_from_db()

    def reload_from_db(self):
        self.user = User.objects.get(id=self.user.id)

class CoreBuilderBase(ReloadableDbBuilderInterface):
    object_attribute_name = None

    def _save(self):
        getattr(self, self.object_attribute_name).save()

    def update(self, **attributes):
        obj = getattr(self, self.object_attribute_name)
        for attrname, value in attributes.iteritems():
            setattr(obj, attrname, value)
        self._save()
        self.reload_from_db()

    def reload_from_db(self):
        obj = getattr(self, self.object_attribute_name)
        setattr(self, self.object_attribute_name, obj.__class__.objects.get(pk=obj.pk))

class BaseNodeBuilderBase(CoreBuilderBase):
    modelcls = None

    def __init__(self, short_name, long_name=None, **kwargs):
        full_kwargs = {
            'short_name': short_name,
            'long_name': long_name or short_name
        }
        full_kwargs.update(kwargs)
        setattr(self, self.object_attribute_name, self.modelcls.objects.create(**full_kwargs))

class FileMetaBuilder(CoreBuilderBase):
    object_attribute_name = 'filemeta'

    def __init__(self, delivery, filename, data):
        self.filemeta = FileMeta.objects.create(delivery=delivery, filename=filename, size=0)
        f = FileMeta.deliverystore.write_open(self.filemeta)
        f.write(data)
        f.close()
        self.filemeta.size = len(data)
        self.filemeta.save()

class StaticFeedbackBuilder(CoreBuilderBase):
    object_attribute_name = 'feedback'

    def __init__(self, **kwargs):
        self.feedback = StaticFeedback.objects.create(**kwargs)

class DeliveryBuilder(CoreBuilderBase):
    object_attribute_name = 'delivery'

    @classmethod
    def set_memory_deliverystore(cls):
        FileMeta.deliverystore = MemoryDeliveryStore()

    def __init__(self, **kwargs):
        if not 'time_of_delivery' in kwargs:
            kwargs['time_of_delivery'] = datetime.now()
        self.delivery = Delivery(**kwargs)
        self.delivery.save(autoset_time_of_delivery=False)

    def _save(self):
        self.delivery.save(autoset_time_of_delivery=False)

    def add_filemeta(self, **kwargs):
        kwargs['delivery'] = self.delivery
        return FileMetaBuilder(**kwargs)

    def add_feedback(self, **kwargs):
        kwargs['delivery'] = self.delivery
        return StaticFeedbackBuilder(**kwargs)

    def add_passed_feedback(self, **kwargs):
        kwargs['points'] = 1
        kwargs['grade'] = 'Passed'
        kwargs['is_passing_grade'] = True
        kwargs['delivery'] = self.delivery
        return StaticFeedbackBuilder(**kwargs)

    def add_failed_feedback(self, **kwargs):
        kwargs['points'] = 0
        kwargs['grade'] = 'Failed'
        kwargs['is_passing_grade'] = False
        kwargs['delivery'] = self.delivery
        return StaticFeedbackBuilder(**kwargs)

class DeadlineBuilder(CoreBuilderBase):
    object_attribute_name = 'deadline'

    def __init__(self, **kwargs):
        self.deadline = Deadline.objects.create(**kwargs)

    def add_delivery(self, **kwargs):
        kwargs['deadline'] = self.deadline
        kwargs['successful'] = kwargs.get('successful', True)
        return DeliveryBuilder(**kwargs)

    def add_delivery_after_deadline(self, timedeltaobject, **kwargs):
        if 'time_of_delivery' in kwargs:
            raise ValueError('add_delivery_after_deadline does not accept ``time_of_delivery`` as kwarg, it sets it automatically.')
        kwargs['time_of_delivery'] = self.deadline.deadline + timedeltaobject
        return self.add_delivery(**kwargs)

    def add_delivery_before_deadline(self, timedeltaobject, **kwargs):
        if 'time_of_delivery' in kwargs:
            raise ValueError('add_delivery_before_deadline does not accept ``time_of_delivery`` as kwarg, it sets it automatically.')
        kwargs['time_of_delivery'] = self.deadline.deadline - timedeltaobject
        return self.add_delivery(**kwargs)

    def add_delivery_x_hours_after_deadline(self, hours, **kwargs):
        return self.add_delivery_after_deadline(timedelta(hours=hours), **kwargs)

    def add_delivery_x_hours_before_deadline(self, hours, **kwargs):
        return self.add_delivery_before_deadline(timedelta(hours=hours), **kwargs)

class AssignmentGroupBuilder(CoreBuilderBase):
    object_attribute_name = 'group'

    def __init__(self, students=[], candidates=[], examiners=[], **kwargs):
        self.group = AssignmentGroup.objects.create(**kwargs)
        self.add_students(*students)
        self.add_candidates(*candidates)
        self.add_examiners(*examiners)

    def add_students(self, *users):
        for user in users:
            self.group.candidates.create(student=user)
        return self

    def add_candidates(self, *candidates):
        for candidate in candidates:
            self.group.candidates.add(candidate)
        return self

    def add_examiners(self, *users):
        for user in users:
            self.group.examiners.create(user=user)
        return self

    def add_deadline(self, **kwargs):
        kwargs['assignment_group'] = self.group
        return DeadlineBuilder(**kwargs)

    def add_deadline_in_x_weeks(self, weeks, **kwargs):
        if 'deadline' in kwargs:
            raise ValueError('add_deadline_in_x_weeks does not accept ``deadline`` as kwarg, it sets it automatically.')
        kwargs['deadline'] = DateTimeBuilder.now().plus(weeks=weeks)
        return self.add_deadline(**kwargs)

    def add_deadline_x_weeks_ago(self, weeks, **kwargs):
        if 'deadline' in kwargs:
            raise ValueError('add_deadline_x_weeks_ago does not accept ``deadline`` as kwarg, it sets it automatically.')
        kwargs['deadline'] = DateTimeBuilder.now().minus(weeks=weeks)
        return self.add_deadline(**kwargs)

class AssignmentBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'assignment'
    modelcls = Assignment

    def __init__(self, *args, **kwargs):
        if not 'publishing_time' in kwargs:
            kwargs['publishing_time'] = datetime.now()
        super(AssignmentBuilder, self).__init__(*args, **kwargs)

    def add_group(self, *args, **kwargs):
        kwargs['parentnode'] = self.assignment
        return AssignmentGroupBuilder(*args, **kwargs)

class PeriodBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'period'
    modelcls = Period

    @classmethod
    def quickadd_ducku_duck1010_active(cls):
        return SubjectBuilder.quickadd_ducku_duck1010()\
            .add_6month_active_period()

    def add_assignment(self, *args, **kwargs):
        kwargs['parentnode'] = self.period
        return AssignmentBuilder(*args, **kwargs)

class SubjectBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'subject'
    modelcls = Subject

    @classmethod
    def quickadd_ducku_duck1010(cls):
        return NodeBuilder('ducku').add_subject('duck1010')

    def add_period(self, *args, **kwargs):
        kwargs['parentnode'] = self.subject
        return PeriodBuilder(*args, **kwargs)

    def add_6month_active_period(self, **kwargs):
        kwargs['parentnode'] = self.subject
        if 'start_time' in kwargs or 'end_time' in kwargs:
            raise ValueError('add_6month_active_period does not accept ``start_time`` or ``end_time`` as kwargs, it sets them automatically.')
        kwargs['start_time'] = DateTimeBuilder.now().minus(days=30*3)
        kwargs['end_time'] = DateTimeBuilder.now().plus(days=30*3)
        if not 'short_name' in kwargs:
            kwargs['short_name'] = 'active'
        return self.add_period(**kwargs)

    def add_6month_lastyear_period(self, **kwargs):
        kwargs['parentnode'] = self.subject
        if 'start_time' in kwargs or 'end_time' in kwargs:
            raise ValueError('add_6month_lastyear_period does not accept ``start_time`` or ``end_time`` as kwargs, it sets them automatically.')
        kwargs['start_time'] = DateTimeBuilder.now().minus(days=365 - 30*3)
        kwargs['end_time'] = DateTimeBuilder.now().minus(days=365 + 30*3)
        if not 'short_name' in kwargs:
            kwargs['short_name'] = 'lastyear'
        return self.add_period(**kwargs)

    def add_6month_nextyear_period(self, **kwargs):
        kwargs['parentnode'] = self.subject
        if 'start_time' in kwargs or 'end_time' in kwargs:
            raise ValueError('add_6month_nextyear_period does not accept ``start_time`` or ``end_time`` as kwargs, it sets them automatically.')
        kwargs['start_time'] = DateTimeBuilder.now().plus(days=365 - 30*3)
        kwargs['end_time'] = DateTimeBuilder.now().plus(days=365 + 30*3)
        if not 'short_name' in kwargs:
            kwargs['short_name'] = 'nextyear'
        return self.add_period(**kwargs)

class NodeBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'node'
    modelcls = Node

    def add_subject(self, *args, **kwargs):
        kwargs['parentnode'] = self.node
        return SubjectBuilder(*args, **kwargs)

    def add_childnode(self, *args, **kwargs):
        kwargs['parentnode'] = self.node
        return NodeBuilder(*args, **kwargs)<commit_msg>devilry_developer...corebuilder: Added add_admins().<commit_after>from django.contrib.auth.models import User
from datetime import datetime
from datetime import timedelta

from devilry.apps.core.models import Node
from devilry.apps.core.models import Subject
from devilry.apps.core.models import Period
from devilry.apps.core.models import Assignment
from devilry.apps.core.models import AssignmentGroup
from devilry.apps.core.models import Deadline
from devilry.apps.core.models import Delivery
from devilry.apps.core.models import StaticFeedback
from devilry.apps.core.models import FileMeta
from devilry.apps.core.deliverystore import MemoryDeliveryStore
from .datebuilder import DateTimeBuilder

class ReloadableDbBuilderInterface(object):
    def update(self, **attributes):
        raise NotImplementedError()

    def reload_from_db(self):
        raise NotImplementedError()

class UserBuilder(ReloadableDbBuilderInterface):
    def __init__(self, username, full_name=None, email=None):
        email = email or u'{}@example.com'.format(username)
        self.user = User(username=username, email=email)
        self.user.set_password('test')
        self.user.full_clean()
        self.user.save()
        profile = self.user.get_profile()
        if full_name:
            profile.full_name = full_name
        profile.save()

    def update(self, **attributes):
        for attrname, value in attributes.iteritems():
            setattr(self.user, attrname, value)
        self.user.save()
        self.reload_from_db()

    def update_profile(self, **attributes):
        profile = self.user.get_profile()
        for attrname, value in attributes.iteritems():
            setattr(profile, attrname, value)
        profile.save()
        self.reload_from_db()

    def reload_from_db(self):
        self.user = User.objects.get(id=self.user.id)

class CoreBuilderBase(ReloadableDbBuilderInterface):
    object_attribute_name = None

    def _save(self):
        getattr(self, self.object_attribute_name).save()

    def update(self, **attributes):
        obj = getattr(self, self.object_attribute_name)
        for attrname, value in attributes.iteritems():
            setattr(obj, attrname, value)
        self._save()
        self.reload_from_db()

    def reload_from_db(self):
        obj = getattr(self, self.object_attribute_name)
        setattr(self, self.object_attribute_name, obj.__class__.objects.get(pk=obj.pk))

class BaseNodeBuilderBase(CoreBuilderBase):
    modelcls = None

    def __init__(self, short_name, long_name=None, **kwargs):
        full_kwargs = {
            'short_name': short_name,
            'long_name': long_name or short_name
        }
        full_kwargs.update(kwargs)
        setattr(self, self.object_attribute_name, self.modelcls.objects.create(**full_kwargs))

    def add_admins(self, *users):
        for user in users:
            obj = getattr(self, self.object_attribute_name)
            obj.admins.add(user)
        return self

class FileMetaBuilder(CoreBuilderBase):
    object_attribute_name = 'filemeta'

    def __init__(self, delivery, filename, data):
        self.filemeta = FileMeta.objects.create(delivery=delivery, filename=filename, size=0)
        f = FileMeta.deliverystore.write_open(self.filemeta)
        f.write(data)
        f.close()
        self.filemeta.size = len(data)
        self.filemeta.save()

class StaticFeedbackBuilder(CoreBuilderBase):
    object_attribute_name = 'feedback'

    def __init__(self, **kwargs):
        self.feedback = StaticFeedback.objects.create(**kwargs)

class DeliveryBuilder(CoreBuilderBase):
    object_attribute_name = 'delivery'

    @classmethod
    def set_memory_deliverystore(cls):
        FileMeta.deliverystore = MemoryDeliveryStore()

    def __init__(self, **kwargs):
        if not 'time_of_delivery' in kwargs:
            kwargs['time_of_delivery'] = datetime.now()
        self.delivery = Delivery(**kwargs)
        self.delivery.save(autoset_time_of_delivery=False)

    def _save(self):
        self.delivery.save(autoset_time_of_delivery=False)

    def add_filemeta(self, **kwargs):
        kwargs['delivery'] = self.delivery
        return FileMetaBuilder(**kwargs)

    def add_feedback(self, **kwargs):
        kwargs['delivery'] = self.delivery
        return StaticFeedbackBuilder(**kwargs)

    def add_passed_feedback(self, **kwargs):
        kwargs['points'] = 1
        kwargs['grade'] = 'Passed'
        kwargs['is_passing_grade'] = True
        kwargs['delivery'] = self.delivery
        return StaticFeedbackBuilder(**kwargs)

    def add_failed_feedback(self, **kwargs):
        kwargs['points'] = 0
        kwargs['grade'] = 'Failed'
        kwargs['is_passing_grade'] = False
        kwargs['delivery'] = self.delivery
        return StaticFeedbackBuilder(**kwargs)

class DeadlineBuilder(CoreBuilderBase):
    object_attribute_name = 'deadline'

    def __init__(self, **kwargs):
        self.deadline = Deadline.objects.create(**kwargs)

    def add_delivery(self, **kwargs):
        kwargs['deadline'] = self.deadline
        kwargs['successful'] = kwargs.get('successful', True)
        return DeliveryBuilder(**kwargs)

    def add_delivery_after_deadline(self, timedeltaobject, **kwargs):
        if 'time_of_delivery' in kwargs:
            raise ValueError('add_delivery_after_deadline does not accept ``time_of_delivery`` as kwarg, it sets it automatically.')
        kwargs['time_of_delivery'] = self.deadline.deadline + timedeltaobject
        return self.add_delivery(**kwargs)

    def add_delivery_before_deadline(self, timedeltaobject, **kwargs):
        if 'time_of_delivery' in kwargs:
            raise ValueError('add_delivery_before_deadline does not accept ``time_of_delivery`` as kwarg, it sets it automatically.')
        kwargs['time_of_delivery'] = self.deadline.deadline - timedeltaobject
        return self.add_delivery(**kwargs)

    def add_delivery_x_hours_after_deadline(self, hours, **kwargs):
        return self.add_delivery_after_deadline(timedelta(hours=hours), **kwargs)

    def add_delivery_x_hours_before_deadline(self, hours, **kwargs):
        return self.add_delivery_before_deadline(timedelta(hours=hours), **kwargs)

class AssignmentGroupBuilder(CoreBuilderBase):
    object_attribute_name = 'group'

    def __init__(self, students=[], candidates=[], examiners=[], **kwargs):
        self.group = AssignmentGroup.objects.create(**kwargs)
        self.add_students(*students)
        self.add_candidates(*candidates)
        self.add_examiners(*examiners)

    def add_students(self, *users):
        for user in users:
            self.group.candidates.create(student=user)
        return self

    def add_candidates(self, *candidates):
        for candidate in candidates:
            self.group.candidates.add(candidate)
        return self

    def add_examiners(self, *users):
        for user in users:
            self.group.examiners.create(user=user)
        return self

    def add_deadline(self, **kwargs):
        kwargs['assignment_group'] = self.group
        return DeadlineBuilder(**kwargs)

    def add_deadline_in_x_weeks(self, weeks, **kwargs):
        if 'deadline' in kwargs:
            raise ValueError('add_deadline_in_x_weeks does not accept ``deadline`` as kwarg, it sets it automatically.')
        kwargs['deadline'] = DateTimeBuilder.now().plus(weeks=weeks)
        return self.add_deadline(**kwargs)

    def add_deadline_x_weeks_ago(self, weeks, **kwargs):
        if 'deadline' in kwargs:
            raise ValueError('add_deadline_x_weeks_ago does not accept ``deadline`` as kwarg, it sets it automatically.')
        kwargs['deadline'] = DateTimeBuilder.now().minus(weeks=weeks)
        return self.add_deadline(**kwargs)

class AssignmentBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'assignment'
    modelcls = Assignment

    def __init__(self, *args, **kwargs):
        if not 'publishing_time' in kwargs:
            kwargs['publishing_time'] = datetime.now()
        super(AssignmentBuilder, self).__init__(*args, **kwargs)

    def add_group(self, *args, **kwargs):
        kwargs['parentnode'] = self.assignment
        return AssignmentGroupBuilder(*args, **kwargs)

class PeriodBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'period'
    modelcls = Period

    @classmethod
    def quickadd_ducku_duck1010_active(cls):
        return SubjectBuilder.quickadd_ducku_duck1010()\
            .add_6month_active_period()

    def add_assignment(self, *args, **kwargs):
        kwargs['parentnode'] = self.period
        return AssignmentBuilder(*args, **kwargs)

class SubjectBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'subject'
    modelcls = Subject

    @classmethod
    def quickadd_ducku_duck1010(cls):
        return NodeBuilder('ducku').add_subject('duck1010')

    def add_period(self, *args, **kwargs):
        kwargs['parentnode'] = self.subject
        return PeriodBuilder(*args, **kwargs)

    def add_6month_active_period(self, **kwargs):
        kwargs['parentnode'] = self.subject
        if 'start_time' in kwargs or 'end_time' in kwargs:
            raise ValueError('add_6month_active_period does not accept ``start_time`` or ``end_time`` as kwargs, it sets them automatically.')
        kwargs['start_time'] = DateTimeBuilder.now().minus(days=30*3)
        kwargs['end_time'] = DateTimeBuilder.now().plus(days=30*3)
        if not 'short_name' in kwargs:
            kwargs['short_name'] = 'active'
        return self.add_period(**kwargs)

    def add_6month_lastyear_period(self, **kwargs):
        kwargs['parentnode'] = self.subject
        if 'start_time' in kwargs or 'end_time' in kwargs:
            raise ValueError('add_6month_lastyear_period does not accept ``start_time`` or ``end_time`` as kwargs, it sets them automatically.')
        kwargs['start_time'] = DateTimeBuilder.now().minus(days=365 - 30*3)
        kwargs['end_time'] = DateTimeBuilder.now().minus(days=365 + 30*3)
        if not 'short_name' in kwargs:
            kwargs['short_name'] = 'lastyear'
        return self.add_period(**kwargs)

    def add_6month_nextyear_period(self, **kwargs):
        kwargs['parentnode'] = self.subject
        if 'start_time' in kwargs or 'end_time' in kwargs:
            raise ValueError('add_6month_nextyear_period does not accept ``start_time`` or ``end_time`` as kwargs, it sets them automatically.')
        kwargs['start_time'] = DateTimeBuilder.now().plus(days=365 - 30*3)
        kwargs['end_time'] = DateTimeBuilder.now().plus(days=365 + 30*3)
        if not 'short_name' in kwargs:
            kwargs['short_name'] = 'nextyear'
        return self.add_period(**kwargs)

class NodeBuilder(BaseNodeBuilderBase):
    object_attribute_name = 'node'
    modelcls = Node

    def add_subject(self, *args, **kwargs):
        kwargs['parentnode'] = self.node
        return SubjectBuilder(*args, **kwargs)

    def add_childnode(self, *args, **kwargs):
        kwargs['parentnode'] = self.node
        return NodeBuilder(*args, **kwargs)<|endoftext|>


<commit_before># Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from benchmarks import silk_flags
from measurements import thread_times
import page_sets
from telemetry import benchmark

class _ThreadTimes(benchmark.Benchmark):
  @classmethod
  def AddBenchmarkCommandLineArgs(cls, parser):
    parser.add_option('--report-silk-details', action='store_true',
                      help='Report details relevant to silk.')

  def CreatePageTest(self, options):
    return thread_times.ThreadTimes(options.report_silk_details)

@benchmark.Enabled('android')
class ThreadTimesKeySilkCases(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on key silk
  cases."""
  page_set = page_sets.KeySilkCasesPageSet

@benchmark.Enabled('android')
class ThreadTimesKeyHitTestCases(_ThreadTimes):
  """Measure timeline metrics while performing smoothness action on key hit
  testing cases."""
  page_set = page_sets.KeyHitTestCasesPageSet

@benchmark.Disabled
class LegacySilkBenchmark(ThreadTimesKeySilkCases):
  """Same as thread_times.key_silk_cases but with the old name."""
  @classmethod
  def Name(cls):
    return "silk.key_silk_cases"

@benchmark.Enabled('android')
class ThreadTimesFastPathMobileSites(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on
  key mobile sites labeled with fast-path tag.
  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
  page_set = page_sets.KeyMobileSitesSmoothPageSet
  options = {'page_label_filter' : 'fastpath'}

@benchmark.Enabled('android')
class ThreadTimesSimpleMobileSites(_ThreadTimes):
  """Measures timeline metric using smoothness action on simple mobile sites
  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
  page_set = page_sets.SimpleMobileSitesPageSet

@benchmark.Disabled('win') # crbug.com/443781
class ThreadTimesCompositorCases(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on
  tough compositor cases, using software rasterization.

  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
  page_set = page_sets.ToughCompositorCasesPageSet
  def CustomizeBrowserOptions(self, options):
    silk_flags.CustomizeBrowserOptionsForSoftwareRasterization(options)

@benchmark.Enabled('android')
class ThreadTimesPolymer(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on
  Polymer cases."""
  page_set = page_sets.PolymerPageSet
<commit_msg>Enable |key_hit_test_cases| benchmark on linux.<commit_after># Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from benchmarks import silk_flags
from measurements import thread_times
import page_sets
from telemetry import benchmark

class _ThreadTimes(benchmark.Benchmark):
  @classmethod
  def AddBenchmarkCommandLineArgs(cls, parser):
    parser.add_option('--report-silk-details', action='store_true',
                      help='Report details relevant to silk.')

  def CreatePageTest(self, options):
    return thread_times.ThreadTimes(options.report_silk_details)

@benchmark.Enabled('android')
class ThreadTimesKeySilkCases(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on key silk
  cases."""
  page_set = page_sets.KeySilkCasesPageSet

@benchmark.Enabled('android', 'linux')
class ThreadTimesKeyHitTestCases(_ThreadTimes):
  """Measure timeline metrics while performing smoothness action on key hit
  testing cases."""
  page_set = page_sets.KeyHitTestCasesPageSet

@benchmark.Disabled
class LegacySilkBenchmark(ThreadTimesKeySilkCases):
  """Same as thread_times.key_silk_cases but with the old name."""
  @classmethod
  def Name(cls):
    return "silk.key_silk_cases"

@benchmark.Enabled('android')
class ThreadTimesFastPathMobileSites(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on
  key mobile sites labeled with fast-path tag.
  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
  page_set = page_sets.KeyMobileSitesSmoothPageSet
  options = {'page_label_filter' : 'fastpath'}

@benchmark.Enabled('android')
class ThreadTimesSimpleMobileSites(_ThreadTimes):
  """Measures timeline metric using smoothness action on simple mobile sites
  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
  page_set = page_sets.SimpleMobileSitesPageSet

@benchmark.Disabled('win') # crbug.com/443781
class ThreadTimesCompositorCases(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on
  tough compositor cases, using software rasterization.

  http://www.chromium.org/developers/design-documents/rendering-benchmarks"""
  page_set = page_sets.ToughCompositorCasesPageSet
  def CustomizeBrowserOptions(self, options):
    silk_flags.CustomizeBrowserOptionsForSoftwareRasterization(options)

@benchmark.Enabled('android')
class ThreadTimesPolymer(_ThreadTimes):
  """Measures timeline metrics while performing smoothness action on
  Polymer cases."""
  page_set = page_sets.PolymerPageSet
<|endoftext|>


<commit_before>import os

from djapian import Field
from djapian.tests.utils import BaseTestCase, BaseIndexerTest, Entry, Person
from djapian.models import Change
from django.utils.encoding import force_unicode

class IndexerTest(BaseTestCase):
    def test_text_fields_count(self):
        self.assertEqual(len(Entry.indexer.fields), 1)

    def test_attributes_count(self):
        self.assertEqual(len(Entry.indexer.tags), 7)

class FieldResolverTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        self.entry = Entry.objects.create(author=p, title="Test entry")

    def test_simple_attribute(self):
        self.assertEqual(Field("title").resolve(self.entry), "Test entry")

    def test_related_attribute(self):
        self.assertEqual(Field("author.name").resolve(self.entry), "Alex")

    def test_fk_attribute(self):
        self.assertEqual(force_unicode(Field("author").resolve(self.entry)), "Alex")

    def test_method(self):
        self.assertEqual(
            Field("headline").resolve(self.entry),
            "Alex - Test entry"
        )

class ChangeTrackingTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        Entry.objects.create(author=p, title="Test entry")
        Entry.objects.create(
            author=p,
            title="Another test entry",
            is_active=False
        )

    def test_change_count(self):
        self.assertEqual(Change.objects.count(), 2)

class ChangeTrackingUpdateTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        entry = Entry.objects.create(author=p, title="Test entry")

        entry.title = "Foobar title"
        entry.save()

    def test_change_count(self):
        self.assertEqual(Change.objects.count(), 1)

    def test_change_action(self):
        self.assertEqual(Change.objects.get().action, "add")

class ChangeTrackingDeleteTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        entry = Entry.objects.create(author=p, title="Test entry")
        entry.delete()

    def test_change_count(self):
        self.assertEqual(Change.objects.count(), 0)
<commit_msg>fixed tests<commit_after>import os

from djapian import Field
from djapian.tests.utils import BaseTestCase, BaseIndexerTest, Entry, Person
from djapian.models import Change
from django.utils.encoding import force_unicode

class IndexerTest(BaseTestCase):
    def test_fields_count(self):
        self.assertEqual(len(Entry.indexer.fields), 1)

    def test_tags_count(self):
        self.assertEqual(len(Entry.indexer.tags), 8)

class FieldResolverTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        self.entry = Entry.objects.create(author=p, title="Test entry")

    def test_simple_attribute(self):
        self.assertEqual(Field("title").resolve(self.entry), "Test entry")

    def test_related_attribute(self):
        self.assertEqual(Field("author.name").resolve(self.entry), "Alex")

    def test_fk_attribute(self):
        self.assertEqual(force_unicode(Field("author").resolve(self.entry)), "Alex")

    def test_method(self):
        self.assertEqual(
            Field("headline").resolve(self.entry),
            "Alex - Test entry"
        )

class ChangeTrackingTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        Entry.objects.create(author=p, title="Test entry")
        Entry.objects.create(
            author=p,
            title="Another test entry",
            is_active=False
        )

    def test_change_count(self):
        self.assertEqual(Change.objects.count(), 2)

class ChangeTrackingUpdateTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        entry = Entry.objects.create(author=p, title="Test entry")

        entry.title = "Foobar title"
        entry.save()

    def test_change_count(self):
        self.assertEqual(Change.objects.count(), 1)

    def test_change_action(self):
        self.assertEqual(Change.objects.get().action, "add")

class ChangeTrackingDeleteTest(BaseTestCase):
    def setUp(self):
        p = Person.objects.create(name="Alex")
        entry = Entry.objects.create(author=p, title="Test entry")
        entry.delete()

    def test_change_count(self):
        self.assertEqual(Change.objects.count(), 0)
<|endoftext|>


<commit_before>from scanclient import ScanClient
from logdata import getDatetime, iterateSamples, iterateTable, createTable<commit_msg>include new methods to package file.--#13<commit_after>from scanclient import ScanClient
from logdata import getDatetime, SampleIterator, createTable
from data import Data, getTimeSeries, getDatetime, alignSerial, getTable<|endoftext|>


<commit_before>import json
import datetime
import sys

# Check the python version at runtime. DECODE_BYTES is True when running on python 3.0 - 3.5
if sys.version_info[0] == 3:
    if sys.version_info[1] <= 5:
        DECODE_BYTES = True

class IpcMessageException(Exception):
    def __init__(self, msg, errno=None):
        self.msg = msg
        self.errno = errno

    def __str__(self):
        return str(self.msg)

class IpcMessage(object):

    ACK = "ack"
    NACK = "nack"

    def __init__(self, msg_type=None, msg_val=None, from_str=None):
        self.attrs = {}

        if from_str is None:
            self.attrs['msg_type'] = msg_type
            self.attrs['msg_val'] = msg_val
            self.attrs['timestamp'] = datetime.datetime.now().isoformat()
            self.attrs['params'] = {}
        else:
            try:
                # Manually decode bytes when operating in python versions 3.0 - 3.5 inclusive
                if DECODE_BYTES:
                    from_str = from_str.decode("utf-8")
                self.attrs = json.loads(from_str)
            except ValueError as e:
                raise IpcMessageException(
                    "Illegal message JSON format: " + str(e))

    def is_valid(self):
        is_valid = True
        try:
            is_valid = is_valid & (self._get_attr("msg_type") is not None)
            is_valid = is_valid & (self._get_attr("msg_val") is not None)
            is_valid = is_valid & (self._get_attr("timestamp") is not None)
        except IpcMessageException:
            is_valid = False

        return is_valid

    def get_msg_type(self):
        return self.attrs['msg_type']

    def get_msg_val(self):
        return self.attrs['msg_val']

    def get_msg_timestamp(self):
        return self.attrs['timestamp']

    def get_param(self, param_name, default_value=None):
        try:
            param_value = self.attrs['params'][param_name]
        except KeyError:
            if default_value is None:
                raise IpcMessageException("Missing parameter " + param_name)
            else:
                param_value = default_value

        return param_value

    def set_msg_type(self, msg_type):
        self.attrs['msg_type'] = msg_type

    def set_msg_val(self, msg_val):
        self.attrs['msg_val'] = msg_val

    def set_param(self, param_name, param_value):
        if "params" not in self.attrs:
            self.attrs['params'] = {}

        self.attrs['params'][param_name] = param_value

    def encode(self):
        return json.dumps(self.attrs)

    def __eq__(self, other):
        return self.attrs == other.attrs

    def __ne__(self, other):
        return self.attrs != other.attrs

    def __str__(self):
        return json.dumps(self.attrs,
                          sort_keys=True, indent=4, separators=(',', ': '))

    def _get_attr(self, attr_name, default_value=None):

        try:
            attr_value = self.attrs[attr_name]
        except KeyError:
            if default_value is None:
                raise IpcMessageException("Missing attribute " + attr_name)
            else:
                attr_value = default_value

        return attr_value
<commit_msg>Changed initialisation of DECODE_BYTES<commit_after>import json
import datetime
import sys

# Check the python version at runtime. DECODE_BYTES is True when running on python 3.0 - 3.5
DECODE_BYTES = False
if sys.version_info[0] == 3:
    if sys.version_info[1] <= 5:
        DECODE_BYTES = True

class IpcMessageException(Exception):
    def __init__(self, msg, errno=None):
        self.msg = msg
        self.errno = errno

    def __str__(self):
        return str(self.msg)

class IpcMessage(object):

    ACK = "ack"
    NACK = "nack"

    def __init__(self, msg_type=None, msg_val=None, from_str=None):
        self.attrs = {}

        if from_str is None:
            self.attrs['msg_type'] = msg_type
            self.attrs['msg_val'] = msg_val
            self.attrs['timestamp'] = datetime.datetime.now().isoformat()
            self.attrs['params'] = {}
        else:
            try:
                # Manually decode bytes when operating in python versions 3.0 - 3.5 inclusive
                if DECODE_BYTES:
                    from_str = from_str.decode("utf-8")
                self.attrs = json.loads(from_str)
            except ValueError as e:
                raise IpcMessageException(
                    "Illegal message JSON format: " + str(e))

    def is_valid(self):
        is_valid = True
        try:
            is_valid = is_valid & (self._get_attr("msg_type") is not None)
            is_valid = is_valid & (self._get_attr("msg_val") is not None)
            is_valid = is_valid & (self._get_attr("timestamp") is not None)
        except IpcMessageException:
            is_valid = False

        return is_valid

    def get_msg_type(self):
        return self.attrs['msg_type']

    def get_msg_val(self):
        return self.attrs['msg_val']

    def get_msg_timestamp(self):
        return self.attrs['timestamp']

    def get_param(self, param_name, default_value=None):
        try:
            param_value = self.attrs['params'][param_name]
        except KeyError:
            if default_value is None:
                raise IpcMessageException("Missing parameter " + param_name)
            else:
                param_value = default_value

        return param_value

    def set_msg_type(self, msg_type):
        self.attrs['msg_type'] = msg_type

    def set_msg_val(self, msg_val):
        self.attrs['msg_val'] = msg_val

    def set_param(self, param_name, param_value):
        if "params" not in self.attrs:
            self.attrs['params'] = {}

        self.attrs['params'][param_name] = param_value

    def encode(self):
        return json.dumps(self.attrs)

    def __eq__(self, other):
        return self.attrs == other.attrs

    def __ne__(self, other):
        return self.attrs != other.attrs

    def __str__(self):
        return json.dumps(self.attrs,
                          sort_keys=True, indent=4, separators=(',', ': '))

    def _get_attr(self, attr_name, default_value=None):

        try:
            attr_value = self.attrs[attr_name]
        except KeyError:
            if default_value is None:
                raise IpcMessageException("Missing attribute " + attr_name)
            else:
                attr_value = default_value

        return attr_value
<|endoftext|>