<commit_before>"""
Created on 26 Nov 2018

@author: Bruno Beloff (bruno.beloff@southcoastscience.com)

This version of MessageManager for AWS lambda function with multi-part response.

Equivalent to cURL:
curl "https://aws.southcoastscience.com/topicMessages?topic=unep/ethiopia/loc/1/climate
&startTime=2018-12-13T07:03:59.712Z&endTime=2018-12-13T15:10:59.712Z"
"""

# import logging

from collections import OrderedDict
from urllib.parse import urlparse, parse_qs

from scs_core.aws.client.rest_client import RESTClient
from scs_core.aws.data.message import Message

from scs_core.data.datetime import LocalizedDatetime
from scs_core.data.datum import Datum
from scs_core.data.json import JSONable
from scs_core.data.str import Str
from scs_core.data.timedelta import Timedelta

# --------------------------------------------------------------------------------------------------------------------

class MessageManager(object):
    """
    classdocs
    """

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, api_key, reporter=None):
        """
        Constructor
        """
        self.__rest_client = RESTClient(api_key)
        self.__reporter = reporter

    # ----------------------------------------------------------------------------------------------------------------

    def find_latest_for_topic(self, topic, end, include_wrapper, rec_only):
        for back_off in (1, 10, 30, 60):
            start = end - Timedelta(seconds=back_off)
            documents = list(self.find_for_topic(topic, start, end, False, None, include_wrapper, rec_only, False))

            if documents:
                return documents[-1]

            end = start

        return None

    def find_for_topic(self, topic, start, end, fetch_last, checkpoint, include_wrapper, rec_only, min_max):
        request_path = '/default/AWSAggregate/'
        # request_path = '/topicMessages'              # Paul lambda

        params = MessageRequest(topic, start, end, fetch_last, checkpoint, include_wrapper, rec_only, min_max).params()

        # request...
        self.__rest_client.connect()

        try:
            while True:
                jdict = self.__rest_client.get(request_path, params)

                # messages...
                block = MessageResponse.construct_from_jdict(jdict)
                # print("block: %s" % block)

                for item in block.items:
                    yield item

                # report...
                if self.__reporter:
                    self.__reporter.print(block.start(), len(block))
                    # self.__reporter.print(None, len(block))     # Paul lambda

                # next request...
                if block.next_url is None:
                    break

                next_url = urlparse(block.next_url)
                next_params = parse_qs(next_url.query)

                # noinspection PyTypeChecker
                params[MessageRequest.START] = next_params[MessageRequest.START][0]

        finally:
            self.__rest_client.close()

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "MessageManager:{rest_client:%s, reporter:%s}" % (self.__rest_client, self.__reporter)

# --------------------------------------------------------------------------------------------------------------------

class MessageRequest(object):
    """
    classdocs
    """

    TOPIC = 'topic'
    START = 'startTime'
    END = 'endTime'
    FETCH_LAST_WRITTEN = 'fetchLastWrittenData'
    CHECKPOINT = 'checkpoint'
    INCLUDE_WRAPPER = 'includeWrapper'
    REC_ONLY = 'recOnly'
    MIN_MAX = 'minMax'

    # ----------------------------------------------------------------------------------------------------------------

    __DAY = Timedelta(days=1)
    __WEEK = Timedelta(weeks=1)
    __MONTH = Timedelta(days=28)
    __YEAR = Timedelta(days=365)

    @classmethod
    def checkpoint_table(cls, start, end):
        delta = end - start

        if delta < cls.__DAY:
            return None             # raw data rate

        if delta < cls.__WEEK:
            return '**:/01:00'

        if delta < cls.__MONTH:
            return '**:/15:00'

        if delta < cls.__YEAR:
            return '/01:00:00'

        return '/06:00:00'

    # ----------------------------------------------------------------------------------------------------------------

    @classmethod
    def construct_from_qsp(cls, qsp):
        if not qsp:
            return None

        # compulsory...
        topic = qsp.get(cls.TOPIC)
        start = LocalizedDatetime.construct_from_iso8601(qsp.get(cls.START))
        end = LocalizedDatetime.construct_from_iso8601(qsp.get(cls.END))

        if topic is None or start is None or end is None:
            return None

        if start > end:
            return None

        # optional...
        fetch_last_written = qsp.get(cls.FETCH_LAST_WRITTEN, 'false') == 'true'
        checkpoint = qsp.get(cls.CHECKPOINT)
        include_wrapper = qsp.get(cls.INCLUDE_WRAPPER, 'false') == 'true'
        rec_only = qsp.get(cls.REC_ONLY, 'false') == 'true'
        min_max = qsp.get(cls.MIN_MAX, 'false') == 'true'

        return cls(topic, start, end, fetch_last_written, checkpoint, include_wrapper, rec_only, min_max)

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, topic, start, end, fetch_last_written, checkpoint, include_wrapper, rec_only, min_max):
        """
        Constructor
        """
        self.__topic = topic                                    # string
        self.__start = start                                    # LocalizedDatetime
        self.__end = end                                        # LocalizedDatetime

        self.__fetch_last_written = bool(fetch_last_written)    # bool
        self.__checkpoint = checkpoint                          # string
        self.__include_wrapper = bool(include_wrapper)          # bool
        self.__rec_only = bool(rec_only)                        # bool
        self.__min_max = bool(min_max)                          # bool

    # ----------------------------------------------------------------------------------------------------------------

    def next_params(self, start):
        return MessageRequest(self.topic, start, self.end, self.fetch_last_written, self.checkpoint,
                              self.include_wrapper, self.rec_only, self.min_max).params()

    def change_params(self, start, end):
        return MessageRequest(self.topic, start, end, self.fetch_last_written, self.checkpoint,
                              self.include_wrapper, self.rec_only, self.min_max).params()

    def params(self):
        params = {
            self.TOPIC: self.topic,
            self.START: self.start.utc().as_iso8601(include_millis=True),
            self.END: self.end.utc().as_iso8601(include_millis=True)
        }

        if self.fetch_last_written:
            params[self.FETCH_LAST_WRITTEN] = 'true'

        if self.checkpoint is not None:
            params[self.CHECKPOINT] = self.checkpoint

        if self.include_wrapper:
            params[self.INCLUDE_WRAPPER] = 'true'

        if self.rec_only:
            params[self.REC_ONLY] = 'true'

        if self.min_max:
            params[self.MIN_MAX] = 'true'

        return params

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def checkpoint(self):
        if self.__checkpoint is None:
            return None

        if self.__checkpoint == 'auto':
            return self.checkpoint_table(self.start, self.end)

        return self.__checkpoint

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def topic(self):
        return self.__topic

    @property
    def start(self):
        return self.__start

    @property
    def end(self):
        return self.__end

    @property
    def fetch_last_written(self):
        return self.__fetch_last_written

    @property
    def include_wrapper(self):
        return self.__include_wrapper

    @property
    def rec_only(self):
        return self.__rec_only

    @property
    def min_max(self):
        return self.__min_max

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "MessageRequest:{topic:%s, start:%s, end:%s, fetch_last_written:%s, checkpoint:%s, " \
               "include_wrapper:%s, rec_only:%s, min_max:%s}" % \
               (self.topic, self.start, self.end, self.fetch_last_written, self.__checkpoint,
                self.include_wrapper, self.rec_only, self.min_max)

# --------------------------------------------------------------------------------------------------------------------

class MessageResponse(JSONable):
    """
    classdocs
    """

    # ----------------------------------------------------------------------------------------------------------------

    @classmethod
    def construct_from_jdict(cls, jdict):
        if not jdict:
            return None

        code = jdict.get('statusCode')
        status = jdict.get('status')
        fetched_last = jdict.get('fetchedLastWrittenData')

        items = []
        for msg_jdict in jdict.get('Items'):
            item = Message.construct_from_jdict(msg_jdict) if 'payload' in msg_jdict else msg_jdict
            # item = msg_jdict['payload']       # Paul lambda
            items.append(item)

        next_url = jdict.get('next')

        return cls(code, status, fetched_last, items, next_url)

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, code, status, fetched_last, items, next_url):
        """
        Constructor
        """
        self.__code = Datum.int(code)               # int
        self.__status = status                      # string
        self.__fetched_last = fetched_last          # Fetched last written data flag

        self.__items = items                        # list of Message

        self.__next_url = next_url                  # URL string

    def __len__(self):
        return len(self.items)

    # ----------------------------------------------------------------------------------------------------------------

    def as_json(self):
        jdict = OrderedDict()

        if self.code is not None:
            jdict['statusCode'] = self.code

        if self.status is not None:
            jdict['status'] = self.status

        if self.fetched_last is not None:
            jdict['fetchedLastWrittenData'] = self.fetched_last

        if self.items is not None:
            jdict['Items'] = self.items
            jdict['itemCount'] = len(self.items)

        if self.next_url is not None:
            jdict['next'] = self.next_url

        return jdict

    # ----------------------------------------------------------------------------------------------------------------

    def start(self):
        if not self.items:
            return None

        item = self.items[0]

        try:
            return item['rec']
        except TypeError:
            return item.payload['rec']

    def end(self):
        if not self.items:
            return None

        item = self.items[len(self) - 1]

        try:
            return item['rec']
        except TypeError:
            return item.payload['rec']

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def code(self):
        return self.__code

    @property
    def status(self):
        return self.__status

    @property
    def fetched_last(self):
        return self.__fetched_last

    @property
    def items(self):
        return self.__items

    @property
    def next_url(self):
        return self.__next_url

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "MessageResponse:{code:%s, status:%s, fetched_last:%s, items:%s, next_url:%s}" % \
               (self.code, self.status, self.fetched_last, Str.collection(self.items), self.next_url)
