<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Covers the scenario of a zPoS block where the coinstake input is a zerocoin spend
of an already spent coin.
'''

from random import choice
from time import sleep

from test_framework.authproxy import JSONRPCException

from base_test import PIVX_FakeStakeTest

class Test_03(PIVX_FakeStakeTest):

    def run_test(self):
        self.description = "Covers the scenario of a zPoS block where the coinstake input is a zerocoin spend of an already spent coin."
        self.init_test()

        DENOM_TO_USE = 5000         # zc denomination
        INITAL_MINED_BLOCKS = 321   # First mined blocks (rewards collected to mint)
        MORE_MINED_BLOCKS = 301     # More blocks mined before spending zerocoins
        self.NUM_BLOCKS = 2         # Number of spammed blocks

        # 1) Starting mining blocks
        self.log.info("Mining %d blocks to get to zPOS activation...." % INITAL_MINED_BLOCKS)
        self.node.generate(INITAL_MINED_BLOCKS)
        sleep(2)

        # 2) Collect the possible prevouts and mint zerocoins with those
        self.log.info("Collecting all unspent coins which we generated from mining...")
        balance = self.node.getbalance("*", 100)
        self.log.info("Minting zerocoins...")
        initial_mints = 0
        while balance > DENOM_TO_USE:
            try:
                self.node.mintzerocoin(DENOM_TO_USE)
            except JSONRPCException:
                break
            sleep(1)
            initial_mints += 1
            self.node.generate(1)
            sleep(1)

            if initial_mints % 5 == 0:
                self.log.info("Minted %d coins" % initial_mints)
            if initial_mints >= 70:
                break
            balance = self.node.getbalance("*", 100)
        self.log.info("Minted %d coins in the %d-denom, remaining balance %d", initial_mints, DENOM_TO_USE, balance)
        sleep(2)

        # 3) mine more blocks
        self.log.info("Mining %d more blocks ... and getting spendable zerocoins" % MORE_MINED_BLOCKS)
        self.node.generate(MORE_MINED_BLOCKS)
        sleep(2)
        mints = self.node.listmintedzerocoins(True, True)
        sleep(1)
        stakingPrevOuts = self.get_prevouts(mints, zpos=True)
        mints_hashes = [x["serial hash"] for x in mints]

        # This mints are not ready spendable, only few of them.
        self.log.info("Got %d confirmed mints" % len(mints_hashes))

        # 4) spend mints
        self.log.info("Spending mints in block %d..." % self.node.getblockcount())
        spends = 0
        spent_mints = []
        for mint in mints_hashes:
            # create a single element list to pass to RPC spendzerocoinmints
            mint_arg = []
            mint_arg.append(mint)
            try:
                self.node.spendzerocoinmints(mint_arg)
                sleep(1)
                spends += 1
                spent_mints.append(mint)
            except JSONRPCException as e:
                self.log.warning(str(e))
                continue
        sleep(1)
        self.log.info("Successfully spent %d mints" % spends)

        # 5) Start mining again so that spends get confirmed in a block.
        self.log.info("Mining 5 more blocks...")
        self.node.generate(5)
        sleep(2)

        # 6) Collect some prevouts for random txes
        self.log.info("Collecting inputs for txes...")
        utxo_list = self.node.listunspent()
        spendingPrevOuts = self.get_prevouts(utxo_list)
        sleep(1)

        # 7) Create "Fake Stake" blocks and send them
        self.log.info("Creating Fake stake zPoS blocks...")
        err_msgs = self.test_spam("Main", stakingPrevOuts, spendingPrevOuts=spendingPrevOuts, fZPoS=True)

        if not len(err_msgs) == 0:
            self.log.error("result: " + " | ".join(err_msgs))
            raise AssertionError("TEST FAILED")

        self.log.info("%s PASSED" % self.__class__.__name__)
<commit_msg>[Tests] fix line separators in Test03<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
Covers the scenario of a zPoS block where the coinstake input is a zerocoin spend
of an already spent coin.
'''

from random import choice
from time import sleep

from test_framework.authproxy import JSONRPCException

from base_test import PIVX_FakeStakeTest

class Test_03(PIVX_FakeStakeTest):

    def run_test(self):
        self.description = "Covers the scenario of a zPoS block where the coinstake input is a zerocoin spend of an already spent coin."
        self.init_test()

        DENOM_TO_USE = 5000         # zc denomination
        INITAL_MINED_BLOCKS = 321   # First mined blocks (rewards collected to mint)
        MORE_MINED_BLOCKS = 301     # More blocks mined before spending zerocoins
        self.NUM_BLOCKS = 2         # Number of spammed blocks

        # 1) Starting mining blocks
        self.log.info("Mining %d blocks to get to zPOS activation...." % INITAL_MINED_BLOCKS)
        self.node.generate(INITAL_MINED_BLOCKS)
        sleep(2)

        # 2) Collect the possible prevouts and mint zerocoins with those
        self.log.info("Collecting all unspent coins which we generated from mining...")
        balance = self.node.getbalance("*", 100)
        self.log.info("Minting zerocoins...")
        initial_mints = 0
        while balance > DENOM_TO_USE:
            try:
                self.node.mintzerocoin(DENOM_TO_USE)
            except JSONRPCException:
                break
            sleep(1)
            initial_mints += 1
            self.node.generate(1)
            sleep(1)

            if initial_mints % 5 == 0:
                self.log.info("Minted %d coins" % initial_mints)
            if initial_mints >= 70:
                break
            balance = self.node.getbalance("*", 100)
        self.log.info("Minted %d coins in the %d-denom, remaining balance %d", initial_mints, DENOM_TO_USE, balance)
        sleep(2)

        # 3) mine more blocks
        self.log.info("Mining %d more blocks ... and getting spendable zerocoins" % MORE_MINED_BLOCKS)
        self.node.generate(MORE_MINED_BLOCKS)
        sleep(2)
        mints = self.node.listmintedzerocoins(True, True)
        sleep(1)
        stakingPrevOuts = self.get_prevouts(mints, zpos=True)
        mints_hashes = [x["serial hash"] for x in mints]

        # This mints are not ready spendable, only few of them.
        self.log.info("Got %d confirmed mints" % len(mints_hashes))

        # 4) spend mints
        self.log.info("Spending mints in block %d..." % self.node.getblockcount())
        spends = 0
        spent_mints = []
        for mint in mints_hashes:
            # create a single element list to pass to RPC spendzerocoinmints
            mint_arg = []
            mint_arg.append(mint)
            try:
                self.node.spendzerocoinmints(mint_arg)
                sleep(1)
                spends += 1
                spent_mints.append(mint)
            except JSONRPCException as e:
                self.log.warning(str(e))
                continue
        sleep(1)
        self.log.info("Successfully spent %d mints" % spends)

        # 5) Start mining again so that spends get confirmed in a block.
        self.log.info("Mining 5 more blocks...")
        self.node.generate(5)
        sleep(2)

        # 6) Collect some prevouts for random txes
        self.log.info("Collecting inputs for txes...")
        utxo_list = self.node.listunspent()
        spendingPrevOuts = self.get_prevouts(utxo_list)
        sleep(1)

        # 7) Create "Fake Stake" blocks and send them
        self.log.info("Creating Fake stake zPoS blocks...")
        err_msgs = self.test_spam("Main", stakingPrevOuts, spendingPrevOuts=spendingPrevOuts, fZPoS=True)

        if not len(err_msgs) == 0:
            self.log.error("result: " + " | ".join(err_msgs))
            raise AssertionError("TEST FAILED")

        self.log.info("%s PASSED" % self.__class__.__name__)
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright (c) 2014-2019 Daniel Kraft
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

# RPC test for basic name registration and access (name_show, name_history).

from test_framework.names import NameTestFramework
from test_framework.util import *

