<commit_before>import collections
import select

from greenhouse._state import state

SHORT_TIMEOUT = 0.0001

class Epoll(object):
    "a greenhouse poller utilizing the 2.6+ stdlib's epoll support"
    INMASK = getattr(select, 'EPOLLIN', None)
    OUTMASK = getattr(select, 'EPOLLOUT', None)
    ERRMASK = getattr(select, 'EPOLLERR', None)
    def __init__(self):
        self._poller = select.epoll()

    def register(self, fd, eventmask=None):
        fd = isinstance(fd, int) and fd or fd.fileno()
        if eventmask is None:
            return self._poller.register(fd)
        return self._poller.register(fd, eventmask)

    def unregister(self, fd):
        fd = isinstance(fd, int) and fd or fd.fileno()
        self._poller.unregister(fd)

    def poll(self, timeout=SHORT_TIMEOUT):
        return self._poller.poll(timeout)

class Poll(object):
    "a greenhouse poller using the poll system call''"
    INMASK = getattr(select, 'POLLIN', None)
    OUTMASK = getattr(select, 'POLLOUT', None)
    ERRMASK = getattr(select, 'POLLERR', None)

    def __init__(self):
        self._poller = select.poll()

    def register(self, fd, eventmask=None):
        fd = isinstance(fd, int) and fd or fd.fileno()
        if event is None:
            return self._poller.register(fd)
        return self._poller.register(fd, eventmask)

    def unregister(self, fd):
        fd = isinstance(fd, int) and fd or fd.fileno()
        self._poller.unregister(fd)

    def poll(self, timeout=SHORT_TIMEOUT):
        return self._poller.poll(timeout)

class Select(object):
    "a greenhouse poller using the select system call"
    INMASK = 1
    OUTMASK = 2
    ERRMASK = 4

    def __init__(self):
        self._fds = {}

    def register(self, fd, eventmask=None):
        fd = isinstance(fd, int) and fd or fd.fileno()
        if eventmask is None:
            eventmask = self.SELECTIN | self.SELECTOUT | self.SELECTERR
        isnew = fd not in self._fds
        self._fds[fd] = eventmask
        return isnew

    def unregister(self, fd):
        fd = isinstance(fd, int) and fd or fd.fileno()
        del self._fds[fd]

    def poll(self, timeout=SHORT_TIMEOUT):
        rlist, wlist, xlist = [], [], []
        for fd, eventmask in self._fds.iteritems():
            if eventmask & self.INMASK:
                rlist.append(fd)
            if eventmask & self.OUTMASK:
                wlist.append(fd)
            if eventmask & self.ERRMASK:
                xlist.append(fd)
        rlist, wlist, xlist = select.select(rlist, wlist, xlist, timeout)
        events = collections.defaultdict(int)
        for fd in rlist:
            events[fd] |= self.INMASK
        for fd in wlist:
            events[fd] |= self.OUTMASK
        for fd in xlist:
            events[fd] |= self.ERRMASK
        return events.items()

def best():
    if hasattr(select, 'epoll'):
        return Epoll()
    elif hasattr(select, 'poll'):
        return Poll()
    return Select()

def set(poller=None):
    state.poller = poller or best()
set()
<commit_msg>bugfix, NameError with select.poll interface<commit_after>import collections
import select

from greenhouse._state import state

SHORT_TIMEOUT = 0.0001

class Epoll(object):
    "a greenhouse poller utilizing the 2.6+ stdlib's epoll support"
    INMASK = getattr(select, 'EPOLLIN', None)
    OUTMASK = getattr(select, 'EPOLLOUT', None)
    ERRMASK = getattr(select, 'EPOLLERR', None)
    def __init__(self):
        self._poller = select.epoll()

    def register(self, fd, eventmask=None):
        fd = isinstance(fd, int) and fd or fd.fileno()
        if eventmask is None:
            return self._poller.register(fd)
        return self._poller.register(fd, eventmask)

    def unregister(self, fd):
        fd = isinstance(fd, int) and fd or fd.fileno()
        self._poller.unregister(fd)

    def poll(self, timeout=SHORT_TIMEOUT):
        return self._poller.poll(timeout)

class Poll(object):
    "a greenhouse poller using the poll system call''"
    INMASK = getattr(select, 'POLLIN', None)
    OUTMASK = getattr(select, 'POLLOUT', None)
    ERRMASK = getattr(select, 'POLLERR', None)

    def __init__(self):
        self._poller = select.poll()

    def register(self, fd, eventmask=None):
        fd = isinstance(fd, int) and fd or fd.fileno()
        if eventmask is None:
            return self._poller.register(fd)
        return self._poller.register(fd, eventmask)

    def unregister(self, fd):
        fd = isinstance(fd, int) and fd or fd.fileno()
        self._poller.unregister(fd)

    def poll(self, timeout=SHORT_TIMEOUT):
        return self._poller.poll(timeout)

class Select(object):
    "a greenhouse poller using the select system call"
    INMASK = 1
    OUTMASK = 2
    ERRMASK = 4

    def __init__(self):
        self._fds = {}

    def register(self, fd, eventmask=None):
        fd = isinstance(fd, int) and fd or fd.fileno()
        if eventmask is None:
            eventmask = self.SELECTIN | self.SELECTOUT | self.SELECTERR
        isnew = fd not in self._fds
        self._fds[fd] = eventmask
        return isnew

    def unregister(self, fd):
        fd = isinstance(fd, int) and fd or fd.fileno()
        del self._fds[fd]

    def poll(self, timeout=SHORT_TIMEOUT):
        rlist, wlist, xlist = [], [], []
        for fd, eventmask in self._fds.iteritems():
            if eventmask & self.INMASK:
                rlist.append(fd)
            if eventmask & self.OUTMASK:
                wlist.append(fd)
            if eventmask & self.ERRMASK:
                xlist.append(fd)
        rlist, wlist, xlist = select.select(rlist, wlist, xlist, timeout)
        events = collections.defaultdict(int)
        for fd in rlist:
            events[fd] |= self.INMASK
        for fd in wlist:
            events[fd] |= self.OUTMASK
        for fd in xlist:
            events[fd] |= self.ERRMASK
        return events.items()

def best():
    if hasattr(select, 'epoll'):
        return Epoll()
    elif hasattr(select, 'poll'):
        return Poll()
    return Select()

def set(poller=None):
    state.poller = poller or best()
set()
<|endoftext|>


<commit_before>from __future__ import absolute_import, division, print_function

__version__ = "2.5.6"
dependencies = ["restnavigator==1.0.1",
                "requests[socks]==2.25.1",
                "configparser==3.5.0",
                "certifi==2020.12.5"]
<commit_msg>update package version<commit_after>from __future__ import absolute_import, division, print_function

__version__ = "2.5.7"
dependencies = ["restnavigator==1.0.1",
                "requests[socks]==2.25.1",
                "configparser==3.5.0",
                "certifi==2020.12.5"]
<|endoftext|>


<commit_before>"""
The PortStatCollector collects metrics about ports listed in config file.

##### Dependencies

* psutil

"""

from collections import defaultdict

import psutil
import diamond.collector

class PortStatCollector(diamond.collector.Collector):

    def __init__(self, *args, **kwargs):
        super(PortStatCollector, self).__init__(*args, **kwargs)
        self.ports = {}
        for port_name, cfg in self.config['port'].items():
            port_cfg = {}
            for key in ('number',):
                port_cfg[key] = cfg.get(key, [])
            self.ports[port_name] = port_cfg

    def get_default_config_help(self):
        config_help = super(PortStatCollector, self).get_default_config_help()
        config_help.update({
        })
        return config_help

    def get_default_config(self):
        config = super(PortStatCollector, self).get_default_config()
        config.update({
            'path': 'port',
            'port': {},
        })
        return config

    @staticmethod
    def get_port_stats(port):
        """
        Iterate over connections and count states for specified port
        :param port: port for which stats are collected
        :return: Counter with port states
        """
        cnts = defaultdict(int)
        for c in psutil.net_connections():
            c_port = c.laddr[1]
            if c_port != port:
                continue
            status = c.status.lower()
            cnts[status] += 1
        return cnts

    def collect(self):
        """
        Overrides the Collector.collect method
        """

        for port_name, port_cfg in self.ports.iteritems():
            port = int(port_cfg['number'])
            stats = PortStatCollector.get_port_stats(port)

            for stat_name, stat_value in stats.iteritems():
                metric_name = '%s.%s' % (port_name, stat_name)
                self.publish(metric_name, stat_value)
<commit_msg>Fix up portstat collector so its tests don't fail<commit_after>"""
The PortStatCollector collects metrics about ports listed in config file.

##### Dependencies

* psutil