<commit_msg>Added validation for MessageRequest<commit_after>"""
Created on 26 Nov 2018

@author: Bruno Beloff (bruno.beloff@southcoastscience.com)

This version of MessageManager for AWS lambda function with multi-part response.

Equivalent to cURL:
curl "https://aws.southcoastscience.com/topicMessages?topic=unep/ethiopia/loc/1/climate
&startTime=2018-12-13T07:03:59.712Z&endTime=2018-12-13T15:10:59.712Z"
"""

# import logging

from collections import OrderedDict
from urllib.parse import urlparse, parse_qs

from scs_core.aws.client.rest_client import RESTClient
from scs_core.aws.data.message import Message

from scs_core.data.datetime import LocalizedDatetime
from scs_core.data.datum import Datum
from scs_core.data.json import JSONable
from scs_core.data.str import Str
from scs_core.data.timedelta import Timedelta

# --------------------------------------------------------------------------------------------------------------------

class MessageManager(object):
    """
    classdocs
    """

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, api_key, reporter=None):
        """
        Constructor
        """
        self.__rest_client = RESTClient(api_key)
        self.__reporter = reporter

    # ----------------------------------------------------------------------------------------------------------------

    def find_latest_for_topic(self, topic, end, include_wrapper, rec_only):
        for back_off in (1, 10, 30, 60):
            start = end - Timedelta(seconds=back_off)
            documents = list(self.find_for_topic(topic, start, end, False, None, include_wrapper, rec_only, False))

            if documents:
                return documents[-1]

            end = start

        return None

    def find_for_topic(self, topic, start, end, fetch_last, checkpoint, include_wrapper, rec_only, min_max):
        request_path = '/default/AWSAggregate/'
        # request_path = '/topicMessages'              # Paul lambda

        params = MessageRequest(topic, start, end, fetch_last, checkpoint, include_wrapper, rec_only, min_max).params()

        # request...
        self.__rest_client.connect()

        try:
            while True:
                jdict = self.__rest_client.get(request_path, params)

                # messages...
                block = MessageResponse.construct_from_jdict(jdict)
                # print("block: %s" % block)

                for item in block.items:
                    yield item

                # report...
                if self.__reporter:
                    self.__reporter.print(block.start(), len(block))
                    # self.__reporter.print(None, len(block))     # Paul lambda

                # next request...
                if block.next_url is None:
                    break

                next_url = urlparse(block.next_url)
                next_params = parse_qs(next_url.query)

                # noinspection PyTypeChecker
                params[MessageRequest.START] = next_params[MessageRequest.START][0]

        finally:
            self.__rest_client.close()

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "MessageManager:{rest_client:%s, reporter:%s}" % (self.__rest_client, self.__reporter)

# --------------------------------------------------------------------------------------------------------------------

class MessageRequest(object):
    """
    classdocs
    """

    TOPIC = 'topic'
    START = 'startTime'
    END = 'endTime'
    FETCH_LAST_WRITTEN = 'fetchLastWrittenData'
    CHECKPOINT = 'checkpoint'
    INCLUDE_WRAPPER = 'includeWrapper'
    REC_ONLY = 'recOnly'
    MIN_MAX = 'minMax'

    # ----------------------------------------------------------------------------------------------------------------

    __DAY = Timedelta(days=1)
    __WEEK = Timedelta(weeks=1)
    __MONTH = Timedelta(days=28)
    __YEAR = Timedelta(days=365)

    @classmethod
    def checkpoint_table(cls, start, end):
        delta = end - start

        if delta < cls.__DAY:
            return None             # raw data rate

        if delta < cls.__WEEK:
            return '**:/01:00'

        if delta < cls.__MONTH:
            return '**:/15:00'

        if delta < cls.__YEAR:
            return '/01:00:00'

        return '/06:00:00'

    # ----------------------------------------------------------------------------------------------------------------

    @classmethod
    def construct_from_qsp(cls, qsp):
        if not qsp:
            return None

        # compulsory...
        topic = qsp.get(cls.TOPIC)
        start = LocalizedDatetime.construct_from_iso8601(qsp.get(cls.START))
        end = LocalizedDatetime.construct_from_iso8601(qsp.get(cls.END))

        # optional...
        fetch_last_written = qsp.get(cls.FETCH_LAST_WRITTEN, 'false').lower() == 'true'
        checkpoint = qsp.get(cls.CHECKPOINT)
        include_wrapper = qsp.get(cls.INCLUDE_WRAPPER, 'false').lower() == 'true'
        rec_only = qsp.get(cls.REC_ONLY, 'false').lower() == 'true'
        min_max = qsp.get(cls.MIN_MAX, 'false').lower() == 'true'

        return cls(topic, start, end, fetch_last_written, checkpoint, include_wrapper, rec_only, min_max)

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, topic, start, end, fetch_last_written, checkpoint, include_wrapper, rec_only, min_max):
        """
        Constructor
        """
        self.__topic = topic                                    # string
        self.__start = start                                    # LocalizedDatetime
        self.__end = end                                        # LocalizedDatetime

        self.__fetch_last_written = bool(fetch_last_written)    # bool
        self.__checkpoint = checkpoint                          # string
        self.__include_wrapper = bool(include_wrapper)          # bool
        self.__rec_only = bool(rec_only)                        # bool
        self.__min_max = bool(min_max)                          # bool

    # ----------------------------------------------------------------------------------------------------------------

    def is_valid(self):
        if self.topic is None or self.start is None or self.end is None:
            return False

        if self.start > self.end:
            return False

        if self.min_max and self.checkpoint is None:
            return False

        if self.include_wrapper and self.checkpoint is not None:
            return False

        if self.rec_only and self.fetch_last_written:
            return False

        if self.rec_only and self.min_max:
            return False

        return True

    # ----------------------------------------------------------------------------------------------------------------

    def next_params(self, start):
        return MessageRequest(self.topic, start, self.end, self.fetch_last_written, self.checkpoint,
                              self.include_wrapper, self.rec_only, self.min_max).params()

    def change_params(self, start, end):
        return MessageRequest(self.topic, start, end, self.fetch_last_written, self.checkpoint,
                              self.include_wrapper, self.rec_only, self.min_max).params()

    def params(self):
        params = {
            self.TOPIC: self.topic,
            self.START: self.start.utc().as_iso8601(include_millis=True),
            self.END: self.end.utc().as_iso8601(include_millis=True)
        }

        if self.fetch_last_written:
            params[self.FETCH_LAST_WRITTEN] = 'true'

        if self.checkpoint is not None:
            params[self.CHECKPOINT] = self.checkpoint

        if self.include_wrapper:
            params[self.INCLUDE_WRAPPER] = 'true'

        if self.rec_only:
            params[self.REC_ONLY] = 'true'

        if self.min_max:
            params[self.MIN_MAX] = 'true'

        return params

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def checkpoint(self):
        if self.__checkpoint is None:
            return None

        if self.__checkpoint == 'auto':
            return self.checkpoint_table(self.start, self.end)

        return self.__checkpoint

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def topic(self):
        return self.__topic

    @property
    def start(self):
        return self.__start

    @property
    def end(self):
        return self.__end

    @property
    def fetch_last_written(self):
        return self.__fetch_last_written

    @property
    def include_wrapper(self):
        return self.__include_wrapper

    @property
    def rec_only(self):
        return self.__rec_only

    @property
    def min_max(self):
        return self.__min_max

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "MessageRequest:{topic:%s, start:%s, end:%s, fetch_last_written:%s, checkpoint:%s, " \
               "include_wrapper:%s, rec_only:%s, min_max:%s}" % \
               (self.topic, self.start, self.end, self.fetch_last_written, self.__checkpoint,
                self.include_wrapper, self.rec_only, self.min_max)

