<commit_before># -*- coding: utf-8 -*-

# Standard library imports
# Third party imports
from django.db.models import get_model
from django.template import Context
from django.template.base import Template
from django.template.loader import render_to_string
from django.test import TestCase
from django.test.client import RequestFactory
from guardian.shortcuts import assign_perm

# Local application / specific library imports
from machina.core.loading import get_class
from machina.test.factories import create_category_forum
from machina.test.factories import create_forum
from machina.test.factories import create_topic
from machina.test.factories import PostFactory
from machina.test.factories import UserFactory

Forum = get_model('forum', 'Forum')
Post = get_model('conversation', 'Post')
Topic = get_model('conversation', 'Topic')

PermissionHandler = get_class('permission.handler', 'PermissionHandler')

class TestForumLastPostTag(TestCase):
    def setUp(self):
        self.loadstatement = '{% load url from future %}{% load forum_tags %}'
        self.user = UserFactory.create()

        # Permission handler
        self.perm_handler = PermissionHandler()

        # Set up a top-level category
        self.top_level_cat = create_category_forum()

        # Set up some forums
        self.forum_1 = create_forum(parent=self.top_level_cat)
        self.forum_2 = create_forum(parent=self.top_level_cat)

        # Set up some topics and posts
        self.forum_1_topic = create_topic(forum=self.forum_1, poster=self.user)
        self.forum_2_topic = create_topic(forum=self.forum_2, poster=self.user)
        self.post_1 = PostFactory.create(topic=self.forum_1_topic, poster=self.user)
        self.post_2 = PostFactory.create(topic=self.forum_2_topic, poster=self.user)

        # Assign some permissions
        assign_perm('can_see_forum', self.user, self.top_level_cat)
        assign_perm('can_see_forum', self.user, self.forum_1)

    def test_can_provide_the_last_post_of_a_forum(self):
        # Setup
        t = Template(self.loadstatement + '{% get_forum_last_post forum user as var %}')
        c = Context({'forum': self.forum_1, 'user': self.user})
        # Run
        rendered = t.render(c)
        # Check
        self.assertEqual(rendered, '')
        self.assertEqual(c['var'], self.post_1)

class TestForumListTag(TestCase):
    def setUp(self):
        self.loadstatement = '{% load forum_tags %}'
        self.request_factory = RequestFactory()
        self.user = UserFactory.create()

        # Set up a top-level category
        self.top_level_cat = create_category_forum()

        # Set up some forums
        self.forum_1 = create_forum(parent=self.top_level_cat)
        self.forum_2 = create_forum(parent=self.top_level_cat)

    def test_can_render_a_list_of_forums_according_to_their_minimum_tree_level(self):
        # Setup
        forums = Forum.objects.all()
        request = self.request_factory.get('/')
        request.user = self.user
        t = Template(self.loadstatement + '{% forum_list forums request %}')
        c = Context({'forums': forums, 'request': request})
        expected_out = render_to_string(
            'machina/forum/forum_list.html',
            {
                'forums': forums,
                'user': self.user,
                'root_level': 0,
                'root_level_middle': 1,
                'root_level_sub': 2,
            }
        )
        # Run
        rendered = t.render(c)
        # Check
        self.assertNotEqual(rendered, '')
        self.assertEqual(rendered, expected_out)
<commit_msg>'forum' templatetags tests added<commit_after># -*- coding: utf-8 -*-

# Standard library imports
# Third party imports
from django.db.models import get_model
from django.template import Context
from django.template.base import Template
from django.template.loader import render_to_string
from django.test import TestCase
from django.test.client import RequestFactory
from guardian.shortcuts import assign_perm

# Local application / specific library imports
from machina.core.loading import get_class
from machina.test.factories import create_category_forum
from machina.test.factories import create_forum
from machina.test.factories import create_topic
from machina.test.factories import PostFactory
from machina.test.factories import UserFactory

Forum = get_model('forum', 'Forum')
Post = get_model('conversation', 'Post')
Topic = get_model('conversation', 'Topic')

PermissionHandler = get_class('permission.handler', 'PermissionHandler')

class TestForumLastPostTag(TestCase):
    def setUp(self):
        self.loadstatement = '{% load url from future %}{% load forum_tags %}'
        self.user = UserFactory.create()

        # Permission handler
        self.perm_handler = PermissionHandler()

        # Set up a top-level category
        self.top_level_cat = create_category_forum()

        # Set up some forums
        self.forum_1 = create_forum(parent=self.top_level_cat)
        self.forum_2 = create_forum(parent=self.top_level_cat)

        # Set up some topics and posts
        self.forum_1_topic = create_topic(forum=self.forum_1, poster=self.user)
        self.forum_2_topic = create_topic(forum=self.forum_2, poster=self.user)
        self.post_1 = PostFactory.create(topic=self.forum_1_topic, poster=self.user)
        self.post_2 = PostFactory.create(topic=self.forum_2_topic, poster=self.user)

        # Assign some permissions
        assign_perm('can_see_forum', self.user, self.top_level_cat)
        assign_perm('can_see_forum', self.user, self.forum_1)

    def test_can_provide_the_last_post_of_a_forum(self):
        # Setup
        t = Template(self.loadstatement + '{% get_forum_last_post forum user as var %}')
        c = Context({'forum': self.forum_1, 'user': self.user})
        # Run
        rendered = t.render(c)
        # Check
        self.assertEqual(rendered, '')
        self.assertEqual(c['var'], self.post_1)

class TestForumListTag(TestCase):
    def setUp(self):
        self.loadstatement = '{% load forum_tags %}'
        self.request_factory = RequestFactory()
        self.user = UserFactory.create()

        # Set up a top-level category
        self.top_level_cat = create_category_forum()

        # Set up some forums
        self.forum_1 = create_forum(parent=self.top_level_cat)
        self.forum_2 = create_forum(parent=self.top_level_cat)

    def test_can_render_a_list_of_forums_according_to_their_minimum_tree_level(self):
        # Setup
        forums = Forum.objects.all()
        request = self.request_factory.get('/')
        request.user = self.user
        t = Template(self.loadstatement + '{% forum_list forums request %}')
        c = Context({'forums': forums, 'request': request})
        expected_out = render_to_string(
            'machina/forum/forum_list.html',
            {
                'forums': forums,
                'user': self.user,
                'root_level': 0,
                'root_level_middle': 1,
                'root_level_sub': 2,
            }
        )
        # Run
        rendered = t.render(c)
        # Check
        self.assertNotEqual(rendered, '')
        self.assertEqual(rendered, expected_out)

class TestCanBeFilledByTag(TestCase):
    def setUp(self):
        self.loadstatement = '{% load forum_tags %}'
        self.request_factory = RequestFactory()
        self.user = UserFactory.create()

        # Set up a top-level category
        self.top_level_cat = create_category_forum()

        # Set up some forums
        self.forum_1 = create_forum(parent=self.top_level_cat)
        self.forum_2 = create_forum(parent=self.top_level_cat)

        # Assign some permissions
        assign_perm('can_start_new_topics', self.user, self.forum_1)

    def test_can_tell_if_a_user_can_create_topics(self):
        # Setup
        def get_rendered(forum, user):
            request = self.request_factory.get('/')
            request.user = user
            t = Template(self.loadstatement + '{% if forum|can_be_filled_by:request.user %}CAN_START_TOPICS{% else %}CANNOT_START_TOPICS{% endif %}')
            c = Context({'forum': forum, 'request': request})
            rendered = t.render(c)

            return rendered

        # Run & check
        self.assertEqual(get_rendered(self.forum_1, self.user), 'CAN_START_TOPICS')
        self.assertEqual(get_rendered(self.forum_2, self.user), 'CANNOT_START_TOPICS')
<|endoftext|>


<commit_before>from C4CApplication.meta import NonMember
from C4CApplication.meta.time import Time
from C4CApplication.models import Message, Job, Branch, Mailbox
from C4CApplication import models
from django.core.urlresolvers import reverse_lazy