class NameRegistrationTest (NameTestFramework):

  def set_test_params (self):
    self.setup_clean_chain = True
    self.setup_name_test ([[], ["-namehistory"]])

  def run_test (self):
    self.generate (0, 50)
    self.generate (1, 50)
    self.generate (0, 100)

    # Perform name_new's.  Check for too long names exception.
    newA = self.nodes[0].name_new ("node-0")
    newAconfl = self.nodes[1].name_new ("node-0")
    addrB = self.nodes[1].getnewaddress ()
    newB = self.nodes[1].name_new ("node-1", {"destAddress": addrB})
    self.nodes[0].name_new ("x" * 255)
    assert_raises_rpc_error (-8, 'name is too long',
                             self.nodes[0].name_new, "x" * 256)
    self.generate (0, 5)

    # Verify that the name_new with explicit address sent really to this
    # address.  Since there is no equivalent to name_show while we only
    # have a name_new, explicitly check the raw tx.
    txHex = self.nodes[1].gettransaction (newB[0])['hex']
    newTx = self.nodes[1].decoderawtransaction (txHex)
    found = False
    for out in newTx['vout']:
      if 'nameOp' in out['scriptPubKey']:
        assert not found
        found = True
        assert_equal (out['scriptPubKey']['addresses'], [addrB])
    assert found

    # Check for exception with name_history and without -namehistory.
    assert_raises_rpc_error (-1, 'namehistory is not enabled',
                             self.nodes[0].name_history, "node-0")

    # first_update the names.  Check for too long values.
    addrA = self.nodes[0].getnewaddress ()
    txidA = self.firstupdateName (0, "node-0", newA, "value-0",
                                  {"destAddress": addrA})
    assert_raises_rpc_error (-8, 'value is too long',
                             self.firstupdateName, 1, "node-1", newB, "x" * 521)
    self.firstupdateName (1, "node-1", newB, "x" * 520)

    # Check for mempool conflict detection with registration of "node-0".
    self.sync_with_mode ('both')
    assert_raises_rpc_error (-25, 'is already being registered',
                             self.firstupdateName,
                             1, "node-0", newAconfl, "foo")

    # Check that the name appears when the name_new is ripe.

    self.generate (0, 7)
    assert_raises_rpc_error (-4, 'name not found',
                             self.nodes[1].name_show, "node-0")
    assert_raises_rpc_error (-4, 'name not found',
                             self.nodes[1].name_history, "node-0")
    self.generate (0, 1)

    data = self.checkName (1, "node-0", "value-0", 30, False)
    assert_equal (data['address'], addrA)
    assert_equal (data['txid'], txidA)
    assert_equal (data['height'], 213)

    self.checkNameHistory (1, "node-0", ["value-0"])
    self.checkNameHistory (1, "node-1", ["x" * 520])

    # Verify the allowExisting option for name_new.
    assert_raises_rpc_error (-25, 'exists already',
                             self.nodes[0].name_new, "node-0")
    assert_raises_rpc_error (-25, 'exists already',
                             self.nodes[0].name_new, "node-0",
                             {"allowExisting": False})
    assert_raises_rpc_error (-3, 'Expected type bool for allowExisting',
                             self.nodes[0].name_new, "other",
                             {"allowExisting": 42.5})
    self.nodes[0].name_new ("node-0", {"allowExisting": True})

    # Check for error with rand mismatch (wrong name)
    newA = self.nodes[0].name_new ("test-name")
    self.generate (0, 10)
    assert_raises_rpc_error (-25, 'rand value is wrong',
                             self.firstupdateName,
                             0, "test-name-wrong", newA, "value")

    # Check for mismatch with prev tx from another node for name_firstupdate
    # and name_update.
    assert_raises_rpc_error (-4, 'Input tx not found in wallet',
                             self.firstupdateName,
                             1, "test-name", newA, "value")
    self.firstupdateName (0, "test-name", newA, "test-value")

    # Check for disallowed firstupdate when the name is active.
    newSteal = self.nodes[1].name_new ("node-0", {"allowExisting": True})
    newSteal2 = self.nodes[1].name_new ("node-0", {"allowExisting": True})
    self.generate (0, 19)
    self.checkName (1, "node-0", "value-0", 1, False)
    assert_raises_rpc_error (-25, 'this name is already active',
                             self.firstupdateName,
                             1, "node-0", newSteal, "stolen")

    # Check for "stealing" of the name after expiry.
    self.generate (0, 1)
    self.firstupdateName (1, "node-0", newSteal, "stolen")
    self.checkName (1, "node-0", "value-0", 0, True)
    self.generate (0, 1)
    self.checkName (1, "node-0", "stolen", 30, False)
    self.checkNameHistory (1, "node-0", ["value-0", "stolen"])

    # Check for firstupdating an active name, but this time without the check
    # present in the RPC call itself.  This should still be prevented by the
    # mempool logic.  There was a bug that allowed these transactiosn to get
    # into the mempool, so make sure it is no longer there.
    self.firstupdateName (1, "node-0", newSteal2, "unstolen",
                          allowActive = True)
    assert_equal (self.nodes[1].getrawmempool (), [])
    self.checkName (1, "node-0", "stolen", None, False)

    # Check basic updating.
    assert_raises_rpc_error (-8, 'value is too long',
                             self.nodes[0].name_update, "test-name", "x" * 521)
    self.nodes[0].name_update ("test-name", "x" * 520)
    self.checkName (0, "test-name", "test-value", None, False)
    self.generate (0, 1)
    self.checkName (1, "test-name", "x" * 520, 30, False)
    self.checkNameHistory (1, "test-name", ["test-value", "x" * 520])

    addrB = self.nodes[1].getnewaddress ()
    self.nodes[0].name_update ("test-name", "sent", {"destAddress": addrB})
    self.generate (0, 1)
    data = self.checkName (0, "test-name", "sent", 30, False)
    assert_equal (data['address'], addrB)
    self.nodes[1].name_update ("test-name", "updated")
    self.generate (0, 1)
    data = self.checkName (0, "test-name", "updated", 30, False)
    self.checkNameHistory (1, "test-name",
                           ["test-value", "x" * 520, "sent", "updated"])

    # Invalid updates.
    assert_raises_rpc_error (-25, 'this name can not be updated',
                             self.nodes[1].name_update, "wrong-name", "foo")
    assert_raises_rpc_error (-4, 'Input tx not found in wallet',
                             self.nodes[0].name_update, "test-name", "stolen?")

    # Update failing after expiry.  Re-registration possible.
    self.checkName (1, "node-1", "x" * 520, None, True)
    assert_raises_rpc_error (-25, 'this name can not be updated',
                             self.nodes[1].name_update, "node-1", "updated?")

    newSteal = self.nodes[0].name_new ("node-1")
    self.generate (0, 10)
    self.firstupdateName (0, "node-1", newSteal, "reregistered")
    self.generate (0, 10)
    self.checkName (1, "node-1", "reregistered", 23, False)
    self.checkNameHistory (1, "node-1", ["x" * 520, "reregistered"])

    # Test that name updates are even possible with less balance in the wallet
    # than what is locked in a name (0.01 NMC).  There was a bug preventing
    # this from working.
    balance = self.nodes[1].getbalance ()
    keep = Decimal ("0.001")
    addr0 = self.nodes[0].getnewaddress ()
    self.nodes[1].sendtoaddress (addr0, balance - keep, "", "", True)
    addr1 = self.nodes[1].getnewaddress ()
    self.nodes[0].name_update ("node-1", "value", {"destAddress": addr1})
    self.generate (0, 1)
    assert_equal (self.nodes[1].getbalance (), keep)
    self.nodes[1].name_update ("node-1", "new value")
    self.generate (0, 1)
    self.checkName (1, "node-1", "new value", None, False)
    assert self.nodes[1].getbalance () < Decimal ("0.01")

if __name__ == '__main__':
  NameRegistrationTest ().main ()
<commit_msg>Streamline name_registration.py.<commit_after>#!/usr/bin/env python3
# Copyright (c) 2014-2019 Daniel Kraft
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

# RPC test for basic name registration and access (name_show, name_history).

from test_framework.names import NameTestFramework
from test_framework.util import *

class NameRegistrationTest (NameTestFramework):

  def set_test_params (self):
    self.setup_clean_chain = True
    self.setup_name_test ([["-namehistory"], []])

  def generateToOther (self, n):
    """
    Generates n blocks on the first node, but to an address of the second
    node (so that the first node does not get any extra coins that could mess
    up our balance tests).
    """

    addr = self.nodes[1].getnewaddress ()
    self.nodes[0].generatetoaddress (n, addr)

  def run_test (self):
    node = self.nodes[0]
    node.generate (50)
    self.generateToOther (150)

    # Perform name_new's.  Check for too long names exception.
    newA = node.name_new ("name-0")
    newAconfl = node.name_new ("name-0")
    addr = node.getnewaddress ()
    newB = node.name_new ("name-1", {"destAddress": addr})
    node.name_new ("x" * 255)
    assert_raises_rpc_error (-8, 'name is too long', node.name_new, "x" * 256)
    self.generateToOther (5)

    # Verify that the name_new with explicit address sent really to this
    # address.  Since there is no equivalent to name_show while we only
    # have a name_new, explicitly check the raw tx.
    txHex = node.gettransaction (newB[0])['hex']
    newTx = node.decoderawtransaction (txHex)
    found = False
    for out in newTx['vout']:
      if 'nameOp' in out['scriptPubKey']:
        assert not found
        found = True
        assert_equal (out['scriptPubKey']['addresses'], [addr])
    assert found

    # Check for exception with name_history and without -namehistory.
    self.sync_blocks ()
    assert_raises_rpc_error (-1, 'namehistory is not enabled',
                             self.nodes[1].name_history, "name-0")

    # first_update the names.  Check for too long values.
    addr = node.getnewaddress ()
    txidA = self.firstupdateName (0, "name-0", newA, "value-0",
                                  {"destAddress": addr})
    assert_raises_rpc_error (-8, 'value is too long',
                             self.firstupdateName, 0, "name-1", newB, "x" * 521)
    self.firstupdateName (0, "name-1", newB, "x" * 520)

    # Check for mempool conflict detection with registration of "name-0".
    assert_raises_rpc_error (-25, 'is already being registered',
                             self.firstupdateName,
                             0, "name-0", newAconfl, "foo")

    # Check that the name appears when the name_new is ripe.
    self.generateToOther (7)
    assert_raises_rpc_error (-4, 'name not found',
                             node.name_show, "name-0")
    assert_raises_rpc_error (-4, 'name not found',
                             node.name_history, "name-0")
    self.generateToOther (1)

    data = self.checkName (0, "name-0", "value-0", 30, False)
    assert_equal (data['address'], addr)
    assert_equal (data['txid'], txidA)
    assert_equal (data['height'], 213)

    self.checkNameHistory (0, "name-0", ["value-0"])
    self.checkNameHistory (0, "name-1", ["x" * 520])

    # Verify the allowExisting option for name_new.
    assert_raises_rpc_error (-25, 'exists already',
                             node.name_new, "name-0")
    assert_raises_rpc_error (-25, 'exists already',
                             node.name_new, "name-0",
                             {"allowExisting": False})
    assert_raises_rpc_error (-3, 'Expected type bool for allowExisting',
                             node.name_new, "other",
                             {"allowExisting": 42.5})
    node.name_new ("name-0", {"allowExisting": True})

    # Check for error with rand mismatch (wrong name)
    newA = node.name_new ("test-name")
    self.generateToOther (10)
    assert_raises_rpc_error (-25, 'rand value is wrong',
                             self.firstupdateName,
                             0, "test-name-wrong", newA, "value")

    # Check for mismatch with prev tx from another node for name_firstupdate
    # and name_update.
    self.sync_blocks ()
    assert_raises_rpc_error (-4, 'Input tx not found in wallet',
                             self.firstupdateName,
                             1, "test-name", newA, "value")
    self.firstupdateName (0, "test-name", newA, "test-value")

    # Check for disallowed firstupdate when the name is active.
    newSteal = node.name_new ("name-0", {"allowExisting": True})
    newSteal2 = node.name_new ("name-0", {"allowExisting": True})
    self.generateToOther (19)
    self.checkName (0, "name-0", "value-0", 1, False)
    assert_raises_rpc_error (-25, 'this name is already active',
                             self.firstupdateName,
                             0, "name-0", newSteal, "stolen")

    # Check for "stealing" of the name after expiry.
    self.generateToOther (1)
    self.firstupdateName (0, "name-0", newSteal, "stolen")
    self.checkName (0, "name-0", "value-0", 0, True)
    self.generateToOther (1)
    self.checkName (0, "name-0", "stolen", 30, False)
    self.checkNameHistory (0, "name-0", ["value-0", "stolen"])

    # Check for firstupdating an active name, but this time without the check
    # present in the RPC call itself.  This should still be prevented by the
    # mempool logic.  There was a bug that allowed these transactiosn to get
    # into the mempool, so make sure it is no longer there.
    self.firstupdateName (0, "name-0", newSteal2, "unstolen", allowActive=True)
    assert_equal (node.getrawmempool (), [])
    self.checkName (0, "name-0", "stolen", None, False)

    # Check basic updating.
    assert_raises_rpc_error (-8, 'value is too long',
                             node.name_update, "test-name", "x" * 521)
    node.name_update ("test-name", "x" * 520)
    self.checkName (0, "test-name", "test-value", None, False)
    self.generateToOther (1)
    self.checkName (0, "test-name", "x" * 520, 30, False)
    self.checkNameHistory (0, "test-name", ["test-value", "x" * 520])

    addrOther = self.nodes[1].getnewaddress ()
    node.name_update ("test-name", "sent", {"destAddress": addrOther})
    self.generateToOther (1)
    self.sync_blocks ()
    data = self.checkName (0, "test-name", "sent", 30, False)
    assert_equal (data['address'], addrOther)
    self.nodes[1].name_update ("test-name", "updated")
    self.nodes[1].generate (1)
    self.sync_blocks ()
    data = self.checkName (1, "test-name", "updated", 30, False)
    self.checkNameHistory (0, "test-name",
                           ["test-value", "x" * 520, "sent", "updated"])

    # Invalid updates.
    assert_raises_rpc_error (-25, 'this name can not be updated',
                             node.name_update, "wrong-name", "foo")
    assert_raises_rpc_error (-4, 'Input tx not found in wallet',
                             node.name_update, "test-name", "stolen?")

    # Update failing after expiry.  Re-registration possible.
    self.checkName (0, "name-1", "x" * 520, None, True)
    assert_raises_rpc_error (-25, 'this name can not be updated',
                             node.name_update, "name-1", "updated?")

    newSteal = node.name_new ("name-1")
    self.generateToOther (10)
    self.firstupdateName (0, "name-1", newSteal, "reregistered")
    self.generateToOther (10)
    self.checkName (0, "name-1", "reregistered", 23, False)
    self.checkNameHistory (0, "name-1", ["x" * 520, "reregistered"])

    # Test that name updates are even possible with less balance in the wallet
    # than what is locked in a name (0.01 NMC).  There was a bug preventing
    # this from working.
    balance = node.getbalance ()
    keep = Decimal ("0.001")
    addrOther = self.nodes[1].getnewaddress ()
    node.sendtoaddress (addrOther, balance - keep, "", "", True)
    self.generateToOther (1)
    assert_equal (node.getbalance (), keep)
    node.name_update ("name-1", "new value")
    self.generateToOther (1)
    assert node.getbalance () < Decimal ("0.01")
    self.checkName (0, "name-1", "new value", None, False)

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