# --------------------------------------------------------------------------------------------------------------------

class MessageResponse(JSONable):
    """
    classdocs
    """

    # ----------------------------------------------------------------------------------------------------------------

    @classmethod
    def construct_from_jdict(cls, jdict):
        if not jdict:
            return None

        code = jdict.get('statusCode')
        status = jdict.get('status')
        fetched_last = jdict.get('fetchedLastWrittenData')

        items = []
        for msg_jdict in jdict.get('Items'):
            item = Message.construct_from_jdict(msg_jdict) if 'payload' in msg_jdict else msg_jdict
            # item = msg_jdict['payload']       # Paul lambda
            items.append(item)

        next_url = jdict.get('next')

        return cls(code, status, fetched_last, items, next_url)

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, code, status, fetched_last, items, next_url):
        """
        Constructor
        """
        self.__code = Datum.int(code)               # int
        self.__status = status                      # string
        self.__fetched_last = fetched_last          # Fetched last written data flag

        self.__items = items                        # list of Message

        self.__next_url = next_url                  # URL string

    def __len__(self):
        return len(self.items)

    # ----------------------------------------------------------------------------------------------------------------

    def as_json(self):
        jdict = OrderedDict()

        if self.code is not None:
            jdict['statusCode'] = self.code

        if self.status is not None:
            jdict['status'] = self.status

        if self.fetched_last is not None:
            jdict['fetchedLastWrittenData'] = self.fetched_last

        if self.items is not None:
            jdict['Items'] = self.items
            jdict['itemCount'] = len(self.items)

        if self.next_url is not None:
            jdict['next'] = self.next_url

        return jdict

    # ----------------------------------------------------------------------------------------------------------------

    def start(self):
        if not self.items:
            return None

        item = self.items[0]

        try:
            return item['rec']
        except TypeError:
            return item.payload['rec']

    def end(self):
        if not self.items:
            return None

        item = self.items[len(self) - 1]

        try:
            return item['rec']
        except TypeError:
            return item.payload['rec']

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def code(self):
        return self.__code

    @property
    def status(self):
        return self.__status

    @property
    def fetched_last(self):
        return self.__fetched_last

    @property
    def items(self):
        return self.__items

    @property
    def next_url(self):
        return self.__next_url

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "MessageResponse:{code:%s, status:%s, fetched_last:%s, items:%s, next_url:%s}" % \
               (self.code, self.status, self.fetched_last, Str.collection(self.items), self.next_url)
<|endoftext|>


<commit_before>#!/usr/bin/env python

from __future__ import print_function, division
import warnings
import numpy as np
import scipy.sparse
import pymor.core
import pymor.problem.stationary.linear.elliptic.analytical
import pymor.common.boundaryinfo
import pymor.grid.oned
import pymor.common.discreteoperator.stationary.linear
from pymor.core.warnings import CallOrderWarning

class Interface(pymor.core.BasicInterface):

    id = 'discretizer.stationary.linear.elliptic.cg'
    trial_order = -1
    test_order = -1
    data_order = -1

    def __str__(self):
        return id

class P1(Interface):

    id = Interface.id + '.p1'
    trial_order = 1
    test_order = 1
    data_order = 0

    def __init__(self, problem=pymor.problem.stationary.linear.elliptic.analytical.Default(),
                 grid=pymor.grid.oned.Oned(),
                 boundaryinfo=pymor.common.boundaryinfo.oned.AllDirichlet()):
        self.problem = problem
        self.grid = grid
        self.boundaryinfo = boundaryinfo
        assert self.grid.dim == 1
        assert self.grid.volumes(0).min() == self.grid.volumes(0).max()
        assert self.problem.diffusion().dim_domain == self.grid.dim
        assert self.problem.diffusion().dim_range == 1
        self._initialized = False
        self._assembled_operator = False
        self._assembled_functional = False

    def operator(self):
        if not self._assembled_operator:
            warnings.warn('Please call init() before calling operator()! Calling init() now...', CallOrderWarning)
            self._assemble_operator()
        return self._operator

    def functional(self):
        if not self._assembled_functional:
            warnings.warn('Please call init() before calling functional()! Calling init() now...', CallOrderWarning)
            self._assemble_functional()()

    def init(self):
        if not self._initialized:
            self._assemble_operator()
            self._assemble_functional()
            self._initialized = True

    def _assemble_operator(self):
        if not self._assembled_operator:
            # preparations
            h = self.grid.volumes(0).min()
            n = self.grid.size(0)
            # project datafunctions
            diffusion = self.problem.diffusion().evaluate(self.grid.centers(1))
            # some maps
            zero_to_n_minus_two = range(n - 1)
            one_to_n_minus_one = range(1, n)
            two_to_n = range(2, n + 1)
            # assemble diagonal entries
            rows_1 = one_to_n_minus_one
            cols_1 = one_to_n_minus_one
            vals_1 = ((1.0/h) * diffusion[zero_to_n_minus_two]
                            + (1.0/h) * diffusion[one_to_n_minus_one])
            # assemble lower diagonal entries
            rows_2 = one_to_n_minus_one
            cols_2 = zero_to_n_minus_two
            vals_2 = (-1.0/h) * diffusion[zero_to_n_minus_two]
            # assemble upper diagonal entries
            rows_3 = one_to_n_minus_one
            cols_3 = two_to_n
            vals_3 = (-1.0/h) * diffusion[one_to_n_minus_one]
            # assemble left boundary values
            rows_4 = [0, 0]
            cols_4 = [0, 1]
            vals_4 = np.zeros(2)
            if self.boundaryinfo.left() == 'dirichlet':
                vals_4[0] = 1.0
            elif self.boundaryinfo.left() == 'neumann':
                vals_4[0] = (1.0/h) * diffusion[0]
                vals_4[1] = (-1.0/h) * diffusion[0]
            else:
                raise ValueError('wrong boundary type!')
            # assemble left boundary values
            rows_5 = [n, n]
            cols_5 = [n, n - 1]
            vals_5 = np.zeros(2)
            if self.boundaryinfo.right() == 'dirichlet':
                vals_5[0] = 1.0
            elif self.boundaryinfo.right() == 'neumann':
                vals_5[0] = (1.0/h) * diffusion[n - 1]
                vals_5[1] = (-1.0/h) * diffusion[n - 1]
            else:
                raise ValueError('wrong boundary type!')
            # create sparse matrix
            rows = np.array(rows_1 + rows_2 + rows_3 + rows_4 + rows_5)
            cols = np.array(cols_1 + cols_2 + cols_3 + cols_4 + cols_5)
            vals = np.concatenate((vals_1, vals_2, vals_3, vals_4, vals_5), axis=0)
            matrix = scipy.sparse.csr_matrix((vals, (rows, cols)), shape=(n + 1,n + 1))
            # create operator
            self._operator = pymor.common.discreteoperator.stationary.linear.ScipySparse(matrix)
            # finished
            self._assembled_operator = True

    def _assemble_functional(self):
        if not self._assembled_functional:
            # finished
            self._assembled_functional = True

if __name__ == '__main__':
    print('creating problem... ', end='')
    problem = pymor.problem.stationary.linear.elliptic.analytical.Default()
    print('done (' + problem.id + ')')
    print('creating grid... ', end='')
    grid = pymor.grid.oned.Oned()
    print('done ({name}, ' 'size {size})'.format(name=grid.id, size=grid.size()))
    print('creating boundaryinfo... ', end='')
    boundaryinfo = pymor.common.boundaryinfo.oned.AllDirichlet()
    print('done (' + boundaryinfo.id + ')')
    print('creating discretizer (', end='')
    discretizer = P1(problem, grid)
    print(discretizer.id + '):')
    print('  initializing... ', end='')
    discretizer.init()
    print('done')<commit_msg>[discretizer.sttionary.linear.elliptic.cg.P1] added functional assembling<commit_after>#!/usr/bin/env python

from __future__ import print_function, division
import warnings
import numpy as np
import scipy.sparse
import pymor.core
import pymor.problem.stationary.linear.elliptic.analytical
import pymor.common.boundaryinfo
import pymor.grid.oned
import pymor.common.discreteoperator.stationary.linear
import pymor.common.discretefunctional.linear

class Interface(pymor.core.BasicInterface):

    id = 'discretizer.stationary.linear.elliptic.cg'
    trial_order = -1
    test_order = -1
    data_order = -1

    def __str__(self):
        return id

