<commit_before>from binascii import hexlify
from twisted.trial import unittest
from twisted.internet import defer

from torba.coin.bitcoinsegwit import MainNetLedger
from torba.baseaccount import HierarchicalDeterministic, SingleKey
from torba.wallet import Wallet

class TestHierarchicalDeterministicAccount(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.ledger = MainNetLedger({'db': MainNetLedger.database_class(':memory:')})
        yield self.ledger.db.start()
        self.account = self.ledger.account_class.generate(self.ledger, Wallet(), "torba")

    @defer.inlineCallbacks
    def test_generate_account(self):
        account = self.account

        self.assertEqual(account.ledger, self.ledger)
        self.assertIsNotNone(account.seed)
        self.assertEqual(account.public_key.ledger, self.ledger)
        self.assertEqual(account.private_key.public_key, account.public_key)

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 0)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 0)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 20)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 6)

        addresses = yield account.get_addresses()
        self.assertEqual(len(addresses), 26)

    @defer.inlineCallbacks
    def test_ensure_address_gap(self):
        account = self.account

        self.assertIsInstance(account.receiving, HierarchicalDeterministic)

        yield account.receiving.generate_keys(4, 7)
        yield account.receiving.generate_keys(0, 3)
        yield account.receiving.generate_keys(8, 11)
        records = yield account.receiving.get_address_records()
        self.assertEqual(
            [r['position'] for r in records],
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
        )

        # we have 12, but default gap is 20
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 8)
        records = yield account.receiving.get_address_records()
        self.assertEqual(
            [r['position'] for r in records],
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
        )

        # case #1: no new addresses needed
        empty = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(empty), 0)

        # case #2: only one new addressed needed
        records = yield account.receiving.get_address_records()
        yield self.ledger.db.set_address_history(records[0]['address'], 'a:1:')
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 1)

        # case #3: 20 addresses needed
        yield self.ledger.db.set_address_history(new_keys[0], 'a:1:')
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 20)

    @defer.inlineCallbacks
    def test_get_or_create_usable_address(self):
        account = self.account

        keys = yield account.receiving.get_addresses()
        self.assertEqual(len(keys), 0)

        address = yield account.receiving.get_or_create_usable_address()
        self.assertIsNotNone(address)

        keys = yield account.receiving.get_addresses()
        self.assertEqual(len(keys), 20)

    @defer.inlineCallbacks
    def test_generate_account_from_seed(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed": "carbon smart garage balance margin twelve chest sword "
                        "toast envelope bottom stomach absent",
                "address_generator": {
                    'name': 'deterministic-chain',
                    'receiving': {'gap': 3, 'maximum_uses_per_address': 1},
                    'change': {'gap': 2, 'maximum_uses_per_address': 1}
                }
            }
        )
        self.assertEqual(
            account.private_key.extended_key_string(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp5BxK'
            'Kfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna'
        )
        self.assertEqual(
            account.public_key.extended_key_string(),
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7UbpV'
            'NzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g'
        )
        address = yield account.receiving.ensure_address_gap()
        self.assertEqual(address[0], '1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J')

        private_key = yield self.ledger.get_private_key_for_address('1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J')
        self.assertEqual(
            private_key.extended_key_string(),
            'xprv9xV7rhbg6M4yWrdTeLorz3Q1GrQb4aQzzGWboP3du7W7UUztzNTUrEYTnDfz7o'
            'ptBygDxXYRppyiuenJpoBTgYP2C26E1Ah5FEALM24CsWi'
        )

        invalid_key = yield self.ledger.get_private_key_for_address('BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX')
        self.assertIsNone(invalid_key)

        self.assertEqual(
            hexlify(private_key.wif()),
            b'1c01ae1e4c7d89e39f6d3aa7792c097a30ca7d40be249b6de52c81ec8cf9aab48b01'
        )

    @defer.inlineCallbacks
    def test_load_and_save_account(self):
        account_data = {
            'name': 'My Account',
            'seed':
                "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
                "h absent",
            'encrypted': False,
            'private_key':
                'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
                '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
            'public_key':
                'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
                'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
            'address_generator': {
                'name': 'deterministic-chain',
                'receiving': {'gap': 5, 'maximum_uses_per_address': 2},
                'change': {'gap': 5, 'maximum_uses_per_address': 2}
            }
        }

        account = self.ledger.account_class.from_dict(self.ledger, Wallet(), account_data)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 5)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 5)

        self.maxDiff = None
        account_data['ledger'] = 'btc_mainnet'
        self.assertDictEqual(account_data, account.to_dict())

class TestSingleKeyAccount(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.ledger = MainNetLedger({'db': MainNetLedger.database_class(':memory:')})
        yield self.ledger.db.start()
        self.account = self.ledger.account_class.generate(
            self.ledger, Wallet(), "torba", {'name': 'single-address'})

    @defer.inlineCallbacks
    def test_generate_account(self):
        account = self.account

        self.assertEqual(account.ledger, self.ledger)
        self.assertIsNotNone(account.seed)
        self.assertEqual(account.public_key.ledger, self.ledger)
        self.assertEqual(account.private_key.public_key, account.public_key)

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 0)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 0)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 1)
        self.assertEqual(addresses[0], account.public_key.address)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 1)
        self.assertEqual(addresses[0], account.public_key.address)

        addresses = yield account.get_addresses()
        self.assertEqual(len(addresses), 1)
        self.assertEqual(addresses[0], account.public_key.address)

    @defer.inlineCallbacks
    def test_ensure_address_gap(self):
        account = self.account

        self.assertIsInstance(account.receiving, SingleKey)
        addresses = yield account.receiving.get_addresses()
        self.assertEqual(addresses, [])

        # we have 12, but default gap is 20
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 1)
        self.assertEqual(new_keys[0], account.public_key.address)
        records = yield account.receiving.get_address_records()
        self.assertEqual(records, [{
            'position': 0, 'address': account.public_key.address, 'used_times': 0
        }])

        # case #1: no new addresses needed
        empty = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(empty), 0)

        # case #2: after use, still no new address needed
        records = yield account.receiving.get_address_records()
        yield self.ledger.db.set_address_history(records[0]['address'], 'a:1:')
        empty = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(empty), 0)

    @defer.inlineCallbacks
    def test_get_or_create_usable_address(self):
        account = self.account

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 0)

        address1 = yield account.receiving.get_or_create_usable_address()
        self.assertIsNotNone(address1)

        yield self.ledger.db.set_address_history(address1, 'a:1:b:2:c:3:')
        records = yield account.receiving.get_address_records()
        self.assertEqual(records[0]['used_times'], 3)

        address2 = yield account.receiving.get_or_create_usable_address()
        self.assertEqual(address1, address2)

        keys = yield account.receiving.get_addresses()
        self.assertEqual(len(keys), 1)

    @defer.inlineCallbacks
    def test_generate_account_from_seed(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed":
                    "carbon smart garage balance margin twelve chest sword toas"
                    "t envelope bottom stomach absent",
                'address_generator': {'name': 'single-address'}
            }
        )
        self.assertEqual(
            account.private_key.extended_key_string(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
        )
        self.assertEqual(
            account.public_key.extended_key_string(),
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
            'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
        )
        address = yield account.receiving.ensure_address_gap()
        self.assertEqual(address[0], account.public_key.address)

        private_key = yield self.ledger.get_private_key_for_address(address[0])
        self.assertEqual(
            private_key.extended_key_string(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
        )

        invalid_key = yield self.ledger.get_private_key_for_address('BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX')
        self.assertIsNone(invalid_key)

        self.assertEqual(
            hexlify(private_key.wif()),
            b'1c92caa0ef99bfd5e2ceb73b66da8cd726a9370be8c368d448a322f3c5b23aaab901'
        )

    @defer.inlineCallbacks
    def test_load_and_save_account(self):
        account_data = {
            'name': 'My Account',
            'seed':
                "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
                "h absent",
            'encrypted': False,
            'private_key':
                'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
                '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
            'public_key':
                'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
                'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
            'address_generator': {'name': 'single-address'}
        }

        account = self.ledger.account_class.from_dict(self.ledger, Wallet(), account_data)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 1)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 1)

        self.maxDiff = None
        account_data['ledger'] = 'btc_mainnet'
        self.assertDictEqual(account_data, account.to_dict())