<commit_before>try:
    from PySide.QtCore import *
    from PySide.QtGui import *
    from PySide.QtTest import *

    app = qApp or QApplication([])
    HAVE_QT = True
except ImportError:
    HAVE_QT = False

if HAVE_QT:
    from zasim.gui.display import ZasimDisplay
    from zasim.gui.histogram import HistogramExtraDisplay
    from zasim.gui.animation import WaitAnimationWindow
    from zasim import cagen

import time
import pytest

import numpy as np

def seconds(num):
    end = time.time() + num
    while time.time() < end:
        yield 1

import sys
import traceback

_exceptions = []
def my_except_hook(cls, instance, traceback):
    print "oh god, an exception!"
    print cls
    print instance
    print traceback
    print
    traceback.print_exception(cls, instance, traceback)
    _exceptions.append((cls, instance, traceback))

def fail_on_exceptions():
    exc = _exceptions[:]
    [_exceptions.remove(a) for a in exc]
    if exc:
        pytest.fail("There were exceptions in the base.\n%s" % (exc[0]))

def setup_module():
    sys.excepthook = my_except_hook

def teardown_module():
    sys.excepthook = sys.__excepthook__

@pytest.mark.skipif("not HAVE_QT")
class TestGui:
    def test_start_stop_binrule(self, size, base, scale, histogram):
        print size, base, scale, histogram
        sim_obj = cagen.ElementarySimulator(size, copy_borders=True, base=base, histogram=histogram)

        display = ZasimDisplay(sim_obj)
        display.set_scale(scale)

        if histogram:
            extra_hist = HistogramExtraDisplay(sim_obj, parent=display,
                        height=200, maximum=size[0] * size[1])
            extra_hist.show()
            display.window.attach_display(extra_hist)
            display.window.addDockWidget(Qt.RightDockWidgetArea, extra_hist)

        QTest.qWaitForWindowShown(display.window)

        QTest.mouseClick(display.control.start_button, Qt.LeftButton)

        for execution in seconds(0.1):
            app.processEvents()
        assert not display.control.start_button.isVisible()
        for execution in seconds(0.1):
            app.processEvents()
        QTest.mouseClick(display.control.stop_button, Qt.LeftButton)
        for execution in seconds(0.1):
            app.processEvents()
        assert not display.control.stop_button.isVisible()

        app.closeAllWindows()
        fail_on_exceptions()

    def test_reset_button(self):
        sim_obj = cagen.ElementarySimulator((1000, 100), copy_borders=True, base=3)

        display = ZasimDisplay(sim_obj)
        display.set_scale(1)

        QTest.qWaitForWindowShown(display.window)

        reset_button = display.control.findChild(QWidget, u"reset")
        assert reset_button is not None

        display.control.zero_percentage.setValue(33)
        QTest.mouseClick(reset_button, Qt.LeftButton)

        config = sim_obj.get_config()
        histogram = np.bincount(config.ravel())
        zeros = histogram[0]
        other = sum(histogram[1:])
        assert abs((1.0 * zeros / (zeros + other)) - 0.33) < 0.2

        display.control.zero_percentage.setValue(99)
        QTest.mouseClick(reset_button, Qt.LeftButton)

        config = sim_obj.get_config()
        histogram = np.bincount(config.ravel())
        zeros = histogram[0]
        other = sum(histogram[1:])
        assert abs((1.0 * zeros / (zeros + other)) - 0.99) < 0.2

        fail_on_exceptions()

    def find_message_box(self, timeout=10):
        end = time.time() + timeout
        while time.time() < end:
            widgets = app.allWidgets()
            for widget in widgets:
                if isinstance(widget, QMessageBox):
                    return widget
            app.processEvents()

    def SKIP_elementary_gui(self, base):
        sim_obj = cagen.ElementarySimulator((10, 10), copy_borders=True, base=base)

        display = ZasimDisplay(sim_obj)
        display.set_scale(1)

        QTest.qWaitForWindowShown(display.window)

        menu = display.window.menuBar().findChild(QMenu, u"simulator_menu")
        assert menu is not None
        QTest.mouseClick(menu, Qt.LeftButton)

        elementary_action = menu.findChild(QAction, u"stepfunc_table")
        elementary_action.trigger()

        for execution in seconds(0.1):
            app.processEvents()

        elementary_window = app.activeWindow()

        actions = [act for act in elementary_window.findChildren(QPushButton)
                    if act.objectName().startswith("action_")]

        for action in actions:
            QTest.mouseClick(action, Qt.LeftButton)
            for execution in seconds(0.1):
                app.processEvents()

        app.closeAllWindows()

        fail_on_exceptions()

        #minimize = elementary_window.findChild(QPushButton, u"minimize")

        #print "clicking now"
        #class foo(QThread):
            #def run(self):
                #QTest.mouseClick(minimize, Qt.LeftButton)
        #t = foo()
        #t.start()

        #popup = self.find_message_box()
        #popup.close()

    def SKIP_stepfunc_comp(self):
        sim_obj = cagen.ElementarySimulator((10, 10), copy_borders=True, base=2)

        display = ZasimDisplay(sim_obj)
        display.set_scale(1)

        QTest.qWaitForWindowShown(display.window)

        menu = display.window.menuBar().findChild(QMenu, u"simulator_menu")
        assert menu is not None
        QTest.mouseClick(menu, Qt.LeftButton)

        stepfunc_action = menu.findChild(QAction, u"new")
        stepfunc_action.trigger()

        for execution in seconds(0.2):
            app.processEvents()

        stepfunc_window = app.activeWindow()
        tree = stepfunc_window.findChild(QWidget, u"parts")
        assert tree is not None
        QTest.keyClick(tree, Qt.Key_Right)
        for execution in seconds(0.05):
            app.processEvents()
        QTest.keyClick(tree, Qt.Key_Return)
        for execution in seconds(0.05):
            app.processEvents()
        for i in range(5):
            QTest.keyClick(tree, Qt.Key_Left)
            QTest.keyClick(tree, Qt.Key_Left)
            QTest.keyClick(tree, Qt.Key_Down)
            QTest.keyClick(tree, Qt.Key_Return)

        close = stepfunc_window.findChild(QPushButton, u"cancel")
        assert close is not None
        QTest.mouseClick(close, Qt.LeftButton)
        for execution in seconds(0.05):
            app.processEvents()

        app.closeAllWindows()

    def test_animation(self):
        anim = WaitAnimationWindow()

        for execution in seconds(1):
            app.processEvents()

        fail_on_exceptions()