"""

from collections import defaultdict
import diamond.collector

try:
    import psutil
except ImportError:
    psutil = None

def get_port_stats(port):
    """
    Iterate over connections and count states for specified port
    :param port: port for which stats are collected
    :return: Counter with port states
    """
    cnts = defaultdict(int)
    for c in psutil.net_connections():
        c_port = c.laddr[1]
        if c_port != port:
            continue
        status = c.status.lower()
        cnts[status] += 1
    return cnts

class PortStatCollector(diamond.collector.Collector):

    def __init__(self, *args, **kwargs):
        super(PortStatCollector, self).__init__(*args, **kwargs)
        self.ports = {}
        for port_name, cfg in self.config['port'].items():
            port_cfg = {}
            for key in ('number',):
                port_cfg[key] = cfg.get(key, [])
            self.ports[port_name] = port_cfg

    def get_default_config_help(self):
        config_help = super(PortStatCollector, self).get_default_config_help()
        config_help.update({
        })
        return config_help

    def get_default_config(self):
        config = super(PortStatCollector, self).get_default_config()
        config.update({
            'path': 'port',
            'port': {},
        })
        return config

    def collect(self):
        """
        Overrides the Collector.collect method
        """

        if psutil is None:
            self.log.error('Unable to import module psutil')
            return {}

        for port_name, port_cfg in self.ports.iteritems():
            port = int(port_cfg['number'])
            stats = PortStatCollector.get_port_stats(port)

            for stat_name, stat_value in stats.iteritems():
                metric_name = '%s.%s' % (port_name, stat_name)
                self.publish(metric_name, stat_value)
<|endoftext|>


<commit_before>from ..utils import *

##
# Hero Powers

# Pile On!
class BRMA01_2:
	activate = (
		Summon(CONTROLLER, RANDOM(CONTROLLER_DECK + MINION)),
		Summon(OPPONENT, RANDOM(OPPONENT_DECK + MINION))
	)

class BRMA01_2H:
	activate = (
		Summon(CONTROLLER, RANDOM(CONTROLLER_DECK + MINION) * 2),
		Summon(OPPONENT, RANDOM(OPPONENT_DECK + MINION))
	)

# Jeering Crowd
class BRMA02_2:
	activate = Summon(CONTROLLER, "BRMA02_2t")

class BRMA02_2H:
	activate = Summon(CONTROLLER, "BRMA02_2t")

# Power of the Firelord
class BRMA03_2:
	activate = Hit(TARGET, 2)

# Magma Pulse
class BRMA04_2:
	activate = Hit(ALL_MINIONS, 1)

# The Majordomo
class BRMA06_2:
	activate = Summon(CONTROLLER, "BRMA06_4")

class BRMA06_2H:
	activate = Summon(CONTROLLER, "BRMA06_4H")

# ME SMASH
class BRMA07_2:
	activate = Destroy(RANDOM(ENEMY_MINIONS + DAMAGED))

class BRMA07_2H:
	activate = Destroy(RANDOM_ENEMY_MINION)

# The Rookery
class BRMA10_3:
	activate = Buff(ALL_MINIONS + ID("BRMA10_4"), "BRMA10_3e"), Summon(CONTROLLER, "BRMA10_4")

# The Rookery
class BRMA10_3H:
	activate = Buff(ALL_MINIONS + ID("BRMA10_4"), "BRMA10_3e"), Summon(CONTROLLER, "BRMA10_4")

# Essence of the Red
class BRMA11_2:
	activate = Draw(ALL_PLAYERS) * 2

class BRMA11_2H:
	activate = Draw(ALL_PLAYERS) * 3, GainMana(CONTROLLER, 1)

# Mutation (Unused)
class BRMA12_10:
	activate = Discard(RANDOM(CONTROLLER_HAND))

##
# Minions

# Son of the Flame
class BRMA13_5:
	play = Hit(TARGET, 6)

##
# Spells

# Flameheart
class BRMA_01:
	play = Draw(CONTROLLER) * 2, GainArmor(FRIENDLY_HERO, 4)

# Get 'em!
class BRMA01_4:
	play = Summon(CONTROLLER, "BRMA01_4t") * 4

# TIME FOR SMASH
class BRMA07_3:
	play = Hit(RANDOM_ENEMY_MINION, 5), GainArmor(FRIENDLY_HERO, 5)

# Drakkisath's Command
class BRMA08_3:
	play = Destroy(TARGET), GainArmor(FRIENDLY_HERO, 10)

# The True Warchief
class BRMA09_6:
	play = Destroy(TARGET)

# Rock Out
class BRMA04_4:
	play = Summon(CONTROLLER, "BRMA04_3") * 3

class BRMA04_4H:
	play = Summon(CONTROLLER, "BRMA04_3H") * 3

# Burning Adrenaline
class BRMA11_3:
	play = Hit(ENEMY_HERO, 2)

##
# Weapons

# Razorgore's Claws (Unused)
class BRMA10_6:
	events = Death(MINION + ID("BRMA10_4")).on(Buff(SELF, "BRMA10_6e"))
<commit_msg>Implement more Blackrock Mountain Adventure cards<commit_after>from ..utils import *

##
# Hero Powers

# Pile On!
class BRMA01_2:
	activate = (
		Summon(CONTROLLER, RANDOM(CONTROLLER_DECK + MINION)),
		Summon(OPPONENT, RANDOM(OPPONENT_DECK + MINION))
	)

class BRMA01_2H:
	activate = (
		Summon(CONTROLLER, RANDOM(CONTROLLER_DECK + MINION) * 2),
		Summon(OPPONENT, RANDOM(OPPONENT_DECK + MINION))
	)

# Jeering Crowd
class BRMA02_2:
	activate = Summon(CONTROLLER, "BRMA02_2t")

class BRMA02_2H:
	activate = Summon(CONTROLLER, "BRMA02_2t")

# Power of the Firelord
class BRMA03_2:
	activate = Hit(TARGET, 2)

# Magma Pulse
class BRMA04_2:
	activate = Hit(ALL_MINIONS, 1)

# The Majordomo
class BRMA06_2:
	activate = Summon(CONTROLLER, "BRMA06_4")

class BRMA06_2H:
	activate = Summon(CONTROLLER, "BRMA06_4H")

# ME SMASH
class BRMA07_2:
	activate = Destroy(RANDOM(ENEMY_MINIONS + DAMAGED))

class BRMA07_2H:
	activate = Destroy(RANDOM_ENEMY_MINION)

# The Rookery
class BRMA10_3:
	activate = Buff(ALL_MINIONS + ID("BRMA10_4"), "BRMA10_3e"), Summon(CONTROLLER, "BRMA10_4")

# The Rookery
class BRMA10_3H:
	activate = Buff(ALL_MINIONS + ID("BRMA10_4"), "BRMA10_3e"), Summon(CONTROLLER, "BRMA10_4")

# Essence of the Red
class BRMA11_2:
	activate = Draw(ALL_PLAYERS) * 2

class BRMA11_2H:
	activate = Draw(ALL_PLAYERS) * 3, GainMana(CONTROLLER, 1)

# Echolocate
class BRMA16_2:
	activate = Summon(CONTROLLER, "BRMA16_5")

class BRMA16_2H:
	activate = Summon(CONTROLLER, "BRMA16_5")

# Mutation (Unused)
class BRMA12_10:
	activate = Discard(RANDOM(CONTROLLER_HAND))

# Bone Minions
class BRMA17_5:
	activate = Summon(CONTROLLER, "BRMA17_6") * 2

class BRMA17_5H:
	activate = Summon(CONTROLLER, "BRMA17_6H") * 2

##
# Minions

# Son of the Flame
class BRMA13_5:
	play = Hit(TARGET, 6)

##
# Spells

# Flameheart
class BRMA_01:
	play = Draw(CONTROLLER) * 2, GainArmor(FRIENDLY_HERO, 4)

# Get 'em!
class BRMA01_4:
	play = Summon(CONTROLLER, "BRMA01_4t") * 4

# TIME FOR SMASH
class BRMA07_3:
	play = Hit(RANDOM_ENEMY_MINION, 5), GainArmor(FRIENDLY_HERO, 5)

# Drakkisath's Command
class BRMA08_3:
	play = Destroy(TARGET), GainArmor(FRIENDLY_HERO, 10)

# The True Warchief
class BRMA09_6:
	play = Destroy(TARGET)

# Rock Out
class BRMA04_4:
	play = Summon(CONTROLLER, "BRMA04_3") * 3

class BRMA04_4H:
	play = Summon(CONTROLLER, "BRMA04_3H") * 3

# Burning Adrenaline
class BRMA11_3:
	play = Hit(ENEMY_HERO, 2)

# DIE, INSECT!
class BRMA13_8:
	play = Hit(RANDOM_ENEMY_CHARACTER, 8)

# Release the Aberrations!
class BRMA15_3:
	play = Summon(CONTROLLER, "BRMA15_4") * 3

# Sonic Breath
class BRMA16_3:
	play = Hit(TARGET, 3), Buff(FRIENDLY_WEAPON, "BRMA16_3e")

# Reverberating Gong
class BRMA16_4:
	play = Destroy(ENEMY_WEAPON)

# LAVA!
class BRMA17_4:
	play = Hit(ALL_MINIONS, 2)

##
# Weapons

# Razorgore's Claws (Unused)
class BRMA10_6:
	events = Death(MINION + ID("BRMA10_4")).on(Buff(SELF, "BRMA10_6e"))

# Dragonteeth
class BRMA16_5:
	events = Play(OPPONENT).on(Buff(SELF, "BRMA16_5e"))
<|endoftext|>


<commit_before>"""
URLConf for Django user registration and authentication.

Recommended usage is a call to ``include()`` in your project's root
URLConf to include this URLConf for any URL beginning with
``/accounts/``.