class Member(NonMember):
    """
    This class represents a kind of Users called Members
    """

    def register_job_done(self, job_number, job_creator_mail, helped_one_email=None, new_time=0):
        """
        Registers a job as done (with the new time to put).
        The helped one will be warned by email and will be able to accept the 'payment' or not

        :param job_number: it's the number of the job created by the job_creator_mail
        :param job_creator_mail: The mail of the creator of the job
        :param helped_one_email: it can't be None
        :param new_time:
        :return: False if there was a problem and True otherwise.
        """

        if helped_one_email is None:
            return False
        job = Job.objects.filter(mail=job_creator_mail, number=job_number)
        if len(job) != 1:
            return False
        job = job[0]
        job.done = True
        job.duration = new_time
        job.save()

        #We send a mail
        helper_mail = ''
        if not job.type : # offer
            helper_mail = job_creator_mail
        else : # demand
            participants = job.member_set.all()
            for participant in participants:
                if participant.mail != helped_one_email:
                    helper_mail = participant.mail
                    break
        if helper_mail == '':
            return False
        subject = 'The ' + \
                  ' job ' + ' is done'
        content = 'The ' + \
                  ' job ' + ' is done'\
                  + ' is done. Please, consult your account to accept or contest the bill.'
        type = 1
        return self.send_mail(helper_mail, helped_one_email, subject, content, type)

    def accept_bill(self, job_number, job_creator_mail, amount):
        """
        Accepts the bill and transfers money to the helper

        :param job_number: it's the number of the job created by the job_creator_mail
        :param job_creator_mail: The mail of the creator of the job
        :param amount: amount of the bill
        :return: False if there was a problem and True otherwise.
        """
        job = Job.objects.filter(mail=job_creator_mail, number=job_number)
        if len(job) != 1 or job[0].payed:
            return False
        job = job[0]
        job.payed = True
        job.save()

        helper_mail = None
        if not job.type:  # offer
            helper_mail = job_creator_mail
        else:  # demand
            participants = job.member_set.all()
            for participant in participants:
                if participant.mail != self.db_member.mail:
                    helper_mail = participant.mail
                    break
        if helper_mail is None:
            return False
        helper = models.Member.objects.filter(mail=helper_mail)
        if len(helper) != 1:
            return False
        helper = helper[0]

        #We transfer money
        self.db_member.time_credit -= amount
        helper.time_credit += amount
        helper.save()
        self.db_member.save()

        #We send a mail to warn
        subject = "You've been payed"
        content = "You've been payed by "+str(self.db_member.mail)
        type = 3
        return self.send_mail(self.db_member.mail, helper.mail, subject, content, type)

    def refuse_bill(self, job_number, job_creator_mail):
        """
        Refuses the bill and warns the branch officer by email

        :param job_number: it's the number of the job created by the job_creator_mail
        :param job_creator_mail: The mail of the creator of the job
        :return: False if there was a problem and True otherwise.
        """
        job = Job.objects.filter(mail=job_creator_mail, number=job_number)
        if len(job)!=1:
            return False
        job = job[0]
        mail_branch_officer = job.branch.branch_officer

        helper_email = None
        if not job.type:  # offer
            helper_email = job_creator_mail
        else:  # demand
            participants = job.member_set.all()
            for participant in participants:
                if participant.mail != self.db_member.mail:
                    helper_email = participant.mail
                    break

        #Send the mails
        subject = "bill refused"
        content = "Your bill has been refused by "+str(self.db_member.mail)
        type = 1
        res = self.send_mail(self.db_member.mail, helper_email, subject, content, type)
        if not res:
            return False

        content = "A bill has been refused by "+str(self.db_member.mail)
        return self.send_mail(self.db_member.mail, mail_branch_officer, subject, content, type)

    def transfer_time(self, destination_email, time):
        """
        Transfers 'time' to a member with 'destination_email' as email

        :param destination_email: the email address of the member to transfer time
        :return: False if there was a problem and True otherwise.
        """
        if self.db_member.mail == destination_email:
            return False
        sender_gift = self.db_member
        receiver_gift = models.Member.objects.filter(mail=destination_email)
        if len(receiver_gift) != 1:
            return False
        receiver_gift = receiver_gift[0]

        sender_gift.time_credit -= time
        receiver_gift.time_credit += time
        sender_gift.save()
        receiver_gift.save()

        #Send the message
        subject = "You've received a gift"
        content = "You've received a gift from "+str(sender_gift.mail)
        type = 3
        return self.send_mail(sender_gift.mail, receiver_gift.mail, subject, content, type)

    def make_donation(self, time, branch_name=None):
        """
        Makes a donation to the branch of the member

        :param branch_name:
        :param time:
        :return: True if donation proceeds correctly
        """
        branch = Branch.objects.filter(name=branch_name)
        if len(branch) != 1:
            return False
        branch = branch[0]
        branch_off = models.Member.objects.filter(mail=branch.branch_officer)
        if len(branch_off) != 1:
            return False
        branch_off=branch_off[0]
        if branch_off.mail == self.db_member.mail :
            return False
        #We make the donation
        self.db_member.time_credit -= time
        branch_off.time_credit += time
        branch.donation += time
        self.db_member.save()
        branch.save()
        branch_off.save()
        return True
<commit_msg>Pblm solved ?<commit_after>from C4CApplication.meta import NonMember
from C4CApplication.meta.time import Time
from C4CApplication.models import Message, Job, Branch, Mailbox
from C4CApplication import models
from django.core.urlresolvers import reverse_lazy

class Member(NonMember):
    """
    This class represents a kind of Users called Members
    """

    def register_job_done(self, job_number, job_creator_mail, helped_one_email=None, new_time=0):
        """
        Registers a job as done (with the new time to put).
        The helped one will be warned by email and will be able to accept the 'payment' or not

        :param job_number: it's the number of the job created by the job_creator_mail
        :param job_creator_mail: The mail of the creator of the job
        :param helped_one_email: it can't be None
        :param new_time:
        :return: False if there was a problem and True otherwise.
        """

        if helped_one_email is None:
            return False
        job = Job.objects.filter(mail=job_creator_mail, number=job_number)
        if len(job) != 1:
            return False
        job = job[0]
        job.done = True
        job.duration = new_time
        job.save()

        #We send a mail
        helper_mail = ''
        if not job.type : # offer
            helper_mail = job_creator_mail
        else : # demand
            participants = job.member_set.all()
            for participant in participants:
                if participant.mail != helped_one_email:
                    helper_mail = participant.mail
                    break
        if helper_mail == '':
            return False
        subject = 'The job is done !'
        content = 'The ' + \
                  ' job ' + \
                   ' is done. Please, consult your account to accept or contest the bill.'
        type = 1
        return self.send_mail(helper_mail, helped_one_email, subject, content, type)

    def accept_bill(self, job_number, job_creator_mail, amount):
        """
        Accepts the bill and transfers money to the helper

        :param job_number: it's the number of the job created by the job_creator_mail
        :param job_creator_mail: The mail of the creator of the job
        :param amount: amount of the bill
        :return: False if there was a problem and True otherwise.
        """
        job = Job.objects.filter(mail=job_creator_mail, number=job_number)
        if len(job) != 1 or job[0].payed:
            return False
        job = job[0]
        job.payed = True
        job.save()

        helper_mail = None
        if not job.type:  # offer
            helper_mail = job_creator_mail
        else:  # demand
            participants = job.member_set.all()
            for participant in participants:
                if participant.mail != self.db_member.mail:
                    helper_mail = participant.mail
                    break
        if helper_mail is None:
            return False
        helper = models.Member.objects.filter(mail=helper_mail)
        if len(helper) != 1:
            return False
        helper = helper[0]

        #We transfer money
        self.db_member.time_credit -= amount
        helper.time_credit += amount
        helper.save()
        self.db_member.save()

        #We send a mail to warn
        subject = "You've been payed"
        content = "You've been payed by "+str(self.db_member.mail)
        type = 3
        return self.send_mail(self.db_member.mail, helper.mail, subject, content, type)

    def refuse_bill(self, job_number, job_creator_mail):
        """
        Refuses the bill and warns the branch officer by email

        :param job_number: it's the number of the job created by the job_creator_mail
        :param job_creator_mail: The mail of the creator of the job
        :return: False if there was a problem and True otherwise.
        """
        job = Job.objects.filter(mail=job_creator_mail, number=job_number)
        if len(job)!=1:
            return False
        job = job[0]
        mail_branch_officer = job.branch.branch_officer

        helper_email = None
        if not job.type:  # offer
            helper_email = job_creator_mail
        else:  # demand
            participants = job.member_set.all()
            for participant in participants:
                if participant.mail != self.db_member.mail:
                    helper_email = participant.mail
                    break

        #Send the mails
        subject = "bill refused"
        content = "Your bill has been refused by "+str(self.db_member.mail)
        type = 1
        res = self.send_mail(self.db_member.mail, helper_email, subject, content, type)
        if not res:
            return False

        content = "A bill has been refused by "+str(self.db_member.mail)
        return self.send_mail(self.db_member.mail, mail_branch_officer, subject, content, type)

    def transfer_time(self, destination_email, time):
        """
        Transfers 'time' to a member with 'destination_email' as email

        :param destination_email: the email address of the member to transfer time
        :return: False if there was a problem and True otherwise.
        """
        if self.db_member.mail == destination_email:
            return False
        sender_gift = self.db_member
        receiver_gift = models.Member.objects.filter(mail=destination_email)
        if len(receiver_gift) != 1:
            return False
        receiver_gift = receiver_gift[0]

        sender_gift.time_credit -= time
        receiver_gift.time_credit += time
        sender_gift.save()
        receiver_gift.save()

        #Send the message
        subject = "You've received a gift"
        content = "You've received a gift from "+str(sender_gift.mail)
        type = 3
        return self.send_mail(sender_gift.mail, receiver_gift.mail, subject, content, type)

    def make_donation(self, time, branch_name=None):
        """
        Makes a donation to the branch of the member

        :param branch_name:
        :param time:
        :return: True if donation proceeds correctly
        """
        branch = Branch.objects.filter(name=branch_name)
        if len(branch) != 1:
            return False
        branch = branch[0]
        branch_off = models.Member.objects.filter(mail=branch.branch_officer)
        if len(branch_off) != 1:
            return False
        branch_off=branch_off[0]
        if branch_off.mail == self.db_member.mail :
            return False
        #We make the donation
        self.db_member.time_credit -= time
        branch_off.time_credit += time
        branch.donation += time
        self.db_member.save()
        branch.save()
        branch_off.save()
        return True