def produce_more(calls, arg, values, filter_func=lambda call: True):
    """Add, to all `calls`, a call for each `value` for the `arg`, so that
    all combinations will exist in the returned list.

    If calls is empty, generate a dict for each value as the result.

    If the filter_func is supplied, every old call will be passed to it and,
    if the filter_func returns True, new calls will be produced based on the
    values supplied. If the filter_func returns False, only the first value
    will be set on the old call.
    """
    if not calls:
        return [{arg: value} for value in values]

    ncalls = []
    for call in calls:
        if filter_func(call):
            values_to_use = values
        else:
            values_to_use = values[:1]
        for value in values_to_use:
            new_call = call.copy()
            new_call[arg] = value
            ncalls.append(new_call)

    return ncalls

def pytest_generate_tests(metafunc):
    calls = []
    if "scale" in metafunc.funcargnames:
        calls = produce_more(calls, "scale", [1, 4])
    if "size" in metafunc.funcargnames:
        calls = produce_more(calls, "size", [(100,), (100, 100)])
    if "base" in metafunc.funcargnames:
        calls = produce_more(calls, "base", [2, 3])
    if "histogram" in metafunc.funcargnames:
        calls = produce_more(calls, "histogram", [False, True],
                lambda call: len(call["size"]) == 2)

    for call in calls:
        metafunc.addcall(funcargs=call)
<commit_msg>this could hopefully make the test less likely for an abort signal.<commit_after>try:
    from PySide.QtCore import *
    from PySide.QtGui import *
    from PySide.QtTest import *

    app = qApp or QApplication([])
    HAVE_QT = True
except ImportError:
    HAVE_QT = False

if HAVE_QT:
    from zasim.gui.display import ZasimDisplay
    from zasim.gui.histogram import HistogramExtraDisplay
    from zasim.gui.animation import WaitAnimationWindow
    from zasim import cagen

import time
import pytest

import numpy as np

def seconds(num):
    end = time.time() + num
    while time.time() < end:
        yield 1

import sys
import traceback

_exceptions = []
def my_except_hook(cls, instance, traceback):
    print "oh god, an exception!"
    print cls
    print instance
    print traceback
    print
    traceback.print_exception(cls, instance, traceback)
    _exceptions.append((cls, instance, traceback))

def fail_on_exceptions():
    exc = _exceptions[:]
    [_exceptions.remove(a) for a in exc]
    if exc:
        pytest.fail("There were exceptions in the base.\n%s" % (exc[0]))

def setup_module():
    sys.excepthook = my_except_hook

def teardown_module():
    sys.excepthook = sys.__excepthook__

@pytest.mark.skipif("not HAVE_QT")
class TestGui:
    def test_start_stop_binrule(self, size, base, scale, histogram):
        print size, base, scale, histogram
        sim_obj = cagen.ElementarySimulator(size, copy_borders=True, base=base, histogram=histogram)

        display = ZasimDisplay(sim_obj)
        display.set_scale(scale)

        if histogram:
            extra_hist = HistogramExtraDisplay(sim_obj, parent=display,
                        height=200, maximum=size[0] * size[1])
            extra_hist.show()
            display.window.attach_display(extra_hist)
            display.window.addDockWidget(Qt.RightDockWidgetArea, extra_hist)

        QTest.qWaitForWindowShown(display.window)

        QTest.mouseClick(display.control.start_button, Qt.LeftButton)

        for execution in seconds(0.1):
            app.processEvents()
        assert not display.control.start_button.isVisible()
        for execution in seconds(0.1):
            app.processEvents()
        QTest.mouseClick(display.control.stop_button, Qt.LeftButton)
        for execution in seconds(0.1):
            app.processEvents()
        assert not display.control.stop_button.isVisible()

        app.closeAllWindows()
        fail_on_exceptions()

    def test_reset_button(self):
        sim_obj = cagen.ElementarySimulator((1000, 100), copy_borders=True, base=3)

        display = ZasimDisplay(sim_obj)
        display.set_scale(1)

        QTest.qWaitForWindowShown(display.window)

        reset_button = display.control.findChild(QWidget, u"reset")
        assert reset_button is not None

        display.control.zero_percentage.setValue(33)
        QTest.mouseClick(reset_button, Qt.LeftButton)

        config = sim_obj.get_config()
        histogram = np.bincount(config.ravel())
        zeros = histogram[0]
        other = sum(histogram[1:])
        assert abs((1.0 * zeros / (zeros + other)) - 0.33) < 0.2

        display.control.zero_percentage.setValue(99)
        QTest.mouseClick(reset_button, Qt.LeftButton)

        config = sim_obj.get_config()
        histogram = np.bincount(config.ravel())
        zeros = histogram[0]
        other = sum(histogram[1:])
        assert abs((1.0 * zeros / (zeros + other)) - 0.99) < 0.2

        fail_on_exceptions()

    def find_message_box(self, timeout=10):
        end = time.time() + timeout
        while time.time() < end:
            widgets = app.allWidgets()
            for widget in widgets:
                if isinstance(widget, QMessageBox):
                    return widget
            app.processEvents()

    def SKIP_elementary_gui(self, base):
        sim_obj = cagen.ElementarySimulator((10, 10), copy_borders=True, base=base)

        display = ZasimDisplay(sim_obj)
        display.set_scale(1)

        QTest.qWaitForWindowShown(display.window)

        menu = display.window.menuBar().findChild(QMenu, u"simulator_menu")
        assert menu is not None
        QTest.mouseClick(menu, Qt.LeftButton)

        elementary_action = menu.findChild(QAction, u"stepfunc_table")
        elementary_action.trigger()

        for execution in seconds(0.1):
            app.processEvents()

        elementary_window = app.activeWindow()
        assert elementary_window is not None

        actions = [act for act in elementary_window.findChildren(QPushButton)
                    if act is not None and act.objectName().startswith("action_")]

        for action in actions:
            QTest.mouseClick(action, Qt.LeftButton)
            for execution in seconds(0.1):
                app.processEvents()

        app.closeAllWindows()

        fail_on_exceptions()

        #minimize = elementary_window.findChild(QPushButton, u"minimize")

        #print "clicking now"
        #class foo(QThread):
            #def run(self):
                #QTest.mouseClick(minimize, Qt.LeftButton)
        #t = foo()
        #t.start()

        #popup = self.find_message_box()
        #popup.close()

    def SKIP_stepfunc_comp(self):
        sim_obj = cagen.ElementarySimulator((10, 10), copy_borders=True, base=2)

        display = ZasimDisplay(sim_obj)
        display.set_scale(1)

        QTest.qWaitForWindowShown(display.window)

        menu = display.window.menuBar().findChild(QMenu, u"simulator_menu")
        assert menu is not None
        QTest.mouseClick(menu, Qt.LeftButton)

        stepfunc_action = menu.findChild(QAction, u"new")
        stepfunc_action.trigger()

        for execution in seconds(0.2):
            app.processEvents()

        stepfunc_window = app.activeWindow()
        tree = stepfunc_window.findChild(QWidget, u"parts")
        assert tree is not None
        QTest.keyClick(tree, Qt.Key_Right)
        for execution in seconds(0.05):
            app.processEvents()
        QTest.keyClick(tree, Qt.Key_Return)
        for execution in seconds(0.05):
            app.processEvents()
        for i in range(5):
            QTest.keyClick(tree, Qt.Key_Left)
            QTest.keyClick(tree, Qt.Key_Left)
            QTest.keyClick(tree, Qt.Key_Down)
            QTest.keyClick(tree, Qt.Key_Return)

        close = stepfunc_window.findChild(QPushButton, u"cancel")
        assert close is not None
        QTest.mouseClick(close, Qt.LeftButton)
        for execution in seconds(0.05):
            app.processEvents()

        app.closeAllWindows()

    def test_animation(self):
        anim = WaitAnimationWindow()

        for execution in seconds(1):
            app.processEvents()

        fail_on_exceptions()

def produce_more(calls, arg, values, filter_func=lambda call: True):
    """Add, to all `calls`, a call for each `value` for the `arg`, so that
    all combinations will exist in the returned list.

    If calls is empty, generate a dict for each value as the result.

    If the filter_func is supplied, every old call will be passed to it and,
    if the filter_func returns True, new calls will be produced based on the
    values supplied. If the filter_func returns False, only the first value
    will be set on the old call.
    """
    if not calls:
        return [{arg: value} for value in values]

    ncalls = []
    for call in calls:
        if filter_func(call):
            values_to_use = values
        else:
            values_to_use = values[:1]
        for value in values_to_use:
            new_call = call.copy()
            new_call[arg] = value
            ncalls.append(new_call)

    return ncalls

def pytest_generate_tests(metafunc):
    calls = []
    if "scale" in metafunc.funcargnames:
        calls = produce_more(calls, "scale", [1, 4])
    if "size" in metafunc.funcargnames:
        calls = produce_more(calls, "size", [(100,), (100, 100)])
    if "base" in metafunc.funcargnames:
        calls = produce_more(calls, "base", [2, 3])
    if "histogram" in metafunc.funcargnames:
        calls = produce_more(calls, "histogram", [False, True],
                lambda call: len(call["size"]) == 2)

    for call in calls:
        metafunc.addcall(funcargs=call)
<|endoftext|>


<commit_before>from abc import ABCMeta, abstractmethod

class Forcing(object):
    """
    Base class for forcing terms for dcore.

    :arg state: x :class:`.State` object.
    """
    __metaclass__ = ABCMeta

    def __init__(self, state):
        self.state = state

    @abstractmethod
    def apply(self, scale, x, x_out):
        """
        Function takes x as input, computes F(x) and returns
        x_out = x + scale*F(x)
        as output.

        :arg scale: parameter to scale the output by.
        :arg x: :class:`.Function` object, the input Function.
        :arg x_out: :class:`.Function` object, the output Function.
        """
        pass