"""

from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
from django.contrib.auth import views as auth_views

from registration.views import activate, register

urlpatterns = patterns('',
                       # Activation keys get matched by \w+ instead of the more specific
                       # [a-fA-F0-9]{40} because a bad activation key should still get to the view;
                       # that way it can return a sensible "invalid key" message instead of a
                       # confusing 404.
                       url(r'^activate/(?P<activation_key>\w+)/$',
                           activate,
                           name='registration_activate'),
                       url(r'^login/$',
                           auth_views.login,
                           {'template_name': 'registration/login.html'},
                           name='auth_login'),
                       url(r'^logout/$',
                           auth_views.logout,
                           {'template_name': 'registration/logout.html'},
                           name='auth_logout'),
                       url(r'^password/change/$',
                           auth_views.password_change,
                           name='auth_password_change'),
                       url(r'^password/change/done/$',
                           auth_views.password_change_done,
                           name='auth_password_change_done'),
                       url(r'^password/reset/$',
                           auth_views.password_reset,
                           name='auth_password_reset'),
                       url(r'^password/reset/done/$',
                           auth_views.password_reset_done,
                           name='auth_password_reset_done'),
                       url(r'^register/$',
                           register,
                           name='registration_register'),
                       url(r'^register/complete/$',
                           direct_to_template,
                           {'template': 'registration/registration_complete.html'},
                           name='registration_complete'),
                       )
<commit_msg>Some PEP 8 cleanup<commit_after>"""
URLConf for Django user registration and authentication.

Recommended usage is a call to ``include()`` in your project's root
URLConf to include this URLConf for any URL beginning with
``/accounts/``.