class P1(Interface):

    id = Interface.id + '.p1'
    trial_order = 1
    test_order = 1
    data_order = 0

    def __init__(self, problem=pymor.problem.stationary.linear.elliptic.analytical.Default(),
                 grid=pymor.grid.oned.Oned(),
                 boundaryinfo=pymor.common.boundaryinfo.oned.AllDirichlet()):
        self.problem = problem
        self.grid = grid
        self.boundaryinfo = boundaryinfo
        assert self.grid.dim == 1
        assert self.grid.volumes(0).min() == self.grid.volumes(0).max()
        assert self.problem.diffusion().dim_domain == self.grid.dim
        assert self.problem.diffusion().dim_range == 1
        self._discretized = False

    def discretize(self):
        if not self._discretized:
            # create common stuff for operator and functional
            self._h = self.grid.volumes(0).min()
            self._n = self.grid.size(0)
            # project data functions only once
            self._diffusion = self.problem.diffusion().evaluate(self.grid.centers(1))
            self._force = self.problem.force().evaluate(self.grid.centers(1))
            # create some maps
            self._zero_to_n_minus_two = range(self._n - 1)
            self._one_to_n_minus_one = range(1, self._n)
            self._two_to_n = range(2, self._n + 1)
            # assemble
            self._assemble_operator()
            self._assemble_functional()
            # clear common stuff
            del self._h
            del self._n
            del self._diffusion
            del self._zero_to_n_minus_two
            del self._one_to_n_minus_one
            del self._two_to_n
            # finished
            self._discretized = True

    def _assemble_operator(self):
        # get stuff
        h = self._h
        n = self._n
        diffusion = self._diffusion
        # get maps
        zero_to_n_minus_two = self._zero_to_n_minus_two
        one_to_n_minus_one = self._one_to_n_minus_one
        two_to_n = self._two_to_n
        # assemble diagonal entries
        rows_1 = one_to_n_minus_one
        cols_1 = one_to_n_minus_one
        vals_1 = ((1.0 / h) * diffusion[zero_to_n_minus_two]
                        + (1.0 / h) * diffusion[one_to_n_minus_one])
        # assemble lower diagonal entries
        rows_2 = one_to_n_minus_one
        cols_2 = zero_to_n_minus_two
        vals_2 = (-1.0 / h) * diffusion[zero_to_n_minus_two]
        # assemble upper diagonal entries
        rows_3 = one_to_n_minus_one
        cols_3 = two_to_n
        vals_3 = (-1.0 / h) * diffusion[one_to_n_minus_one]
        # assemble left boundary values
        rows_4 = [0, 0]
        cols_4 = [0, 1]
        vals_4 = np.zeros(2)
        if self.boundaryinfo.left() == 'dirichlet':
            vals_4[0] = 1.0
        elif self.boundaryinfo.left() == 'neumann':
            vals_4[0] = (1.0 / h) * diffusion[0]
            vals_4[1] = (-1.0 / h) * diffusion[0]
        else:
            raise ValueError('wrong boundary type!')
        # assemble right boundary values
        rows_5 = [n, n]
        cols_5 = [n, n - 1]
        vals_5 = np.zeros(2)
        if self.boundaryinfo.right() == 'dirichlet':
            vals_5[0] = 1.0
        elif self.boundaryinfo.right() == 'neumann':
            vals_5[0] = (1.0 / h) * diffusion[n - 1]
            vals_5[1] = (-1.0 / h) * diffusion[n - 1]
        else:
            raise ValueError('wrong boundary type!')
        # create sparse matrix
        rows = np.array(rows_1 + rows_2 + rows_3 + rows_4 + rows_5)
        cols = np.array(cols_1 + cols_2 + cols_3 + cols_4 + cols_5)
        vals = np.concatenate((vals_1, vals_2, vals_3, vals_4, vals_5), axis=0)
        matrix = scipy.sparse.csr_matrix((vals, (rows, cols)), shape=(n + 1, n + 1))
        # create operator
        self._operator = pymor.common.discreteoperator.stationary.linear.ScipySparse(matrix)

    def _assemble_functional(self):
        # get stuff
        h = self._h
        n = self._n
        diffusion = self._diffusion
        force = self._force
        # get maps
        zero_to_n_minus_two = self._zero_to_n_minus_two
        one_to_n_minus_one = self._one_to_n_minus_one
        # assemble dense vector
        vector = np.zeros(n + 1)
        vector[one_to_n_minus_one] = (0.5 * h) * (force[zero_to_n_minus_two]
                                                  + force[one_to_n_minus_one]);
        # assemble left boundary values
        x_left = self.grid.centers(1)[0]
        if self.boundaryinfo.left() == 'dirichlet':
            vector[0] = self.problem.dirichlet().evaluate(x_left)
        elif self.boundaryinfo.left() == 'neumann':
            vector[0] = (h * force[0]
                         + diffusion[0] * self.problem.neumann.evaluate(x_left));
        else:
            raise ValueError('wrong boundary type!')
        # assemble right boundary values
        x_right = self.grid.centers(1)[-1]
        if self.boundaryinfo.right() == 'dirichlet':
            vector[-1] = self.problem.dirichlet().evaluate(x_right)
        elif self.boundaryinfo.right() == 'neumann':
            vector[-1] = (h * force[-1]
                         + diffusion[-1] * self.problem.neumann.evaluate(x_right));
        else:
            raise ValueError('wrong boundary type!')
        # create functional
        self._functional = pymor.common.discretefunctional.linear.NumpyDense(vector)

if __name__ == '__main__':
    print('creating problem... ', end='')
    problem = pymor.problem.stationary.linear.elliptic.analytical.Default()
    print('done (' + problem.id + ')')
    print('creating grid... ', end='')
    grid = pymor.grid.oned.Oned()
    print('done ({name}, ' 'size {size})'.format(name=grid.id, size=grid.size()))
    print('creating boundaryinfo... ', end='')
    boundaryinfo = pymor.common.boundaryinfo.oned.AllDirichlet()
    print('done (' + boundaryinfo.id + ')')
    print('creating discretizer (', end='')
    discretizer = P1(problem, grid)
    print(discretizer.id + '):')
    print('  discretizing... ', end='')
    discretizer.discretize()
    print('done')
<|endoftext|>


<commit_before>#!/usr/bin/env python

"""A static execution plugin for single tasks.
"""

__author__    = "Ole Weider <ole.weidner@rutgers.edu>"
__copyright__ = "Copyright 2014, http://radical.rutgers.edu"
__license__   = "MIT"

import os
import sys
import saga
import pickle
import datetime
import radical.pilot

from radical.ensemblemd.exceptions import NotImplementedError, EnsemblemdError
from radical.ensemblemd.exec_plugins.plugin_base import PluginBase

# ------------------------------------------------------------------------------
#
_PLUGIN_INFO = {
    "name":         "pipeline.static.default",
    "pattern":      "Pipeline",
    "context_type": "Static"
}

_PLUGIN_OPTIONS = []