<commit_msg>unit test fixes<commit_after>from binascii import hexlify
from twisted.trial import unittest
from twisted.internet import defer

from torba.coin.bitcoinsegwit import MainNetLedger as ledger_class
from torba.baseaccount import HierarchicalDeterministic, SingleKey
from torba.wallet import Wallet

class TestHierarchicalDeterministicAccount(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.ledger = ledger_class({
            'db': ledger_class.database_class(':memory:'),
            'headers': ledger_class.headers_class(':memory:'),
        })
        yield self.ledger.db.open()
        self.account = self.ledger.account_class.generate(self.ledger, Wallet(), "torba")

    @defer.inlineCallbacks
    def test_generate_account(self):
        account = self.account

        self.assertEqual(account.ledger, self.ledger)
        self.assertIsNotNone(account.seed)
        self.assertEqual(account.public_key.ledger, self.ledger)
        self.assertEqual(account.private_key.public_key, account.public_key)

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 0)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 0)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 20)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 6)

        addresses = yield account.get_addresses()
        self.assertEqual(len(addresses), 26)

    @defer.inlineCallbacks
    def test_ensure_address_gap(self):
        account = self.account

        self.assertIsInstance(account.receiving, HierarchicalDeterministic)

        yield account.receiving.generate_keys(4, 7)
        yield account.receiving.generate_keys(0, 3)
        yield account.receiving.generate_keys(8, 11)
        records = yield account.receiving.get_address_records()
        self.assertEqual(
            [r['position'] for r in records],
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
        )

        # we have 12, but default gap is 20
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 8)
        records = yield account.receiving.get_address_records()
        self.assertEqual(
            [r['position'] for r in records],
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
        )

        # case #1: no new addresses needed
        empty = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(empty), 0)

        # case #2: only one new addressed needed
        records = yield account.receiving.get_address_records()
        yield self.ledger.db.set_address_history(records[0]['address'], 'a:1:')
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 1)

        # case #3: 20 addresses needed
        yield self.ledger.db.set_address_history(new_keys[0], 'a:1:')
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 20)

    @defer.inlineCallbacks
    def test_get_or_create_usable_address(self):
        account = self.account

        keys = yield account.receiving.get_addresses()
        self.assertEqual(len(keys), 0)

        address = yield account.receiving.get_or_create_usable_address()
        self.assertIsNotNone(address)

        keys = yield account.receiving.get_addresses()
        self.assertEqual(len(keys), 20)

    @defer.inlineCallbacks
    def test_generate_account_from_seed(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed": "carbon smart garage balance margin twelve chest sword "
                        "toast envelope bottom stomach absent",
                "address_generator": {
                    'name': 'deterministic-chain',
                    'receiving': {'gap': 3, 'maximum_uses_per_address': 1},
                    'change': {'gap': 2, 'maximum_uses_per_address': 1}
                }
            }
        )
        self.assertEqual(
            account.private_key.extended_key_string(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp5BxK'
            'Kfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna'
        )
        self.assertEqual(
            account.public_key.extended_key_string(),
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7UbpV'
            'NzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g'
        )
        address = yield account.receiving.ensure_address_gap()
        self.assertEqual(address[0], '1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J')

        private_key = yield self.ledger.get_private_key_for_address('1CDLuMfwmPqJiNk5C2Bvew6tpgjAGgUk8J')
        self.assertEqual(
            private_key.extended_key_string(),
            'xprv9xV7rhbg6M4yWrdTeLorz3Q1GrQb4aQzzGWboP3du7W7UUztzNTUrEYTnDfz7o'
            'ptBygDxXYRppyiuenJpoBTgYP2C26E1Ah5FEALM24CsWi'
        )

        invalid_key = yield self.ledger.get_private_key_for_address('BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX')
        self.assertIsNone(invalid_key)

        self.assertEqual(
            hexlify(private_key.wif()),
            b'1c01ae1e4c7d89e39f6d3aa7792c097a30ca7d40be249b6de52c81ec8cf9aab48b01'
        )

    @defer.inlineCallbacks
    def test_load_and_save_account(self):
        account_data = {
            'name': 'My Account',
            'seed':
                "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
                "h absent",
            'encrypted': False,
            'private_key':
                'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
                '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
            'public_key':
                'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
                'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
            'address_generator': {
                'name': 'deterministic-chain',
                'receiving': {'gap': 5, 'maximum_uses_per_address': 2},
                'change': {'gap': 5, 'maximum_uses_per_address': 2}
            }
        }

        account = self.ledger.account_class.from_dict(self.ledger, Wallet(), account_data)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 5)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 5)

        self.maxDiff = None
        account_data['ledger'] = 'btc_mainnet'
        self.assertDictEqual(account_data, account.to_dict())