<|endoftext|>


<commit_before># Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""Tests that check if the release binary sizes fall within expected size."""

import os
import platform
import pytest

import host_tools.cargo_build as host

MACHINE = platform.machine()
""" Platform definition used to select the correct size target"""

SIZES_DICT = {
    "x86_64": {
        "FC_BINARY_SIZE_TARGET": 2067944,
        "JAILER_BINARY_SIZE_TARGET": 1439512,
        "FC_BINARY_SIZE_LIMIT": 2171516,
        "JAILER_BINARY_SIZE_LIMIT": 1511488,
    },
    "aarch64": {
        "FC_BINARY_SIZE_TARGET": 2016400,
        "JAILER_BINARY_SIZE_TARGET": 1338312,
        "FC_BINARY_SIZE_LIMIT": 2050000,
        "JAILER_BINARY_SIZE_LIMIT": 1511488,
    }
}

FC_BINARY_SIZE_TARGET = SIZES_DICT[MACHINE]["FC_BINARY_SIZE_TARGET"]
"""Firecracker target binary size in bytes"""

FC_BINARY_SIZE_LIMIT = SIZES_DICT[MACHINE]["FC_BINARY_SIZE_LIMIT"]
"""Firecracker maximum binary size in bytes"""

JAILER_BINARY_SIZE_TARGET = SIZES_DICT[MACHINE]["JAILER_BINARY_SIZE_TARGET"]
"""Jailer target binary size in bytes"""

JAILER_BINARY_SIZE_LIMIT = SIZES_DICT[MACHINE]["JAILER_BINARY_SIZE_LIMIT"]
"""Jailer maximum binary size in bytes"""

BINARY_SIZE_TOLERANCE = 0.05
"""Tolerance of 5% allowed for binary size"""

@pytest.mark.timeout(500)
def test_binary_sizes():
    """Test if the sizes of the release binaries are within expected ranges."""
    fc_binary, jailer_binary = host.get_firecracker_binaries()

    check_binary_size("firecracker", fc_binary, FC_BINARY_SIZE_TARGET,
                      BINARY_SIZE_TOLERANCE, FC_BINARY_SIZE_LIMIT)

    check_binary_size("jailer", jailer_binary, JAILER_BINARY_SIZE_TARGET,
                      BINARY_SIZE_TOLERANCE, JAILER_BINARY_SIZE_LIMIT)

def check_binary_size(name, binary_path, size_target, tolerance, limit):
    """Check if the specified binary falls within the expected range."""
    # Get the size of the release binary.
    binary_size = os.path.getsize(binary_path)

    # Get the name of the variable that needs updating.
    namespace = globals()
    size_target_name = [name for name in namespace if namespace[name]
                        is size_target][0]

    # Compute concrete binary size difference.
    delta_size = size_target - binary_size

    binary_low_msg = (
        'Current {} binary size of {} bytes is below the target'
        ' of {} bytes with {} bytes.\n'
        'Update the {} threshold'
        .format(name, binary_size, size_target, delta_size, size_target_name)
    )

    assert binary_size > size_target * (1 - tolerance), binary_low_msg

    binary_high_msg = (
        'Current {} binary size of {} bytes is above the target'
        ' of {} bytes with {} bytes.\n'
        .format(name, binary_size, size_target, -delta_size)
    )

    assert binary_size < size_target * (1 + tolerance), binary_high_msg

    binary_limit_msg = (
        'Current {} binary size of {} bytes is above the limit'
        ' of {} bytes with {} bytes.\n'
        .format(name, binary_size, limit, binary_size - limit)
    )

    assert binary_size < limit, binary_limit_msg
<commit_msg>tests: add docstring to binary sizes test<commit_after># Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""Tests that check if the release binary sizes fall within expected size."""

import os
import platform
import pytest

import host_tools.cargo_build as host

MACHINE = platform.machine()
""" Platform definition used to select the correct size target"""

SIZES_DICT = {
    "x86_64": {
        "FC_BINARY_SIZE_TARGET": 2067944,
        "JAILER_BINARY_SIZE_TARGET": 1439512,
        "FC_BINARY_SIZE_LIMIT": 2171516,
        "JAILER_BINARY_SIZE_LIMIT": 1511488,
    },
    "aarch64": {
        "FC_BINARY_SIZE_TARGET": 2016400,
        "JAILER_BINARY_SIZE_TARGET": 1338312,
        "FC_BINARY_SIZE_LIMIT": 2050000,
        "JAILER_BINARY_SIZE_LIMIT": 1511488,
    }
}

FC_BINARY_SIZE_TARGET = SIZES_DICT[MACHINE]["FC_BINARY_SIZE_TARGET"]
"""Firecracker target binary size in bytes"""

FC_BINARY_SIZE_LIMIT = SIZES_DICT[MACHINE]["FC_BINARY_SIZE_LIMIT"]
"""Firecracker maximum binary size in bytes"""

JAILER_BINARY_SIZE_TARGET = SIZES_DICT[MACHINE]["JAILER_BINARY_SIZE_TARGET"]
"""Jailer target binary size in bytes"""

JAILER_BINARY_SIZE_LIMIT = SIZES_DICT[MACHINE]["JAILER_BINARY_SIZE_LIMIT"]
"""Jailer maximum binary size in bytes"""

BINARY_SIZE_TOLERANCE = 0.05
"""Tolerance of 5% allowed for binary size"""

@pytest.mark.timeout(500)
def test_firecracker_binary_size():
    """
    Test if the size of the firecracker binary is within expected ranges.

    @type: build
    """
    fc_binary, _ = host.get_firecracker_binaries()

    result = check_binary_size("firecracker", fc_binary, FC_BINARY_SIZE_TARGET,
                               BINARY_SIZE_TOLERANCE, FC_BINARY_SIZE_LIMIT)

    return f"{result} B", \
           f"{FC_BINARY_SIZE_TARGET} +/- {BINARY_SIZE_TOLERANCE * 100}% B"

@pytest.mark.timeout(500)
def test_jailer_binary_size():
    """
    Test if the size of the jailer binary is within expected ranges.

    @type: build
    """
    _, jailer_binary = host.get_firecracker_binaries()

    result = check_binary_size("jailer", jailer_binary,
                               JAILER_BINARY_SIZE_TARGET,
                               BINARY_SIZE_TOLERANCE, JAILER_BINARY_SIZE_LIMIT)

    return f"{result} B", \
           f"{JAILER_BINARY_SIZE_TARGET} +/- {BINARY_SIZE_TOLERANCE * 100}% B"

def check_binary_size(name, binary_path, size_target, tolerance, limit):
    """Check if the specified binary falls within the expected range."""
    # Get the size of the release binary.
    binary_size = os.path.getsize(binary_path)

    # Get the name of the variable that needs updating.
    namespace = globals()
    size_target_name = [name for name in namespace if namespace[name]
                        is size_target][0]

    # Compute concrete binary size difference.
    delta_size = size_target - binary_size

    binary_low_msg = (
        'Current {} binary size of {} bytes is below the target'
        ' of {} bytes with {} bytes.\n'
        'Update the {} threshold'
        .format(name, binary_size, size_target, delta_size, size_target_name)
    )

    assert binary_size > size_target * (1 - tolerance), binary_low_msg

    binary_high_msg = (
        'Current {} binary size of {} bytes is above the target'
        ' of {} bytes with {} bytes.\n'
        .format(name, binary_size, size_target, -delta_size)
    )

    assert binary_size < size_target * (1 + tolerance), binary_high_msg

    binary_limit_msg = (
        'Current {} binary size of {} bytes is above the limit'
        ' of {} bytes with {} bytes.\n'
        .format(name, binary_size, limit, binary_size - limit)
    )

    assert binary_size < limit, binary_limit_msg

    return binary_size
<|endoftext|>


<commit_before># coding: utf-8
from __future__ import unicode_literals

import re

from .common import InfoExtractor
from ..utils import (
    determine_ext,
    clean_html,
    get_element_by_attribute,
    ExtractorError,
)