# ------------------------------------------------------------------------------
#
class Plugin(PluginBase):

    # --------------------------------------------------------------------------
    #
    def __init__(self):
        super(Plugin, self).__init__(_PLUGIN_INFO, _PLUGIN_OPTIONS)

    # --------------------------------------------------------------------------
    #
    def verify_pattern(self, pattern):
        self.get_logger().info("Verifying pattern...")

    # --------------------------------------------------------------------------
    #
    def execute_pattern(self, pattern, resource):

        #-----------------------------------------------------------------------
        #
        def pilot_state_cb (pilot, state) :
            self.get_logger().info("Resource {0} state has changed to {1}".format(
                resource._resource_key, state))

            if state == radical.pilot.FAILED:
                self.get_logger().error("Resource error: {0}".format(pilot.log))
                self.get_logger().error("Pattern execution FAILED.")

                # Try to get some information here...
                if os.getenv("RADICAL_ENMD_TRAVIS_DEBUG") is not None:

                    sb = saga.Url(pilot.sandbox).path
                    agent_stderr = "{0}/AGENT.STDERR".format(sb)
                    agent_stdout = "{0}/AGENT.STDOUT".format(sb)
                    agent_log = "{0}/AGENT.LOG".format(sb)
                    pip_cmd = "{0}/virtualenv/bin/pip".format(sb)

                    self.get_logger().error(pip_cmd)
                    os.system("head {0}".format(pip_cmd))
                    self.get_logger().error(agent_stderr)
                    os.system("cat {0}".format(agent_stderr))
                    self.get_logger().error(agent_stdout)
                    os.system("cat {0}".format(agent_stdout))
                    self.get_logger().error(agent_log)
                    os.system("cat {0}".format(agent_log))

        #-----------------------------------------------------------------------
        #
        def unit_state_cb (unit, state) :

            if state == radical.pilot.DONE:
                self.get_logger().info("Task with ID {0} has completed.".format(unit.uid))

            if state == radical.pilot.FAILED:
                self.get_logger().error("Task with ID {0} failed: STDERR: {1}, STDOUT: {2}".format(unit.uid, unit.stderr, unit.stdout))

        pipeline_instances = pattern.instances

        self.get_logger().info("Executing {0} pipeline instances on {1} allocated core(s) on '{2}'".format(
            pipeline_instances, resource._cores, resource._resource_key))

        try:
            # We use the journal to keep track of the stage / instance to
            # job mapping as well as to record associated timing informations.
            journal= {}
            # journal["metainfo"] = {
            #     "pattern_name": "pipeline"
            # }
            steps = 0

            session = radical.pilot.Session()

            if resource._username is not None:
                # Add an ssh identity to the session.
                c = radical.pilot.Context('ssh')
                c.user_id = resource._username
                session.add_context(c)

            pmgr = radical.pilot.PilotManager(session=session)
            pmgr.register_callback(pilot_state_cb)

            pdesc = radical.pilot.ComputePilotDescription()
            pdesc.resource = resource._resource_key
            pdesc.runtime  = resource._walltime
            pdesc.cores    = resource._cores

            if resource._queue is not None:
                pdesc.queue = resource._queue

            pdesc.cleanup  = True

            if resource._allocation is not None:
                pdesc.project = resource._allocation

            self.get_logger().info("Requesting resources on {0}".format(resource._resource_key))

            pilot = pmgr.submit_pilots(pdesc)

            umgr = radical.pilot.UnitManager(
                session=session,
                scheduler=radical.pilot.SCHED_DIRECT_SUBMISSION)
            umgr.register_callback(unit_state_cb)

            umgr.add_pilots(pilot)

            self.get_logger().info("Launched {0}-core pilot on {1}.".format(resource._cores, resource._resource_key))

            working_dirs = {}

            # Iterate over the different steps.
            for step in range(1, 64):
                # Create a new empty journal entry for the step.
                journal["step_{0}".format(step)] = {}

                # Get the method names
                s_meth = getattr(pattern, 'step_{0}'.format(step))

                # Build up the working dir bookkeeping structure.
                working_dirs["step_{0}".format(step)] = {}

                try:
                    kernel = s_meth(0)
                    steps += 1
                except NotImplementedError, ex:
                    # Not implemented means there are no further steps.
                    break

                for instance in range(1, pipeline_instances+1):

                    # Create a new journal entry for the instance.
                    journal["step_{0}".format(step)]["instance_{0}".format(instance)] = {}
                    inst_entry = journal["step_{0}".format(step)]["instance_{0}".format(instance)]

                    kernel = s_meth(instance)
                    kernel._bind_to_resource(resource._resource_key)

                    cud = radical.pilot.ComputeUnitDescription()

                    cud.pre_exec       = kernel._cu_def_pre_exec
                    cud.executable     = kernel._cu_def_executable
                    cud.arguments      = kernel.arguments
                    cud.mpi            = kernel.uses_mpi
                    cud.input_staging  = kernel._cu_def_input_data
                    cud.output_staging = kernel._cu_def_output_data

                    inst_entry["unit_description"] = cud
                    inst_entry["compute_unit"] = None
                    inst_entry["working_dir"] = "WORKDIR-s%s-i%s" % (step, instance)

                    self.get_logger().debug("Created step_1 CU ({0}/{1}): {2}.".format(instance+1, pipeline_instances, cud.as_dict()))

                self.get_logger().info("Created {0} ComputeUnits for pipeline step {1}.".format(pipeline_instances, step))

            # -----------------------------------------------------------------
            # At this point, we have created a complete journal for the
            # pattern instance. We can now start 'enacting' it through
            # radical pilot.
            for step in range(1, steps+1):
                step_key = "step_%s" % step

                for instance in range(1, pipeline_instances+1):
                    instance_key = "instance_%s" % instance

                    step_units = []

                    # Now we can replace the data-linkage placeholders.
                    jd = journal[step_key][instance_key]["unit_description"]
                    for pe in jd.pre_exec:

                        for i in range(1,33):
                            placeholder = "$STEP_{step}".format(step=i)
                            journal_key = "step_{step}".format(step=i)

                            if placeholder in pe:
                                jd.pre_exec.remove(pe)
                                expanded_pe = pe.replace(placeholder, journal[journal_key][instance_key]["working_dir"])
                                jd.pre_exec.append(expanded_pe)

                    unit = umgr.submit_units(jd)
                    step_units.append(unit)
                    journal[step_key][instance_key]["compute_unit"] = unit

                self.get_logger().info("Submitted ComputeUnits for pipeline step {0}.".format(step))
                umgr.wait_units()

                # Update all working directories so they can be accessed from
                # the next step(s).
                for instance in range(1, pipeline_instances+1):
                    instance_key = "instance_%s" % instance
                    work_dir = saga.Url(journal[step_key][instance_key]["compute_unit"].working_directory).path
                    journal[step_key][instance_key]["working_dir"] = work_dir

                failed_units = ""
                for unit in step_units:
                    if unit.state != radical.pilot.DONE:
                        failed_units += " * Compute Unit {0} failed with an error: {1}\n".format(unit.uid, unit.stderr)

                if len(failed_units) > 0:
                    raise EnsemblemdError("One or more ComputeUnits failed in pipeline step {0}: \n{1}".format(step, failed_units))

        except Exception, ex:
            self.get_logger().exception("Fatal error during execution: {0}.".format(str(ex)))
            raise

        finally:
            self.get_logger().info("Deallocating resource.")
            try:
                session.close()
            except Exception:
                pass

        # -----------------------------------------------------------------
        # At this point, we have executed the pattern succesfully. Now,
        # if profiling is enabled, we can write the profiling data to
        # a file.
        do_profile = os.getenv('RADICAL_ENDM_PROFILING', '0')

        if do_profile != 0:

            outfile = "execution_profile_{time}.log".format(time=datetime.datetime.now().isoformat())
            self.get_logger().info("Saving execution profile in {outfile}".format(outfile=outfile))

            with open(outfile, 'w+') as f:
                # General format of a profiling file is row based and follows the
                # structure <unit id>; <s_time>; <stop_t>; <tag1>; <tag2>; ...
                head = "task; start_time; stop_time; step; iteration"
                f.write("{row}\n".format(row=head))

                for step in journal.keys():
                    for iteration in journal[step].keys():
                        data = journal[step][iteration]
                        cu = data["compute_unit"]

                        row = "{uid}; {start_time}; {stop_time}; {tags}".format(
                            uid=cu.uid,
                            start_time=cu.start_time,
                            stop_time=cu.stop_time,
                            tags="{step}; {iteration}".format(step=step, iteration=iteration)
                        )
                        f.write("{row}\n".format(row=row))
<commit_msg>use proper file ending<commit_after>#!/usr/bin/env python

"""A static execution plugin for single tasks.
"""

__author__    = "Ole Weider <ole.weidner@rutgers.edu>"
__copyright__ = "Copyright 2014, http://radical.rutgers.edu"
__license__   = "MIT"

import os
import sys
import saga
import pickle
import datetime
import radical.pilot

from radical.ensemblemd.exceptions import NotImplementedError, EnsemblemdError
from radical.ensemblemd.exec_plugins.plugin_base import PluginBase

# ------------------------------------------------------------------------------
#
_PLUGIN_INFO = {
    "name":         "pipeline.static.default",
    "pattern":      "Pipeline",
    "context_type": "Static"
}

_PLUGIN_OPTIONS = []