class CompressibleForcing(Forcing):
    """
    Forcing class for compressible Euler equations.
    """

    def __init__(self, state):
        self.state = state

        self._build_forcing_solver()

    def _build_forcing_solver(self):
        """
        Only put forcing terms into the u equation.
        """

        state = self.state
        V2 = state.V2
        W = state.W

        self.x0 = Function(W) #copy x to here

        u0,rho0,theta0 = split(self.x0)

        F = TrialFunction(V2)
        w = TestFunction(V2)
        self.uF = Function(V2)

        Omega = state.Omega

        n = FacetNormal(state.mesh)
        pi = exner(theta0, rho0, state)

        a = inner(w,F)*dx
        L = (
            -inner(w,cross(Omega,u0))*dx #Coriolis term
            -div(theta0*w)*pi*dx #pressure gradient (volume integral)
            +jump(w*theta0,n)*avg(pi)*dS_v #pressure gradient (surface integral)
            +div(w)*state.Phi*dx #gravity term (Phi is geopotential)
        )

        bcs = [DirichletBC(V2, 0.0, "bottom"),
               DirichletBC(V2, 0.0, "top")]

        u_forcing_problem = LinearVariationalProblem(
            a,L,self.uF, bcs=bcs
        )

        self.u_forcing_solver = LinearVariationalSolver(u_forcing_problem)

    def apply(self, scaling, x_in, x_out):

        self.x0.assign(x_in)

        self.u_forcing_solver.solve() #places forcing in self.uF
        self.uF.scale(scaling)

        uF, _, _ = x_out.split()

        x_out.assign(x_in)
        uF += self.uF

def exner(theta,rho,state):
    """
    Compute the exner function.
    """
    R_d = state.R_d
    p_0 = state.p_0
    kappa = state.kappa

    return (R_d/p_0)**(kappa/(1-kappa))*pow(rho*theta, kappa/(1-kappa))

def exner_rho(theta,rho,state):
    R_d = state.R_d
    p_0 = state.p_0
    kappa = state.kappa

    return (R_d/p_0)**(kappa/(1-kappa))*pow(rho*theta, kappa/(1-kappa)-1)*theta*kappa/(1-kappa)

def exner_theta(theta,rho,state):
    R_d = state.R_d
    p_0 = state.p_0
    kappa = state.kappa

    return (R_d/p_0)**(kappa/(1-kappa))*pow(rho*theta, kappa/(1-kappa)-1)*rho*kappa/(1-kappa)
<commit_msg>tweaking forcing.<commit_after>from abc import ABCMeta, abstractmethod

class Forcing(object):
    """
    Base class for forcing terms for dcore.

    :arg state: x :class:`.State` object.
    """
    __metaclass__ = ABCMeta

    def __init__(self, state):
        self.state = state

    @abstractmethod
    def apply(self, scale, x, x_out):
        """
        Function takes x as input, computes F(x) and returns
        x_out = x + scale*F(x)
        as output.

        :arg scale: parameter to scale the output by.
        :arg x: :class:`.Function` object, the input Function.
        :arg x_out: :class:`.Function` object, the output Function.
        """
        pass

class CompressibleForcing(Forcing):
    """
    Forcing class for compressible Euler equations.
    """

    def __init__(self, state):
        self.state = state

        self._build_forcing_solver()

    def _build_forcing_solver(self):
        """
        Only put forcing terms into the u equation.
        """

        state = self.state
        V2 = state.V2
        W = state.W

        self.x0 = Function(W) #copy x to here

        u0,rho0,theta0 = split(self.x0)

        F = TrialFunction(V2)
        w = TestFunction(V2)
        self.uF = Function(V2)

        Omega = state.Omega

        n = FacetNormal(state.mesh)
        pi = exner(theta0, rho0, state)

        a = inner(w,F)*dx
        L = (
            -inner(w,cross(2*Omega,u0))*dx #Coriolis term
            -div(theta0*w)*pi*dx #pressure gradient (volume integral)
            +jump(w*theta0,n)*avg(pi)*dS_v #pressure gradient (surface integral)
            +div(w)*state.Phi*dx #gravity term (Phi is geopotential)
        )

        bcs = [DirichletBC(V2, 0.0, "bottom"),
               DirichletBC(V2, 0.0, "top")]

        u_forcing_problem = LinearVariationalProblem(
            a,L,self.uF, bcs=bcs
        )

        self.u_forcing_solver = LinearVariationalSolver(u_forcing_problem)

    def apply(self, scaling, x_in, x_out):

        self.x0.assign(x_in)

        self.u_forcing_solver.solve() #places forcing in self.uF
        self.uF.scale(scaling)

        uF, _, _ = x_out.split()

        x_out.assign(x_in)
        uF += self.uF

def exner(theta,rho,state):
    """
    Compute the exner function.
    """
    R_d = state.R_d
    p_0 = state.p_0
    kappa = state.kappa

    return (R_d/p_0)**(kappa/(1-kappa))*pow(rho*theta, kappa/(1-kappa))

def exner_rho(theta,rho,state):
    R_d = state.R_d
    p_0 = state.p_0
    kappa = state.kappa

    return (R_d/p_0)**(kappa/(1-kappa))*pow(rho*theta, kappa/(1-kappa)-1)*theta*kappa/(1-kappa)

def exner_theta(theta,rho,state):
    R_d = state.R_d
    p_0 = state.p_0
    kappa = state.kappa

    return (R_d/p_0)**(kappa/(1-kappa))*pow(rho*theta, kappa/(1-kappa)-1)*rho*kappa/(1-kappa)
<|endoftext|>


<commit_before>import scrapy

class BritBoxSpider(scrapy.Spider):
    name = "shows"
    #  Doesn't handle /us/programme, or /us/show/ with only one season
    #  Works for /us/show/ with > 1 seson
    start_urls = [
            'https://www.britbox.com/us/programmes',                              # Top level
            'https://www.britbox.com/us/movie/70_Glorious_Years_13550',           # Movie
            'https://www.britbox.com/us/movie/A_Christmas_Carol_15128',           # Movie
            'https://www.britbox.com/us/show/New_Blood_9275',                     # Show (1 season)
            'https://www.britbox.com/us/show/Till_Death_Us_Do_Part_15810',        # Show (1 season)
            'https://www.britbox.com/us/show/A_History_of_Ancient_Britain_6385',  # Show (1+ seasons)
            'https://www.britbox.com/us/show/A_Bit_of_Fry_and_Laurie_6393',       # Show (+1 seasons)
            'https://www.britbox.com/us/show/The_Jury_9565',                      # Show (2 seasons)
            'https://www.britbox.com/us/season/Vera_S8_15720',                    # Season (2 seasons)
            'https://www.britbox.com/us/episode/Superhomes_S1_E1_9008',           # Episode (1 season)
            'https://www.britbox.com/us/episode/Cold_Blood_S2_E2_10298',          # Episode (2 seasons)
            ]

    def parse(self, response):
        for page in self.start_urls:
            if "/episode/" in page:
                yield scrapy.Request(page, callback=self.parse1Episode)
            elif "/movie/" in page:
                yield scrapy.Request(page, callback=self.parseEpisode)
            else:
                seasons = response.css('div.program-item__title-wrapper p.program-item__program-subtitle::text').extract_first()
                if seasons is not None:
                    if "Season " in seasons:
                        print(seasons)
                        yield scrapy.Request(page, callback=self.parse2Seasons)

    def parseEpisode(self, response):
        for show in response.css('div.program-item'):
            yield {
                    'URL': show.css('a.program-item__block::attr(href)').extract(),
                    'Title': show.css('h3.program-item__program-title::text').extract(),
                    'Subtitle': show.css('p.program-item__program-subtitle::text').extract(),
                    'Duration': show.css('span.programme-metadata__duration::text').re(r'(\d+)'),
                    'Year': show.css('span.programme-metadata__year::text').extract(),
                    'Rating': show.css('span.programme-metadata__classification::text').extract(),
                    'Description': show.css('p.program-item__program-description::text').extract(),
                    }

    def parse2Seasons(self, response):
        # for season in response.css('a.brand-season-item'):
        title = response.css('h1.brand-hero-info__title::text').extract()

        for season in response.css('a.brand-season-item'):
            yield {
                    'URL': season.css('a.brand-season-item::attr(href)').extract(),
                    'Title': title,
                    'SeasonNumber': season.css('h2.program-item__program-title::text').re(r'Season (\d+)'),
                    'Year': season.css('p.season-metadata::text').extract(),
                    'NumEpisodes': season.css('p.season-metadata span::text')[2].re(r'(\d+)'),
                    }

            for href in response.css('a.brand-season-item::attr(href)'):
                yield response.follow(href, self.parseEpisode)

    def parse1Episode(self, response):
        shortURL = "/" + response.url.split('/', 3)[3]
        URLs = (response.css('div.program-item a.program-item__block::attr(href)').extract())
        for i, item in enumerate(URLs):
            if (item == shortURL):
                URL = URLs[i]
                Title = response.css('div.program-item h3.program-item__program-title::text')[i].extract()
                Subtitle = response.css('div.program-item p.program-item__program-subtitle::text')[i].extract()
                Duration = response.css('div.program-item span.programme-metadata__duration::text')[i].re(r'(\d+)')
                Year = response.css('div.program-item span.programme-metadata__year::text')[i].extract()
                Rating = response.css('div.program-item span.programme-metadata__classification::text')[i].extract()
                yield {
                        'URL': URL,
                        'Title': Title,
                        'Subtitle': Subtitle,
                        'Duration': Duration,
                        'Year': Year,
                        'Rating': Rating,
                        # 'Description': response.css('div.program-item p.program-item__program-description::text')[i].extract(),
                        }
<commit_msg>Formatted with yapf<commit_after>import scrapy