class TVPIE(InfoExtractor):
    IE_NAME = 'tvp'
    IE_DESC = 'Telewizja Polska'
    _VALID_URL = r'https?://[^/]+\.tvp\.(?:pl|info)/(?:(?!\d+/)[^/]+/)*(?P<id>\d+)'

    _TESTS = [{
        'url': 'http://vod.tvp.pl/194536/i-seria-odc-13',
        'md5': '8aa518c15e5cc32dfe8db400dc921fbb',
        'info_dict': {
            'id': '194536',
            'ext': 'mp4',
            'title': 'Czas honoru, I seria – odc. 13',
        },
    }, {
        'url': 'http://www.tvp.pl/there-can-be-anything-so-i-shortened-it/17916176',
        'md5': 'b0005b542e5b4de643a9690326ab1257',
        'info_dict': {
            'id': '17916176',
            'ext': 'mp4',
            'title': 'TVP Gorzów pokaże filmy studentów z podroży dookoła świata',
        },
    }, {
        'url': 'http://vod.tvp.pl/seriale/obyczajowe/na-sygnale/sezon-2-27-/odc-39/17834272',
        'only_matching': True,
    }, {
        'url': 'http://wiadomosci.tvp.pl/25169746/24052016-1200',
        'only_matching': True,
    }, {
        'url': 'http://krakow.tvp.pl/25511623/25lecie-mck-wyjatkowe-miejsce-na-mapie-krakowa',
        'only_matching': True,
    }, {
        'url': 'http://teleexpress.tvp.pl/25522307/wierni-wzieli-udzial-w-procesjach',
        'only_matching': True,
    }, {
        'url': 'http://sport.tvp.pl/25522165/krychowiak-uspokaja-w-sprawie-kontuzji-dwa-tygodnie-to-maksimum',
        'only_matching': True,
    }, {
        'url': 'http://www.tvp.info/25511919/trwa-rewolucja-wladza-zdecydowala-sie-na-pogwalcenie-konstytucji',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)

        webpage = self._download_webpage(
            'http://www.tvp.pl/sess/tvplayer.php?object_id=%s' % video_id, video_id)

        error_massage = get_element_by_attribute('class', 'msg error', webpage)
        if error_massage:
            raise ExtractorError('%s said: %s' % (
                self.IE_NAME, clean_html(error_massage)), expected=True)

        title = self._search_regex(
            r'name\s*:\s*([\'"])Title\1\s*,\s*value\s*:\s*\1(?P<title>.+?)\1',
            webpage, 'title', group='title')
        series_title = self._search_regex(
            r'name\s*:\s*([\'"])SeriesTitle\1\s*,\s*value\s*:\s*\1(?P<series>.+?)\1',
            webpage, 'series', group='series', default=None)
        if series_title:
            title = '%s, %s' % (series_title, title)

        thumbnail = self._search_regex(
            r"poster\s*:\s*'([^']+)'", webpage, 'thumbnail', default=None)

        video_url = self._search_regex(
            r'0:{src:([\'"])(?P<url>.*?)\1', webpage,
            'formats', group='url', default=None)
        if not video_url or 'material_niedostepny.mp4' in video_url:
            video_url = self._download_json(
                'http://www.tvp.pl/pub/stat/videofileinfo?video_id=%s' % video_id,
                video_id)['video_url']

        formats = []
        video_url_base = self._search_regex(
            r'(https?://.+?/video)(?:\.(?:ism|f4m|m3u8)|-\d+\.mp4)',
            video_url, 'video base url', default=None)
        if video_url_base:
            # TODO: Current DASH formats are broken - $Time$ pattern in
            # <SegmentTemplate> not implemented yet
            # formats.extend(self._extract_mpd_formats(
            #     video_url_base + '.ism/video.mpd',
            #     video_id, mpd_id='dash', fatal=False))
            formats.extend(self._extract_f4m_formats(
                video_url_base + '.ism/video.f4m',
                video_id, f4m_id='hds', fatal=False))
            m3u8_formats = self._extract_m3u8_formats(
                video_url_base + '.ism/video.m3u8', video_id,
                'mp4', 'm3u8_native', m3u8_id='hls', fatal=False)
            self._sort_formats(m3u8_formats)
            m3u8_formats = list(filter(
                lambda f: f.get('vcodec') != 'none' and f.get('resolution') != 'multiple',
                m3u8_formats))
            formats.extend(m3u8_formats)
            for i, m3u8_format in enumerate(m3u8_formats, 2):
                http_url = '%s-%d.mp4' % (video_url_base, i)
                if self._is_valid_url(http_url, video_id):
                    f = m3u8_format.copy()
                    f.update({
                        'url': http_url,
                        'format_id': f['format_id'].replace('hls', 'http'),
                        'protocol': 'http',
                    })
                    formats.append(f)
        else:
            formats = [{
                'format_id': 'direct',
                'url': video_url,
                'ext': determine_ext(video_url, 'mp4'),
            }]

        self._sort_formats(formats)

        return {
            'id': video_id,
            'title': title,
            'thumbnail': thumbnail,
            'formats': formats,
        }

class TVPSeriesIE(InfoExtractor):
    IE_NAME = 'tvp:series'
    _VALID_URL = r'https?://vod\.tvp\.pl/(?:[^/]+/){2}(?P<id>[^/]+)/?$'

    _TESTS = [{
        'url': 'http://vod.tvp.pl/filmy-fabularne/filmy-za-darmo/ogniem-i-mieczem',
        'info_dict': {
            'title': 'Ogniem i mieczem',
            'id': '4278026',
        },
        'playlist_count': 4,
    }, {
        'url': 'http://vod.tvp.pl/audycje/podroze/boso-przez-swiat',
        'info_dict': {
            'title': 'Boso przez świat',
            'id': '9329207',
        },
        'playlist_count': 86,
    }]

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id, tries=5)

        title = self._html_search_regex(
            r'(?s) id=[\'"]path[\'"]>(?:.*? / ){2}(.*?)', webpage, 'series')
        playlist_id = self._search_regex(r'nodeId:\s*(\d+)', webpage, 'playlist id')
        playlist = self._download_webpage(
            'http://vod.tvp.pl/vod/seriesAjax?type=series&nodeId=%s&recommend'
            'edId=0&sort=&page=0&pageSize=10000' % playlist_id, display_id, tries=5,
            note='Downloading playlist')

        videos_paths = re.findall(
            '(?s)class="shortTitle">.*?href="(/[^"]+)', playlist)
        entries = [
            self.url_result('http://vod.tvp.pl%s' % v_path, ie=TVPIE.ie_key())
            for v_path in videos_paths]

        return {
            '_type': 'playlist',
            'id': playlist_id,
            'display_id': display_id,
            'title': title,
            'entries': entries,
        }
<commit_msg>[tvp] Update dash format comment<commit_after># coding: utf-8
from __future__ import unicode_literals

import re

from .common import InfoExtractor
from ..utils import (
    determine_ext,
    clean_html,
    get_element_by_attribute,
    ExtractorError,
)