# ------------------------------------------------------------------------------
#
class Plugin(PluginBase):

    # --------------------------------------------------------------------------
    #
    def __init__(self):
        super(Plugin, self).__init__(_PLUGIN_INFO, _PLUGIN_OPTIONS)

    # --------------------------------------------------------------------------
    #
    def verify_pattern(self, pattern):
        self.get_logger().info("Verifying pattern...")

    # --------------------------------------------------------------------------
    #
    def execute_pattern(self, pattern, resource):

        #-----------------------------------------------------------------------
        #
        def pilot_state_cb (pilot, state) :
            self.get_logger().info("Resource {0} state has changed to {1}".format(
                resource._resource_key, state))

            if state == radical.pilot.FAILED:
                self.get_logger().error("Resource error: {0}".format(pilot.log))
                self.get_logger().error("Pattern execution FAILED.")

                # Try to get some information here...
                if os.getenv("RADICAL_ENMD_TRAVIS_DEBUG") is not None:

                    sb = saga.Url(pilot.sandbox).path
                    agent_stderr = "{0}/AGENT.STDERR".format(sb)
                    agent_stdout = "{0}/AGENT.STDOUT".format(sb)
                    agent_log = "{0}/AGENT.LOG".format(sb)
                    pip_cmd = "{0}/virtualenv/bin/pip".format(sb)

                    self.get_logger().error(pip_cmd)
                    os.system("head {0}".format(pip_cmd))
                    self.get_logger().error(agent_stderr)
                    os.system("cat {0}".format(agent_stderr))
                    self.get_logger().error(agent_stdout)
                    os.system("cat {0}".format(agent_stdout))
                    self.get_logger().error(agent_log)
                    os.system("cat {0}".format(agent_log))

        #-----------------------------------------------------------------------
        #
        def unit_state_cb (unit, state) :

            if state == radical.pilot.DONE:
                self.get_logger().info("Task with ID {0} has completed.".format(unit.uid))

            if state == radical.pilot.FAILED:
                self.get_logger().error("Task with ID {0} failed: STDERR: {1}, STDOUT: {2}".format(unit.uid, unit.stderr, unit.stdout))

        pipeline_instances = pattern.instances

        self.get_logger().info("Executing {0} pipeline instances on {1} allocated core(s) on '{2}'".format(
            pipeline_instances, resource._cores, resource._resource_key))

        try:
            # We use the journal to keep track of the stage / instance to
            # job mapping as well as to record associated timing informations.
            journal= {}
            # journal["metainfo"] = {
            #     "pattern_name": "pipeline"
            # }
            steps = 0

            session = radical.pilot.Session()

            if resource._username is not None:
                # Add an ssh identity to the session.
                c = radical.pilot.Context('ssh')
                c.user_id = resource._username
                session.add_context(c)

            pmgr = radical.pilot.PilotManager(session=session)
            pmgr.register_callback(pilot_state_cb)

            pdesc = radical.pilot.ComputePilotDescription()
            pdesc.resource = resource._resource_key
            pdesc.runtime  = resource._walltime
            pdesc.cores    = resource._cores

            if resource._queue is not None:
                pdesc.queue = resource._queue

            pdesc.cleanup  = True

            if resource._allocation is not None:
                pdesc.project = resource._allocation

            self.get_logger().info("Requesting resources on {0}".format(resource._resource_key))

            pilot = pmgr.submit_pilots(pdesc)

            umgr = radical.pilot.UnitManager(
                session=session,
                scheduler=radical.pilot.SCHED_DIRECT_SUBMISSION)
            umgr.register_callback(unit_state_cb)

            umgr.add_pilots(pilot)

            self.get_logger().info("Launched {0}-core pilot on {1}.".format(resource._cores, resource._resource_key))

            working_dirs = {}

            # Iterate over the different steps.
            for step in range(1, 64):
                # Create a new empty journal entry for the step.
                journal["step_{0}".format(step)] = {}

                # Get the method names
                s_meth = getattr(pattern, 'step_{0}'.format(step))

                # Build up the working dir bookkeeping structure.
                working_dirs["step_{0}".format(step)] = {}

                try:
                    kernel = s_meth(0)
                    steps += 1
                except NotImplementedError, ex:
                    # Not implemented means there are no further steps.
                    break

                for instance in range(1, pipeline_instances+1):

                    # Create a new journal entry for the instance.
                    journal["step_{0}".format(step)]["instance_{0}".format(instance)] = {}
                    inst_entry = journal["step_{0}".format(step)]["instance_{0}".format(instance)]

                    kernel = s_meth(instance)
                    kernel._bind_to_resource(resource._resource_key)

                    cud = radical.pilot.ComputeUnitDescription()

                    cud.pre_exec       = kernel._cu_def_pre_exec
                    cud.executable     = kernel._cu_def_executable
                    cud.arguments      = kernel.arguments
                    cud.mpi            = kernel.uses_mpi
                    cud.input_staging  = kernel._cu_def_input_data
                    cud.output_staging = kernel._cu_def_output_data

                    inst_entry["unit_description"] = cud
                    inst_entry["compute_unit"] = None
                    inst_entry["working_dir"] = "WORKDIR-s%s-i%s" % (step, instance)

                    self.get_logger().debug("Created step_1 CU ({0}/{1}): {2}.".format(instance+1, pipeline_instances, cud.as_dict()))

                self.get_logger().info("Created {0} ComputeUnits for pipeline step {1}.".format(pipeline_instances, step))

            # -----------------------------------------------------------------
            # At this point, we have created a complete journal for the
            # pattern instance. We can now start 'enacting' it through
            # radical pilot.
            for step in range(1, steps+1):
                step_key = "step_%s" % step

                for instance in range(1, pipeline_instances+1):
                    instance_key = "instance_%s" % instance

                    step_units = []

                    # Now we can replace the data-linkage placeholders.
                    jd = journal[step_key][instance_key]["unit_description"]
                    for pe in jd.pre_exec:

                        for i in range(1,33):
                            placeholder = "$STEP_{step}".format(step=i)
                            journal_key = "step_{step}".format(step=i)

                            if placeholder in pe:
                                jd.pre_exec.remove(pe)
                                expanded_pe = pe.replace(placeholder, journal[journal_key][instance_key]["working_dir"])
                                jd.pre_exec.append(expanded_pe)

                    unit = umgr.submit_units(jd)
                    step_units.append(unit)
                    journal[step_key][instance_key]["compute_unit"] = unit

                self.get_logger().info("Submitted ComputeUnits for pipeline step {0}.".format(step))
                umgr.wait_units()

                # Update all working directories so they can be accessed from
                # the next step(s).
                for instance in range(1, pipeline_instances+1):
                    instance_key = "instance_%s" % instance
                    work_dir = saga.Url(journal[step_key][instance_key]["compute_unit"].working_directory).path
                    journal[step_key][instance_key]["working_dir"] = work_dir

                failed_units = ""
                for unit in step_units:
                    if unit.state != radical.pilot.DONE:
                        failed_units += " * Compute Unit {0} failed with an error: {1}\n".format(unit.uid, unit.stderr)

                if len(failed_units) > 0:
                    raise EnsemblemdError("One or more ComputeUnits failed in pipeline step {0}: \n{1}".format(step, failed_units))

        except Exception, ex:
            self.get_logger().exception("Fatal error during execution: {0}.".format(str(ex)))
            raise

        finally:
            self.get_logger().info("Deallocating resource.")
            try:
                session.close()
            except Exception:
                pass

        # -----------------------------------------------------------------
        # At this point, we have executed the pattern succesfully. Now,
        # if profiling is enabled, we can write the profiling data to
        # a file.
        do_profile = os.getenv('RADICAL_ENDM_PROFILING', '0')

        if do_profile != 0:

            outfile = "execution_profile_{time}.csv".format(time=datetime.datetime.now().isoformat())
            self.get_logger().info("Saving execution profile in {outfile}".format(outfile=outfile))

            with open(outfile, 'w+') as f:
                # General format of a profiling file is row based and follows the
                # structure <unit id>; <s_time>; <stop_t>; <tag1>; <tag2>; ...
                head = "task; start_time; stop_time; step; iteration"
                f.write("{row}\n".format(row=head))

                for step in journal.keys():
                    for iteration in journal[step].keys():
                        data = journal[step][iteration]
                        cu = data["compute_unit"]

                        row = "{uid}; {start_time}; {stop_time}; {tags}".format(
                            uid=cu.uid,
                            start_time=cu.start_time,
                            stop_time=cu.stop_time,
                            tags="{step}; {iteration}".format(step=step.split('_')[1], iteration=iteration.split('_')[1])
                        )
                        f.write("{row}\n".format(row=row))
<|endoftext|>


<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
#    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.

import base64
import sys
import uuid

from tempest.api.compute import base
from tempest import clients
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.test import attr