class BritBoxSpider(scrapy.Spider):
    name = "shows"
    #  Doesn't handle /us/programme, or /us/show/ with only one season
    #  Works for /us/show/ with > 1 seson
    start_urls = [
        'https://www.britbox.com/us/programmes',  # Top level
        'https://www.britbox.com/us/movie/70_Glorious_Years_13550',  # Movie
        'https://www.britbox.com/us/movie/A_Christmas_Carol_15128',  # Movie
        'https://www.britbox.com/us/show/New_Blood_9275',  # Show (1 season)
        'https://www.britbox.com/us/show/Till_Death_Us_Do_Part_15810',  # Show (1 season)
        'https://www.britbox.com/us/show/A_History_of_Ancient_Britain_6385',  # Show (1+ seasons)
        'https://www.britbox.com/us/show/A_Bit_of_Fry_and_Laurie_6393',  # Show (+1 seasons)
        'https://www.britbox.com/us/show/The_Jury_9565',  # Show (2 seasons)
        'https://www.britbox.com/us/season/Vera_S8_15720',  # Season (2 seasons)
        'https://www.britbox.com/us/episode/Superhomes_S1_E1_9008',  # Episode (1 season)
        'https://www.britbox.com/us/episode/Cold_Blood_S2_E2_10298',  # Episode (2 seasons)
    ]

    def parse(self, response):
        for page in self.start_urls:
            if "/episode/" in page:
                yield scrapy.Request(page, callback=self.parse1Episode)
            elif "/movie/" in page:
                yield scrapy.Request(page, callback=self.parseEpisode)
            else:
                seasons = response.css(
                    'div.program-item__title-wrapper p.program-item__program-subtitle::text'
                ).extract_first()
                if seasons is not None:
                    if "Season " in seasons:
                        print(seasons)
                        yield scrapy.Request(page, callback=self.parse2Seasons)

    def parseEpisode(self, response):
        for show in response.css('div.program-item'):
            yield {
                'URL': show.css('a.program-item__block::attr(href)').extract(),
                'Title': show.css('h3.program-item__program-title::text').extract(),
                'Subtitle': show.css('p.program-item__program-subtitle::text').extract(),
                'Duration': show.css('span.programme-metadata__duration::text').re(r'(\d+)'),
                'Year': show.css('span.programme-metadata__year::text').extract(),
                'Rating': show.css('span.programme-metadata__classification::text').extract(),
                'Description': show.css('p.program-item__program-description::text').extract(),
            }

    def parse2Seasons(self, response):
        # for season in response.css('a.brand-season-item'):
        title = response.css('h1.brand-hero-info__title::text').extract()

        for season in response.css('a.brand-season-item'):
            yield {
                'URL': season.css('a.brand-season-item::attr(href)').extract(),
                'Title': title,
                'SeasonNumber': season.css('h2.program-item__program-title::text').re(r'Season (\d+)'),
                'Year': season.css('p.season-metadata::text').extract(),
                'NumEpisodes': season.css('p.season-metadata span::text')[2].re(r'(\d+)'),
            }

            for href in response.css('a.brand-season-item::attr(href)'):
                yield response.follow(href, self.parseEpisode)

    def parse1Episode(self, response):
        shortURL = "/" + response.url.split('/', 3)[3]
        URLs = (response.css('div.program-item a.program-item__block::attr(href)').extract())
        for i, item in enumerate(URLs):
            if (item == shortURL):
                URL = URLs[i]
                Title = response.css('div.program-item h3.program-item__program-title::text')[
                    i].extract()
                Subtitle = response.css('div.program-item p.program-item__program-subtitle::text')[
                    i].extract()
                Duration = response.css('div.program-item span.programme-metadata__duration::text')[
                    i].re(r'(\d+)')
                Year = response.css('div.program-item span.programme-metadata__year::text')[
                    i].extract()
                Rating = response.css(
                    'div.program-item span.programme-metadata__classification::text')[i].extract()
                yield {
                    'URL': URL,
                    'Title': Title,
                    'Subtitle': Subtitle,
                    'Duration': Duration,
                    'Year': Year,
                    'Rating': Rating,
                    # 'Description': response.css('div.program-item p.program-item__program-description::text')[i].extract(),
                }
<|endoftext|>


<commit_before>import os
import logging
from subprocess import check_call, CalledProcessError

from ... import constants
from ...config import get_config_value, assert_config_key
from ...demote import check_call_demoted, check_and_log_output_and_error_demoted
from ...source import repo_is_overridden, get_expanded_repo_name
from ...path import local_repo_path, vm_repo_path, parent_dir
from ...log import log_to_client
from dusty.compiler.spec_assembler import get_repo_of_app_or_library, get_assembled_specs

def _ensure_vm_dir_exists(remote_dir):
    check_call_demoted(['boot2docker', 'ssh', 'sudo mkdir -p {0}; sudo chown -R docker {0}'.format(remote_dir)])

def _rsync_command(local_path, remote_path, is_dir=True, from_local=True):
    ssh_opts = 'ssh -p 2022 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /Users/{}/.ssh/id_boot2docker'.format(get_config_value('mac_username'))
    command = ['rsync', '-e', ssh_opts, '-az', '--exclude', '*/.git', '--force']
    if from_local:
        path_args = ['{}{}'.format(local_path, '/' if is_dir else ''), 'docker@localhost:{}'.format(remote_path)]
    else:
        path_args = ['docker@localhost:{}{}'.format(remote_path, '/' if is_dir else ''), local_path]
    command += path_args
    return command

def vm_path_is_directory(remote_path):
    """A weak check of whether a path in the boot2docker VM is a directory.
    This function returns False on any process error, so False may indicate
    other failures such as the path not actually existing."""
    try:
        check_call_demoted(['boot2docker', 'ssh', 'test -d {}'.format(remote_path)])
    except CalledProcessError:
        return False
    return True

def sync_local_path_to_vm(local_path, remote_path, demote=False):
    is_dir = os.path.isdir(local_path)
    _ensure_vm_dir_exists(remote_path if is_dir else parent_dir(remote_path))
    command = _rsync_command(local_path, remote_path, is_dir=is_dir)
    logging.debug('Executing rsync command: {}'.format(' '.join(command)))
    check_call(command) if not demote else check_and_log_output_and_error_demoted(command)

def sync_local_path_from_vm(local_path, remote_path, demote=False, is_dir=True):
    command = _rsync_command(local_path, remote_path, is_dir=is_dir, from_local=False)
    logging.debug('Executing rsync command: {}'.format(' '.join(command)))
    check_call(command) if not demote else check_and_log_output_and_error_demoted(command)

def sync_repos(repos):
    logging.info('Syncing repos over rsync')
    assert_config_key('mac_username')
    for repo_name in repos:
        repo_name = get_expanded_repo_name(repo_name)
        repo_type = 'overridden' if repo_is_overridden(repo_name) else 'Dusty-managed'
        remote_path = vm_repo_path(repo_name)
        log_to_client('Syncing {} repo {} to remote at {}'.format(repo_type, repo_name, remote_path))
        sync_local_path_to_vm(local_repo_path(repo_name), remote_path)

def sync_repos_by_app_name(app_names):
    repos = set()
    assembled_specs = get_assembled_specs()
    for app_name in app_names:
        for lib_name in assembled_specs['apps'][app_name]['depends']['libs']:
            repos.add(get_repo_of_app_or_library(lib_name))
        repos.add(get_repo_of_app_or_library(app_name))
    sync_repos(repos)
<commit_msg>Parameterize excluding git from rsync commands<commit_after>import os
import logging
from subprocess import check_call, CalledProcessError

from ... import constants
from ...config import get_config_value, assert_config_key
from ...demote import check_call_demoted, check_and_log_output_and_error_demoted
from ...source import repo_is_overridden, get_expanded_repo_name
from ...path import local_repo_path, vm_repo_path, parent_dir
from ...log import log_to_client
from dusty.compiler.spec_assembler import get_repo_of_app_or_library, get_assembled_specs

def _ensure_vm_dir_exists(remote_dir):
    check_call_demoted(['boot2docker', 'ssh', 'sudo mkdir -p {0}; sudo chown -R docker {0}'.format(remote_dir)])

def _rsync_command(local_path, remote_path, is_dir=True, from_local=True, exclude_git=True):
    ssh_opts = 'ssh -p 2022 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /Users/{}/.ssh/id_boot2docker'.format(get_config_value('mac_username'))
    command = ['rsync', '-e', ssh_opts, '-az', '--force']
    if exclude_git:
        command += ['--exclude', '*/.git']
    if from_local:
        path_args = ['{}{}'.format(local_path, '/' if is_dir else ''), 'docker@localhost:{}'.format(remote_path)]
    else:
        path_args = ['docker@localhost:{}{}'.format(remote_path, '/' if is_dir else ''), local_path]
    command += path_args
    return command

def vm_path_is_directory(remote_path):
    """A weak check of whether a path in the boot2docker VM is a directory.
    This function returns False on any process error, so False may indicate
    other failures such as the path not actually existing."""
    try:
        check_call_demoted(['boot2docker', 'ssh', 'test -d {}'.format(remote_path)])
    except CalledProcessError:
        return False
    return True

def sync_local_path_to_vm(local_path, remote_path, demote=False):
    is_dir = os.path.isdir(local_path)
    _ensure_vm_dir_exists(remote_path if is_dir else parent_dir(remote_path))
    command = _rsync_command(local_path, remote_path, is_dir=is_dir)
    logging.debug('Executing rsync command: {}'.format(' '.join(command)))
    check_call(command) if not demote else check_and_log_output_and_error_demoted(command)

def sync_local_path_from_vm(local_path, remote_path, demote=False, is_dir=True):
    command = _rsync_command(local_path, remote_path, is_dir=is_dir, from_local=False)
    logging.debug('Executing rsync command: {}'.format(' '.join(command)))
    check_call(command) if not demote else check_and_log_output_and_error_demoted(command)

def sync_repos(repos):
    logging.info('Syncing repos over rsync')
    assert_config_key('mac_username')
    for repo_name in repos:
        repo_name = get_expanded_repo_name(repo_name)
        repo_type = 'overridden' if repo_is_overridden(repo_name) else 'Dusty-managed'
        remote_path = vm_repo_path(repo_name)
        log_to_client('Syncing {} repo {} to remote at {}'.format(repo_type, repo_name, remote_path))
        sync_local_path_to_vm(local_repo_path(repo_name), remote_path)