"""

from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
from django.contrib.auth import views as auth_views

from registration.views import activate
from registration.views import register

urlpatterns = patterns('',
                       # Activation keys get matched by \w+ instead of the more specific
                       # [a-fA-F0-9]{40} because a bad activation key should still get to the view;
                       # that way it can return a sensible "invalid key" message instead of a
                       # confusing 404.
                       url(r'^activate/(?P<activation_key>\w+)/$',
                           activate,
                           name='registration_activate'),
                       url(r'^login/$',
                           auth_views.login,
                           {'template_name': 'registration/login.html'},
                           name='auth_login'),
                       url(r'^logout/$',
                           auth_views.logout,
                           {'template_name': 'registration/logout.html'},
                           name='auth_logout'),
                       url(r'^password/change/$',
                           auth_views.password_change,
                           name='auth_password_change'),
                       url(r'^password/change/done/$',
                           auth_views.password_change_done,
                           name='auth_password_change_done'),
                       url(r'^password/reset/$',
                           auth_views.password_reset,
                           name='auth_password_reset'),
                       url(r'^password/reset/done/$',
                           auth_views.password_reset_done,
                           name='auth_password_reset_done'),
                       url(r'^register/$',
                           register,
                           name='registration_register'),
                       url(r'^register/complete/$',
                           direct_to_template,
                           {'template': 'registration/registration_complete.html'},
                           name='registration_complete'),
                       )
<|endoftext|>


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

from phasortoolbox import PDC,Client
import matplotlib.pyplot as plt
import numpy as np
import logging
logging.basicConfig(level=logging.DEBUG)

class FreqMeter(object):
    def __init__(self):
        x = np.linspace(-10.0, 0.0, num=300, endpoint=False)
        y = [60.0]*300

        plt.ion()
        self.fig = plt.figure()
        self.ax1 = self.fig.add_subplot(211)
        self.line1, = self.ax1.plot(x, y)
        plt.title('PMU1 Frequency Plot')
        plt.xlabel('Time (s)')
        plt.ylabel('Freq (Hz)')
        self.ax2 = self.fig.add_subplot(212)
        self.line2, = self.ax2.plot(x, y)
        plt.title('PMU2 Frequency Plot')
        plt.xlabel('Time (s)')
        plt.ylabel('Freq (Hz)')
        plt.tight_layout()

    def update_plot(self, synchrophasors):
        y_data = [[],[]]
        for synchrophasor in synchrophasors:
            for i, msg in enumerate(synchrophasor):
                y_data[i].append(msg.data.pmu_data[0].freq)

        self.line1.set_ydata(y_data[0])
        self.line2.set_ydata(y_data[1])
        self.ax1.set_ylim(min(y_data[0]),max(y_data[0]))
        self.ax2.set_ylim(min(y_data[1]),max(y_data[1]))
        self.fig.canvas.draw()
        self.fig.canvas.flush_events()

if __name__ == '__main__':
    pmu_client1 = Client(remote_ip='10.0.0.1', remote_port=4722, idcode=1, mode='TCP')
    pmu_client2 = Client(remote_ip='10.0.0.2', remote_port=4722, idcode=2, mode='TCP')

    fm = FreqMeter()
    pdc = PDC(clients=[pmu_client1,pmu_client2],history=300)
    pdc.callback = fm.update_plot

    pdc.run()
<commit_msg>Update examples<commit_after>#!/usr/bin/env python3

from phasortoolbox import PDC,Client
import matplotlib.pyplot as plt
import numpy as np
import gc
import logging
logging.basicConfig(level=logging.DEBUG)

class FreqMeter(object):
    def __init__(self):
        x = np.linspace(-10.0, 0.0, num=300, endpoint=False)
        y = [60.0]*300

        plt.ion()
        self.fig = plt.figure()
        self.ax1 = self.fig.add_subplot(211)
        self.line1, = self.ax1.plot(x, y)
        plt.title('PMU1 Frequency Plot')
        plt.xlabel('Time (s)')
        plt.ylabel('Freq (Hz)')
        self.ax2 = self.fig.add_subplot(212)
        self.line2, = self.ax2.plot(x, y)
        plt.title('PMU2 Frequency Plot')
        plt.xlabel('Time (s)')
        plt.ylabel('Freq (Hz)')
        plt.tight_layout()

    def update_plot(self, synchrophasors):
        y_data = [[],[]]
        for synchrophasor in synchrophasors:
            for i, msg in enumerate(synchrophasor):
                y_data[i].append(msg.data.pmu_data[0].freq)

        self.line1.set_ydata(y_data[0])
        self.line2.set_ydata(y_data[1])
        self.ax1.set_ylim(min(y_data[0]),max(y_data[0]))
        self.ax2.set_ylim(min(y_data[1]),max(y_data[1]))
        self.fig.canvas.draw()
        self.fig.canvas.flush_events()
        del(synchrophasors)
        gc.collect()

if __name__ == '__main__':
    pmu_client1 = Client(remote_ip='10.0.0.1', remote_port=4722, idcode=1, mode='TCP')
    pmu_client2 = Client(remote_ip='10.0.0.2', remote_port=4722, idcode=2, mode='TCP')

    fm = FreqMeter()
    pdc = PDC(clients=[pmu_client1,pmu_client2],history=300)
    pdc.callback = fm.update_plot

    pdc.run()
<|endoftext|>


<commit_before> #!/usr/bin/env python
# encoding: utf-8
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 sys
import os
import json

from gcecloudstack import app
from flask import jsonify, Response, request, url_for

from gcecloudstack.services import requester
from gcecloudstack.controllers import zones
from gcecloudstack import authentication

def _cloudstack_machinetype_to_gcutil(cloudstack_response):
    return ({
        'name': cloudstack_response['name'],
        'description': cloudstack_response['displaytext'],
        'id': cloudstack_response['id'],
        'creationTimestamp': cloudstack_response['created'],
        'guestCpus': cloudstack_response['cpunumber'],
        'memoryMb': cloudstack_response['memory']
    })

@app.route('/' + app.config['PATH'] + '<projectid>/aggregated/machineTypes')
@authentication.required
def aggregatedlist(projectid, authorization):
    command = 'listServiceOfferings'
    args = {}
    cloudstack_response = requester.make_request(
        command,
        args,
        authorization.jsessionid,
        authorization.sessionkey
    )

    cloudstack_responses = json.loads(cloudstack_response)

    machine_types = []
    if cloudstack_responses['listserviceofferingsresponse']:
        for cloudstack_response in cloudstack_responses[
                'listserviceofferingsresponse']['serviceoffering']:
            machine_types.append(_cloudstack_machinetype_to_gcutil(cloudstack_response))

    populated_response = {
        'kind': "compute#machineTypeAggregatedList",
        'id': 'blah',
        'selfLink': '',
        'items': {
            'Dummy Zone': {
                'machineTypes': machine_types
            },
            'Another Zone': {
                'machineTypes': machine_types
            }
        }
    }

    res = jsonify(populated_response)
    res.status_code = 200
    return res

@app.route('/' + app.config['PATH'] +
           '<projectid>/zones/<zone>/machineTypes/<machinetype>')
@authentication.required
def getmachinetype(projectid, authorization, zone, machinetype):
    command = 'listServiceOfferings'
    args = {
        'keyword': machinetype
    }
    cloudstack_response = requester.make_request(
        command,
        args,
        authorization.jsessionid,
        authorization.sessionkey
    )
    cloudstack_responses = json.loads(cloudstack_response)

    if cloudstack_responses['listserviceofferingsresponse']:
        cloudstack_response = cloudstack_responses[
            'listserviceofferingsresponse']['serviceoffering'][0]
        machine_type = _cloudstack_machinetype_to_gcutil(cloudstack_response)
        res = jsonify(machine_type)
        res.status_code = 200

    else:
        res = jsonify({
            'error': {
                'errors': [
                    {
                        "domain": "global",
                        "reason": "notFound",
                        "message": 'The resource \'projects/' + projectid + '/zones/' + zone + '/machineTypes/' + machinetype + '\' was not found'
                    }
                ],
                'code': 404,
                "message": 'The resource \'projects/' + projectid + '/zones/' + zone + '/machineTypes/' + machinetype + '\' was not found'
            }
        })
        res.status_code = 404

    return res

@app.route('/' + app.config['PATH'] + '<projectid>/zones/<zone>/machineTypes')
@authentication.required
def listmachinetype(projectid, authorization,  zone):
    command = 'listServiceOfferings'
    args = {}
    cloudstack_response = requester.make_request(
        command,
        args,
        authorization.jsessionid,
        authorization.sessionkey
    )

    cloudstack_responses = json.loads(cloudstack_response)

    machine_types = []
    if cloudstack_responses['listserviceofferingsresponse']:
        for cloudstack_response in cloudstack_responses[
                'listserviceofferingsresponse']['serviceoffering']:
            machine_types.append(_cloudstack_machinetype_to_gcutil(cloudstack_response))

    populated_response = {
        'kind': "compute#machineTypeList",
        'id': 'blah',
        'selfLink': '',
        'items': machine_types
    }

    res = jsonify(populated_response)
    res.status_code = 200
    return res
<commit_msg>Remove unused imports<commit_after> #!/usr/bin/env python
# encoding: utf-8
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

from gcecloudstack import app
from gcecloudstack import authentication
from gcecloudstack.services import requester
from flask import jsonify, request
import json

def _cloudstack_machinetype_to_gcutil(cloudstack_response):
    return ({
        'name': cloudstack_response['name'],
        'description': cloudstack_response['displaytext'],
        'id': cloudstack_response['id'],
        'creationTimestamp': cloudstack_response['created'],
        'guestCpus': cloudstack_response['cpunumber'],
        'memoryMb': cloudstack_response['memory']
    })

@app.route('/' + app.config['PATH'] + '<projectid>/aggregated/machineTypes')
@authentication.required
def aggregatedlist(projectid, authorization):
    command = 'listServiceOfferings'
    args = {}
    cloudstack_response = requester.make_request(
        command,
        args,
        authorization.jsessionid,
        authorization.sessionkey
    )

    cloudstack_responses = json.loads(cloudstack_response)

    machine_types = []
    if cloudstack_responses['listserviceofferingsresponse']:
        for cloudstack_response in cloudstack_responses[
                'listserviceofferingsresponse']['serviceoffering']:
            machine_types.append(_cloudstack_machinetype_to_gcutil(cloudstack_response))

    populated_response = {
        'kind': "compute#machineTypeAggregatedList",
        'id': 'blah',
        'selfLink': '',
        'items': {
            'Dummy Zone': {
                'machineTypes': machine_types
            },
            'Another Zone': {
                'machineTypes': machine_types
            }
        }
    }

    res = jsonify(populated_response)
    res.status_code = 200
    return res

@app.route('/' + app.config['PATH'] +
           '<projectid>/zones/<zone>/machineTypes/<machinetype>')
@authentication.required
def getmachinetype(projectid, authorization, zone, machinetype):
    command = 'listServiceOfferings'
    args = {
        'keyword': machinetype
    }
    cloudstack_response = requester.make_request(
        command,
        args,
        authorization.jsessionid,
        authorization.sessionkey
    )
    cloudstack_responses = json.loads(cloudstack_response)

    if cloudstack_responses['listserviceofferingsresponse']:
        cloudstack_response = cloudstack_responses[
            'listserviceofferingsresponse']['serviceoffering'][0]
        machine_type = _cloudstack_machinetype_to_gcutil(cloudstack_response)
        res = jsonify(machine_type)
        res.status_code = 200

    else:
        res = jsonify({
            'error': {
                'errors': [
                    {
                        "domain": "global",
                        "reason": "notFound",
                        "message": 'The resource \'projects/' + projectid + '/zones/' + zone + '/machineTypes/' + machinetype + '\' was not found'
                    }
                ],
                'code': 404,
                "message": 'The resource \'projects/' + projectid + '/zones/' + zone + '/machineTypes/' + machinetype + '\' was not found'
            }
        })
        res.status_code = 404

    return res

@app.route('/' + app.config['PATH'] + '<projectid>/zones/<zone>/machineTypes')
@authentication.required
def listmachinetype(projectid, authorization,  zone):
    command = 'listServiceOfferings'
    args = {}
    cloudstack_response = requester.make_request(
        command,
        args,
        authorization.jsessionid,
        authorization.sessionkey
    )

    cloudstack_responses = json.loads(cloudstack_response)

    machine_types = []
    if cloudstack_responses['listserviceofferingsresponse']:
        for cloudstack_response in cloudstack_responses[
                'listserviceofferingsresponse']['serviceoffering']:
            machine_types.append(_cloudstack_machinetype_to_gcutil(cloudstack_response))

    populated_response = {
        'kind': "compute#machineTypeList",
        'id': 'blah',
        'selfLink': '',
        'items': machine_types
    }

    res = jsonify(populated_response)
    res.status_code = 200
    return res
<|endoftext|>


<commit_before>
def get_uppercase():
    for c in range(26):
        yield chr(65 + c)

def get_lowercase():
    for c in range(26):
        yield chr(97 + c)

def get_uppercase_and_lowercase():
    """
    As of Python 3.3 you can use 'yield from' to yield values from
    other generators. You can use the following to print the uppercase
    and lowercase characters in the English alphabet:

    for c in get_uppercase_and_lowercase():
        print(c)
    """
    yield from get_uppercase()
    yield from get_lowercase()
<commit_msg>Move basic generators inside the example generator<commit_after>
def get_uppercase_and_lowercase():
    """
    As of Python 3.3 you can use 'yield from' to yield values from
    other generators. You can use the following to print the uppercase
    and lowercase characters in the English alphabet:

    for c in get_uppercase_and_lowercase():
        print(c)
    """
    def get_uppercase():
        for c in range(26):
            yield chr(65 + c)

    def get_lowercase():
        for c in range(26):
            yield chr(97 + c)

    yield from get_uppercase()
    yield from get_lowercase()
<|endoftext|>


<commit_before>'''
Created on Oct 13, 2016

Copyright 2016, Institute for Systems Biology.

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.

@author: michael
'''
import gzip
import pandas as pd

from bigquery_etl.extract.utils import convert_file_to_dataframe
from bigquery_etl.transform.tools import cleanup_dataframe
from bigquery_etl.extract.gcloud_wrapper import GcsConnector
from . import load
from util import flatten_map

def add_metadata(data_df, info, config):
    """Add metadata info to the dataframe
    """
    metadata_list = flatten_map(info, config['process_files']['data_table_mapping'])
    metadata = metadata_list[0]
    for next_metadata in metadata_list[1:]:
        metadata.update(next_metadata)

    data_df['FileID'] = metadata['FileID']
    data_df['AliquotsAliquotID'] = metadata['AliquotsAliquotID']
    data_df['AliquotsSubmitterID'] = metadata['AliquotsSubmitterID']
    data_df['SampleID'] = metadata['SampleID']
    data_df['SamplesSubmitterID'] = metadata['SamplesSubmitterID']
    data_df['CaseID'] = metadata['CaseID']
    data_df['CasesSubmitterID'] = metadata['CasesSubmitterID']
    data_df['ProgramName'] = metadata['ProgramName'].upper()
    data_df['ProjectID'] = metadata['ProjectID'].upper()
    data_df['SampleTypeLetterCode'] = config['sample_code2letter'][metadata['SamplesSubmitterID'][13:15]]
    data_df['DataType'] = metadata['DataType']
    data_df['ExperimentalStrategy'] = metadata['ExperimentalStrategy']

    return data_df

def process_per_sample_files(config, outputdir, associated_paths, types, info, log):
    dfs = [None] * 3
    curindex = 0
    for associated_path in associated_paths:
        # convert blob into dataframe
        log.info('\t\tcalling convert_file_to_dataframe() for %s' % (associated_path))
        dfs[curindex] = convert_file_to_dataframe(gzip.open(outputdir + associated_path), header=None)
        dfs[curindex].columns = ['Ensembl_versioned_gene_ID', types[curindex]]
        add_metadata(dfs[curindex], info, config)
        if 'HTSeq - Counts' == types[curindex]:
            dfs[curindex] = dfs[curindex].drop(dfs[curindex].index[[60483, 60484, 60485, 60486, 60487]])
        log.info('\t\tdone calling convert_file_to_dataframe() for %s' % (associated_path))
        curindex += 1

    merge_df = dfs[0]
    for df in dfs[1:]:
        merge_df = merge_df.merge(df, how='inner', on=[
                'Ensembl_versioned_gene_ID',
                'FileID',
                'AliquotsAliquotID',
                'AliquotsSubmitterID',
                'SampleID',
                'SamplesSubmitterID',
                'CaseID',
                'CasesSubmitterID',
                'ProgramName',
                'ProjectID',
                'SampleTypeLetterCode',
                'DataType',
                'ExperimentalStrategy'])

    log.info('merge workflow(%d):\n%s\n\t...\n%s' % (len(merge_df), merge_df.head(3), merge_df.tail(3)))
    return merge_df

def process_paths(config, outputdir, paths, file2info, log):
    types = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['analysis_types']
    idents = set()
    count = 0
    associated_paths = [None] * 3
    complete_df = None
    for path in paths:
        fields = path.split('/')
        info = file2info[fields[-2] + '/' + fields[-1]]
        type_index = types.index(info['analysis']['workflow_type'])
        if associated_paths[type_index]:
            raise ValueError('files in bad order, found two of the same type for %s:%s' % (associated_paths[type_index], fields[1]))
        idents.add(fields[1].split('.')[0])
        if 1 < len(idents):
            raise ValueError('files in bad order, found two different identifiers %s:%s' % (associated_paths[type_index], fields[1]))
        associated_paths[type_index] = path
        count += 1
        if 0 == count % 3:
            merge_df = process_per_sample_files(config, outputdir, associated_paths, types, info, log)
            if complete_df is None:
                complete_df = merge_df
            else:
                complete_df = pd.concat([complete_df, merge_df], ignore_index = True)
            idents = set()
            count = 0
            associated_paths = [None] * 3

    # add unversioned gene column
    complete_df['Ensembl_gene_ID'] = complete_df['Ensembl_versioned_gene_ID'].str.split('.').str[0]

    # clean-up dataframe
    log.info('\t\tcalling cleanup_dataframe() for %s' % (paths))
    complete_df = cleanup_dataframe(complete_df, log)
    log.info('\t\tdone calling cleanup_dataframe() for %s' % (paths))

    log.info('\tcomplete data frame(%d):\n%s\n%s' % (len(complete_df), complete_df.head(3), complete_df.tail(3)))
    return complete_df

def upload_batch_etl(config, outputdir, paths, file2info, project, data_type, log):
    log.info('\tstart upload_batch_etl() for gene expression quantification for %s and %s' % (project, data_type))
    try:
        if 0 != len(paths) % 3:
            raise RuntimeError('need to process the three RNA files per sample together.  adjust the configuration option \'download_files_per\' accordingly')
        complete_df = process_paths(config, outputdir, paths, file2info, log)
        gcs = GcsConnector(config['cloud_projects']['open'], config['buckets']['open'])
        keyname = config['buckets']['folders']['base_run_folder'] + 'etl/%s/%s/%s' % (project, data_type, paths[0].split('/')[1][:-3])
        log.info('start convert and upload %s to the cloud' % (keyname))
        gcs.convert_df_to_njson_and_upload(complete_df, keyname)
        log.info('finished convert and upload %s to the cloud' % (keyname))
    except Exception as e:
        log.exception('problem finishing the etl: %s' % (e))
        raise
    log.info('\tfinished upload_batch_etl() for gene expression quantification for %s and %s' % (project, data_type))

def finish_etl(config, project, data_type, log):
    log.info('\tstart finish_etl() for gene expression quantification')
    try:
        bq_dataset = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['bq_dataset']
        bq_table = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['bq_table']
        schema_file = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['schema_file']
        gcs_file_path = 'gs://' + config['buckets']['open'] + '/' + config['buckets']['folders']['base_run_folder'] + 'etl/%s/%s' % (project, data_type)
        write_disposition = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['write_disposition']
        load(config['cloud_projects']['open'], [bq_dataset], [bq_table], [schema_file], [gcs_file_path], [write_disposition], log)
    except Exception as e:
        log.exception('problem finishing the etl: %s' % (e))
        raise
    log.info('\tfinished finish_etl() for gene expression quantification')
<commit_msg>fixed import pronlem<commit_after>'''
Created on Oct 13, 2016

Copyright 2016, Institute for Systems Biology.

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.

@author: michael
'''
import gzip
import pandas as pd

from bigquery_etl.extract.utils import convert_file_to_dataframe
from bigquery_etl.transform.tools import cleanup_dataframe
from bigquery_etl.extract.gcloud_wrapper import GcsConnector
from . import load
from util import flatten_map

def add_metadata(data_df, info, config):
    """Add metadata info to the dataframe
    """
    metadata_list = flatten_map(info, config['process_files']['data_table_mapping'])
    metadata = metadata_list[0]
    for next_metadata in metadata_list[1:]:
        metadata.update(next_metadata)

    data_df['FileID'] = metadata['FileID']
    data_df['AliquotsAliquotID'] = metadata['AliquotsAliquotID']
    data_df['AliquotsSubmitterID'] = metadata['AliquotsSubmitterID']
    data_df['SampleID'] = metadata['SampleID']
    data_df['SamplesSubmitterID'] = metadata['SamplesSubmitterID']
    data_df['CaseID'] = metadata['CaseID']
    data_df['CasesSubmitterID'] = metadata['CasesSubmitterID']
    data_df['ProgramName'] = metadata['ProgramName'].upper()
    data_df['ProjectID'] = metadata['ProjectID'].upper()
    data_df['SampleTypeLetterCode'] = config['sample_code2letter'][metadata['SamplesSubmitterID'][13:15]]
    data_df['DataType'] = metadata['DataType']
    data_df['ExperimentalStrategy'] = metadata['ExperimentalStrategy']

    return data_df

def process_per_sample_files(config, outputdir, associated_paths, types, info, log):
    dfs = [None] * 3
    curindex = 0
    for associated_path in associated_paths:
        # convert blob into dataframe
        log.info('\t\tcalling convert_file_to_dataframe() for %s' % (associated_path))
        dfs[curindex] = convert_file_to_dataframe(gzip.open(outputdir + associated_path), header=None)
        dfs[curindex].columns = ['Ensembl_versioned_gene_ID', types[curindex]]
        add_metadata(dfs[curindex], info, config)
        if 'HTSeq - Counts' == types[curindex]:
            dfs[curindex] = dfs[curindex].drop(dfs[curindex].index[[60483, 60484, 60485, 60486, 60487]])
        log.info('\t\tdone calling convert_file_to_dataframe() for %s' % (associated_path))
        curindex += 1

    merge_df = dfs[0]
    for df in dfs[1:]:
        merge_df = merge_df.merge(df, how='inner', on=[
                'Ensembl_versioned_gene_ID',
                'FileID',
                'AliquotsAliquotID',
                'AliquotsSubmitterID',
                'SampleID',
                'SamplesSubmitterID',
                'CaseID',
                'CasesSubmitterID',
                'ProgramName',
                'ProjectID',
                'SampleTypeLetterCode',
                'DataType',
                'ExperimentalStrategy'])

    log.info('merge workflow(%d):\n%s\n\t...\n%s' % (len(merge_df), merge_df.head(3), merge_df.tail(3)))
    return merge_df

def process_paths(config, outputdir, paths, file2info, log):
    types = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['analysis_types']
    idents = set()
    count = 0
    associated_paths = [None] * 3
    complete_df = None
    for path in paths:
        fields = path.split('/')
        info = file2info[fields[-2] + '/' + fields[-1]]
        type_index = types.index(info['analysis']['workflow_type'])
        if associated_paths[type_index]:
            raise ValueError('files in bad order, found two of the same type for %s:%s' % (associated_paths[type_index], fields[1]))
        idents.add(fields[1].split('.')[0])
        if 1 < len(idents):
            raise ValueError('files in bad order, found two different identifiers %s:%s' % (associated_paths[type_index], fields[1]))
        associated_paths[type_index] = path
        count += 1
        if 0 == count % 3:
            merge_df = process_per_sample_files(config, outputdir, associated_paths, types, info, log)
            if complete_df is None:
                complete_df = merge_df
            else:
                complete_df = pd.concat([complete_df, merge_df], ignore_index = True)
            idents = set()
            count = 0
            associated_paths = [None] * 3

    # add unversioned gene column
    complete_df['Ensembl_gene_ID'] = complete_df['Ensembl_versioned_gene_ID'].str.split('.').str[0]

    # clean-up dataframe
    log.info('\t\tcalling cleanup_dataframe() for %s' % (paths))
    complete_df = cleanup_dataframe(complete_df, log)
    log.info('\t\tdone calling cleanup_dataframe() for %s' % (paths))

    log.info('\tcomplete data frame(%d):\n%s\n%s' % (len(complete_df), complete_df.head(3), complete_df.tail(3)))
    return complete_df

def upload_batch_etl(config, outputdir, paths, file2info, project, data_type, log):
    log.info('\tstart upload_batch_etl() for gene expression quantification for %s and %s' % (project, data_type))
    try:
        if 0 != len(paths) % 3:
            raise RuntimeError('need to process the three RNA files per sample together.  adjust the configuration option \'download_files_per\' accordingly')
        complete_df = process_paths(config, outputdir, paths, file2info, log)
        gcs = GcsConnector(config['cloud_projects']['open'], config['buckets']['open'])
        keyname = config['buckets']['folders']['base_run_folder'] + 'etl/%s/%s/%s' % (project, data_type, paths[0].split('/')[1][:-3])
        log.info('start convert and upload %s to the cloud' % (keyname))
        gcs.convert_df_to_njson_and_upload(complete_df, keyname)
        log.info('finished convert and upload %s to the cloud' % (keyname))
    except Exception as e:
        log.exception('problem finishing the etl: %s' % (e))
        raise
    log.info('\tfinished upload_batch_etl() for gene expression quantification for %s and %s' % (project, data_type))

def finish_etl(config, project, data_type, log):
    log.info('\tstart finish_etl() for gene expression quantification')
    try:
        bq_dataset = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['bq_dataset']
        bq_table = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['bq_table']
        schema_file = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['schema_file']
        gcs_file_path = 'gs://' + config['buckets']['open'] + '/' + config['buckets']['folders']['base_run_folder'] + 'etl/%s/%s' % (project, data_type)
        write_disposition = config['process_files']['datatype2bqscript']['Gene Expression Quantification']['write_disposition']
        load.load(config['cloud_projects']['open'], [bq_dataset], [bq_table], [schema_file], [gcs_file_path], [write_disposition], log)
    except Exception as e:
        log.exception('problem finishing the etl: %s' % (e))
        raise
    log.info('\tfinished finish_etl() for gene expression quantification')
<|endoftext|>


<commit_before>from django.db import models
from django import forms

from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailcore.fields import RichTextField, StreamField
from wagtail.wagtailadmin.edit_handlers import (FieldPanel,
                                                InlinePanel,
                                                MultiFieldPanel,
                                                PageChooserPanel,
                                                StreamFieldPanel)
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel
from wagtail.wagtailsnippets.models import register_snippet
from wagtail.wagtailsearch import index

from wagtail.wagtailcore.blocks import TextBlock, ChooserBlock, StructBlock, ListBlock, StreamBlock, FieldBlock, CharBlock, RichTextBlock, PageChooserBlock, RawHTMLBlock
from wagtail.wagtailimages.blocks import ImageChooserBlock
from wagtail.wagtaildocs.blocks import DocumentChooserBlock

from modelcluster.fields import ParentalKey

class ImageFormatChoiceBlock(FieldBlock):
    field = forms.ChoiceField(choices=(('left','Wrap left'),('right','Wrap right'),('mid','Mid width'),('full','Full width'),))

class HTMLAlignmentChoiceBlock(FieldBlock):
    field = forms.ChoiceField(choices=(('normal','Normal'),('full','Full width'),))

class ImageBlock(StructBlock):
    image = ImageChooserBlock()
    alignment = ImageFormatChoiceBlock()

class AlignedHTMLBlock(StructBlock):
    html = RawHTMLBlock()
    alignment = HTMLAlignmentChoiceBlock()

    class Meta:
        icon = "code"

class CommonStreamBlock(StreamBlock):
    h2 = CharBlock(icon="title", classname="title")
    h3 = CharBlock(icon="title", classname="title")
    h4 = CharBlock(icon="title", classname="title")
    intro = RichTextBlock(icon="pilcrow")
    paragraph = RichTextBlock(icon="pilcrow")
    aligned_image = ImageBlock(icon="image", label="Aligned image")
    aligned_html = AlignedHTMLBlock(icon="code", label='Raw HTML')
    document = DocumentChooserBlock(icon="doc-full-inverse")
    page = PageChooserBlock(icon="doc-full-inverse", label="Internal Link")

class LinkFields(models.Model):
    link_external = models.URLField("External link", blank=True)
    link_page = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        related_name='+'
    )
    link_document = models.ForeignKey(
        'wagtaildocs.Document',
        null=True,
        blank=True,
        related_name='+'
    )

    @property
    def link(self):
        if self.link_page:
            return self.link_page.url
        elif self.link_document:
            return self.link_document.url
        else:
            return self.link_external

    panels = [
        FieldPanel('link_external'),
        PageChooserPanel('link_page'),
        DocumentChooserPanel('link_document'),
    ]

    class Meta:
        abstract = True

class CarouselItem(LinkFields):
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    embed_url = models.URLField("Embed URL", blank=True)
    caption = models.CharField(max_length=255, blank=True)

    panels = [
        ImageChooserPanel('image'),
        FieldPanel('embed_url'),
        FieldPanel('caption'),
        MultiFieldPanel(LinkFields.panels, "Link"),
    ]

    class Meta:
        abstract = True

class RelatedLink(LinkFields):
    title = models.CharField(max_length=255, help_text="Link title")

    panels = [
        FieldPanel('title'),
        MultiFieldPanel(LinkFields.panels, "Link"),
    ]

    class Meta:
        abstract = True

# Home Page

class HomePageCarouselItem(Orderable, CarouselItem):
    page = ParentalKey('pages.HomePage', related_name='carousel_items')

class HomePageRelatedLink(Orderable, RelatedLink):
    page = ParentalKey('pages.HomePage', related_name='related_links')

class HomePage(Page):
    body = StreamField(CommonStreamBlock())
    search_fields = Page.search_fields + (
        index.SearchField('body'),
    )

    api_fields = ('body', )

    class Meta:
        verbose_name = "Website Page"

HomePage.content_panels = [
    FieldPanel('title', classname="full title"),
    StreamFieldPanel('body'),
    InlinePanel('carousel_items', label="Carousel items"),
    InlinePanel('related_links', label="Related links"),
]
<commit_msg>add carousel and related_links to api<commit_after>from django.db import models
from django import forms

from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailcore.fields import RichTextField, StreamField
from wagtail.wagtailadmin.edit_handlers import (FieldPanel,
                                                InlinePanel,
                                                MultiFieldPanel,
                                                PageChooserPanel,
                                                StreamFieldPanel)
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel
from wagtail.wagtailsnippets.models import register_snippet
from wagtail.wagtailsearch import index

from wagtail.wagtailcore.blocks import TextBlock, ChooserBlock, StructBlock, ListBlock, StreamBlock, FieldBlock, CharBlock, RichTextBlock, PageChooserBlock, RawHTMLBlock
from wagtail.wagtailimages.blocks import ImageChooserBlock
from wagtail.wagtaildocs.blocks import DocumentChooserBlock

from modelcluster.fields import ParentalKey

class ImageFormatChoiceBlock(FieldBlock):
    field = forms.ChoiceField(choices=(('left','Wrap left'),('right','Wrap right'),('mid','Mid width'),('full','Full width'),))

class HTMLAlignmentChoiceBlock(FieldBlock):
    field = forms.ChoiceField(choices=(('normal','Normal'),('full','Full width'),))

class ImageBlock(StructBlock):
    image = ImageChooserBlock()
    alignment = ImageFormatChoiceBlock()

class AlignedHTMLBlock(StructBlock):
    html = RawHTMLBlock()
    alignment = HTMLAlignmentChoiceBlock()

    class Meta:
        icon = "code"

class CommonStreamBlock(StreamBlock):
    h2 = CharBlock(icon="title", classname="title")
    h3 = CharBlock(icon="title", classname="title")
    h4 = CharBlock(icon="title", classname="title")
    intro = RichTextBlock(icon="pilcrow")
    paragraph = RichTextBlock(icon="pilcrow")
    aligned_image = ImageBlock(icon="image", label="Aligned image")
    aligned_html = AlignedHTMLBlock(icon="code", label='Raw HTML')
    document = DocumentChooserBlock(icon="doc-full-inverse")
    page = PageChooserBlock(icon="doc-full-inverse", label="Internal Link")

class LinkFields(models.Model):
    link_external = models.URLField("External link", blank=True)
    link_page = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        related_name='+'
    )
    link_document = models.ForeignKey(
        'wagtaildocs.Document',
        null=True,
        blank=True,
        related_name='+'
    )

    @property
    def link(self):
        if self.link_page:
            return self.link_page.url
        elif self.link_document:
            return self.link_document.url
        else:
            return self.link_external

    panels = [
        FieldPanel('link_external'),
        PageChooserPanel('link_page'),
        DocumentChooserPanel('link_document'),
    ]

    class Meta:
        abstract = True

class CarouselItem(LinkFields):
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    embed_url = models.URLField("Embed URL", blank=True)
    caption = models.CharField(max_length=255, blank=True)

    panels = [
        ImageChooserPanel('image'),
        FieldPanel('embed_url'),
        FieldPanel('caption'),
        MultiFieldPanel(LinkFields.panels, "Link"),
    ]

    class Meta:
        abstract = True

class RelatedLink(LinkFields):
    title = models.CharField(max_length=255, help_text="Link title")

    panels = [
        FieldPanel('title'),
        MultiFieldPanel(LinkFields.panels, "Link"),
    ]

    class Meta:
        abstract = True

# Home Page

class HomePageCarouselItem(Orderable, CarouselItem):
    page = ParentalKey('pages.HomePage', related_name='carousel_items')

class HomePageRelatedLink(Orderable, RelatedLink):
    page = ParentalKey('pages.HomePage', related_name='related_links')

class HomePage(Page):
    body = StreamField(CommonStreamBlock())
    search_fields = Page.search_fields + (
        index.SearchField('body'),
    )

    api_fields = ('body', 'carousel_items', 'related_links')

    class Meta:
        verbose_name = "Website Page"

HomePage.content_panels = [
    FieldPanel('title', classname="full title"),
    StreamFieldPanel('body'),
    InlinePanel('carousel_items', label="Carousel items"),
    InlinePanel('related_links', label="Related links"),
]
<|endoftext|>


<commit_before># Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""
Functional tests for ``flocker.node._deploy``.
"""