class TVPIE(InfoExtractor):
    IE_NAME = 'tvp'
    IE_DESC = 'Telewizja Polska'
    _VALID_URL = r'https?://[^/]+\.tvp\.(?:pl|info)/(?:(?!\d+/)[^/]+/)*(?P<id>\d+)'

    _TESTS = [{
        'url': 'http://vod.tvp.pl/194536/i-seria-odc-13',
        'md5': '8aa518c15e5cc32dfe8db400dc921fbb',
        'info_dict': {
            'id': '194536',
            'ext': 'mp4',
            'title': 'Czas honoru, I seria – odc. 13',
        },
    }, {
        'url': 'http://www.tvp.pl/there-can-be-anything-so-i-shortened-it/17916176',
        'md5': 'b0005b542e5b4de643a9690326ab1257',
        'info_dict': {
            'id': '17916176',
            'ext': 'mp4',
            'title': 'TVP Gorzów pokaże filmy studentów z podroży dookoła świata',
        },
    }, {
        'url': 'http://vod.tvp.pl/seriale/obyczajowe/na-sygnale/sezon-2-27-/odc-39/17834272',
        'only_matching': True,
    }, {
        'url': 'http://wiadomosci.tvp.pl/25169746/24052016-1200',
        'only_matching': True,
    }, {
        'url': 'http://krakow.tvp.pl/25511623/25lecie-mck-wyjatkowe-miejsce-na-mapie-krakowa',
        'only_matching': True,
    }, {
        'url': 'http://teleexpress.tvp.pl/25522307/wierni-wzieli-udzial-w-procesjach',
        'only_matching': True,
    }, {
        'url': 'http://sport.tvp.pl/25522165/krychowiak-uspokaja-w-sprawie-kontuzji-dwa-tygodnie-to-maksimum',
        'only_matching': True,
    }, {
        'url': 'http://www.tvp.info/25511919/trwa-rewolucja-wladza-zdecydowala-sie-na-pogwalcenie-konstytucji',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        video_id = self._match_id(url)

        webpage = self._download_webpage(
            'http://www.tvp.pl/sess/tvplayer.php?object_id=%s' % video_id, video_id)

        error_massage = get_element_by_attribute('class', 'msg error', webpage)
        if error_massage:
            raise ExtractorError('%s said: %s' % (
                self.IE_NAME, clean_html(error_massage)), expected=True)

        title = self._search_regex(
            r'name\s*:\s*([\'"])Title\1\s*,\s*value\s*:\s*\1(?P<title>.+?)\1',
            webpage, 'title', group='title')
        series_title = self._search_regex(
            r'name\s*:\s*([\'"])SeriesTitle\1\s*,\s*value\s*:\s*\1(?P<series>.+?)\1',
            webpage, 'series', group='series', default=None)
        if series_title:
            title = '%s, %s' % (series_title, title)

        thumbnail = self._search_regex(
            r"poster\s*:\s*'([^']+)'", webpage, 'thumbnail', default=None)

        video_url = self._search_regex(
            r'0:{src:([\'"])(?P<url>.*?)\1', webpage,
            'formats', group='url', default=None)
        if not video_url or 'material_niedostepny.mp4' in video_url:
            video_url = self._download_json(
                'http://www.tvp.pl/pub/stat/videofileinfo?video_id=%s' % video_id,
                video_id)['video_url']

        formats = []
        video_url_base = self._search_regex(
            r'(https?://.+?/video)(?:\.(?:ism|f4m|m3u8)|-\d+\.mp4)',
            video_url, 'video base url', default=None)
        if video_url_base:
            # TODO: <Group> found instead of <AdaptationSet> in MPD manifest.
            # It's not mentioned in MPEG-DASH standard. Figure that out.
            # formats.extend(self._extract_mpd_formats(
            #     video_url_base + '.ism/video.mpd',
            #     video_id, mpd_id='dash', fatal=False))
            formats.extend(self._extract_f4m_formats(
                video_url_base + '.ism/video.f4m',
                video_id, f4m_id='hds', fatal=False))
            m3u8_formats = self._extract_m3u8_formats(
                video_url_base + '.ism/video.m3u8', video_id,
                'mp4', 'm3u8_native', m3u8_id='hls', fatal=False)
            self._sort_formats(m3u8_formats)
            m3u8_formats = list(filter(
                lambda f: f.get('vcodec') != 'none' and f.get('resolution') != 'multiple',
                m3u8_formats))
            formats.extend(m3u8_formats)
            for i, m3u8_format in enumerate(m3u8_formats, 2):
                http_url = '%s-%d.mp4' % (video_url_base, i)
                if self._is_valid_url(http_url, video_id):
                    f = m3u8_format.copy()
                    f.update({
                        'url': http_url,
                        'format_id': f['format_id'].replace('hls', 'http'),
                        'protocol': 'http',
                    })
                    formats.append(f)
        else:
            formats = [{
                'format_id': 'direct',
                'url': video_url,
                'ext': determine_ext(video_url, 'mp4'),
            }]

        self._sort_formats(formats)

        return {
            'id': video_id,
            'title': title,
            'thumbnail': thumbnail,
            'formats': formats,
        }

class TVPSeriesIE(InfoExtractor):
    IE_NAME = 'tvp:series'
    _VALID_URL = r'https?://vod\.tvp\.pl/(?:[^/]+/){2}(?P<id>[^/]+)/?$'

    _TESTS = [{
        'url': 'http://vod.tvp.pl/filmy-fabularne/filmy-za-darmo/ogniem-i-mieczem',
        'info_dict': {
            'title': 'Ogniem i mieczem',
            'id': '4278026',
        },
        'playlist_count': 4,
    }, {
        'url': 'http://vod.tvp.pl/audycje/podroze/boso-przez-swiat',
        'info_dict': {
            'title': 'Boso przez świat',
            'id': '9329207',
        },
        'playlist_count': 86,
    }]

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id, tries=5)

        title = self._html_search_regex(
            r'(?s) id=[\'"]path[\'"]>(?:.*? / ){2}(.*?)', webpage, 'series')
        playlist_id = self._search_regex(r'nodeId:\s*(\d+)', webpage, 'playlist id')
        playlist = self._download_webpage(
            'http://vod.tvp.pl/vod/seriesAjax?type=series&nodeId=%s&recommend'
            'edId=0&sort=&page=0&pageSize=10000' % playlist_id, display_id, tries=5,
            note='Downloading playlist')

        videos_paths = re.findall(
            '(?s)class="shortTitle">.*?href="(/[^"]+)', playlist)
        entries = [
            self.url_result('http://vod.tvp.pl%s' % v_path, ie=TVPIE.ie_key())
            for v_path in videos_paths]

        return {
            '_type': 'playlist',
            'id': playlist_id,
            'display_id': display_id,
            'title': title,
            'entries': entries,
        }
<|endoftext|>


<commit_before>"""Tink rules for java."""

load("//tools/build_defs/android:rules.bzl", "android_binary", "android_instrumentation_test")

## TODO(b/185807287): Remove the remaining instances of collect_android_libraries_and_make_test_suite
## by replacing them with tink_android_test as in cl/423316322.
def collect_android_libraries_and_make_test_suite(name, shard_count = 1):
    """Creates an android test suite for android_library in the current package.

    Creates, for a bunch of devices, an android_instrumentation_test which
    runs all tests previously defined in android_library, but only for
    the versions specified there.

    If the android_library target has a tag "android_min_version:xx", the
    corresponding test is only added to android versions xx and above.

    Args:
        name: The prefix of the generated android test rules.
        shard_count: the number of shards under which the resulting binary runs.
    """

    TARGET_DEVICES = {
        19: "//tools/mobile/devices/android/nexus_5:google_19_x86_gms_stable",
        21: "//tools/mobile/devices/android/nexus_6:google_21_x86",
        22: "//tools/mobile/devices/android/nexus_6:google_22_x86",
        23: "//tools/mobile/devices/android/nexus_6:google_23_x86",
        24: "//tools/mobile/devices/android/nexus_6:google_24_x86",
        25: "//tools/mobile/devices/android/nexus_6p:google_25_x86",
        26: "//tools/mobile/devices/android/pixel_c:google_26_x86",
        27: "//tools/mobile/devices/android/pixel_xl:google_27_x86",
    }

    for version_num, device in TARGET_DEVICES.items():
        dependencies = {}
        data = {}
        for target_name, library_target in native.existing_rules().items():
            android_min_version = 0
            if "tags" in library_target:
                for tag in library_target["tags"]:
                    if tag.startswith("android_min_version"):
                        _, x = tag.split(":")
                        android_min_version = int(x)
                        break
            if library_target["kind"] == "android_library" and android_min_version <= version_num:
                dependencies[target_name] = True
                if "data" in library_target:
                    for entry in library_target["data"]:
                        data[entry] = True
        if len(dependencies) == 0:
            # Do not create a test target if there is nothing to test.
            continue
        dependencies["//java/com/google/android/apps/common/testing/testrunner"] = True

        binary_name = name + "_" + str(version_num) + "_collected_binary"

        # Some tests require --config=android_java8_libs which in turn requires enabling multidex.
        # See go/java8-libs-for-android-faq for details.
        multidex = "native"
        if version_num < 21:
            multidex = "legacy"
            dependencies["//third_party/java/android/android_sdk_linux/extras/android/compatibility/multidex"] = True
        android_binary(
            name = binary_name,
            deps = list(dependencies),
            manifest = "//third_party/tink/java_src/src/androidtest:AndroidManifest.xml",
            testonly = 1,
            multidex = multidex,
        )
        android_instrumentation_test(
            name = name + "_" + str(version_num) + "_test",
            shard_count = shard_count,
            target_device = device,
            test_app = binary_name,
            data = list(data),
            tags = ["manual"],
        )

def tink_android_test(name, srcs, deps, min_version = 19):
    """Creates android_instrumentation_test targets, testing them on multiple devices.

    Args:
        name: The name of the test created.
        srcs: The test source of the test.
        deps: The dependencies.
        min_version: The minimum version of android which should be tested.
    """
    TARGET_DEVICES = {
        19: "//tools/mobile/devices/android/nexus_5:google_19_x86_gms_stable",
        21: "//tools/mobile/devices/android/nexus_6:google_21_x86",
        22: "//tools/mobile/devices/android/nexus_6:google_22_x86",
        23: "//tools/mobile/devices/android/nexus_6:google_23_x86",
        24: "//tools/mobile/devices/android/nexus_6:google_24_x86",
        25: "//tools/mobile/devices/android/nexus_6p:google_25_x86",
        26: "//tools/mobile/devices/android/pixel_c:google_26_x86",
        27: "//tools/mobile/devices/android/pixel_xl:google_27_x86",
    }

    deps.append("//java/com/google/android/apps/common/testing/testrunner")

    # Some tests require --config=android_java8_libs  which in turn requires enabling multidex.
    # See go/java8-libs-for-android-faq for details.

    native_multidex_binary = name + "_native_binary"
    android_binary(
        srcs = srcs,
        name = native_multidex_binary,
        deps = deps,
        manifest = "//third_party/tink/java_src/src/androidtest:AndroidManifest.xml",
        testonly = 1,
        multidex = "native",
    )

    legacy_multidex_binary = name + "_legacy_binary"
    deps_copy = list(deps)
    deps_copy.append("//third_party/java/android/android_sdk_linux/extras/android/compatibility/multidex")
    android_binary(
        srcs = srcs,
        name = legacy_multidex_binary,
        deps = deps_copy,
        manifest = "//third_party/tink/java_src/src/androidtest:AndroidManifest.xml",
        testonly = 1,
        multidex = "legacy",
    )

    for version_num, device in TARGET_DEVICES.items():
        if version_num >= min_version:
            android_instrumentation_test(
                name = name + "_" + str(version_num) + "_test",
                target_device = device,
                test_app = legacy_multidex_binary if version_num < 21 else native_multidex_binary,
                tags = ["manual"],
            )
<commit_msg>Add an internal way to add data for tests in android_tests.<commit_after>"""Tink rules for java."""

load("//tools/build_defs/android:rules.bzl", "android_binary", "android_instrumentation_test")

## TODO(b/185807287): Remove the remaining instances of collect_android_libraries_and_make_test_suite
## by replacing them with tink_android_test as in cl/423316322.
def collect_android_libraries_and_make_test_suite(name, shard_count = 1):
    """Creates an android test suite for android_library in the current package.

    Creates, for a bunch of devices, an android_instrumentation_test which
    runs all tests previously defined in android_library, but only for
    the versions specified there.

    If the android_library target has a tag "android_min_version:xx", the
    corresponding test is only added to android versions xx and above.

    Args:
        name: The prefix of the generated android test rules.
        shard_count: the number of shards under which the resulting binary runs.
    """

    TARGET_DEVICES = {
        19: "//tools/mobile/devices/android/nexus_5:google_19_x86_gms_stable",
        21: "//tools/mobile/devices/android/nexus_6:google_21_x86",
        22: "//tools/mobile/devices/android/nexus_6:google_22_x86",
        23: "//tools/mobile/devices/android/nexus_6:google_23_x86",
        24: "//tools/mobile/devices/android/nexus_6:google_24_x86",
        25: "//tools/mobile/devices/android/nexus_6p:google_25_x86",
        26: "//tools/mobile/devices/android/pixel_c:google_26_x86",
        27: "//tools/mobile/devices/android/pixel_xl:google_27_x86",
    }

    for version_num, device in TARGET_DEVICES.items():
        dependencies = {}
        data = {}
        for target_name, library_target in native.existing_rules().items():
            android_min_version = 0
            if "tags" in library_target:
                for tag in library_target["tags"]:
                    if tag.startswith("android_min_version"):
                        _, x = tag.split(":")
                        android_min_version = int(x)
                        break
            if library_target["kind"] == "android_library" and android_min_version <= version_num:
                dependencies[target_name] = True
                if "data" in library_target:
                    for entry in library_target["data"]:
                        data[entry] = True
        if len(dependencies) == 0:
            # Do not create a test target if there is nothing to test.
            continue
        dependencies["//java/com/google/android/apps/common/testing/testrunner"] = True

        binary_name = name + "_" + str(version_num) + "_collected_binary"

        # Some tests require --config=android_java8_libs which in turn requires enabling multidex.
        # See go/java8-libs-for-android-faq for details.
        multidex = "native"
        if version_num < 21:
            multidex = "legacy"
            dependencies["//third_party/java/android/android_sdk_linux/extras/android/compatibility/multidex"] = True
        android_binary(
            name = binary_name,
            deps = list(dependencies),
            manifest = "//third_party/tink/java_src/src/androidtest:AndroidManifest.xml",
            testonly = 1,
            multidex = multidex,
        )
        android_instrumentation_test(
            name = name + "_" + str(version_num) + "_test",
            shard_count = shard_count,
            target_device = device,
            test_app = binary_name,
            data = list(data),
            tags = ["manual"],
        )

def tink_android_test(name, srcs, deps, data = [], min_version = 19):
    """Creates android_instrumentation_test targets, testing them on multiple devices.

    Args:
        name: The name of the test created.
        srcs: The test source of the test.
        deps: The dependencies.
        data: Data dependencies.
        min_version: The minimum version of android which should be tested.
    """
    TARGET_DEVICES = {
        19: "//tools/mobile/devices/android/nexus_5:google_19_x86_gms_stable",
        21: "//tools/mobile/devices/android/nexus_6:google_21_x86",
        22: "//tools/mobile/devices/android/nexus_6:google_22_x86",
        23: "//tools/mobile/devices/android/nexus_6:google_23_x86",
        24: "//tools/mobile/devices/android/nexus_6:google_24_x86",
        25: "//tools/mobile/devices/android/nexus_6p:google_25_x86",
        26: "//tools/mobile/devices/android/pixel_c:google_26_x86",
        27: "//tools/mobile/devices/android/pixel_xl:google_27_x86",
    }

    deps.append("//java/com/google/android/apps/common/testing/testrunner")

    # Some tests require --config=android_java8_libs  which in turn requires enabling multidex.
    # See go/java8-libs-for-android-faq for details.

    native_multidex_binary = name + "_native_binary"
    android_binary(
        srcs = srcs,
        name = native_multidex_binary,
        deps = deps,
        manifest = "//third_party/tink/java_src/src/androidtest:AndroidManifest.xml",
        testonly = 1,
        multidex = "native",
    )

    legacy_multidex_binary = name + "_legacy_binary"
    deps_copy = list(deps)
    deps_copy.append("//third_party/java/android/android_sdk_linux/extras/android/compatibility/multidex")
    android_binary(
        srcs = srcs,
        name = legacy_multidex_binary,
        deps = deps_copy,
        manifest = "//third_party/tink/java_src/src/androidtest:AndroidManifest.xml",
        testonly = 1,
        multidex = "legacy",
    )

    for version_num, device in TARGET_DEVICES.items():
        if version_num >= min_version:
            android_instrumentation_test(
                name = name + "_" + str(version_num) + "_test",
                target_device = device,
                test_app = legacy_multidex_binary if version_num < 21 else native_multidex_binary,
                data = data,
                tags = ["manual"],
            )
<|endoftext|>


<commit_before>import os
import subprocess

def update(token=None):
    if token is None:
        token = os.environ["STATUS_GH_TOKEN"]

    subprocess.check_call([
        "statuspage",
        "update",
        "--org",
        "conda-forge",
        "--name",
        "status",
        "--token",
        token
    ])

def main():
    import argparse

    parser = argparse.ArgumentParser(
        prog="status",
        description="Updates the status page.",
    )

    update(os.environ["GH_TOKEN"])

if __name__ == '__main__':
    main()
<commit_msg>status: Fix token that was not renamed.<commit_after>import os
import subprocess

def update(token=None):
    if token is None:
        token = os.environ["STATUS_GH_TOKEN"]

    subprocess.check_call([
        "statuspage",
        "update",
        "--org",
        "conda-forge",
        "--name",
        "status",
        "--token",
        token
    ])

def main():
    import argparse

    parser = argparse.ArgumentParser(
        prog="status",
        description="Updates the status page.",
    )

    update(os.environ["STATUS_GH_TOKEN"])

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# encoding: utf-8

'''
Version information constants and auxiliary functions.
'''

VERSION = (0, 5, 0)

import os
import subprocess as sub

__here__ = os.path.abspath(os.path.dirname(__file__))

def _check_output(*cmd):
    p = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, cwd=__here__)
    return p.communicate()[0].rstrip('\n')