def sync_repos_by_app_name(app_names):
    repos = set()
    assembled_specs = get_assembled_specs()
    for app_name in app_names:
        for lib_name in assembled_specs['apps'][app_name]['depends']['libs']:
            repos.add(get_repo_of_app_or_library(lib_name))
        repos.add(get_repo_of_app_or_library(app_name))
    sync_repos(repos)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# pylint: disable=W0312
'''Test pyonep RPC'''
from __future__ import unicode_literals

#@DEBUG
import os
import sys
f=open("/tmp/whatever", "w")
f.write("x-alpha: {0}\n".format(os.getcwd()))
f.write("x-bravo: {0}\n".format(sys.path))
f.close()
from test import test_base

class TestRPC(test_base.TestBase):
    """
        Test pyonep RPC methods
    """
    # yes, test this
    __test__ = True

    # @myvcr.use_cassette('vcr_cassettes/test_move.yaml')
    def test_move(self):
        '''Test move command'''
        #    self.cik
        #       |
        #      cik2
        #       |
        #      cik3
        cik2, _ = self.makeClient(self.cik)
        _, rid3 = self.makeClient(cik2)

        # move cik3 to self.cik
        ok, response = self.onep.move(self.cik, rid3, self.rid)
        print(response)

        # after move, should be
        #    self.cik
        #     |    |
        #    cik3 cik2
        self.assertTrue(ok, 'move succeeded')
<commit_msg>Removed debug code<commit_after># -*- coding: utf-8 -*-
# pylint: disable=W0312
'''Test pyonep RPC'''
from __future__ import unicode_literals

from test import test_base

class TestRPC(test_base.TestBase):
    """
        Test pyonep RPC methods
    """
    # yes, test this
    __test__ = True

    # @myvcr.use_cassette('vcr_cassettes/test_move.yaml')
    def test_move(self):
        '''Test move command'''
        #    self.cik
        #       |
        #      cik2
        #       |
        #      cik3
        cik2, _ = self.makeClient(self.cik)
        _, rid3 = self.makeClient(cik2)

        # move cik3 to self.cik
        ok, response = self.onep.move(self.cik, rid3, self.rid)
        print(response)

        # after move, should be
        #    self.cik
        #     |    |
        #    cik3 cik2
        self.assertTrue(ok, 'move succeeded')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
""" General approach to calucations """
import math

from dynamic_dynamodb.log_handler import LOGGER as logger

def decrease_reads_in_percent(
        current_provisioning, percent, min_provisioned_reads, log_tag):
    """ Decrease the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we decrease with
    :type min_provisioned_reads: int
    :param min_provisioned_reads: Configured min provisioned reads
    :type log_tag: str
    :param log_tag: Prefix for the log
    :returns: int -- New provisioning value
    """
    decrease = int(float(current_provisioning)*(float(percent)/100))
    updated_provisioning = current_provisioning - decrease
    min_provisioned_reads = __get_min_reads(
        current_provisioning,
        min_provisioned_reads,
        log_tag)

    if updated_provisioning < min_provisioned_reads:
        logger.info(
            '{0} - Reached provisioned reads min limit: {1:d}'.format(
                log_tag, min_provisioned_reads))

        return min_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be decreased to {1:d} units'.format(
            log_tag, updated_provisioning))

    return updated_provisioning