class ServersNegativeTestJSON(base.BaseComputeTest):
    _interface = 'json'

    def setUp(self):
        super(ServersNegativeTestJSON, self).setUp()
        try:
            self.client.wait_for_server_status(self.server_id, 'ACTIVE')
        except Exception:
            self.rebuild_server()

    @classmethod
    def setUpClass(cls):
        super(ServersNegativeTestJSON, cls).setUpClass()
        cls.client = cls.servers_client
        cls.img_client = cls.images_client
        cls.alt_os = clients.AltManager()
        cls.alt_client = cls.alt_os.servers_client
        resp, server = cls.create_server(wait_until='ACTIVE')
        cls.server_id = server['id']

    @attr(type=['negative', 'gate'])
    def test_server_name_blank(self):
        # Create a server with name parameter empty

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          name='')

    @attr(type=['negative', 'gate'])
    def test_personality_file_contents_not_encoded(self):
        # Use an unencoded file when creating a server with personality

        file_contents = 'This is a test file.'
        person = [{'path': '/etc/testfile.txt',
                   'contents': file_contents}]

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          personality=person)

    @attr(type=['negative', 'gate'])
    def test_create_with_invalid_image(self):
        # Create a server with an unknown image

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          image_id=-1)

    @attr(type=['negative', 'gate'])
    def test_create_with_invalid_flavor(self):
        # Create a server with an unknown flavor

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          flavor=-1,)

    @attr(type=['negative', 'gate'])
    def test_invalid_access_ip_v4_address(self):
        # An access IPv4 address must match a valid address pattern

        IPv4 = '1.1.1.1.1.1'
        self.assertRaises(exceptions.BadRequest,
                          self.create_server, accessIPv4=IPv4)

    @attr(type=['negative', 'gate'])
    def test_invalid_ip_v6_address(self):
        # An access IPv6 address must match a valid address pattern

        IPv6 = 'notvalid'

        self.assertRaises(exceptions.BadRequest,
                          self.create_server, accessIPv6=IPv6)

    @attr(type=['negative', 'gate'])
    def test_resize_server_with_non_existent_flavor(self):
        # Resize a server with non-existent flavor
        nonexistent_flavor = str(uuid.uuid4())
        self.assertRaises(exceptions.BadRequest, self.client.resize,
                          self.server_id, flavor_ref=nonexistent_flavor)

    @attr(type=['negative', 'gate'])
    def test_resize_server_with_null_flavor(self):
        # Resize a server with null flavor
        self.assertRaises(exceptions.BadRequest, self.client.resize,
                          self.server_id, flavor_ref="")

    @attr(type=['negative', 'gate'])
    def test_reboot_non_existent_server(self):
        # Reboot a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.reboot,
                          nonexistent_server, 'SOFT')

    @attr(type=['negative', 'gate'])
    def test_reboot_deleted_server(self):
        # Reboot a deleted server
        self.client.delete_server(self.server_id)
        self.client.wait_for_server_termination(self.server_id)
        self.assertRaises(exceptions.NotFound, self.client.reboot,
                          self.server_id, 'SOFT')

    @attr(type=['negative', 'gate'])
    def test_pause_paused_server(self):
        # Pause a paused server.
        self.client.pause_server(self.server_id)
        self.client.wait_for_server_status(self.server_id, 'PAUSED')
        self.assertRaises(exceptions.Duplicate,
                          self.client.pause_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_rebuild_deleted_server(self):
        # Rebuild a deleted server
        self.client.delete_server(self.server_id)
        self.client.wait_for_server_termination(self.server_id)

        self.assertRaises(exceptions.NotFound,
                          self.client.rebuild,
                          self.server_id, self.image_ref_alt)

    @attr(type=['negative', 'gate'])
    def test_rebuild_non_existent_server(self):
        # Rebuild a non existent server
        nonexistent_server = str(uuid.uuid4())
        meta = {'rebuild': 'server'}
        new_name = rand_name('server')
        file_contents = 'Test server rebuild.'
        personality = [{'path': '/etc/rebuild.txt',
                        'contents': base64.b64encode(file_contents)}]
        self.assertRaises(exceptions.NotFound,
                          self.client.rebuild,
                          nonexistent_server,
                          self.image_ref_alt,
                          name=new_name, meta=meta,
                          personality=personality,
                          adminPass='rebuild')

    @attr(type=['negative', 'gate'])
    def test_create_numeric_server_name(self):
        # Create a server with a numeric name
        if self.__class__._interface == "xml":
            raise self.skipException("Not testable in XML")

        server_name = 12345
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          name=server_name)

    @attr(type=['negative', 'gate'])
    def test_create_server_name_length_exceeds_256(self):
        # Create a server with name length exceeding 256 characters

        server_name = 'a' * 256
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          name=server_name)

    @attr(type=['negative', 'gate'])
    def test_create_with_invalid_network_uuid(self):
        # Pass invalid network uuid while creating a server

        networks = [{'fixed_ip': '10.0.1.1', 'uuid': 'a-b-c-d-e-f-g-h-i-j'}]

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          networks=networks)

    @attr(type=['negative', 'gate'])
    def test_create_with_non_existant_keypair(self):
        # Pass a non-existent keypair while creating a server

        key_name = rand_name('key')
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          key_name=key_name)

    @attr(type=['negative', 'gate'])
    def test_create_server_metadata_exceeds_length_limit(self):
        # Pass really long metadata while creating a server

        metadata = {'a': 'b' * 260}
        self.assertRaises(exceptions.OverLimit,
                          self.create_server,
                          meta=metadata)

    @attr(type=['negative', 'gate'])
    def test_update_name_of_non_existent_server(self):
        # Update name of a non-existent server

        server_name = rand_name('server')
        new_name = rand_name('server') + '_updated'

        self.assertRaises(exceptions.NotFound, self.client.update_server,
                          server_name, name=new_name)

    @attr(type=['negative', 'gate'])
    def test_update_server_set_empty_name(self):
        # Update name of the server to an empty string

        server_name = rand_name('server')
        new_name = ''

        self.assertRaises(exceptions.BadRequest, self.client.update_server,
                          server_name, name=new_name)

    @attr(type=['negative', 'gate'])
    def test_update_server_of_another_tenant(self):
        # Update name of a server that belongs to another tenant

        new_name = self.server_id + '_new'
        self.assertRaises(exceptions.NotFound,
                          self.alt_client.update_server, self.server_id,
                          name=new_name)

    @attr(type=['negative', 'gate'])
    def test_update_server_name_length_exceeds_256(self):
        # Update name of server exceed the name length limit

        new_name = 'a' * 256
        self.assertRaises(exceptions.BadRequest,
                          self.client.update_server,
                          self.server_id,
                          name=new_name)

    @attr(type=['negative', 'gate'])
    def test_delete_non_existent_server(self):
        # Delete a non existent server

        self.assertRaises(exceptions.NotFound, self.client.delete_server,
                          '999erra43')

    @attr(type=['negative', 'gate'])
    def test_delete_a_server_of_another_tenant(self):
        # Delete a server that belongs to another tenant
        self.assertRaises(exceptions.NotFound,
                          self.alt_client.delete_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_delete_server_pass_negative_id(self):
        # Pass an invalid string parameter to delete server

        self.assertRaises(exceptions.NotFound, self.client.delete_server, -1)

    @attr(type=['negative', 'gate'])
    def test_delete_server_pass_id_exceeding_length_limit(self):
        # Pass a server ID that exceeds length limit to delete server

        self.assertRaises(exceptions.NotFound, self.client.delete_server,
                          sys.maxint + 1)

    @attr(type=['negative', 'gate'])
    def test_create_with_nonexistent_security_group(self):
        # Create a server with a nonexistent security group

        security_groups = [{'name': 'does_not_exist'}]
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          security_groups=security_groups)

    @attr(type=['negative', 'gate'])
    def test_get_non_existent_server(self):
        # Get a non existent server details

        self.assertRaises(exceptions.NotFound, self.client.get_server,
                          '999erra43')

    @attr(type=['negative', 'gate'])
    def test_stop_non_existent_server(self):
        # Stop a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.servers_client.stop,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_pause_non_existent_server(self):
        # pause a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.pause_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_unpause_non_existent_server(self):
        # unpause a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.unpause_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_unpause_server_invalid_state(self):
        # unpause an active server.
        self.assertRaises(exceptions.Duplicate,
                          self.client.unpause_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_suspend_non_existent_server(self):
        # suspend a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.suspend_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_suspend_server_invalid_state(self):
        # suspend a suspended server.
        resp, _ = self.client.suspend_server(self.server_id)
        self.assertEqual(202, resp.status)
        self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
        self.assertRaises(exceptions.Duplicate,
                          self.client.suspend_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_resume_non_existent_server(self):
        # resume a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.resume_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_resume_server_invalid_state(self):
        # resume an active server.
        self.assertRaises(exceptions.Duplicate,
                          self.client.resume_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_get_console_output_of_non_existent_server(self):
        # get the console output for a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound,
                          self.client.get_console_output,
                          nonexistent_server, 10)

class ServersNegativeTestXML(ServersNegativeTestJSON):
    _interface = 'xml'
<commit_msg>server status remained in unexpected state<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
#    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.

import base64
import sys
import uuid

from tempest.api.compute import base
from tempest import clients
from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.test import attr

class ServersNegativeTestJSON(base.BaseComputeTest):
    _interface = 'json'

    def setUp(self):
        super(ServersNegativeTestJSON, self).setUp()
        try:
            self.client.wait_for_server_status(self.server_id, 'ACTIVE')
        except Exception:
            self.rebuild_server()

    @classmethod
    def setUpClass(cls):
        super(ServersNegativeTestJSON, cls).setUpClass()
        cls.client = cls.servers_client
        cls.img_client = cls.images_client
        cls.alt_os = clients.AltManager()
        cls.alt_client = cls.alt_os.servers_client
        resp, server = cls.create_server(wait_until='ACTIVE')
        cls.server_id = server['id']

    @attr(type=['negative', 'gate'])
    def test_server_name_blank(self):
        # Create a server with name parameter empty

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          name='')

    @attr(type=['negative', 'gate'])
    def test_personality_file_contents_not_encoded(self):
        # Use an unencoded file when creating a server with personality

        file_contents = 'This is a test file.'
        person = [{'path': '/etc/testfile.txt',
                   'contents': file_contents}]

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          personality=person)

    @attr(type=['negative', 'gate'])
    def test_create_with_invalid_image(self):
        # Create a server with an unknown image

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          image_id=-1)

    @attr(type=['negative', 'gate'])
    def test_create_with_invalid_flavor(self):
        # Create a server with an unknown flavor

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          flavor=-1,)

    @attr(type=['negative', 'gate'])
    def test_invalid_access_ip_v4_address(self):
        # An access IPv4 address must match a valid address pattern

        IPv4 = '1.1.1.1.1.1'
        self.assertRaises(exceptions.BadRequest,
                          self.create_server, accessIPv4=IPv4)

    @attr(type=['negative', 'gate'])
    def test_invalid_ip_v6_address(self):
        # An access IPv6 address must match a valid address pattern

        IPv6 = 'notvalid'

        self.assertRaises(exceptions.BadRequest,
                          self.create_server, accessIPv6=IPv6)

    @attr(type=['negative', 'gate'])
    def test_resize_server_with_non_existent_flavor(self):
        # Resize a server with non-existent flavor
        nonexistent_flavor = str(uuid.uuid4())
        self.assertRaises(exceptions.BadRequest, self.client.resize,
                          self.server_id, flavor_ref=nonexistent_flavor)

    @attr(type=['negative', 'gate'])
    def test_resize_server_with_null_flavor(self):
        # Resize a server with null flavor
        self.assertRaises(exceptions.BadRequest, self.client.resize,
                          self.server_id, flavor_ref="")

    @attr(type=['negative', 'gate'])
    def test_reboot_non_existent_server(self):
        # Reboot a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.reboot,
                          nonexistent_server, 'SOFT')

    @attr(type=['negative', 'gate'])
    def test_pause_paused_server(self):
        # Pause a paused server.
        self.client.pause_server(self.server_id)
        self.addCleanup(self.client.unpause_server,
                        self.server_id)
        self.client.wait_for_server_status(self.server_id, 'PAUSED')
        self.assertRaises(exceptions.Duplicate,
                          self.client.pause_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_rebuild_reboot_deleted_server(self):
        # Rebuild and Reboot a deleted server
        _, server = self.create_server()
        self.client.delete_server(server['id'])
        self.client.wait_for_server_termination(server['id'])

        self.assertRaises(exceptions.NotFound,
                          self.client.rebuild,
                          server['id'], self.image_ref_alt)
        self.assertRaises(exceptions.NotFound, self.client.reboot,
                          server['id'], 'SOFT')

    @attr(type=['negative', 'gate'])
    def test_rebuild_non_existent_server(self):
        # Rebuild a non existent server
        nonexistent_server = str(uuid.uuid4())
        meta = {'rebuild': 'server'}
        new_name = rand_name('server')
        file_contents = 'Test server rebuild.'
        personality = [{'path': '/etc/rebuild.txt',
                        'contents': base64.b64encode(file_contents)}]
        self.assertRaises(exceptions.NotFound,
                          self.client.rebuild,
                          nonexistent_server,
                          self.image_ref_alt,
                          name=new_name, meta=meta,
                          personality=personality,
                          adminPass='rebuild')

    @attr(type=['negative', 'gate'])
    def test_create_numeric_server_name(self):
        # Create a server with a numeric name
        if self.__class__._interface == "xml":
            raise self.skipException("Not testable in XML")

        server_name = 12345
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          name=server_name)

    @attr(type=['negative', 'gate'])
    def test_create_server_name_length_exceeds_256(self):
        # Create a server with name length exceeding 256 characters

        server_name = 'a' * 256
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          name=server_name)

    @attr(type=['negative', 'gate'])
    def test_create_with_invalid_network_uuid(self):
        # Pass invalid network uuid while creating a server

        networks = [{'fixed_ip': '10.0.1.1', 'uuid': 'a-b-c-d-e-f-g-h-i-j'}]

        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          networks=networks)

    @attr(type=['negative', 'gate'])
    def test_create_with_non_existant_keypair(self):
        # Pass a non-existent keypair while creating a server

        key_name = rand_name('key')
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          key_name=key_name)

    @attr(type=['negative', 'gate'])
    def test_create_server_metadata_exceeds_length_limit(self):
        # Pass really long metadata while creating a server

        metadata = {'a': 'b' * 260}
        self.assertRaises(exceptions.OverLimit,
                          self.create_server,
                          meta=metadata)

    @attr(type=['negative', 'gate'])
    def test_update_name_of_non_existent_server(self):
        # Update name of a non-existent server

        server_name = rand_name('server')
        new_name = rand_name('server') + '_updated'

        self.assertRaises(exceptions.NotFound, self.client.update_server,
                          server_name, name=new_name)

    @attr(type=['negative', 'gate'])
    def test_update_server_set_empty_name(self):
        # Update name of the server to an empty string

        server_name = rand_name('server')
        new_name = ''

        self.assertRaises(exceptions.BadRequest, self.client.update_server,
                          server_name, name=new_name)

    @attr(type=['negative', 'gate'])
    def test_update_server_of_another_tenant(self):
        # Update name of a server that belongs to another tenant

        new_name = self.server_id + '_new'
        self.assertRaises(exceptions.NotFound,
                          self.alt_client.update_server, self.server_id,
                          name=new_name)

    @attr(type=['negative', 'gate'])
    def test_update_server_name_length_exceeds_256(self):
        # Update name of server exceed the name length limit

        new_name = 'a' * 256
        self.assertRaises(exceptions.BadRequest,
                          self.client.update_server,
                          self.server_id,
                          name=new_name)

    @attr(type=['negative', 'gate'])
    def test_delete_non_existent_server(self):
        # Delete a non existent server

        self.assertRaises(exceptions.NotFound, self.client.delete_server,
                          '999erra43')

    @attr(type=['negative', 'gate'])
    def test_delete_a_server_of_another_tenant(self):
        # Delete a server that belongs to another tenant
        self.assertRaises(exceptions.NotFound,
                          self.alt_client.delete_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_delete_server_pass_negative_id(self):
        # Pass an invalid string parameter to delete server

        self.assertRaises(exceptions.NotFound, self.client.delete_server, -1)

    @attr(type=['negative', 'gate'])
    def test_delete_server_pass_id_exceeding_length_limit(self):
        # Pass a server ID that exceeds length limit to delete server

        self.assertRaises(exceptions.NotFound, self.client.delete_server,
                          sys.maxint + 1)

    @attr(type=['negative', 'gate'])
    def test_create_with_nonexistent_security_group(self):
        # Create a server with a nonexistent security group

        security_groups = [{'name': 'does_not_exist'}]
        self.assertRaises(exceptions.BadRequest,
                          self.create_server,
                          security_groups=security_groups)

    @attr(type=['negative', 'gate'])
    def test_get_non_existent_server(self):
        # Get a non existent server details

        self.assertRaises(exceptions.NotFound, self.client.get_server,
                          '999erra43')

    @attr(type=['negative', 'gate'])
    def test_stop_non_existent_server(self):
        # Stop a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.servers_client.stop,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_pause_non_existent_server(self):
        # pause a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.pause_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_unpause_non_existent_server(self):
        # unpause a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.unpause_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_unpause_server_invalid_state(self):
        # unpause an active server.
        self.assertRaises(exceptions.Duplicate,
                          self.client.unpause_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_suspend_non_existent_server(self):
        # suspend a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.suspend_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_suspend_server_invalid_state(self):
        # suspend a suspended server.
        resp, _ = self.client.suspend_server(self.server_id)
        self.addCleanup(self.client.resume_server,
                        self.server_id)
        self.assertEqual(202, resp.status)
        self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
        self.assertRaises(exceptions.Duplicate,
                          self.client.suspend_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_resume_non_existent_server(self):
        # resume a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound, self.client.resume_server,
                          nonexistent_server)

    @attr(type=['negative', 'gate'])
    def test_resume_server_invalid_state(self):
        # resume an active server.
        self.assertRaises(exceptions.Duplicate,
                          self.client.resume_server,
                          self.server_id)

    @attr(type=['negative', 'gate'])
    def test_get_console_output_of_non_existent_server(self):
        # get the console output for a non existent server
        nonexistent_server = str(uuid.uuid4())
        self.assertRaises(exceptions.NotFound,
                          self.client.get_console_output,
                          nonexistent_server, 10)

class ServersNegativeTestXML(ServersNegativeTestJSON):
    _interface = 'xml'
<|endoftext|>