# PEP8 hates me
_gitsha = lambda : _check_output('git', 'rev-parse',    'HEAD')
_gitbrc = lambda : _check_output('git', 'symbolic-ref', 'HEAD').replace('refs/heads/', '')

def version():
    return '.'.join([str(i) for i in VERSION])

def version_verbose():
    res = 'jenkins-autojobs version %s' % version()
    try:
        sha = _gitsha() ; brc = _gitbrc()
        if sha or brc:
            res = '%s (%s:%s)' % (res, brc, sha[:8])
    except:
        pass

    return res

__all__ = (VERSION, version, version_verbose)

if __name__ == '__main__':
    from sys import stdout
    stdout.write(version_verbose())
<commit_msg>bump version to 0.6.0<commit_after>#!/usr/bin/env python
# encoding: utf-8

'''
Version information constants and auxiliary functions.
'''

VERSION = (0, 6, 0)

import os
import subprocess as sub

__here__ = os.path.abspath(os.path.dirname(__file__))

def _check_output(*cmd):
    p = sub.Popen(cmd, stdout=sub.PIPE, stderr=sub.PIPE, cwd=__here__)
    return p.communicate()[0].rstrip('\n')

# PEP8 hates me
_gitsha = lambda : _check_output('git', 'rev-parse',    'HEAD')
_gitbrc = lambda : _check_output('git', 'symbolic-ref', 'HEAD').replace('refs/heads/', '')

def version():
    return '.'.join([str(i) for i in VERSION])

def version_verbose():
    res = 'jenkins-autojobs version %s' % version()
    try:
        sha = _gitsha() ; brc = _gitbrc()
        if sha or brc:
            res = '%s (%s:%s)' % (res, brc, sha[:8])
    except:
        pass

    return res

__all__ = (VERSION, version, version_verbose)

if __name__ == '__main__':
    from sys import stdout
    stdout.write(version_verbose())
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright (c) 2014, Andreas Pakulat <apaku@gmx.de>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from PyQt4 import QtCore, QtGui, uic
from PyQt4.Qt import QProgressDialog
from threading import Thread
from ..jenkinsmonitor import JenkinsMonitor

class ServerListModel(QtGui.QStringListModel):
    pass

class JobListModel(QtGui.QStringListModel):
    def __init__(self, jobs, parent):
        QtGui.QStringListModel.__init__(self, map(lambda x: x["name"], jobs), parent)
        self.jobs = jobs

    def data(self, idx, role):
        """
        :type idx: QtCore.QModelIndex
        :type role: QtCore.Qt.ItemDataRole
        """
        if role == QtCore.Qt.CheckStateRole:
            return QtCore.Qt.Checked if self.jobs[idx.row()]["monitored"] else QtCore.Qt.Unchecked
        else:
            return QtGui.QStringListModel.data(self, idx, role)

    def setData(self, idx, data, role):
        """
        :type idx: QtCore.QModelIndex
        :type data: QtCore.QVariant
        :type role: QtCore.Qt.ItemDataRole
        """
        if role == QtCore.Qt.CheckStateRole:
            self.jobs[idx.row()]["monitored"] = True if data == QtCore.Qt.Checked else False
            return True
        else:
            return QtGui.QStringListModel.setData(self, idx, data, role)

    def flags(self, idx):
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable

def loadJobs(settingsWidget, serverurl):
    monitor = JenkinsMonitor(serverurl)
    monitor.refreshFromServer()
    settingsWidget.jobsReceived(serverurl, map(lambda job: {"name": job.name,
                                                            "monitored": False}, monitor.jobs))

class SettingsWidget(QtGui.QWidget):

    jobsDone = QtCore.pyqtSignal()

    def __init__(self, parent, settingsobj):
        QtGui.QWidget.__init__(self, parent)
        self.settings = settingsobj
        self.uiFile = QtCore.QFile(":///gui/settings.ui")
        self.uiFile.open(QtCore.QIODevice.ReadOnly)
        uic.loadUi(self.uiFile, self)
        self.refreshInterval.setValue(self.settings["refreshInterval"])
        self.refreshInterval.valueChanged.connect(self.updateRefreshInterval)
        self.refreshModel()
        self.removeServerBtn.setEnabled(False)
        self.addServerBtn.clicked.connect(self.addServer)
        self.removeServerBtn.clicked.connect(self.removeServer)

    def addServer(self):
        dlg = QtGui.QInputDialog(self)
        dlg.setLabelText("Provide the normal url the Jenkins server can be contacted at:")
        dlg.setWindowTitle("Add Jenkins Server")
        dlg.setInputMode(QtGui.QInputDialog.TextInput)
        dlg.setMinimumSize(120, 400)
        if dlg.exec_() == QtGui.QDialog.Accepted:
            self.settings["servers"].append({"url":dlg.textValue(), "jobs":[]})
            serverurl = dlg.textValue()
            self.fetchJobs(serverurl)
            self.refreshModel(serverurl)

    def fetchJobs(self, serverurl):
        dlg = QProgressDialog(self)
        thread = Thread(target=lambda: loadJobs(self, serverurl))
        thread.start()
        self.jobsDone.connect(dlg.close)
        dlg.exec_()

    def jobsReceived(self, serverurl, joblist):
        server = filter(lambda server: server["url"] == serverurl, self.settings["servers"])[0]
        server["jobs"] = joblist
        self.jobsDone.emit()

    def removeServer(self):
        selection = self.serverList.selectionModel().selectedRows()
        for idx in selection:
            del self.settings["servers"][idx.row()]
            self.refreshModel()

    def refreshModel(self, selectServer=None):
        self.serverList.setModel(ServerListModel(map(lambda x: x["url"], self.settings["servers"]), self.serverList))
        self.serverList.selectionModel().selectionChanged.connect(self.serverSelected)
        if selectServer is not None:
            row = -1
            for i in range(len(self.settings["servers"])):
                if self.settings["servers"][i]["url"] == selectServer:
                    row = i
            if row != -1:
                model = self.serverList.model()
                self.serverList.selectionModel().select(model.index(row, 0, QtCore.QModelIndex()), QtGui.QItemSelectionModel.ClearAndSelect)
        else:
            self.jobList.setModel(None)

    def updateRefreshInterval(self, val):
        self.settings["refreshInterval"] = val

    def serverSelected(self, selected, deselected):
        """
        :type selected: QtGui.QItemSelection
        :type deselected: QtGui.QItemSelection
        """
        if len(selected.indexes()) > 0:
            idx = selected.indexes()[0]
            self.removeServerBtn.setEnabled(True)
            serverUrl = idx.data()
            server = filter(lambda x: x["url"] == serverUrl, self.settings["servers"])[0]
            self.jobList.setModel(JobListModel(server["jobs"], self.jobList))
        else:
            self.removeServerBtn.setEnabled(False)
            self.jobList.setModel(None)
<commit_msg>Handle errors and cancellation of the job-loading<commit_after># -*- coding: utf-8 -*-
# Copyright (c) 2014, Andreas Pakulat <apaku@gmx.de>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from PyQt4 import QtCore, QtGui, uic
from PyQt4.Qt import QProgressDialog
from threading import Thread
from ..jenkinsmonitor import JenkinsMonitor

class ServerListModel(QtGui.QStringListModel):
    pass

class JobListModel(QtGui.QStringListModel):
    def __init__(self, jobs, parent):
        QtGui.QStringListModel.__init__(self, map(lambda x: x["name"], jobs), parent)
        self.jobs = jobs

    def data(self, idx, role):
        """
        :type idx: QtCore.QModelIndex
        :type role: QtCore.Qt.ItemDataRole
        """
        if role == QtCore.Qt.CheckStateRole:
            return QtCore.Qt.Checked if self.jobs[idx.row()]["monitored"] else QtCore.Qt.Unchecked
        else:
            return QtGui.QStringListModel.data(self, idx, role)

    def setData(self, idx, data, role):
        """
        :type idx: QtCore.QModelIndex
        :type data: QtCore.QVariant
        :type role: QtCore.Qt.ItemDataRole
        """
        if role == QtCore.Qt.CheckStateRole:
            self.jobs[idx.row()]["monitored"] = True if data == QtCore.Qt.Checked else False
            return True
        else:
            return QtGui.QStringListModel.setData(self, idx, data, role)

    def flags(self, idx):
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable

def loadJobs(settingsWidget, serverurl):
    try:
        monitor = JenkinsMonitor(serverurl)
        monitor.refreshFromServer()
        settingsWidget.jobsReceived.emit(serverurl, map(lambda job: {"name": job.name,
                                                                     "monitored": False}, monitor.jobs))
    except Exception, e:
        settingsWidget.jobLoadFailed.emit(serverurl, repr(e))

class SettingsWidget(QtGui.QWidget):

    jobsReceived = QtCore.pyqtSignal(str, list)
    jobLoadFailed = QtCore.pyqtSignal(str, str)

    def __init__(self, parent, settingsobj):
        QtGui.QWidget.__init__(self, parent)
        self.settings = settingsobj
        self.uiFile = QtCore.QFile(":///gui/settings.ui")
        self.uiFile.open(QtCore.QIODevice.ReadOnly)
        uic.loadUi(self.uiFile, self)
        self.refreshInterval.setValue(self.settings["refreshInterval"])
        self.refreshInterval.valueChanged.connect(self.updateRefreshInterval)
        self.refreshModel()
        self.removeServerBtn.setEnabled(False)
        self.addServerBtn.clicked.connect(self.addServer)
        self.removeServerBtn.clicked.connect(self.removeServer)

    def reportError(self, serverurl, error):
        QtGui.QMessageBox.critical(self, "Error loading job list", "Failed to fetch job list for %s: %s." % (serverurl, error))

    def addJobs(self, serverurl, joblist):
        server = filter(lambda server: server["url"] == serverurl, self.settings["servers"])[0]
        server["jobs"] = joblist

    def addServer(self):
        dlg = QtGui.QInputDialog(self)
        dlg.setLabelText("Provide the normal url the Jenkins server can be contacted at:")
        dlg.setWindowTitle("Add Jenkins Server")
        dlg.setInputMode(QtGui.QInputDialog.TextInput)
        dlg.setMinimumSize(120, 400)
        if dlg.exec_() == QtGui.QDialog.Accepted:
            self.settings["servers"].append({"url":dlg.textValue(), "jobs":[]})
            serverurl = dlg.textValue()
            self.fetchJobs(serverurl)
            self.refreshModel(serverurl)

    def fetchJobs(self, serverurl):
        dlg = QProgressDialog(self)
        self.jobsReceived.connect(self.addJobs)
        self.jobLoadFailed.connect(self.reportError)
        self.jobsReceived.connect(dlg.accept)
        self.jobLoadFailed.connect(dlg.accept)
        thread = Thread(target=lambda: loadJobs(self, serverurl))
        thread.start()
        dlg.exec_()
        self.jobLoadFailed.disconnect()
        self.jobsReceived.disconnect()
        if dlg.wasCanceled():
            server = filter(lambda server: server["url"] == serverurl, self.settings["servers"])[0]
            self.settings["servers"].remove(server)

    def removeServer(self):
        selection = self.serverList.selectionModel().selectedRows()
        for idx in selection:
            del self.settings["servers"][idx.row()]
            self.refreshModel()

    def refreshModel(self, selectServer=None):
        self.serverList.setModel(ServerListModel(map(lambda x: x["url"], self.settings["servers"]), self.serverList))
        self.serverList.selectionModel().selectionChanged.connect(self.serverSelected)
        if selectServer is not None:
            row = -1
            for i in range(len(self.settings["servers"])):
                if self.settings["servers"][i]["url"] == selectServer:
                    row = i
            if row != -1:
                model = self.serverList.model()
                self.serverList.selectionModel().select(model.index(row, 0, QtCore.QModelIndex()), QtGui.QItemSelectionModel.ClearAndSelect)
        else:
            self.jobList.setModel(None)

    def updateRefreshInterval(self, val):
        self.settings["refreshInterval"] = val

    def serverSelected(self, selected, deselected):
        """
        :type selected: QtGui.QItemSelection
        :type deselected: QtGui.QItemSelection
        """
        if len(selected.indexes()) > 0:
            idx = selected.indexes()[0]
            self.removeServerBtn.setEnabled(True)
            serverUrl = idx.data()
            server = filter(lambda x: x["url"] == serverUrl, self.settings["servers"])[0]
            self.jobList.setModel(JobListModel(server["jobs"], self.jobList))
        else:
            self.removeServerBtn.setEnabled(False)
            self.jobList.setModel(None)