from uuid import uuid4

from pyrsistent import pmap

from twisted.trial.unittest import TestCase
from twisted.python.filepath import FilePath

from .. import P2PManifestationDeployer, ApplicationNodeDeployer, sequentially
from ...control._model import (
    Deployment, Application, DockerImage, Node, AttachedVolume, Link,
    Manifestation, Dataset, DeploymentState, NodeState)
from .._docker import DockerClient
from ..testtools import wait_for_unit_state, if_docker_configured
from ...testtools import (
    random_name, DockerImageBuilder, assertContainsAll, loop_until,
    run_process)
from ...volume.testtools import create_volume_service
from ...route import make_memory_network

class P2PNodeDeployer(object):
    """
    Combination of ZFS and container deployer.

    Should really be gotten rid of:
    https://clusterhq.atlassian.net/browse/FLOC-1732
    """
    def __init__(self, hostname, volume_service, docker_client=None,
                 network=None):
        self.manifestations_deployer = P2PManifestationDeployer(
            hostname, volume_service)
        self.applications_deployer = ApplicationNodeDeployer(
            hostname, docker_client, network)
        self.hostname = hostname
        self.volume_service = self.manifestations_deployer.volume_service
        self.docker_client = self.applications_deployer.docker_client
        self.network = self.applications_deployer.network

    def discover_state(self, local_state):
        d = self.manifestations_deployer.discover_state(local_state)

        def got_manifestations_state(manifestations_state):
            manifestations_state = manifestations_state[0]
            app_discovery = self.applications_deployer.discover_state(
                manifestations_state)
            app_discovery.addCallback(
                lambda app_state: [app_state[0].set(
                    "manifestations", manifestations_state.manifestations).set(
                        "paths", manifestations_state.paths)])
            return app_discovery
        d.addCallback(got_manifestations_state)
        return d

    def calculate_changes(
            self, configuration, cluster_state):
        """
        Combine changes from the application and ZFS agents.
        """
        return sequentially(changes=[
            self.applications_deployer.calculate_changes(
                configuration, cluster_state),
            self.manifestations_deployer.calculate_changes(
                configuration, cluster_state),
        ])