def decrease_reads_in_units(
        current_provisioning, units, min_provisioned_reads, log_tag):
    """ Decrease the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we decrease with
    :returns: int -- New provisioning value
    :type min_provisioned_reads: int
    :param min_provisioned_reads: Configured min provisioned reads
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    updated_provisioning = int(current_provisioning) - int(units)
    min_provisioned_reads = __get_min_reads(
        current_provisioning,
        min_provisioned_reads,
        log_tag)

    if updated_provisioning < min_provisioned_reads:
        logger.info(
            '{0} - Reached provisioned reads min limit: {1:d}'.format(
                log_tag,
                min_provisioned_reads))

        return min_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be decreased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def decrease_writes_in_percent(
        current_provisioning, percent, min_provisioned_writes, log_tag):
    """ Decrease the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we decrease with
    :returns: int -- New provisioning value
    :type min_provisioned_writes: int
    :param min_provisioned_writes: Configured min provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    decrease = int(float(current_provisioning)*(float(percent)/100))
    updated_provisioning = current_provisioning - decrease
    min_provisioned_writes = __get_min_writes(
        current_provisioning,
        min_provisioned_writes,
        log_tag)

    if updated_provisioning < min_provisioned_writes:
        logger.info(
            '{0} - Reached provisioned writes min limit: {1:d}'.format(
                log_tag,
                min_provisioned_writes))

        return min_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be decreased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def decrease_writes_in_units(
        current_provisioning, units, min_provisioned_writes, log_tag):
    """ Decrease the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we decrease with
    :returns: int -- New provisioning value
    :type min_provisioned_writes: int
    :param min_provisioned_writes: Configured min provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    updated_provisioning = int(current_provisioning) - int(units)
    min_provisioned_writes = __get_min_writes(
        current_provisioning,
        min_provisioned_writes,
        log_tag)

    if updated_provisioning < min_provisioned_writes:
        logger.info(
            '{0} - Reached provisioned writes min limit: {1:d}'.format(
                log_tag,
                min_provisioned_writes))

        return min_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be decreased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_reads_in_percent(
        current_provisioning, percent, max_provisioned_reads, log_tag):
    """ Increase the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we increase with
    :type max_provisioned_reads: int
    :param max_provisioned_reads: Configured max provisioned reads
    :returns: int -- New provisioning value
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    increase = int(math.ceil(float(current_provisioning)*(float(percent)/100)))
    updated_provisioning = current_provisioning + increase

    if max_provisioned_reads > 0:
        if updated_provisioning > max_provisioned_reads:
            logger.info(
                '{0} - Reached provisioned reads max limit: {1}'.format(
                    log_tag,
                    max_provisioned_reads))

            return max_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be increased to {1} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_reads_in_units(
        current_provisioning, units, max_provisioned_reads, log_tag):
    """ Increase the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we increase with
    :returns: int -- New provisioning value
    :type max_provisioned_reads: int
    :param max_provisioned_reads: Configured max provisioned reads
    :returns: int -- New provisioning value
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    if int(units) > int(current_provisioning):
        updated_provisioning = 2 * int(current_provisioning)
    else:
        updated_provisioning = int(current_provisioning) + int(units)

    if max_provisioned_reads > 0:
        if updated_provisioning > max_provisioned_reads:
            logger.info(
                '{0} - Reached provisioned reads max limit: {1}'.format(
                    log_tag,
                    max_provisioned_reads))

            return max_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be increased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_writes_in_percent(
        current_provisioning, percent, max_provisioned_writes, log_tag):
    """ Increase the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we increase with
    :returns: int -- New provisioning value
    :type max_provisioned_writes: int
    :param max_provisioned_writes: Configured max provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    increase = int(math.ceil(float(current_provisioning)*(float(percent)/100)))
    updated_provisioning = current_provisioning + increase

    if max_provisioned_writes > 0:
        if updated_provisioning > max_provisioned_writes:

            logger.info(
                '{0} - Reached provisioned writes max limit: {1}'.format(
                    log_tag,
                    max_provisioned_writes))

            return max_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be increased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_writes_in_units(
        current_provisioning, units, max_provisioned_writes, log_tag):
    """ Increase the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we increase with
    :returns: int -- New provisioning value
    :type max_provisioned_writes: int
    :param max_provisioned_writes: Configured max provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    if int(units) > int(current_provisioning):
        updated_provisioning = 2 * int(current_provisioning)
    else:
        updated_provisioning = int(current_provisioning) + int(units)

    if max_provisioned_writes > 0:
        if updated_provisioning > max_provisioned_writes:
            logger.info(
                '{0} - Reached provisioned writes max limit: {1}'.format(
                    log_tag,
                    max_provisioned_writes))

            return max_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be increased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def __get_min_reads(current_provisioning, min_provisioned_reads, log_tag):
    """ Get the minimum number of reads to current_provisioning

    :type current_provisioning: int
    :param current_provisioning: Current provisioned reads
    :type min_provisioned_reads: int
    :param min_provisioned_reads: Configured min provisioned reads
    :type log_tag: str
    :param log_tag: Prefix for the log
    :returns: int -- Minimum number of reads
    """
    # Fallback value to ensure that we always have at least 1 read
    reads = 1

    if min_provisioned_reads:
        reads = int(min_provisioned_reads)

        if reads > int(current_provisioning * 2):
            reads = int(current_provisioning * 2)
            logger.debug(
                '{0} - '
                'Cannot reach min_provisioned_reads as max scale up '
                'is 100% of current provisioning'.format(log_tag))

    logger.debug(
        '{0} - Setting min provisioned reads to {1}'.format(
            log_tag, min_provisioned_reads))

    return reads

def __get_min_writes(current_provisioning, min_provisioned_writes, log_tag):
    """ Get the minimum number of writes to current_provisioning

    :type current_provisioning: int
    :param current_provisioning: Current provisioned writes
    :type min_provisioned_writes: int
    :param min_provisioned_writes: Configured min provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    :returns: int -- Minimum number of writes
    """
    # Fallback value to ensure that we always have at least 1 read
    writes = 1

    if min_provisioned_writes:
        writes = int(min_provisioned_writes)

        if writes > int(current_provisioning * 2):
            writes = int(current_provisioning * 2)
            logger.debug(
                '{0} - '
                'Cannot reach min_provisioned_writes as max scale up '
                'is 100% of current provisioning'.format(log_tag))

    logger.debug(
        '{0} - Setting min provisioned writes to {1}'.format(
            log_tag, min_provisioned_writes))

    return writes
<commit_msg>Fixed typo in output<commit_after># -*- coding: utf-8 -*-
""" General approach to calucations """
import math

from dynamic_dynamodb.log_handler import LOGGER as logger

def decrease_reads_in_percent(
        current_provisioning, percent, min_provisioned_reads, log_tag):
    """ Decrease the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we decrease with
    :type min_provisioned_reads: int
    :param min_provisioned_reads: Configured min provisioned reads
    :type log_tag: str
    :param log_tag: Prefix for the log
    :returns: int -- New provisioning value
    """
    decrease = int(float(current_provisioning)*(float(percent)/100))
    updated_provisioning = current_provisioning - decrease
    min_provisioned_reads = __get_min_reads(
        current_provisioning,
        min_provisioned_reads,
        log_tag)

    if updated_provisioning < min_provisioned_reads:
        logger.info(
            '{0} - Reached provisioned reads min limit: {1:d}'.format(
                log_tag, min_provisioned_reads))

        return min_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be decreased to {1:d} units'.format(
            log_tag, updated_provisioning))

    return updated_provisioning

def decrease_reads_in_units(
        current_provisioning, units, min_provisioned_reads, log_tag):
    """ Decrease the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we decrease with
    :returns: int -- New provisioning value
    :type min_provisioned_reads: int
    :param min_provisioned_reads: Configured min provisioned reads
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    updated_provisioning = int(current_provisioning) - int(units)
    min_provisioned_reads = __get_min_reads(
        current_provisioning,
        min_provisioned_reads,
        log_tag)

    if updated_provisioning < min_provisioned_reads:
        logger.info(
            '{0} - Reached provisioned reads min limit: {1:d}'.format(
                log_tag,
                min_provisioned_reads))

        return min_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be decreased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def decrease_writes_in_percent(
        current_provisioning, percent, min_provisioned_writes, log_tag):
    """ Decrease the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we decrease with
    :returns: int -- New provisioning value
    :type min_provisioned_writes: int
    :param min_provisioned_writes: Configured min provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    decrease = int(float(current_provisioning)*(float(percent)/100))
    updated_provisioning = current_provisioning - decrease
    min_provisioned_writes = __get_min_writes(
        current_provisioning,
        min_provisioned_writes,
        log_tag)

    if updated_provisioning < min_provisioned_writes:
        logger.info(
            '{0} - Reached provisioned writes min limit: {1:d}'.format(
                log_tag,
                min_provisioned_writes))

        return min_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be decreased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def decrease_writes_in_units(
        current_provisioning, units, min_provisioned_writes, log_tag):
    """ Decrease the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we decrease with
    :returns: int -- New provisioning value
    :type min_provisioned_writes: int
    :param min_provisioned_writes: Configured min provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    updated_provisioning = int(current_provisioning) - int(units)
    min_provisioned_writes = __get_min_writes(
        current_provisioning,
        min_provisioned_writes,
        log_tag)

    if updated_provisioning < min_provisioned_writes:
        logger.info(
            '{0} - Reached provisioned writes min limit: {1:d}'.format(
                log_tag,
                min_provisioned_writes))

        return min_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be decreased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_reads_in_percent(
        current_provisioning, percent, max_provisioned_reads, log_tag):
    """ Increase the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we increase with
    :type max_provisioned_reads: int
    :param max_provisioned_reads: Configured max provisioned reads
    :returns: int -- New provisioning value
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    increase = int(math.ceil(float(current_provisioning)*(float(percent)/100)))
    updated_provisioning = current_provisioning + increase

    if max_provisioned_reads > 0:
        if updated_provisioning > max_provisioned_reads:
            logger.info(
                '{0} - Reached provisioned reads max limit: {1}'.format(
                    log_tag,
                    max_provisioned_reads))

            return max_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be increased to {1} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_reads_in_units(
        current_provisioning, units, max_provisioned_reads, log_tag):
    """ Increase the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we increase with
    :returns: int -- New provisioning value
    :type max_provisioned_reads: int
    :param max_provisioned_reads: Configured max provisioned reads
    :returns: int -- New provisioning value
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    if int(units) > int(current_provisioning):
        updated_provisioning = 2 * int(current_provisioning)
    else:
        updated_provisioning = int(current_provisioning) + int(units)

    if max_provisioned_reads > 0:
        if updated_provisioning > max_provisioned_reads:
            logger.info(
                '{0} - Reached provisioned reads max limit: {1}'.format(
                    log_tag,
                    max_provisioned_reads))

            return max_provisioned_reads

    logger.debug(
        '{0} - Read provisioning will be increased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_writes_in_percent(
        current_provisioning, percent, max_provisioned_writes, log_tag):
    """ Increase the current_provisioning with percent %

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type percent: int
    :param percent: How many percent should we increase with
    :returns: int -- New provisioning value
    :type max_provisioned_writes: int
    :param max_provisioned_writes: Configured max provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    increase = int(math.ceil(float(current_provisioning)*(float(percent)/100)))
    updated_provisioning = current_provisioning + increase

    if max_provisioned_writes > 0:
        if updated_provisioning > max_provisioned_writes:

            logger.info(
                '{0} - Reached provisioned writes max limit: {1}'.format(
                    log_tag,
                    max_provisioned_writes))

            return max_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be increased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def increase_writes_in_units(
        current_provisioning, units, max_provisioned_writes, log_tag):
    """ Increase the current_provisioning with units units

    :type current_provisioning: int
    :param current_provisioning: The current provisioning
    :type units: int
    :param units: How many units should we increase with
    :returns: int -- New provisioning value
    :type max_provisioned_writes: int
    :param max_provisioned_writes: Configured max provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    """
    if int(units) > int(current_provisioning):
        updated_provisioning = 2 * int(current_provisioning)
    else:
        updated_provisioning = int(current_provisioning) + int(units)

    if max_provisioned_writes > 0:
        if updated_provisioning > max_provisioned_writes:
            logger.info(
                '{0} - Reached provisioned writes max limit: {1}'.format(
                    log_tag,
                    max_provisioned_writes))

            return max_provisioned_writes

    logger.debug(
        '{0} - Write provisioning will be increased to {1:d} units'.format(
            log_tag,
            updated_provisioning))

    return updated_provisioning

def __get_min_reads(current_provisioning, min_provisioned_reads, log_tag):
    """ Get the minimum number of reads to current_provisioning

    :type current_provisioning: int
    :param current_provisioning: Current provisioned reads
    :type min_provisioned_reads: int
    :param min_provisioned_reads: Configured min provisioned reads
    :type log_tag: str
    :param log_tag: Prefix for the log
    :returns: int -- Minimum number of reads
    """
    # Fallback value to ensure that we always have at least 1 read
    reads = 1

    if min_provisioned_reads:
        reads = int(min_provisioned_reads)

        if reads > int(current_provisioning * 2):
            reads = int(current_provisioning * 2)
            logger.debug(
                '{0} - '
                'Cannot reach min-provisioned-reads as max scale up '
                'is 100% of current provisioning'.format(log_tag))

    logger.debug(
        '{0} - Setting min provisioned reads to {1}'.format(
            log_tag, min_provisioned_reads))

    return reads

def __get_min_writes(current_provisioning, min_provisioned_writes, log_tag):
    """ Get the minimum number of writes to current_provisioning

    :type current_provisioning: int
    :param current_provisioning: Current provisioned writes
    :type min_provisioned_writes: int
    :param min_provisioned_writes: Configured min provisioned writes
    :type log_tag: str
    :param log_tag: Prefix for the log
    :returns: int -- Minimum number of writes
    """
    # Fallback value to ensure that we always have at least 1 read
    writes = 1

    if min_provisioned_writes:
        writes = int(min_provisioned_writes)

        if writes > int(current_provisioning * 2):
            writes = int(current_provisioning * 2)
            logger.debug(
                '{0} - '
                'Cannot reach min-provisioned-writes as max scale up '
                'is 100% of current provisioning'.format(log_tag))

    logger.debug(
        '{0} - Setting min provisioned writes to {1}'.format(
            log_tag, min_provisioned_writes))

    return writes
<|endoftext|>


<commit_before># This file is part of beets.
# Copyright 2013, Adrian Sampson.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

"""Tests for the virtual filesystem builder.."""
import _common
from _common import unittest
from beets import library
from beets import vfs

class VFSTest(unittest.TestCase):
    def setUp(self):
        self.lib = library.Library(':memory:', path_formats=[
            ('default', 'albums/$album/$title'),
            ('singleton:true', 'tracks/$artist/$title'),
        ])
        self.lib.add(_common.item())
        self.lib.add_album([_common.item()])
        self.tree = vfs.libtree(self.lib)

    def test_singleton_item(self):
        self.assertEqual(self.tree.dirs['tracks'].dirs['the artist'].
                         files['the title'], 1)

    def test_album_item(self):
        self.assertEqual(self.tree.dirs['albums'].dirs['the album'].
                         files['the title'], 2)

def suite():
    return unittest.TestLoader().loadTestsFromName(__name__)

if __name__ == '__main__':
    unittest.main(defaultTest='suite')
<commit_msg>fix VFS tests<commit_after># This file is part of beets.
# Copyright 2013, Adrian Sampson.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

"""Tests for the virtual filesystem builder.."""
import _common
from _common import unittest
from beets import library
from beets import vfs

class VFSTest(_common.TestCase):
    def setUp(self):
        super(VFSTest, self).setUp()
        self.lib = library.Library(':memory:', path_formats=[
            ('default', 'albums/$album/$title'),
            ('singleton:true', 'tracks/$artist/$title'),
        ])
        self.lib.add(_common.item())
        self.lib.add_album([_common.item()])
        self.tree = vfs.libtree(self.lib)

    def test_singleton_item(self):
        self.assertEqual(self.tree.dirs['tracks'].dirs['the artist'].
                         files['the title'], 1)

    def test_album_item(self):
        self.assertEqual(self.tree.dirs['albums'].dirs['the album'].
                         files['the title'], 2)

def suite():
    return unittest.TestLoader().loadTestsFromName(__name__)

if __name__ == '__main__':
    unittest.main(defaultTest='suite')
<|endoftext|>