<|endoftext|>


<commit_before>from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from builtins import *  # NOQA
from future import standard_library
standard_library.install_aliases()

import unittest

import chainer
import chainer.functions as F
from chainer import testing
from chainer.testing import attr
import numpy as np

import chainerrl

class _TestDeterministicPolicy(unittest.TestCase):

    def _test_call_given_model(self, model, gpu):
        # This method only check if a given model can receive random input
        # data and return output data with the correct interface.
        min_action = np.full((self.action_size,), -0.01, dtype=np.float32)
        max_action = np.full((self.action_size,), 0.01, dtype=np.float32)
        batch_size = 7
        x = np.random.rand(
            batch_size, self.n_input_channels).astype(np.float32)
        if gpu >= 0:
            model.to_gpu(gpu)
            x = chainer.cuda.to_gpu(x)
            min_action = chainer.cuda.to_gpu(min_action)
            max_action = chainer.cuda.to_gpu(max_action)
        y = model(x)
        self.assertTrue(isinstance(
            y, chainerrl.distribution.ContinuousDeterministicDistribution))
        a = y.sample()
        self.assertTrue(isinstance(a, chainer.Variable))
        self.assertEqual(a.shape, (batch_size, self.action_size))
        self.assertEqual(chainer.cuda.get_array_module(a),
                         chainer.cuda.get_array_module(x))
        if self.bound_action:
            self.assertTrue((a.data <= max_action).all())
            self.assertTrue((a.data >= min_action).all())

@testing.parameterize(
    *testing.product({
        'n_input_channels': [1, 5],
        'action_size': [1, 2],
        'bound_action': [True, False],
        'nonlinearity': ['relu', 'elu'],
        'model_kwargs': testing.product({
            'n_hidden_layers': [0, 1, 2],
            'n_hidden_channels': [1, 2],
            'last_wscale': [1, 1e-3],
        }),
    })
)
class TestFCDeterministicPolicy(_TestDeterministicPolicy):

    def _test_call(self, gpu):
        nonlinearity = getattr(F, self.nonlinearity)
        min_action = np.full((self.action_size,), -0.01, dtype=np.float32)
        max_action = np.full((self.action_size,), 0.01, dtype=np.float32)
        model = chainerrl.policies.FCDeterministicPolicy(
            n_input_channels=self.n_input_channels,
            action_size=self.action_size,
            bound_action=self.bound_action,
            min_action=min_action,
            max_action=max_action,
            nonlinearity=nonlinearity,
            **self.model_kwargs,
        )
        self._test_call_given_model(model, gpu)

    def test_call_cpu(self):
        self._test_call(gpu=-1)

    @attr.gpu
    def test_call_gpu(self):
        self._test_call(gpu=0)

@testing.parameterize(
    *testing.product({
        'n_input_channels': [1, 5],
        'action_size': [1, 2],
        'bound_action': [True, False],
        'nonlinearity': ['relu', 'elu'],
        'model_kwargs': testing.product({
            'n_hidden_layers': [0, 1, 2],
            'n_hidden_channels': [1, 2],
            'normalize_input': [True, False],
            'last_wscale': [1, 1e-3],
        }),
    })
)
class TestFCBNDeterministicPolicy(_TestDeterministicPolicy):

    def _test_call(self, gpu):
        nonlinearity = getattr(F, self.nonlinearity)
        min_action = np.full((self.action_size,), -0.01, dtype=np.float32)
        max_action = np.full((self.action_size,), 0.01, dtype=np.float32)
        model = chainerrl.policies.FCBNDeterministicPolicy(
            n_input_channels=self.n_input_channels,
            action_size=self.action_size,
            bound_action=self.bound_action,
            min_action=min_action,
            max_action=max_action,
            nonlinearity=nonlinearity,
            **self.model_kwargs,
        )
        self._test_call_given_model(model, gpu)

    def test_call_cpu(self):
        self._test_call(gpu=-1)

    @attr.gpu
    def test_call_gpu(self):
        self._test_call(gpu=0)

@testing.parameterize(
    *testing.product({
        'n_input_channels': [1, 5],
        'action_size': [1, 2],
        'bound_action': [True, False],
        'nonlinearity': ['relu', 'elu'],
        'model_kwargs': testing.product({
            'n_hidden_layers': [0, 1, 2],
            'n_hidden_channels': [1, 2],
            'last_wscale': [1, 1e-3],
        }),
    })
)
class TestFCLSTMDeterministicPolicy(_TestDeterministicPolicy):

    def _test_call(self, gpu):
        nonlinearity = getattr(F, self.nonlinearity)
        min_action = np.full((self.action_size,), -0.01, dtype=np.float32)
        max_action = np.full((self.action_size,), 0.01, dtype=np.float32)
        model = chainerrl.policies.FCLSTMDeterministicPolicy(
            n_input_channels=self.n_input_channels,
            action_size=self.action_size,
            bound_action=self.bound_action,
            min_action=min_action,
            max_action=max_action,
            nonlinearity=nonlinearity,
            **self.model_kwargs,
        )
        self._test_call_given_model(model, gpu)

    def test_call_cpu(self):
        self._test_call(gpu=-1)

    @attr.gpu
    def test_call_gpu(self):
        self._test_call(gpu=0)
<commit_msg>Parameterize tests<commit_after>from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from builtins import *  # NOQA
from future import standard_library
standard_library.install_aliases()

import unittest

import chainer
import chainer.functions as F
from chainer import testing
from chainer.testing import attr
import numpy as np

import chainerrl

@testing.parameterize(
    *testing.product({
        'n_input_channels': [1, 5],
        'action_size': [1, 2],
        'bound_action': [True, False],
        'nonlinearity': ['relu', 'elu'],
        'model_class': [chainerrl.policies.FCDeterministicPolicy],
        'model_kwargs': testing.product({
            'n_hidden_layers': [0, 1, 2],
            'n_hidden_channels': [1, 2],
            'last_wscale': [1, 1e-3],
        }),
    }),
    *testing.product({
        'n_input_channels': [1, 5],
        'action_size': [1, 2],
        'bound_action': [True, False],
        'nonlinearity': ['relu', 'elu'],
        'model_class': [chainerrl.policies.FCBNDeterministicPolicy],
        'model_kwargs': testing.product({
            'n_hidden_layers': [0, 1, 2],
            'n_hidden_channels': [1, 2],
            'normalize_input': [True, False],
            'last_wscale': [1, 1e-3],
        }),
    }),
    *testing.product({
        'n_input_channels': [1, 5],
        'action_size': [1, 2],
        'bound_action': [True, False],
        'nonlinearity': ['relu', 'elu'],
        'model_class': [chainerrl.policies.FCLSTMDeterministicPolicy],
        'model_kwargs': testing.product({
            'n_hidden_layers': [0, 1, 2],
            'n_hidden_channels': [1, 2],
            'last_wscale': [1, 1e-3],
        }),
    })
)
class TestDeterministicPolicy(unittest.TestCase):

    def _test_call(self, gpu):
        # This method only check if a given model can receive random input
        # data and return output data with the correct interface.
        nonlinearity = getattr(F, self.nonlinearity)
        min_action = np.full((self.action_size,), -0.01, dtype=np.float32)
        max_action = np.full((self.action_size,), 0.01, dtype=np.float32)
        model = self.model_class(
            n_input_channels=self.n_input_channels,
            action_size=self.action_size,
            bound_action=self.bound_action,
            min_action=min_action,
            max_action=max_action,
            nonlinearity=nonlinearity,
            **self.model_kwargs,
        )

        batch_size = 7
        x = np.random.rand(
            batch_size, self.n_input_channels).astype(np.float32)
        if gpu >= 0:
            model.to_gpu(gpu)
            x = chainer.cuda.to_gpu(x)
            min_action = chainer.cuda.to_gpu(min_action)
            max_action = chainer.cuda.to_gpu(max_action)
        y = model(x)
        self.assertTrue(isinstance(
            y, chainerrl.distribution.ContinuousDeterministicDistribution))
        a = y.sample()
        self.assertTrue(isinstance(a, chainer.Variable))
        self.assertEqual(a.shape, (batch_size, self.action_size))
        self.assertEqual(chainer.cuda.get_array_module(a),
                         chainer.cuda.get_array_module(x))
        if self.bound_action:
            self.assertTrue((a.data <= max_action).all())
            self.assertTrue((a.data >= min_action).all())

    def test_call_cpu(self):
        self._test_call(gpu=-1)

    @attr.gpu
    def test_call_gpu(self):
        self._test_call(gpu=0)
<|endoftext|>