def change_node_state(deployer, desired_configuration):
    """
    Change the local state to match the given desired state.

    :param IDeployer deployer: Deployer to discover local state and
        calculate changes.
    :param Deployment desired_configuration: The intended configuration of all
        nodes.
    :return: ``Deferred`` that fires when the necessary changes are done.
    """
    def converge():
        d = deployer.discover_state(NodeState(hostname=deployer.hostname))

        def got_changes(changes):
            cluster_state = DeploymentState()
            for change in changes:
                cluster_state = change.update_cluster_state(cluster_state)
            return deployer.calculate_changes(
                desired_configuration, cluster_state)
        d.addCallback(got_changes)
        d.addCallback(lambda change: change.run(deployer))
        return d
    # Repeat a few times until things settle down:
    result = converge()
    result.addCallback(lambda _: converge())
    result.addCallback(lambda _: converge())
    return result

class DeployerTests(TestCase):
    """
    Functional tests for ``Deployer``.
    """
    @if_docker_configured
    def test_restart(self):
        """
        Stopped applications that are supposed to be running are restarted
        when the calcualted actions are run.
        """
        name = random_name()
        docker_client = DockerClient()
        deployer = ApplicationNodeDeployer(
            u"localhost", docker_client, make_memory_network(), node_uuid=uuid4())
        self.addCleanup(docker_client.remove, name)

        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=name,
                     image=DockerImage.from_string(
                         u"openshift/busybox-http-app"),
                     links=frozenset(),
                     )]))]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: wait_for_unit_state(docker_client, name,
                                                    [u'active']))

        def started(_):
            # Now that it's running, stop it behind our back:
            run_process([b"docker", b"stop",
                         docker_client._to_container_name(name)])
            return wait_for_unit_state(docker_client, name,
                                       [u'inactive', u'failed'])
        d.addCallback(started)

        def stopped(_):
            # Redeploy, which should restart it:
            return change_node_state(deployer, desired_state)
        d.addCallback(stopped)
        d.addCallback(lambda _: wait_for_unit_state(docker_client, name,
                                                    [u'active']))

        # Test will timeout if unit was not restarted:
        return d

    @if_docker_configured
    def test_environment(self):
        """
        The environment specified in an ``Application`` is passed to the
        container.
        """
        docker_dir = FilePath(__file__).sibling('env-docker')
        image = DockerImageBuilder(test=self, source_dir=docker_dir)
        image_name = image.build()

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        volume_service = create_volume_service(self)
        deployer = P2PNodeDeployer(
            u"localhost", volume_service, docker_client,
            make_memory_network(), node_uuid=uuid4())

        expected_variables = frozenset({
            'key1': 'value1',
            'key2': 'value2',
        }.items())

        dataset = Dataset(
            dataset_id=unicode(uuid4()),
            metadata=pmap({"name": application_name}))
        manifestation = Manifestation(dataset=dataset, primary=True)
        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=DockerImage.from_string(
                         image_name),
                     environment=expected_variables,
                     volume=AttachedVolume(
                         manifestation=manifestation,
                         mountpoint=FilePath('/data'),
                         ),
                     links=frozenset(),
                     )]),
                 manifestations={manifestation.dataset_id: manifestation})]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: volume_service.enumerate())
        d.addCallback(lambda volumes:
                      list(volumes)[0].get_filesystem().get_path().child(
                          b'env'))

        def got_result_path(result_path):
            d = loop_until(result_path.exists)
            d.addCallback(lambda _: result_path)
            return d
        d.addCallback(got_result_path)

        def started(result_path):
            contents = result_path.getContent()

            assertContainsAll(
                haystack=contents,
                test_case=self,
                needles=['{}={}\n'.format(k, v)
                         for k, v in expected_variables])
        d.addCallback(started)
        return d

    @if_docker_configured
    def test_links(self):
        """
        The links specified in an ``Application`` are passed to the
        container as environment variables.
        """
        docker_dir = FilePath(__file__).sibling('env-docker')
        image = DockerImageBuilder(test=self, source_dir=docker_dir)
        image_name = image.build()

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        volume_service = create_volume_service(self)
        deployer = P2PNodeDeployer(
            u"locahost", volume_service, docker_client,
            make_memory_network(), node_uuid=uuid4())

        expected_variables = frozenset({
            'ALIAS_PORT_80_TCP': 'tcp://localhost:8080',
            'ALIAS_PORT_80_TCP_PROTO': 'tcp',
            'ALIAS_PORT_80_TCP_ADDR': 'localhost',
            'ALIAS_PORT_80_TCP_PORT': '8080',
        }.items())

        link = Link(alias=u"alias",
                    local_port=80,
                    remote_port=8080)

        dataset = Dataset(
            dataset_id=unicode(uuid4()),
            metadata=pmap({"name": application_name}))
        manifestation = Manifestation(dataset=dataset, primary=True)
        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=DockerImage.from_string(
                         image_name),
                     links=frozenset([link]),
                     volume=AttachedVolume(
                         manifestation=manifestation,
                         mountpoint=FilePath('/data'),
                         ),
                     )]),
                 manifestations={manifestation.dataset_id: manifestation})]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: volume_service.enumerate())
        d.addCallback(lambda volumes:
                      list(volumes)[0].get_filesystem().get_path().child(
                          b'env'))

        def got_result_path(result_path):
            d = loop_until(result_path.exists)
            d.addCallback(lambda _: result_path)
            return d
        d.addCallback(got_result_path)

        def started(result_path):
            contents = result_path.getContent()

            assertContainsAll(
                haystack=contents,
                test_case=self,
                needles=['{}={}\n'.format(k, v)
                         for k, v in expected_variables])
        d.addCallback(started)
        return d

    @if_docker_configured
    def test_memory_limit(self):
        """
        The memory limit number specified in an ``Application`` is passed to
        the container.
        """
        EXPECTED_MEMORY_LIMIT = 100000000
        image = DockerImage.from_string(u"openshift/busybox-http-app")

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        deployer = ApplicationNodeDeployer(
            u"localhost", docker_client, make_memory_network(),
            node_uuid=uuid4())

        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=image,
                     memory_limit=EXPECTED_MEMORY_LIMIT
                     )]))]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: wait_for_unit_state(
            docker_client,
            application_name,
            [u'active'])
        )

        def inspect_application(_):
            deferred_list = docker_client.list()

            def app_memory(units):
                unit = units.pop()
                self.assertEqual(unit.mem_limit, EXPECTED_MEMORY_LIMIT)
                return deferred_list

            deferred_list.addCallback(app_memory)
        d.addCallback(inspect_application)
        return d

    @if_docker_configured
    def test_cpu_shares(self):
        """
        The CPU shares number specified in an ``Application`` is passed to the
        container.
        """
        EXPECTED_CPU_SHARES = 512

        image = DockerImage.from_string(u"openshift/busybox-http-app")

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        deployer = ApplicationNodeDeployer(
            u"localhost", docker_client, make_memory_network(),
            node_uuid=uuid4())

        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=image,
                     cpu_shares=EXPECTED_CPU_SHARES
                     )]))]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: wait_for_unit_state(
            docker_client,
            application_name,
            [u'active'])
        )

        def inspect_application(_):
            deferred_list = docker_client.list()

            def app_memory(units):
                unit = units.pop()
                self.assertEqual(unit.cpu_shares, EXPECTED_CPU_SHARES)
                return deferred_list

            deferred_list.addCallback(app_memory)
        d.addCallback(inspect_application)
        return d