class TestSingleKeyAccount(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.ledger = ledger_class({
            'db': ledger_class.database_class(':memory:'),
            'headers': ledger_class.headers_class(':memory:'),
        })
        yield self.ledger.db.open()
        self.account = self.ledger.account_class.generate(
            self.ledger, Wallet(), "torba", {'name': 'single-address'})

    @defer.inlineCallbacks
    def test_generate_account(self):
        account = self.account

        self.assertEqual(account.ledger, self.ledger)
        self.assertIsNotNone(account.seed)
        self.assertEqual(account.public_key.ledger, self.ledger)
        self.assertEqual(account.private_key.public_key, account.public_key)

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 0)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 0)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 1)
        self.assertEqual(addresses[0], account.public_key.address)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 1)
        self.assertEqual(addresses[0], account.public_key.address)

        addresses = yield account.get_addresses()
        self.assertEqual(len(addresses), 1)
        self.assertEqual(addresses[0], account.public_key.address)

    @defer.inlineCallbacks
    def test_ensure_address_gap(self):
        account = self.account

        self.assertIsInstance(account.receiving, SingleKey)
        addresses = yield account.receiving.get_addresses()
        self.assertEqual(addresses, [])

        # we have 12, but default gap is 20
        new_keys = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(new_keys), 1)
        self.assertEqual(new_keys[0], account.public_key.address)
        records = yield account.receiving.get_address_records()
        self.assertEqual(records, [{
            'position': 0, 'address': account.public_key.address, 'used_times': 0
        }])

        # case #1: no new addresses needed
        empty = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(empty), 0)

        # case #2: after use, still no new address needed
        records = yield account.receiving.get_address_records()
        yield self.ledger.db.set_address_history(records[0]['address'], 'a:1:')
        empty = yield account.receiving.ensure_address_gap()
        self.assertEqual(len(empty), 0)

    @defer.inlineCallbacks
    def test_get_or_create_usable_address(self):
        account = self.account

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 0)

        address1 = yield account.receiving.get_or_create_usable_address()
        self.assertIsNotNone(address1)

        yield self.ledger.db.set_address_history(address1, 'a:1:b:2:c:3:')
        records = yield account.receiving.get_address_records()
        self.assertEqual(records[0]['used_times'], 3)

        address2 = yield account.receiving.get_or_create_usable_address()
        self.assertEqual(address1, address2)

        keys = yield account.receiving.get_addresses()
        self.assertEqual(len(keys), 1)

    @defer.inlineCallbacks
    def test_generate_account_from_seed(self):
        account = self.ledger.account_class.from_dict(
            self.ledger, Wallet(), {
                "seed":
                    "carbon smart garage balance margin twelve chest sword toas"
                    "t envelope bottom stomach absent",
                'address_generator': {'name': 'single-address'}
            }
        )
        self.assertEqual(
            account.private_key.extended_key_string(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
        )
        self.assertEqual(
            account.public_key.extended_key_string(),
            'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
            'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
        )
        address = yield account.receiving.ensure_address_gap()
        self.assertEqual(address[0], account.public_key.address)

        private_key = yield self.ledger.get_private_key_for_address(address[0])
        self.assertEqual(
            private_key.extended_key_string(),
            'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
            '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
        )

        invalid_key = yield self.ledger.get_private_key_for_address('BcQjRlhDOIrQez1WHfz3whnB33Bp34sUgX')
        self.assertIsNone(invalid_key)

        self.assertEqual(
            hexlify(private_key.wif()),
            b'1c92caa0ef99bfd5e2ceb73b66da8cd726a9370be8c368d448a322f3c5b23aaab901'
        )

    @defer.inlineCallbacks
    def test_load_and_save_account(self):
        account_data = {
            'name': 'My Account',
            'seed':
                "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac"
                "h absent",
            'encrypted': False,
            'private_key':
                'xprv9s21ZrQH143K3TsAz5efNV8K93g3Ms3FXcjaWB9fVUsMwAoE3ZT4vYymkp'
                '5BxKKfnpz8J6sHDFriX1SnpvjNkzcks8XBnxjGLS83BTyfpna',
            'public_key':
                'xpub661MyMwAqRbcFwwe67Bfjd53h5WXmKm6tqfBJZZH3pQLoy8Nb6mKUMJFc7'
                'UbpVNzmwFPN2evn3YHnig1pkKVYcvCV8owTd2yAcEkJfCX53g',
            'address_generator': {'name': 'single-address'}
        }

        account = self.ledger.account_class.from_dict(self.ledger, Wallet(), account_data)

        yield account.ensure_address_gap()

        addresses = yield account.receiving.get_addresses()
        self.assertEqual(len(addresses), 1)
        addresses = yield account.change.get_addresses()
        self.assertEqual(len(addresses), 1)

        self.maxDiff = None
        account_data['ledger'] = 'btc_mainnet'
        self.assertDictEqual(account_data, account.to_dict())
<|endoftext|>


<commit_before>import email
import logging
import mailbox
import os
import unittest
from pathlib import Path

import networkx as nx
import pandas as pd
from testfixtures import LogCapture

import bigbang.archive as archive
import bigbang.mailman as mailman
import bigbang.parse as parse
import bigbang.process as process
import bigbang.utils as utils
from bigbang import repo_loader
from config.config import CONFIG

test_txt = ""
TEMP_DIR = os.path.join(CONFIG.test_data_path, "tmp")
project_directory = str(Path(os.path.abspath(__file__)).parent.parent.parent)

class TestGit(unittest.TestCase):
    def test_git_dependancy(self):
        repo_loader.get_repo(
            "https://github.com/sbenthall/bigbang.git",
            in_type="remote",
        )

class TestMailman(unittest.TestCase):
    def setUp(self):
        try:
            os.mkdir(TEMP_DIR)
        except OSError:  # Python 2.7-specific, alas; FileExistsError in py3
            pass  # temporary directory already exists, that's cool

    def tearDown(self):
        # remove all files in the temporary files directory, as cleanup
        temp_files = os.listdir(TEMP_DIR)
        for f in temp_files:
            os.remove(os.path.join(TEMP_DIR, f))

    def test_provenance(self):
        test_list_name = "test-list-name"
        test_list_url = "https://example.com/test-list-url/"
        test_notes = "Test notes."
        mailman.populate_provenance(
            TEMP_DIR,
            list_name=test_list_name,
            list_url=test_list_url,
            notes=test_notes,
        )

        self.assertTrue(
            os.path.exists(
                os.path.join(TEMP_DIR, mailman.PROVENANCE_FILENAME)
            ),
            msg="provenance file should have been created",
        )

        provenance = mailman.access_provenance(TEMP_DIR)
        self.assertTrue(
            provenance is not None, "provenance should be something"
        )
        self.assertTrue(
            provenance["list"]["list_name"] == test_list_name,
            "list name should be in the provenance",
        )
        self.assertTrue(
            provenance["list"]["list_url"] == test_list_url,
            "list url should be in the provenance",
        )
        self.assertTrue(
            provenance["notes"] == test_notes,
            "notes should be in the provenance",
        )

        provenance["notes"] = "modified provenance"
        mailman.update_provenance(TEMP_DIR, provenance)
        provenance_next = mailman.access_provenance(TEMP_DIR)
        self.assertTrue(
            provenance_next["notes"] == "modified provenance",
            "confirm modified provenance",
        )

    def test_valid_urls(self):
        test_urls_path = os.path.join(
            CONFIG.test_data_path, "urls-test-file.txt"
        )
        with LogCapture() as _l:
            urls = mailman.urls_to_collect(test_urls_path)
            self.assertTrue(
                "#ignored" not in urls, msg="failed to ignore a comment line"
            )
            self.assertTrue(
                "http://www.example.com/1" in urls,
                msg="failed to find valid url",
            )

            self.assertTrue(
                "http://www.example.com/2/" in urls,
                msg="failed to find valid url, whitespace strip issue",
            )
            self.assertTrue(
                "https://www.example.com/3/" in urls,
                msg="failed to find valid url, whitespace strip issue",
            )
            self.assertTrue(
                "invalid.com" not in urls, msg="accepted invalid url"
            )
            self.assertTrue(
                len(list(_l.actual())) == 2, msg="wrong number of log entries"
            )
            for (fromwhere, level, msg) in _l.actual():
                self.assertTrue(
                    level == "WARNING",
                    msg="logged something that wasn't a warning",
                )
                self.assertTrue(
                    len(urls) == 3, msg="wrong number of urls parsed from file"
                )

    def test_empty_list_compute_activity_issue_246(self):
        test_df_csv_path = os.path.join(
            CONFIG.test_data_path, "empty-archive-df.csv"
        )
        df = pd.read_csv(test_df_csv_path)

        with self.assertRaises(mailman.MissingDataException):
            empty_archive = archive.Archive(df)
            empty_archive.get_activity()

    def test_mailman_normalizer(self):
        browse_url = "https://mailarchive.ietf.org/arch/browse/ietf/"
        search_url = (
            "https://mailarchive.ietf.org/arch/search/?email_list=ietf"
        )
        random_url = "http://example.com"

        better_url = "https://www.ietf.org/mail-archive/text/ietf/"

        self.assertTrue(
            mailman.normalize_archives_url(browse_url) == better_url,
            msg="failed to normalize",
        )
        self.assertTrue(
            mailman.normalize_archives_url(search_url) == better_url,
            msg="failed to normalize",
        )
        self.assertTrue(
            mailman.normalize_archives_url(random_url) == random_url,
            msg="should not have changed other url",
        )

    def test_mailman_list_name(self):
        ietf_archive_url = "https://www.ietf.org/mail-archive/text/ietf/"
        w3c_archive_url = (
            "https://lists.w3.org/Archives/Public/public-privacy/"
        )
        random_url = "http://example.com"

        self.assertTrue(
            mailman.get_list_name(ietf_archive_url) == "ietf",
            msg="failed to grab ietf list name",
        )
        self.assertTrue(
            mailman.get_list_name(w3c_archive_url) == "public-privacy",
            msg="failed to grab w3c list name",
        )
        self.assertTrue(
            mailman.get_list_name(random_url) == random_url,
            msg="should not have changed other url",
        )

    def test_activity_summary(self):
        list_url = (
            "https://lists.w3.org/Archives/Public/test-activity-summary/"
        )
        activity_frame = mailman.open_activity_summary(
            list_url, archive_dir=CONFIG.test_data_path
        )

        self.assertTrue(
            str(type(activity_frame))
            == "<class 'pandas.core.frame.DataFrame'>",
            msg="not a DataFrame?",
        )
        self.assertTrue(
            len(activity_frame.columns) == 1,
            msg="activity summary should have one column",
        )

class TestArchive(unittest.TestCase):
    def test_mailman_chain(self):
        name = "bigbang-dev-test.txt"
        dir = project_directory + "/tests/data"

        # archive loaded from mbox
        arx = archive.Archive(name, archive_dir=dir, mbox=True)

        arx.save("test.csv")

        # archive loaded from stored csv
        arx2 = archive.load("test.csv")

        print(arx.data.dtypes)
        print(arx.data.shape)

        self.assertTrue(
            arx.data.shape == arx2.data.shape,
            msg="Original and restored archives are different shapes",
        )

        self.assertTrue(
            (arx2.data.index == arx.data.index).all(),
            msg="Original and restored archives have nonidentical indices",
        )

        self.assertTrue(
            [t.get_num_messages() for t in arx.get_threads()] == [3, 1, 2],
            msg="Thread message count in mbox archive is off",
        )
        self.assertTrue(
            [t.get_num_messages() for t in arx2.get_threads()] == [3, 1, 2],
            msg="Thread message count in restored archive is off",
        )

        # smoke test entity resolution
        arx2.resolve_entities()

        os.remove("test.csv")

    def test_clean_message(self):
        name = "2001-November.txt"
        dir = project_directory + "/tests/data"

        arx = archive.Archive(name, archive_dir=dir, mbox=True)

        body = arx.data["Body"]["<E165uMn-0002IJ-00@spock.physics.mcgill.ca>"]

        self.assertTrue(
            "But seemingly it is even stranger than this." in body,
            msg="Selected wrong message",
        )

        self.assertTrue(
            "Is it a problem of lapack3.0 of of" in body,
            msg="Quoted text is not in uncleaned message",
        )

        self.assertTrue(
            "Is it a problem of lapack3.0 of of"
            not in utils.clean_message(body),
            msg="Quoted text is in cleaned message",
        )

    def test_email_entity_resolution(self):
        name = "2001-November.txt"
        dir = project_directory + "/tests/data"

        arx = archive.Archive(name, archive_dir=dir, mbox=True)

        e = process.resolve_sender_entities(arx.get_activity(resolved=False))

        utils.repartition_dataframe(arx.get_activity(), e)

        self.assertTrue(True, msg="email entity resolution crashed")

class TestMailParsing(unittest.TestCase):
    def test_split_references(self):
        refs = " <ye1y9ljtxwk.fsf@orange30.ex.ac.uk>\n\t<055701c16727$b57fed90$8fd6afcf@pixi.com>"
        split = parse.split_references(refs)
        self.assertTrue(len(split) == 2, msg=split)

    def test_name_email_parsing(self):
        from_header = "John_Doe (?) <John.Doe@example.com>"
        (raw_name, raw_email) = email.utils.parseaddr(from_header)
        normalized_email = parse.normalize_email_address(raw_email)
        self.assertTrue(
            normalized_email == "john.doe@example.com",
            msg="normalized email case incorrect",
        )

        clean_name = parse.clean_name(raw_name)
        self.assertTrue(clean_name == "John Doe", msg="name not fully cleaned")

        empty_name = parse.clean_name(" ")
        self.assertTrue(
            empty_name is None, msg="empty name not cleaned to None"
        )

        tokenized_name = parse.tokenize_name(clean_name)
        self.assertTrue(
            tokenized_name == "doe john",
            msg="name not properly normalized and tokenized",
        )

        parse.tokenize_name(str("   "))
        self.assertTrue(
            empty_name is None, msg="empty name not tokenized to None"
        )

class TestMailProcessing(unittest.TestCase):
    def test_from_header_distance(self):
        a = "Fernando.Perez at colorado.edu (Fernando.Perez at colorado.edu)"
        b = "Fernando.Perez at colorado.edu (Fernando.Perez@colorado.edu)"

        self.assertTrue(
            process.from_header_distance(a, b) == 0,
            msg="from_header_distance computing incorrect value",
        )

        a = ""
        b = ""

class TestUtils(unittest.TestCase):
    def test_labeled_blockmodel(self):
        g = nx.DiGraph()

        g.add_edge(0, 1)
        g.add_edge(0, 2)
        g.add_edge(0, 3)
        g.add_edge(0, 4)

        p = {"B": [1, 2, 3, 4], "A": [0]}

        bg = utils.labeled_blockmodel(g, p)

        self.assertTrue(
            list(bg.edges(data=True))[0][2]["weight"] == 4.0,
            msg="Incorrect edge weight in labeled blockmodel",
        )

        self.assertTrue(
            list(bg.edges()) == [("A", "B")],
            msg="Incorrected edges in labeled blockmodel",
        )
<commit_msg>test_bigbang.py: use CONFIG.test_data_path instead of pathlib.Path<commit_after>import email
import logging
import mailbox
import os
import unittest

import networkx as nx
import pandas as pd
from testfixtures import LogCapture

import bigbang.archive as archive
import bigbang.mailman as mailman
import bigbang.parse as parse
import bigbang.process as process
import bigbang.utils as utils
from bigbang import repo_loader
from config.config import CONFIG

test_txt = ""
TEMP_DIR = os.path.join(CONFIG.test_data_path, "tmp")

class TestGit(unittest.TestCase):
    def test_git_dependancy(self):
        repo_loader.get_repo(
            "https://github.com/sbenthall/bigbang.git",
            in_type="remote",
        )

class TestMailman(unittest.TestCase):
    def setUp(self):
        try:
            os.mkdir(TEMP_DIR)
        except OSError:  # Python 2.7-specific, alas; FileExistsError in py3
            pass  # temporary directory already exists, that's cool

    def tearDown(self):
        # remove all files in the temporary files directory, as cleanup
        temp_files = os.listdir(TEMP_DIR)
        for f in temp_files:
            os.remove(os.path.join(TEMP_DIR, f))

    def test_provenance(self):
        test_list_name = "test-list-name"
        test_list_url = "https://example.com/test-list-url/"
        test_notes = "Test notes."
        mailman.populate_provenance(
            TEMP_DIR,
            list_name=test_list_name,
            list_url=test_list_url,
            notes=test_notes,
        )

        self.assertTrue(
            os.path.exists(
                os.path.join(TEMP_DIR, mailman.PROVENANCE_FILENAME)
            ),
            msg="provenance file should have been created",
        )

        provenance = mailman.access_provenance(TEMP_DIR)
        self.assertTrue(
            provenance is not None, "provenance should be something"
        )
        self.assertTrue(
            provenance["list"]["list_name"] == test_list_name,
            "list name should be in the provenance",
        )
        self.assertTrue(
            provenance["list"]["list_url"] == test_list_url,
            "list url should be in the provenance",
        )
        self.assertTrue(
            provenance["notes"] == test_notes,
            "notes should be in the provenance",
        )

        provenance["notes"] = "modified provenance"
        mailman.update_provenance(TEMP_DIR, provenance)
        provenance_next = mailman.access_provenance(TEMP_DIR)
        self.assertTrue(
            provenance_next["notes"] == "modified provenance",
            "confirm modified provenance",
        )

    def test_valid_urls(self):
        test_urls_path = os.path.join(
            CONFIG.test_data_path, "urls-test-file.txt"
        )
        with LogCapture() as _l:
            urls = mailman.urls_to_collect(test_urls_path)
            self.assertTrue(
                "#ignored" not in urls, msg="failed to ignore a comment line"
            )
            self.assertTrue(
                "http://www.example.com/1" in urls,
                msg="failed to find valid url",
            )

            self.assertTrue(
                "http://www.example.com/2/" in urls,
                msg="failed to find valid url, whitespace strip issue",
            )
            self.assertTrue(
                "https://www.example.com/3/" in urls,
                msg="failed to find valid url, whitespace strip issue",
            )
            self.assertTrue(
                "invalid.com" not in urls, msg="accepted invalid url"
            )
            self.assertTrue(
                len(list(_l.actual())) == 2, msg="wrong number of log entries"
            )
            for (fromwhere, level, msg) in _l.actual():
                self.assertTrue(
                    level == "WARNING",
                    msg="logged something that wasn't a warning",
                )
                self.assertTrue(
                    len(urls) == 3, msg="wrong number of urls parsed from file"
                )

    def test_empty_list_compute_activity_issue_246(self):
        test_df_csv_path = os.path.join(
            CONFIG.test_data_path, "empty-archive-df.csv"
        )
        df = pd.read_csv(test_df_csv_path)

        with self.assertRaises(mailman.MissingDataException):
            empty_archive = archive.Archive(df)
            empty_archive.get_activity()

    def test_mailman_normalizer(self):
        browse_url = "https://mailarchive.ietf.org/arch/browse/ietf/"
        search_url = (
            "https://mailarchive.ietf.org/arch/search/?email_list=ietf"
        )
        random_url = "http://example.com"

        better_url = "https://www.ietf.org/mail-archive/text/ietf/"

        self.assertTrue(
            mailman.normalize_archives_url(browse_url) == better_url,
            msg="failed to normalize",
        )
        self.assertTrue(
            mailman.normalize_archives_url(search_url) == better_url,
            msg="failed to normalize",
        )
        self.assertTrue(
            mailman.normalize_archives_url(random_url) == random_url,
            msg="should not have changed other url",
        )

    def test_mailman_list_name(self):
        ietf_archive_url = "https://www.ietf.org/mail-archive/text/ietf/"
        w3c_archive_url = (
            "https://lists.w3.org/Archives/Public/public-privacy/"
        )
        random_url = "http://example.com"

        self.assertTrue(
            mailman.get_list_name(ietf_archive_url) == "ietf",
            msg="failed to grab ietf list name",
        )
        self.assertTrue(
            mailman.get_list_name(w3c_archive_url) == "public-privacy",
            msg="failed to grab w3c list name",
        )
        self.assertTrue(
            mailman.get_list_name(random_url) == random_url,
            msg="should not have changed other url",
        )

    def test_activity_summary(self):
        list_url = (
            "https://lists.w3.org/Archives/Public/test-activity-summary/"
        )
        activity_frame = mailman.open_activity_summary(
            list_url, archive_dir=CONFIG.test_data_path
        )

        self.assertTrue(
            str(type(activity_frame))
            == "<class 'pandas.core.frame.DataFrame'>",
            msg="not a DataFrame?",
        )
        self.assertTrue(
            len(activity_frame.columns) == 1,
            msg="activity summary should have one column",
        )

class TestArchive(unittest.TestCase):
    def test_mailman_chain(self):
        name = "bigbang-dev-test.txt"

        # archive loaded from mbox
        arx = archive.Archive(
            name, archive_dir=CONFIG.test_data_path, mbox=True
        )

        arx.save("test.csv")

        # archive loaded from stored csv
        arx2 = archive.load("test.csv")

        print(arx.data.dtypes)
        print(arx.data.shape)

        self.assertTrue(
            arx.data.shape == arx2.data.shape,
            msg="Original and restored archives are different shapes",
        )

        self.assertTrue(
            (arx2.data.index == arx.data.index).all(),
            msg="Original and restored archives have nonidentical indices",
        )

        self.assertTrue(
            [t.get_num_messages() for t in arx.get_threads()] == [3, 1, 2],
            msg="Thread message count in mbox archive is off",
        )
        self.assertTrue(
            [t.get_num_messages() for t in arx2.get_threads()] == [3, 1, 2],
            msg="Thread message count in restored archive is off",
        )

        # smoke test entity resolution
        arx2.resolve_entities()

        os.remove("test.csv")

    def test_clean_message(self):
        name = "2001-November.txt"

        arx = archive.Archive(
            name, archive_dir=CONFIG.test_data_path, mbox=True
        )

        body = arx.data["Body"]["<E165uMn-0002IJ-00@spock.physics.mcgill.ca>"]

        self.assertTrue(
            "But seemingly it is even stranger than this." in body,
            msg="Selected wrong message",
        )

        self.assertTrue(
            "Is it a problem of lapack3.0 of of" in body,
            msg="Quoted text is not in uncleaned message",
        )

        self.assertTrue(
            "Is it a problem of lapack3.0 of of"
            not in utils.clean_message(body),
            msg="Quoted text is in cleaned message",
        )

    def test_email_entity_resolution(self):
        name = "2001-November.txt"

        arx = archive.Archive(
            name, archive_dir=CONFIG.test_data_path, mbox=True
        )

        e = process.resolve_sender_entities(arx.get_activity(resolved=False))

        utils.repartition_dataframe(arx.get_activity(), e)

        self.assertTrue(True, msg="email entity resolution crashed")

class TestMailParsing(unittest.TestCase):
    def test_split_references(self):
        refs = " <ye1y9ljtxwk.fsf@orange30.ex.ac.uk>\n\t<055701c16727$b57fed90$8fd6afcf@pixi.com>"
        split = parse.split_references(refs)
        self.assertTrue(len(split) == 2, msg=split)

    def test_name_email_parsing(self):
        from_header = "John_Doe (?) <John.Doe@example.com>"
        (raw_name, raw_email) = email.utils.parseaddr(from_header)
        normalized_email = parse.normalize_email_address(raw_email)
        self.assertTrue(
            normalized_email == "john.doe@example.com",
            msg="normalized email case incorrect",
        )

        clean_name = parse.clean_name(raw_name)
        self.assertTrue(clean_name == "John Doe", msg="name not fully cleaned")

        empty_name = parse.clean_name(" ")
        self.assertTrue(
            empty_name is None, msg="empty name not cleaned to None"
        )

        tokenized_name = parse.tokenize_name(clean_name)
        self.assertTrue(
            tokenized_name == "doe john",
            msg="name not properly normalized and tokenized",
        )

        parse.tokenize_name(str("   "))
        self.assertTrue(
            empty_name is None, msg="empty name not tokenized to None"
        )

class TestMailProcessing(unittest.TestCase):
    def test_from_header_distance(self):
        a = "Fernando.Perez at colorado.edu (Fernando.Perez at colorado.edu)"
        b = "Fernando.Perez at colorado.edu (Fernando.Perez@colorado.edu)"

        self.assertTrue(
            process.from_header_distance(a, b) == 0,
            msg="from_header_distance computing incorrect value",
        )

        a = ""
        b = ""

class TestUtils(unittest.TestCase):
    def test_labeled_blockmodel(self):
        g = nx.DiGraph()

        g.add_edge(0, 1)
        g.add_edge(0, 2)
        g.add_edge(0, 3)
        g.add_edge(0, 4)

        p = {"B": [1, 2, 3, 4], "A": [0]}

        bg = utils.labeled_blockmodel(g, p)

        self.assertTrue(
            list(bg.edges(data=True))[0][2]["weight"] == 4.0,
            msg="Incorrect edge weight in labeled blockmodel",
        )

        self.assertTrue(
            list(bg.edges()) == [("A", "B")],
            msg="Incorrected edges in labeled blockmodel",
        )
<|endoftext|>


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

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""
Unit Tests for remote procedure calls using queue
"""
import os
import signal
import time
import traceback

from eventlet import greenthread
from oslo.config import cfg

from openstack.common.gettextutils import _
from openstack.common import log as logging
from openstack.common.notifier import api as notifier_api
from openstack.common import service
from tests import utils

CONF = cfg.CONF
LOG = logging.getLogger(__name__)

class ExtendedService(service.Service):
    def test_method(self):
        return 'service'

class ServiceManagerTestCase(utils.BaseTestCase):
    """Test cases for Services"""
    def test_override_manager_method(self):
        serv = ExtendedService()
        serv.start()
        self.assertEqual(serv.test_method(), 'service')

class ServiceWithTimer(service.Service):
    def start(self):
        super(ServiceWithTimer, self).start()
        self.timer_fired = 0
        self.tg.add_timer(1, self.timer_expired)

    def timer_expired(self):
        self.timer_fired = self.timer_fired + 1

class ServiceLauncherTest(utils.BaseTestCase):
    """
    Originally from nova/tests/integrated/test_multiprocess_api.py
    """

    def _spawn(self):
        self.workers = 2
        pid = os.fork()
        if pid == 0:
            # NOTE(johannes): We can't let the child processes exit back
            # into the unit test framework since then we'll have multiple
            # processes running the same tests (and possibly forking more
            # processes that end up in the same situation). So we need
            # to catch all exceptions and make sure nothing leaks out, in
            # particlar SystemExit, which is raised by sys.exit(). We use
            # os._exit() which doesn't have this problem.
            status = 0
            try:
                launcher = service.ProcessLauncher()
                serv = ServiceWithTimer()
                launcher.launch_service(serv, workers=self.workers)
                launcher.wait()
            except SystemExit as exc:
                status = exc.code
            except BaseException:
                # We need to be defensive here too
                try:
                    traceback.print_exc()
                except BaseException:
                    print "Couldn't print traceback"
                status = 2

            # Really exit
            os._exit(status)

        self.pid = pid

        # Wait at most 10 seconds to spawn workers
        cond = lambda: self.workers == len(self._get_workers())
        timeout = 10
        self._wait(cond, timeout)

        workers = self._get_workers()
        self.assertEqual(len(workers), self.workers)
        return workers

    def _wait(self, cond, timeout):
        start = time.time()
        while True:
            if cond():
                break
            if time.time() - start > timeout:
                break
            time.sleep(.1)

    def setUp(self):
        super(ServiceLauncherTest, self).setUp()
        # FIXME(markmc): Ugly hack to workaround bug #1073732
        CONF.unregister_opts(notifier_api.notifier_opts)
        # NOTE(markmc): ConfigOpts.log_opt_values() uses CONF.config-file
        CONF(args=[], default_config_files=[])
        self.addCleanup(CONF.reset)
        self.addCleanup(CONF.register_opts, notifier_api.notifier_opts)
        self.addCleanup(self._reap_pid)

    def _reap_pid(self):
        if self.pid:
            # Make sure all processes are stopped
            os.kill(self.pid, signal.SIGTERM)

            # Make sure we reap our test process
            self._reap_test()

    def _reap_test(self):
        pid, status = os.waitpid(self.pid, 0)
        self.pid = None
        return status

    def _get_workers(self):
        f = os.popen('ps ax -o pid,ppid,command')
        # Skip ps header
        f.readline()

        processes = [tuple(int(p) for p in l.strip().split()[:2])
                     for l in f.readlines()]
        return [p for p, pp in processes if pp == self.pid]

    def test_killed_worker_recover(self):
        start_workers = self._spawn()

        # kill one worker and check if new worker can come up
        LOG.info('pid of first child is %s' % start_workers[0])
        os.kill(start_workers[0], signal.SIGTERM)

        # Wait at most 5 seconds to respawn a worker
        cond = lambda: start_workers != self._get_workers()
        timeout = 5
        self._wait(cond, timeout)

        # Make sure worker pids don't match
        end_workers = self._get_workers()
        LOG.info('workers: %r' % end_workers)
        self.assertNotEqual(start_workers, end_workers)

    def _terminate_with_signal(self, sig):
        self._spawn()

        os.kill(self.pid, sig)

        # Wait at most 5 seconds to kill all workers
        cond = lambda: not self._get_workers()
        timeout = 5
        self._wait(cond, timeout)

        workers = self._get_workers()
        LOG.info('workers: %r' % workers)
        self.assertFalse(workers, 'No OS processes left.')

    def test_terminate_sigkill(self):
        self._terminate_with_signal(signal.SIGKILL)
        status = self._reap_test()
        self.assertTrue(os.WIFSIGNALED(status))
        self.assertEqual(os.WTERMSIG(status), signal.SIGKILL)

    def test_terminate_sigterm(self):
        self._terminate_with_signal(signal.SIGTERM)
        status = self._reap_test()
        self.assertTrue(os.WIFEXITED(status))
        self.assertEqual(os.WEXITSTATUS(status), 0)
<commit_msg>Removes unused imports in the tests module<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""
Unit Tests for remote procedure calls using queue
"""
import os
import signal
import time
import traceback

from oslo.config import cfg

from openstack.common import log as logging
from openstack.common.notifier import api as notifier_api
from openstack.common import service
from tests import utils

CONF = cfg.CONF
LOG = logging.getLogger(__name__)

class ExtendedService(service.Service):
    def test_method(self):
        return 'service'

class ServiceManagerTestCase(utils.BaseTestCase):
    """Test cases for Services"""
    def test_override_manager_method(self):
        serv = ExtendedService()
        serv.start()
        self.assertEqual(serv.test_method(), 'service')

class ServiceWithTimer(service.Service):
    def start(self):
        super(ServiceWithTimer, self).start()
        self.timer_fired = 0
        self.tg.add_timer(1, self.timer_expired)

    def timer_expired(self):
        self.timer_fired = self.timer_fired + 1

class ServiceLauncherTest(utils.BaseTestCase):
    """
    Originally from nova/tests/integrated/test_multiprocess_api.py
    """

    def _spawn(self):
        self.workers = 2
        pid = os.fork()
        if pid == 0:
            # NOTE(johannes): We can't let the child processes exit back
            # into the unit test framework since then we'll have multiple
            # processes running the same tests (and possibly forking more
            # processes that end up in the same situation). So we need
            # to catch all exceptions and make sure nothing leaks out, in
            # particlar SystemExit, which is raised by sys.exit(). We use
            # os._exit() which doesn't have this problem.
            status = 0
            try:
                launcher = service.ProcessLauncher()
                serv = ServiceWithTimer()
                launcher.launch_service(serv, workers=self.workers)
                launcher.wait()
            except SystemExit as exc:
                status = exc.code
            except BaseException:
                # We need to be defensive here too
                try:
                    traceback.print_exc()
                except BaseException:
                    print "Couldn't print traceback"
                status = 2

            # Really exit
            os._exit(status)

        self.pid = pid

        # Wait at most 10 seconds to spawn workers
        cond = lambda: self.workers == len(self._get_workers())
        timeout = 10
        self._wait(cond, timeout)

        workers = self._get_workers()
        self.assertEqual(len(workers), self.workers)
        return workers

    def _wait(self, cond, timeout):
        start = time.time()
        while True:
            if cond():
                break
            if time.time() - start > timeout:
                break
            time.sleep(.1)

    def setUp(self):
        super(ServiceLauncherTest, self).setUp()
        # FIXME(markmc): Ugly hack to workaround bug #1073732
        CONF.unregister_opts(notifier_api.notifier_opts)
        # NOTE(markmc): ConfigOpts.log_opt_values() uses CONF.config-file
        CONF(args=[], default_config_files=[])
        self.addCleanup(CONF.reset)
        self.addCleanup(CONF.register_opts, notifier_api.notifier_opts)
        self.addCleanup(self._reap_pid)

    def _reap_pid(self):
        if self.pid:
            # Make sure all processes are stopped
            os.kill(self.pid, signal.SIGTERM)

            # Make sure we reap our test process
            self._reap_test()

    def _reap_test(self):
        pid, status = os.waitpid(self.pid, 0)
        self.pid = None
        return status

    def _get_workers(self):
        f = os.popen('ps ax -o pid,ppid,command')
        # Skip ps header
        f.readline()

        processes = [tuple(int(p) for p in l.strip().split()[:2])
                     for l in f.readlines()]
        return [p for p, pp in processes if pp == self.pid]

    def test_killed_worker_recover(self):
        start_workers = self._spawn()

        # kill one worker and check if new worker can come up
        LOG.info('pid of first child is %s' % start_workers[0])
        os.kill(start_workers[0], signal.SIGTERM)

        # Wait at most 5 seconds to respawn a worker
        cond = lambda: start_workers != self._get_workers()
        timeout = 5
        self._wait(cond, timeout)

        # Make sure worker pids don't match
        end_workers = self._get_workers()
        LOG.info('workers: %r' % end_workers)
        self.assertNotEqual(start_workers, end_workers)

    def _terminate_with_signal(self, sig):
        self._spawn()

        os.kill(self.pid, sig)

        # Wait at most 5 seconds to kill all workers
        cond = lambda: not self._get_workers()
        timeout = 5
        self._wait(cond, timeout)

        workers = self._get_workers()
        LOG.info('workers: %r' % workers)
        self.assertFalse(workers, 'No OS processes left.')

    def test_terminate_sigkill(self):
        self._terminate_with_signal(signal.SIGKILL)
        status = self._reap_test()
        self.assertTrue(os.WIFSIGNALED(status))
        self.assertEqual(os.WTERMSIG(status), signal.SIGKILL)

    def test_terminate_sigterm(self):
        self._terminate_with_signal(signal.SIGTERM)
        status = self._reap_test()
        self.assertTrue(os.WIFEXITED(status))
        self.assertEqual(os.WEXITSTATUS(status), 0)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from wsgiref import util
from sqlalchemy import Column, String, Integer, create_engine
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base
from watson.framework import applications, events
from watson.db.models import _DeclarativeMeta
from watson.db.repositories import Base

def start_response(status_line, headers):
    pass

def sample_environ(**kwargs):
    environ = {}
    util.setup_testing_defaults(environ)
    environ.update(kwargs)
    return environ

# Initialize a sample application
app = applications.Http({
    'db': {
        'connections': {
            'default': {
                'connection_string': 'sqlite:///:memory:'
            }
        },
        'fixtures': {
            'path': 'tests/watson/db/fixtures/',
            'data': (
                ('dummy', None),
            )
        }
    },
    'dependencies': {
        'definitions': {}
    },
    'events': {
        events.INIT: [
            ('watson.db.listeners.Init', 1, True)
        ],
    }
})

Model = declarative_base(name='Model', metaclass=_DeclarativeMeta)

class Test(Model):
    id = Column(Integer, primary_key=True)
    value = Column(String(255), nullable=False)

    def __repr__(self):
        return '<Test id:{} value:{}>'.format(self.id, self.value)

def create_session_add_dummy_data():
    engine = create_engine('sqlite:///:memory:')
    session = Session(engine)
    Model.metadata.drop_all(engine)
    Model.metadata.create_all(engine)
    session.add(Test(value=1))
    session.add(Test(value=2))
    session.add(Test(value=3))
    session.add(Test(value=4))
    session.add(Test(value=5))
    session.commit()
    return session

session = create_session_add_dummy_data()

class TestRepository(Base):
    __model__ = Test
<commit_msg>unit test fix for Travis CI<commit_after># -*- coding: utf-8 -*-
from wsgiref import util
from sqlalchemy import Column, String, Integer, create_engine
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base
from watson.framework import applications, events
from watson.db.models import _DeclarativeMeta
from watson.db.repositories import Base

def start_response(status_line, headers):
    pass

def sample_environ(**kwargs):
    environ = {}
    util.setup_testing_defaults(environ)
    environ.update(kwargs)
    return environ

# Initialize a sample application
app = applications.Http({
    'db': {
        'connections': {
            'default': {
                'connection_string': 'sqlite:///:memory:'
            }
        },
        'fixtures': {
            'path': 'tests/watson/db/fixtures/',
            'data': (
                ('dummy', None),
            )
        }
    },
    'dependencies': {
        'definitions': {}
    },
    'events': {
        events.INIT: [
            ('watson.db.listeners.Init', 1, True)
        ],
    },
    'routes': {
        '/': {
            'path': '/'
        }
    }
})

Model = declarative_base(name='Model', metaclass=_DeclarativeMeta)

class Test(Model):
    id = Column(Integer, primary_key=True)
    value = Column(String(255), nullable=False)

    def __repr__(self):
        return '<Test id:{} value:{}>'.format(self.id, self.value)

def create_session_add_dummy_data():
    engine = create_engine('sqlite:///:memory:')
    session = Session(engine)
    Model.metadata.drop_all(engine)
    Model.metadata.create_all(engine)
    session.add(Test(value=1))
    session.add(Test(value=2))
    session.add(Test(value=3))
    session.add(Test(value=4))
    session.add(Test(value=5))
    session.commit()
    return session

session = create_session_add_dummy_data()

class TestRepository(Base):
    __model__ = Test
<|endoftext|>


<commit_before># No shebang line, this module is meant to be imported
#
# This file is part of PyFarm.
# Copyright (C) 2008-2012 Oliver Palmer
#
# PyFarm is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyFarm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PyFarm.  If not, see <http://www.gnu.org/licenses/>.

from base.functions import *<commit_msg>corrected import path<commit_after># No shebang line, this module is meant to be imported
#
# This file is part of PyFarm.
# Copyright (C) 2008-2012 Oliver Palmer
#
# PyFarm is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyFarm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PyFarm.  If not, see <http://www.gnu.org/licenses/>.

from pyfarm.jobtypes.base import load
<|endoftext|>


<commit_before>import h5py
import numpy as np
import re
import sys
import scipy
import timeit

start = timeit.default_timer()

def test_atom():
    coordinate_start = 8
    initial_velocity_start = 137
    coordinates = []
    initial_velocity = []
    n = 0
    n2 = 0
    with open("POSCAR", 'r') as f:
        lines = f.readlines()
        atom_names = lines[5].split()
        atom_amount = lines[6].split()
        total_amount = 0
        for i in atom_amount:
            total_amount += int(i)
        while n < total_amount:
            current = []
            current.append(float(lines[coordinate_start+n].split()[0]))
            current.append(float(lines[coordinate_start+n].split()[1]))
            current.append(float(lines[coordinate_start+n].split()[2]))
            coordinates.append(current)
            n += 1
        while n2 < total_amount:
            print(n2)
            current = []
            current.append(float(lines[initial_velocity_start+n2].split()[0]))
            current.append(float(lines[initial_velocity_start+n2].split()[1]))
            current.append(float(lines[initial_velocity_start+n2].split()[2]))
            initial_velocity.append(current)
            n2 += 1
        return  [atom_names, atom_amount, total_amount, coordinates, initial_velocity]
stop = timeit.default_timer()
print(test_atom())
print('Time: ', float(stop - start), " seconds")
<commit_msg>Parsing<commit_after>import h5py
import numpy as np
import re
import sys
import scipy
import timeit

start = timeit.default_timer()

def test_atom():
    coordinate_start = 8
    initial_velocity_start = 137
    n = 0
    n2 = 0
    with open("POSCAR", 'r') as f:
        lines = f.readlines()
        atom_names = lines[5].split()
        atom_amount = lines[6].split()
        total_amount = 0
        for i in atom_amount:
            total_amount += int(i)
        coordinates = get_data(total_amount,  lines, coordinate_start)
        initial_velocity = get_data(total_amount,  lines, initial_velocity_start)
    return  [atom_names, atom_amount, total_amount, coordinates, initial_velocity]
def get_data(amount, data, start):
    n = 0
    list = []
    while n < amount:
        current = []
        line = data[start+n].split()
        current.append(np.float32(line[0]))
        current.append(np.float32(line[1]))
        current.append(np.float32(line[2]))
        list.append(current)
        n += 1
    return list
stop = timeit.default_timer()
print(test_atom())
print('Time: ', float(stop - start), " seconds")
<|endoftext|>


<commit_before>from tensorflow.python.util import compat
import _layers

_OP_REGISTERY = {
    'NoOp': _layers.skip,
    'ExpandDims' : _layers.skip,
    'Cast' : _layers.skip,
    'Squeeze' : _layers.skip,
    'StopGradient' : _layers.skip,
    'CheckNumerics' : _layers.skip,
    'Floor' : _layers.skip, # TODO - need to handle it better
    'Assert' : _layers.skip,
    'Equal' : _layers.skip,
    'All' : _layers.skip,
    'Pack' : _layers.skip, # TODO - need to handle it better
    'SpaceToBatchND':_layers.skip,
    'BatchToSpaceND':_layers.skip,
    'ConcatV2' : _layers.concat,
    'GreaterEqual' : _layers.greater, # TODO - need to handle it better
    'LogicalAnd' : _layers.mul, # TODO - need to handle it better
    'BiasAdd' : _layers.add,
    'Slice' : _layers.slice,
    'StridedSlice' : _layers.strided_slice,
    'Fill': _layers.fill,
    'ExtractImagePatches': _layers.extract_image_patches,
    'ArgMax': _layers.argmax,
    # TODO - CoreML not supporting random numbers
    'RandomUniform': _layers.random,
    'Shape': _layers.shape,
    'Maximum': _layers.maximum,
    'RealDiv': _layers.real_div,
    'Transpose': _layers.transpose, # TODO - only works 4D tensors
    'Sigmoid': _layers.sigmoid,
    'ResizeNearestNeighbor': _layers.resize_nearest_neighbor,
    'Square': _layers.square,
    'SquaredDifference': _layers.squared_difference,
    'Pad' : _layers.pad,
    'MirrorPad': _layers.mirror_pad,
    'Mean': _layers.mean, # TODO - there're unsupported configurations
    'Prod': _layers.product, # TODO - there're unsupported configurations
    'Sum': _layers.reduce_sum, # TODO - there're unsupported configurations
    'Max': _layers.reduce_max, # TODO - there're unsupported configurations
    'Min': _layers.reduce_min, # TODO - there're unsupported configurations
    'Greater': _layers.greater, # TODO - only works for x > c where c is const
    'Const': _layers.constant,
    'Softmax': _layers.softmax,
    'Relu6': _layers.relu6,
    'Relu': _layers.relu,
    'Rsqrt': _layers.rsqrt,
    'Add': _layers.add,
    'Sub': _layers.sub,
    'Mul': _layers.mul,
    'Neg': _layers.neg,
    'MatMul': _layers.inner_product,
    'DepthwiseConv2dNative': _layers.depthwise_conv2d,
    'MaxPool': _layers.maxpool,
    'AvgPool': _layers.avgpool,
    'Conv2DBackpropInput': _layers.deconv2d,
    'Conv2D': _layers.conv2d,
    'Reshape': _layers.reshape,
    'Concat': _layers.concat,
    'BatchNormWithGlobalNormalization': _layers.batchnorm,
    'Identity': _layers.identity,
    'OneHot': _layers.one_hot,
    'Placeholder': _layers.placeholder,
    'Elu': _layers.elu
}

def _get_translator_function(op_type):
  """Get the right translator function
  """
  if op_type in _OP_REGISTRY:
    return _OP_REGISTRY[op_type]
  else:
    raise TypeError("Translation function missing for op of type %s." % type(op_type))

def connect_skipped_ops(context):
  nn_spec = context.builder.nn_spec
  for layer in nn_spec.layers:
    for i, inp_name in enumerate(layer.input):
      if inp_name in context.skip_map_names:
        layer.input[i] = context.skip_map_names[inp_name]

def check(op, context):
  for inp in op.inputs:
    inp_name = compat.as_bytes(inp.name)
    assert inp_name in context.translated, (
        'No translation found for {}'.format(inp_name))
  for out in op.outputs:
    assert out.name in context.shape_dict, (
        'Shape for {} is not fully defined'.format(out.name))

def translation_required(op, context):
  for out in op.outputs:
    out_name = compat.as_bytes(out.name)
    if out_name in context.translated:
      continue
    else:
      return True
  return False

def stop_translation(context):
  """ Check whether all outputs all translated. If yes return True,
  Otherwise return False
  """
  for out in context.output_names:
    if out not in context.translated:
      return False
  return True

def convert_ops_to_layers(context):
  for i, op in enumerate(context.all_ops):
    if stop_translation(context):
      connect_skipped_ops(context)
      return
    else:
      check(op, context)
      if op.type not in _OP_REGISTRY:
        raise TypeError("Translation function missing for op of type %s." % op.type)
      translator = _get_translator_function(op.type)
      if translation_required(op, context):
        print('%d/%d: Converting op name: %s ( type:  %s )' % (
            i+1, len(context.all_ops), op.name, op.type))
        translator(op, context)
      connect_skipped_ops(context)
<commit_msg>spell fix<commit_after>from tensorflow.python.util import compat
import _layers

_OP_REGISTRY = {
    'NoOp': _layers.skip,
    'ExpandDims' : _layers.skip,
    'Cast' : _layers.skip,
    'Squeeze' : _layers.skip,
    'StopGradient' : _layers.skip,
    'CheckNumerics' : _layers.skip,
    'Floor' : _layers.skip, # TODO - need to handle it better
    'Assert' : _layers.skip,
    'Equal' : _layers.skip,
    'All' : _layers.skip,
    'Pack' : _layers.skip, # TODO - need to handle it better
    'SpaceToBatchND':_layers.skip,
    'BatchToSpaceND':_layers.skip,
    'ConcatV2' : _layers.concat,
    'GreaterEqual' : _layers.greater, # TODO - need to handle it better
    'LogicalAnd' : _layers.mul, # TODO - need to handle it better
    'BiasAdd' : _layers.add,
    'Slice' : _layers.slice,
    'StridedSlice' : _layers.strided_slice,
    'Fill': _layers.fill,
    'ExtractImagePatches': _layers.extract_image_patches,
    'ArgMax': _layers.argmax,
    # TODO - CoreML not supporting random numbers
    'RandomUniform': _layers.random,
    'Shape': _layers.shape,
    'Maximum': _layers.maximum,
    'RealDiv': _layers.real_div,
    'Transpose': _layers.transpose, # TODO - only works 4D tensors
    'Sigmoid': _layers.sigmoid,
    'ResizeNearestNeighbor': _layers.resize_nearest_neighbor,
    'Square': _layers.square,
    'SquaredDifference': _layers.squared_difference,
    'Pad' : _layers.pad,
    'MirrorPad': _layers.mirror_pad,
    'Mean': _layers.mean, # TODO - there're unsupported configurations
    'Prod': _layers.product, # TODO - there're unsupported configurations
    'Sum': _layers.reduce_sum, # TODO - there're unsupported configurations
    'Max': _layers.reduce_max, # TODO - there're unsupported configurations
    'Min': _layers.reduce_min, # TODO - there're unsupported configurations
    'Greater': _layers.greater, # TODO - only works for x > c where c is const
    'Const': _layers.constant,
    'Softmax': _layers.softmax,
    'Relu6': _layers.relu6,
    'Relu': _layers.relu,
    'Rsqrt': _layers.rsqrt,
    'Add': _layers.add,
    'Sub': _layers.sub,
    'Mul': _layers.mul,
    'Neg': _layers.neg,
    'MatMul': _layers.inner_product,
    'DepthwiseConv2dNative': _layers.depthwise_conv2d,
    'MaxPool': _layers.maxpool,
    'AvgPool': _layers.avgpool,
    'Conv2DBackpropInput': _layers.deconv2d,
    'Conv2D': _layers.conv2d,
    'Reshape': _layers.reshape,
    'Concat': _layers.concat,
    'BatchNormWithGlobalNormalization': _layers.batchnorm,
    'Identity': _layers.identity,
    'OneHot': _layers.one_hot,
    'Placeholder': _layers.placeholder,
    'Elu': _layers.elu
}

def _get_translator_function(op_type):
  """Get the right translator function
  """
  if op_type in _OP_REGISTRY:
    return _OP_REGISTRY[op_type]
  else:
    raise TypeError("Translation function missing for op of type %s." % type(op_type))

def connect_skipped_ops(context):
  nn_spec = context.builder.nn_spec
  for layer in nn_spec.layers:
    for i, inp_name in enumerate(layer.input):
      if inp_name in context.skip_map_names:
        layer.input[i] = context.skip_map_names[inp_name]

def check(op, context):
  for inp in op.inputs:
    inp_name = compat.as_bytes(inp.name)
    assert inp_name in context.translated, (
        'No translation found for {}'.format(inp_name))
  for out in op.outputs:
    assert out.name in context.shape_dict, (
        'Shape for {} is not fully defined'.format(out.name))

def translation_required(op, context):
  for out in op.outputs:
    out_name = compat.as_bytes(out.name)
    if out_name in context.translated:
      continue
    else:
      return True
  return False

def stop_translation(context):
  """ Check whether all outputs all translated. If yes return True,
  Otherwise return False
  """
  for out in context.output_names:
    if out not in context.translated:
      return False
  return True

def convert_ops_to_layers(context):
  for i, op in enumerate(context.all_ops):
    if stop_translation(context):
      connect_skipped_ops(context)
      return
    else:
      check(op, context)
      if op.type not in _OP_REGISTRY:
        raise TypeError("Translation function missing for op of type %s." % op.type)
      translator = _get_translator_function(op.type)
      if translation_required(op, context):
        print('%d/%d: Converting op name: %s ( type:  %s )' % (
            i+1, len(context.all_ops), op.name, op.type))
        translator(op, context)
      connect_skipped_ops(context)
<|endoftext|>