<commit_msg>Functional tests pass too now.<commit_after># Copyright Hybrid Logic Ltd.  See LICENSE file for details.

"""
Functional tests for ``flocker.node._deploy``.
"""

from uuid import uuid4

from pyrsistent import pmap

from twisted.trial.unittest import TestCase
from twisted.python.filepath import FilePath

from .. import P2PManifestationDeployer, ApplicationNodeDeployer, sequentially
from ...control._model import (
    Deployment, Application, DockerImage, Node, AttachedVolume, Link,
    Manifestation, Dataset, DeploymentState, NodeState)
from .._docker import DockerClient
from ..testtools import wait_for_unit_state, if_docker_configured
from ...testtools import (
    random_name, DockerImageBuilder, assertContainsAll, loop_until,
    run_process)
from ...volume.testtools import create_volume_service
from ...route import make_memory_network

class P2PNodeDeployer(object):
    """
    Combination of ZFS and container deployer.

    Should really be gotten rid of:
    https://clusterhq.atlassian.net/browse/FLOC-1732
    """
    def __init__(self, hostname, volume_service, docker_client=None,
                 network=None, node_uuid=None):
        self.manifestations_deployer = P2PManifestationDeployer(
            hostname, volume_service, node_uuid=node_uuid)
        self.applications_deployer = ApplicationNodeDeployer(
            hostname, docker_client, network, node_uuid=node_uuid)
        self.hostname = hostname
        self.node_uuid = node_uuid
        self.volume_service = self.manifestations_deployer.volume_service
        self.docker_client = self.applications_deployer.docker_client
        self.network = self.applications_deployer.network

    def discover_state(self, local_state):
        d = self.manifestations_deployer.discover_state(local_state)

        def got_manifestations_state(manifestations_state):
            manifestations_state = manifestations_state[0]
            app_discovery = self.applications_deployer.discover_state(
                manifestations_state)
            app_discovery.addCallback(
                lambda app_state: [app_state[0].set(
                    "manifestations", manifestations_state.manifestations).set(
                        "paths", manifestations_state.paths)])
            return app_discovery
        d.addCallback(got_manifestations_state)
        return d

    def calculate_changes(
            self, configuration, cluster_state):
        """
        Combine changes from the application and ZFS agents.
        """
        return sequentially(changes=[
            self.applications_deployer.calculate_changes(
                configuration, cluster_state),
            self.manifestations_deployer.calculate_changes(
                configuration, cluster_state),
        ])

def change_node_state(deployer, desired_configuration):
    """
    Change the local state to match the given desired state.

    :param IDeployer deployer: Deployer to discover local state and
        calculate changes.
    :param Deployment desired_configuration: The intended configuration of all
        nodes.
    :return: ``Deferred`` that fires when the necessary changes are done.
    """
    def converge():
        d = deployer.discover_state(NodeState(hostname=deployer.hostname))

        def got_changes(changes):
            cluster_state = DeploymentState()
            for change in changes:
                cluster_state = change.update_cluster_state(cluster_state)
            return deployer.calculate_changes(
                desired_configuration, cluster_state)
        d.addCallback(got_changes)
        d.addCallback(lambda change: change.run(deployer))
        return d
    # Repeat a few times until things settle down:
    result = converge()
    result.addCallback(lambda _: converge())
    result.addCallback(lambda _: converge())
    return result

class DeployerTests(TestCase):
    """
    Functional tests for ``Deployer``.
    """
    @if_docker_configured
    def test_restart(self):
        """
        Stopped applications that are supposed to be running are restarted
        when the calcualted actions are run.
        """
        name = random_name()
        docker_client = DockerClient()
        deployer = ApplicationNodeDeployer(
            u"localhost", docker_client, make_memory_network(), node_uuid=uuid4())
        self.addCleanup(docker_client.remove, name)

        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=name,
                     image=DockerImage.from_string(
                         u"openshift/busybox-http-app"),
                     links=frozenset(),
                     )]))]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: wait_for_unit_state(docker_client, name,
                                                    [u'active']))

        def started(_):
            # Now that it's running, stop it behind our back:
            run_process([b"docker", b"stop",
                         docker_client._to_container_name(name)])
            return wait_for_unit_state(docker_client, name,
                                       [u'inactive', u'failed'])
        d.addCallback(started)

        def stopped(_):
            # Redeploy, which should restart it:
            return change_node_state(deployer, desired_state)
        d.addCallback(stopped)
        d.addCallback(lambda _: wait_for_unit_state(docker_client, name,
                                                    [u'active']))

        # Test will timeout if unit was not restarted:
        return d

    @if_docker_configured
    def test_environment(self):
        """
        The environment specified in an ``Application`` is passed to the
        container.
        """
        docker_dir = FilePath(__file__).sibling('env-docker')
        image = DockerImageBuilder(test=self, source_dir=docker_dir)
        image_name = image.build()

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        volume_service = create_volume_service(self)
        deployer = P2PNodeDeployer(
            u"localhost", volume_service, docker_client,
            make_memory_network(), node_uuid=uuid4())

        expected_variables = frozenset({
            'key1': 'value1',
            'key2': 'value2',
        }.items())

        dataset = Dataset(
            dataset_id=unicode(uuid4()),
            metadata=pmap({"name": application_name}))
        manifestation = Manifestation(dataset=dataset, primary=True)
        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=DockerImage.from_string(
                         image_name),
                     environment=expected_variables,
                     volume=AttachedVolume(
                         manifestation=manifestation,
                         mountpoint=FilePath('/data'),
                         ),
                     links=frozenset(),
                     )]),
                 manifestations={manifestation.dataset_id: manifestation})]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: volume_service.enumerate())
        d.addCallback(lambda volumes:
                      list(volumes)[0].get_filesystem().get_path().child(
                          b'env'))

        def got_result_path(result_path):
            d = loop_until(result_path.exists)
            d.addCallback(lambda _: result_path)
            return d
        d.addCallback(got_result_path)

        def started(result_path):
            contents = result_path.getContent()

            assertContainsAll(
                haystack=contents,
                test_case=self,
                needles=['{}={}\n'.format(k, v)
                         for k, v in expected_variables])
        d.addCallback(started)
        return d

    @if_docker_configured
    def test_links(self):
        """
        The links specified in an ``Application`` are passed to the
        container as environment variables.
        """
        docker_dir = FilePath(__file__).sibling('env-docker')
        image = DockerImageBuilder(test=self, source_dir=docker_dir)
        image_name = image.build()

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        volume_service = create_volume_service(self)
        deployer = P2PNodeDeployer(
            u"localhost", volume_service, docker_client,
            make_memory_network(), node_uuid=uuid4())

        expected_variables = frozenset({
            'ALIAS_PORT_80_TCP': 'tcp://localhost:8080',
            'ALIAS_PORT_80_TCP_PROTO': 'tcp',
            'ALIAS_PORT_80_TCP_ADDR': 'localhost',
            'ALIAS_PORT_80_TCP_PORT': '8080',
        }.items())

        link = Link(alias=u"alias",
                    local_port=80,
                    remote_port=8080)

        dataset = Dataset(
            dataset_id=unicode(uuid4()),
            metadata=pmap({"name": application_name}))
        manifestation = Manifestation(dataset=dataset, primary=True)
        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=DockerImage.from_string(
                         image_name),
                     links=frozenset([link]),
                     volume=AttachedVolume(
                         manifestation=manifestation,
                         mountpoint=FilePath('/data'),
                         ),
                     )]),
                 manifestations={manifestation.dataset_id: manifestation})]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: volume_service.enumerate())
        d.addCallback(lambda volumes:
                      list(volumes)[0].get_filesystem().get_path().child(
                          b'env'))

        def got_result_path(result_path):
            d = loop_until(result_path.exists)
            d.addCallback(lambda _: result_path)
            return d
        d.addCallback(got_result_path)

        def started(result_path):
            contents = result_path.getContent()

            assertContainsAll(
                haystack=contents,
                test_case=self,
                needles=['{}={}\n'.format(k, v)
                         for k, v in expected_variables])
        d.addCallback(started)
        return d

    @if_docker_configured
    def test_memory_limit(self):
        """
        The memory limit number specified in an ``Application`` is passed to
        the container.
        """
        EXPECTED_MEMORY_LIMIT = 100000000
        image = DockerImage.from_string(u"openshift/busybox-http-app")

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        deployer = ApplicationNodeDeployer(
            u"localhost", docker_client, make_memory_network(),
            node_uuid=uuid4())

        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=image,
                     memory_limit=EXPECTED_MEMORY_LIMIT
                     )]))]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: wait_for_unit_state(
            docker_client,
            application_name,
            [u'active'])
        )

        def inspect_application(_):
            deferred_list = docker_client.list()

            def app_memory(units):
                unit = units.pop()
                self.assertEqual(unit.mem_limit, EXPECTED_MEMORY_LIMIT)
                return deferred_list

            deferred_list.addCallback(app_memory)
        d.addCallback(inspect_application)
        return d

    @if_docker_configured
    def test_cpu_shares(self):
        """
        The CPU shares number specified in an ``Application`` is passed to the
        container.
        """
        EXPECTED_CPU_SHARES = 512

        image = DockerImage.from_string(u"openshift/busybox-http-app")

        application_name = random_name()

        docker_client = DockerClient()
        self.addCleanup(docker_client.remove, application_name)

        deployer = ApplicationNodeDeployer(
            u"localhost", docker_client, make_memory_network(),
            node_uuid=uuid4())

        desired_state = Deployment(nodes=frozenset([
            Node(uuid=deployer.node_uuid,
                 applications=frozenset([Application(
                     name=application_name,
                     image=image,
                     cpu_shares=EXPECTED_CPU_SHARES
                     )]))]))

        d = change_node_state(deployer, desired_state)
        d.addCallback(lambda _: wait_for_unit_state(
            docker_client,
            application_name,
            [u'active'])
        )

        def inspect_application(_):
            deferred_list = docker_client.list()

            def app_memory(units):
                unit = units.pop()
                self.assertEqual(unit.cpu_shares, EXPECTED_CPU_SHARES)
                return deferred_list

            deferred_list.addCallback(app_memory)
        d.addCallback(inspect_application)
        return d
<|endoftext|>