Esempio n. 1
0
class BaseTestCase(unittest.TestCase):
    """
    Base class for test cases.
    All test cases can feel free to implement this.
    """
    def setUp(self):
        self.gopath_bak = os.environ.get('GOPATH', '')
        gopath = os.path.normpath(
            os.path.join(os.path.dirname(__file__), "../fixtures/chaincode"))
        os.environ['GOPATH'] = os.path.abspath(gopath)
        self.channel_tx = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel.tx']
        self.compose_file_path = \
            E2E_CONFIG['test-network']['docker']['compose_file_tls']

        self.client = Client('test/fixtures/network.json')
        self.channel_name = "businesschannel"  # default application channel
        self.user = self.client.get_user('org1.example.com', 'Admin')
        self.assertIsNotNone(self.user, 'org1 admin should not be None')
        self.start_test_env()

    def tearDown(self):
        self.shutdown_test_env()

    def check_logs(self):
        cli_call([
            "docker-compose", "-f", self.compose_file_path, "logs",
            "--tail=200"
        ])

    def start_test_env(self):
        cli_call(["docker-compose", "-f", self.compose_file_path, "up", "-d"])

    def shutdown_test_env(self):
        cli_call(["docker-compose", "-f", self.compose_file_path, "down"])
Esempio n. 2
0
class ClientBase:
    """Base class for a Hyperledger Fabric client."""
    def __init__(self, profile, channel_name, org_name, peer_name, user_name):
        self.client = Client(profile)
        self._channel_name = channel_name
        self._org_name = org_name
        self._peer_name = peer_name
        self._user_name = user_name

        self._user = self.client.get_user(self._org_name, self._user_name)
        endpoint = self.client.get_net_info('peers', self._peer_name, 'url')
        tlscert = self.client.get_net_info('peers', self._peer_name,
                                           'tlsCACerts', 'path')
        loop = asyncio.get_event_loop()

        peer = create_peer(endpoint=endpoint, tls_cacerts=tlscert)

        loop.run_until_complete(
            self.client.init_with_discovery(self._user, peer,
                                            self._channel_name))

        self._channel = self.client.new_channel(self._channel_name)

    @property
    def channel_name(self):
        return self._channel_name

    @property
    def channel(self):
        return self._channel

    @property
    def org_name(self):
        return self._org_name

    @property
    def peer_name(self):
        return self._peer_name

    @property
    def user_name(self):
        return self._user_name

    @property
    def user(self):
        return self._user
class E2ePrivateDataTest(BaseTestCase):
    def setUp(self):
        self.gopath_bak = os.environ.get('GOPATH', '')
        gopath = os.path.normpath(
            os.path.join(os.path.dirname(__file__), "../fixtures/chaincode"))
        os.environ['GOPATH'] = os.path.abspath(gopath)
        self.channel_tx = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel.tx']
        self.compose_file_path = \
            E2E_CONFIG['test-network']['docker']['compose_file_tls']

        self.config_yaml = \
            E2E_CONFIG['test-network']['channel-artifacts']['config_yaml']
        self.channel_profile = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel_profile']
        self.client = Client('test/fixtures/network.json')
        self.channel_name = "businesschannel"  # default application channel
        self.user = self.client.get_user('org1.example.com', 'Admin')
        self.assertIsNotNone(self.user, 'org1 admin should not be None')

        # Boot up the testing network
        self.shutdown_test_env()
        self.start_test_env()
        time.sleep(1)

    def tearDown(self):
        super(E2ePrivateDataTest, self).tearDown()

    async def channel_create(self):
        """
        Create an channel for further testing.

        :return:
        """
        logger.info(f"E2E: Channel creation start: name={self.channel_name}")

        # By default, self.user is the admin of org1
        response = await self.client.channel_create(
            'orderer.example.com',
            self.channel_name,
            self.user,
            config_yaml=self.config_yaml,
            channel_profile=self.channel_profile)
        self.assertTrue(response)

        logger.info(f"E2E: Channel creation done: name={self.channel_name}")

    async def channel_join(self):
        """
        Join peers of two orgs into an existing channels

        :return:
        """

        logger.info(f"E2E: Channel join start: name={self.channel_name}")

        # channel must already exist when to join
        channel = self.client.get_channel(self.channel_name)
        self.assertIsNotNone(channel)

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, 'Admin')
            response = await self.client.channel_join(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                orderer='orderer.example.com')
            self.assertTrue(response)
            # Verify the ledger exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer0_container = dc.containers.get(peer + '.' + org)
                code, output = peer0_container.exec_run(
                    'test -f '
                    '/var/hyperledger/production/ledgersData/chains/'
                    f'chains/{self.channel_name}'
                    '/blockfile_000000')
                self.assertEqual(code, 0, "Local ledger not exists")

        logger.info(f"E2E: Channel join done: name={self.channel_name}")

    async def channel_update_anchors(self):

        orgs = ["org1.example.com", "org2.example.com"]

        anchors = [
            'test/fixtures/e2e_cli/channel-artifacts/' + msporg + 'anchors.tx'
            for msporg in ['Org1MSP', 'Org2MSP']
        ]

        for org, anchortx in zip(orgs, anchors):
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.channel_update("orderer.example.com",
                                                        self.channel_name,
                                                        org_admin,
                                                        config_tx=anchortx)

            self.assertTrue(response)

    async def chaincode_install(self):
        """
        Test installing an example chaincode to peer
        """
        logger.info("E2E: Chaincode install start")
        cc = f'/var/hyperledger/production/chaincodes/{CC_NAME}.{CC_VERSION}'

        # uncomment for testing with packaged_cc

        # create packaged chaincode before for having same id
        # code_package = package_chaincode(CC_PATH, CC_TYPE_GOLANG)

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:

            # simulate possible different chaincode archive based on timestamp
            time.sleep(2)

            org_admin = self.client.get_user(org, "Admin")
            responses = await self.client.chaincode_install(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
                cc_path=CC_PATH,
                cc_name=CC_NAME,
                cc_version=CC_VERSION,
                # packaged_cc=code_package
            )
            self.assertTrue(responses)
            # Verify the cc pack exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer_container = dc.containers.get(peer + '.' + org)
                code, output = peer_container.exec_run(f'test -f {cc}')
                self.assertEqual(code, 0, "chaincodes pack not exists")

        logger.info("E2E: chaincode install done")

    async def chaincode_instantiate(self):
        """
        Test instantiating an example chaincode to peer
        """
        logger.info("E2E: Chaincode instantiation start")

        org = "org1.example.com"

        policy = s2d().parse("OR('Org1MSP.member', 'Org2MSP.member')")

        collections_config = [{
            "name":
            "collectionMarbles",
            "policy":
            s2d().parse("OR('Org1MSP.member','Org2MSP.member')"),
            "requiredPeerCount":
            0,
            "maxPeerCount":
            1,
            "blockToLive":
            1000000,
            "memberOnlyRead":
            True
        }, {
            "name": "collectionMarblePrivateDetails",
            "policy": s2d().parse("OR('Org1MSP.member')"),
            "requiredPeerCount": 0,
            "maxPeerCount": 1,
            "blockToLive": 5,
            "memberOnlyRead": True
        }]

        org_admin = self.client.get_user(org, "Admin")
        response = await self.client.chaincode_instantiate(
            requestor=org_admin,
            channel_name=self.channel_name,
            peers=['peer0.' + org],
            args=None,
            cc_name=CC_NAME,
            cc_version=CC_VERSION,
            cc_endorsement_policy=policy,
            collections_config=collections_config,
            wait_for_event=True)
        logger.info(
            "E2E: Chaincode instantiation response {}".format(response))
        policy = {
            'version':
            0,
            'rule': {
                'n_out_of': {
                    'n': 1,
                    'rules': [{
                        'signed_by': 0
                    }, {
                        'signed_by': 1
                    }]
                }
            },
            'identities': [
                {
                    'principal_classification': 'ROLE',
                    'principal': {
                        'msp_identifier': 'Org1MSP',
                        'role': 'MEMBER'
                    }
                },
                {
                    'principal_classification': 'ROLE',
                    'principal': {
                        'msp_identifier': 'Org2MSP',
                        'role': 'MEMBER'
                    }
                },
            ]
        }

        self.assertEqual(response['name'], CC_NAME)
        self.assertEqual(response['version'], CC_VERSION)
        self.assertEqual(response['policy'], policy)
        logger.info("E2E: chaincode instantiation done")

    async def chaincode_invoke(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode invoke start")

        orgs = ["org1.example.com"]
        marble = json.dumps({
            "name": "marble1",
            "color": "blue",
            "size": 35,
            "owner": "tom",
            "price": 99
        }).encode()

        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.chaincode_invoke(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                fcn='initMarble',
                args=None,
                cc_name=CC_NAME,
                wait_for_event=True,
                wait_for_event_timeout=120,
                transient_map={"marble": marble})
            self.assertFalse(response)

        # Wait for gossip private data
        time.sleep(5)

        logger.info("E2E: chaincode invoke done")

    async def chaincode_query(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode query start")

        orgs = ["org1.example.com"]

        args = ["marble1"]

        res = {
            "color": "blue",
            "docType": "marble",
            "name": "marble1",
            "owner": "tom",
            "size": 35
        }

        resp = {
            "docType": "marblePrivateDetails",
            "name": "marble1",
            "price": 99
        }

        for org in ["org1.example.com", "org2.example.com"]:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.chaincode_query(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                fcn="readMarble",
                args=args,
                cc_name=CC_NAME)
            self.assertEqual(json.loads(response), res)

        orgs = ["org1.example.com"]
        args = ["marble1"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.chaincode_query(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                fcn="readMarblePrivateDetails",
                args=args,
                cc_name=CC_NAME)
            self.assertEqual(json.loads(response), resp)

        orgs = ["org2.example.com"]
        args = ["marble1"]
        error = "does not have read access permission"
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            with self.assertRaises(Exception) as context:
                response = await self.client.chaincode_query(
                    requestor=org_admin,
                    channel_name=self.channel_name,
                    peers=['peer0.' + org],
                    fcn="readMarblePrivateDetails",
                    args=args,
                    cc_name=CC_NAME)
                self.assertTrue(error in str(context.exception))

        logger.info("E2E: chaincode query done")

    async def query_installed_chaincodes(self):
        """
        Test query installed chaincodes on peer

        :return:
        """
        logger.info("E2E: Query installed chaincode start")

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            responses = await self.client.query_installed_chaincodes(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(responses[0].chaincodes[0].name, CC_NAME,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].version, CC_VERSION,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].path, CC_PATH,
                             "Query failed")

        logger.info("E2E: Query installed chaincode done")

    async def query_instantiated_chaincodes(self):
        """
        Test query instantiated chaincodes on peer

        :return:
        """
        logger.info("E2E: Query instantiated chaincode start")

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            responses = await self.client.query_instantiated_chaincodes(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertTrue(len(responses) >= 1)
            self.assertEqual(responses[0].chaincodes[0].name, CC_NAME,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].version, CC_VERSION,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].path, CC_PATH,
                             "Query failed")

        logger.info("E2E: Query installed chaincode done")

    async def get_channel_config(self):
        """
        Test get channel config on peer

        :return:
        """
        logger.info(f"E2E: Get channel {self.channel_name} config start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            responses = await self.client.get_channel_config(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org])
            self.assertEqual(responses[0].config.sequence, 1,
                             "Get Config Failed")

        logger.info("E2E: Query installed chaincode done")

    async def get_channel_config_with_orderer(self,
                                              chname=SYSTEM_CHANNEL_NAME):
        """
        Test get channel config on orderer
         :return:
        """
        logger.info(f"E2E: Get channel {chname} config start")

        orgs = ["orderer.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.get_channel_config_with_orderer(
                orderer='orderer.example.com',
                requestor=org_admin,
                channel_name=chname,
            )
            self.assertEqual(response['config']['sequence'], '0',
                             "Get Config Failed")

        logger.info(f"E2E: Get channel {chname} config done")

    def test_in_sequence(self):

        loop = asyncio.get_event_loop()

        logger.info("\n\nE2E testing started...")

        self.client.new_channel(SYSTEM_CHANNEL_NAME)

        loop.run_until_complete(self.get_channel_config_with_orderer())

        loop.run_until_complete(self.channel_create())

        loop.run_until_complete(self.channel_join())

        loop.run_until_complete(self.channel_update_anchors())

        loop.run_until_complete(self.get_channel_config())

        loop.run_until_complete(self.chaincode_install())

        loop.run_until_complete(self.query_installed_chaincodes())

        loop.run_until_complete(self.chaincode_instantiate())

        loop.run_until_complete(self.query_instantiated_chaincodes())

        loop.run_until_complete(self.chaincode_invoke())

        loop.run_until_complete(self.chaincode_query())

        logger.info("E2E private data all test cases done\n\n")
class E2eTest(BaseTestCase):
    def setUp(self):
        self.gopath_bak = os.environ.get('GOPATH', '')
        gopath = os.path.normpath(
            os.path.join(os.path.dirname(__file__), "../fixtures/chaincode"))
        os.environ['GOPATH'] = os.path.abspath(gopath)
        self.channel_tx = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel.tx']
        self.compose_file_path = \
            E2E_CONFIG['test-network']['docker']['compose_file_mutual_tls']

        self.config_yaml = \
            E2E_CONFIG['test-network']['channel-artifacts']['config_yaml']
        self.channel_profile = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel_profile']
        self.client = Client('test/fixtures/network-mutual-tls.json')
        self.channel_name = "businesschannel"  # default application channel
        self.user = self.client.get_user('org1.example.com', 'Admin')
        self.assertIsNotNone(self.user, 'org1 admin should not be None')

        # Boot up the testing network
        self.shutdown_test_env()
        self.start_test_env()
        time.sleep(1)

    def tearDown(self):
        super(E2eTest, self).tearDown()

    def channel_create(self):
        """
        Create an channel for further testing.

        :return:
        """
        logger.info("E2E: Channel creation start: name={}".format(
            self.channel_name))

        # By default, self.user is the admin of org1
        response = self.client.channel_create(
            'orderer.example.com',
            self.channel_name,
            self.user,
            config_yaml=self.config_yaml,
            channel_profile=self.channel_profile)

        self.assertTrue(response)

        logger.info("E2E: Channel creation done: name={}".format(
            self.channel_name))

    def channel_join(self):
        """
        Join peers of two orgs into an existing channels

        :return:
        """

        logger.info("E2E: Channel join start: name={}".format(
            self.channel_name))

        # channel must already exist when to join
        channel = self.client.get_channel(self.channel_name)
        self.assertIsNotNone(channel)

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, 'Admin')
            response = self.client.channel_join(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                orderer='orderer.example.com')
            self.assertTrue(response)
            # Verify the ledger exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer0_container = dc.containers.get(peer + '.' + org)
                code, output = peer0_container.exec_run(
                    'test -f '
                    '/var/hyperledger/production/ledgersData/chains/chains/{}'
                    '/blockfile_000000'.format(self.channel_name))
                self.assertEqual(code, 0, "Local ledger not exists")

        logger.info("E2E: Channel join done: name={}".format(
            self.channel_name))

    def chaincode_install(self):
        """
        Test installing an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode install start")

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.chaincode_install(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
                cc_path=CC_PATH,
                cc_name=CC_NAME,
                cc_version=CC_VERSION)
            self.assertTrue(response)
            # Verify the cc pack exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer0_container = dc.containers.get(peer + '.' + org)
                code, output = peer0_container.exec_run(
                    'test -f '
                    '/var/hyperledger/production/chaincodes/example_cc.1.0')
                self.assertEqual(code, 0, "chaincodes pack not exists")

        logger.info("E2E: chaincode install done")

    def chaincode_install_fail(self):

        pass

    def chaincode_instantiate(self):
        """
        Test instantiating an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode instantiation start")

        orgs = ["org1.example.com"]
        args = ['a', '200', 'b', '300']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.chaincode_instantiate(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                args=args,
                cc_name=CC_NAME,
                cc_version=CC_VERSION)
            logger.info(
                "E2E: Chaincode instantiation response {}".format(response))
            self.assertTrue(response)
        logger.info("E2E: chaincode instantiation done")

    def chaincode_invoke(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode invoke start")

        orgs = ["org1.example.com"]
        args = ['a', 'b', '100']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.chaincode_invoke(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer1.' + org],
                args=args,
                cc_name=CC_NAME,
                cc_version=CC_VERSION,
                wait_for_event=True)
            self.assertEqual(response, '')

        logger.info("E2E: chaincode invoke done")

    def chaincode_query(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode query start")

        orgs = ["org1.example.com"]
        args = ['b']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.chaincode_query(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                args=args,
                cc_name=CC_NAME,
                cc_version=CC_VERSION)
            self.assertEqual(response, '400')  # 300 + 100

        logger.info("E2E: chaincode query done")

    def query_installed_chaincodes(self):
        """
        Test query installed chaincodes on peer

        :return:
        """
        logger.info("E2E: Query installed chaincode start")

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.query_installed_chaincodes(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(response.chaincodes[0].name, CC_NAME,
                             "Query failed")
            self.assertEqual(response.chaincodes[0].version, CC_VERSION,
                             "Query failed")
            self.assertEqual(response.chaincodes[0].path, CC_PATH,
                             "Query failed")

        logger.info("E2E: Query installed chaincode done")

    def query_channels(self):
        """
        Test querying channel

        :return:
        """
        logger.info("E2E: Query channel start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.query_channels(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(response.channels[0].channel_id,
                             'businesschannel', "Query failed")

        logger.info("E2E: Query channel done")

    def query_info(self):
        """
        Test querying information on the state of the Channel

        :return:
        """
        logger.info("E2E: Query info start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(response.height, 3, "Query failed")

        logger.info("E2E: Query info done")

    def query_block_by_txid(self):
        """
        Test querying block by tx id

        :return:
        """
        logger.info("E2E: Query block by tx id start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            response = self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            response = self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=response.currentBlockHash)

            tx_id = response.get('data').get('data')[0].get('payload').get(
                'header').get('channel_header').get('tx_id')

            response = self.client.query_block_by_txid(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                tx_id=tx_id)

            self.assertEqual(
                response.get('data').get('data')[0].get('payload').get(
                    'header').get('channel_header').get('tx_id'), tx_id,
                "Query failed")

        logger.info("E2E: Query block by tx id done")

    def query_block_by_hash(self):
        """
        Test querying block by block hash

        :return:
        """
        logger.info("E2E: Query block by block hash start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            response = self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            previous_block_hash = response.previousBlockHash
            current_block_hash = response.currentBlockHash
            response = self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=current_block_hash)

            self.assertEqual(
                response['header']['previous_hash'].decode('utf-8'),
                previous_block_hash.hex(), "Query failed")

        logger.info("E2E: Query block by block hash done")

    def query_block(self):
        """
        Test querying block by block number

        :return:
        """
        logger.info("E2E: Query block by block number start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.query_block(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_number='0')
            self.assertEqual(response['header']['number'], 0, "Query failed")
            self.blockheader = response['header']

        logger.info("E2E: Query block by block number done")

    def query_transaction(self):
        """
        Test querying transaction by tx id

        :return:
        """
        logger.info("E2E: Query transaction by tx id start")
        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            response = self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            response = self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=response.currentBlockHash)

            tx_id = response.get('data').get('data')[0].get('payload').get(
                'header').get('channel_header').get('tx_id')

            response = self.client.query_transaction(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                tx_id=tx_id)

            self.assertEqual(
                response.get('transaction_envelope').get('payload').get(
                    'header').get('channel_header').get('channel_id'),
                self.channel_name, "Query failed")

        logger.info("E2E: Query transaction by tx id done")

    def query_instantiated_chaincodes(self):
        """
        Test query instantiated chaincodes on peer

        :return:
        """
        logger.info("E2E: Query installed chaincode start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.query_instantiated_chaincodes(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org])
            self.assertEqual(response.chaincodes[0].name, CC_NAME,
                             "Query failed")
            self.assertEqual(response.chaincodes[0].version, CC_VERSION,
                             "Query failed")
            self.assertEqual(response.chaincodes[0].path, CC_PATH,
                             "Query failed")

        logger.info("E2E: Query installed chaincode done")

    def get_channel_config(self):
        """
        Test get channel config on peer

        :return:
        """
        logger.info("E2E: Get channel config start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = self.client.get_channel_config(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org])
            self.assertEqual(response.config.sequence, 1, "Get Config Failed")

        logger.info("E2E: Query installed chaincode done")

    def get_events(self):

        org = 'org1.example.com'
        peer = self.client.get_peer('peer0.' + org)

        org_admin = self.client.get_user(org, 'Admin')
        events = self.client.get_events(org_admin,
                                        peer,
                                        self.channel_name,
                                        filtered=True,
                                        behavior='FAIL_IF_NOT_READY')

        self.assertEqual(len(events), 4)

        self.assertEqual(events[0]['number'], 0)
        self.assertEqual(events[0]['channel_id'], self.channel_name)

        filtered_transaction = events[0]['filtered_transactions'][0]
        self.assertEqual(filtered_transaction['tx_validation_code'], 'VALID')
        self.assertEqual(filtered_transaction['txid'], '')
        self.assertEqual(filtered_transaction['type'], 'CONFIG')

        self.assertEqual(events[2]['number'], 2)
        filtered_transaction = events[2]['filtered_transactions'][0]
        self.assertEqual(filtered_transaction['tx_validation_code'], 'VALID')
        self.assertEqual(filtered_transaction['type'], 'ENDORSER_TRANSACTION')

        # test missing block is present
        data = {'channel_id': '', 'filtered_transactions': [], 'number': 0}
        self.assertEqual(events[len(events) - 1], data)

    def test_in_sequence(self):

        logger.info("\n\nE2E testing started...")

        self.channel_create()

        self.channel_join()

        self.chaincode_install()

        self.chaincode_install_fail()

        self.chaincode_instantiate()

        self.chaincode_invoke()

        self.chaincode_query()

        self.query_instantiated_chaincodes()

        self.query_installed_chaincodes()

        self.query_channels()

        self.query_info()

        self.query_block_by_txid()

        self.query_block_by_hash()

        self.query_block()

        self.query_transaction()

        self.get_channel_config()

        self.get_events()

        logger.info("E2E all test cases done\n\n")
Esempio n. 5
0
class E2eMutualTest(BaseTestCase):
    def setUp(self):
        self.gopath_bak = os.environ.get('GOPATH', '')
        gopath = os.path.normpath(
            os.path.join(os.path.dirname(__file__), "../fixtures/chaincode"))
        os.environ['GOPATH'] = os.path.abspath(gopath)
        self.channel_tx = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel.tx']
        self.compose_file_path = \
            E2E_CONFIG['test-network']['docker']['compose_file_mutual_tls']

        self.config_yaml = \
            E2E_CONFIG['test-network']['channel-artifacts']['config_yaml']
        self.channel_profile = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel_profile']
        self.client = Client('test/fixtures/network-mutual-tls.json')

        with open('test/fixtures/network-mutual-tls.json') as f:
            self.network_info = json.load(f)

        self.channel_name = "businesschannel"  # default application channel
        self.user = self.client.get_user('org1.example.com', 'Admin')
        self.assertIsNotNone(self.user, 'org1 admin should not be None')

        # Boot up the testing network
        self.shutdown_test_env()
        self.start_test_env()
        time.sleep(1)

    def tearDown(self):
        super(E2eMutualTest, self).tearDown()

    async def channel_create(self):
        """
        Create an channel for further testing.

        :return:
        """
        logger.info("E2E: Channel creation start: name={}".format(
            self.channel_name))

        # By default, self.user is the admin of org1
        node_info = self.network_info['peers']['peer0.org1.example.com']
        set_tls = self.client.set_tls_client_cert_and_key(
            node_info['clientKey']['path'], node_info['clientCert']['path'])
        self.assertTrue(set_tls)

        response = await self.client.channel_create(
            'orderer.example.com',
            self.channel_name,
            self.user,
            config_yaml=self.config_yaml,
            channel_profile=self.channel_profile)

        self.assertTrue(response)

        logger.info(f"E2E: Channel creation done: name={self.channel_name}")

    async def channel_join(self):
        """
        Join peers of two orgs into an existing channels

        :return:
        """

        logger.info(f"E2E: Channel join start: name={self.channel_name}")

        # channel must already exist when to join
        channel = self.client.get_channel(self.channel_name)
        self.assertIsNotNone(channel)

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, 'Admin')

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.channel_join(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                orderer='orderer.example.com',
            )
            self.assertTrue(response)
            # Verify the ledger exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer0_container = dc.containers.get(peer + '.' + org)
                code, output = peer0_container.exec_run(
                    'test -f '
                    '/var/hyperledger/production/ledgersData/chains/'
                    f'chains/{self.channel_name}'
                    '/blockfile_000000')
                self.assertEqual(code, 0, "Local ledger not exists")

        logger.info(f"E2E: Channel join done: name={self.channel_name}")

    async def chaincode_install(self):
        """
        Test installing an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode install start")
        cc = f'/var/hyperledger/production/chaincodes/{CC_NAME}.{CC_VERSION}'

        # create packaged chaincode before for having same id
        code_package = package_chaincode(CC_PATH, CC_TYPE_GOLANG)

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            responses = await self.client.chaincode_install(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
                cc_path=CC_PATH,
                cc_name=CC_NAME,
                cc_version=CC_VERSION,
                packaged_cc=code_package)
            self.assertTrue(responses)
            # Verify the cc pack exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer_container = dc.containers.get(peer + '.' + org)
                code, output = peer_container.exec_run(f'test -f {cc}')
                self.assertEqual(code, 0, "chaincodes pack not exists")

        logger.info("E2E: chaincode install done")

    def chaincode_install_fail(self):
        pass

    async def chaincode_instantiate(self):
        """
        Test instantiating an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode instantiation start")

        org = "org1.example.com"
        args = ['a', '200', 'b', '300']
        policy = {
            'identities': [
                {
                    'role': {
                        'name': 'member',
                        'mspId': 'Org1MSP'
                    }
                },
                # {'role': {'name': 'admin', 'mspId': 'Org1MSP'}},
            ],
            'policy': {
                '1-of': [
                    {
                        'signed-by': 0
                    },
                    # {'signed-by': 1},
                ]
            }
        }
        org_admin = self.client.get_user(org, "Admin")

        node_info = self.network_info['peers']['peer0.' + org]
        set_tls = self.client.set_tls_client_cert_and_key(
            node_info['clientKey']['path'], node_info['clientCert']['path'])
        self.assertTrue(set_tls)

        response = await self.client.chaincode_instantiate(
            requestor=org_admin,
            channel_name=self.channel_name,
            peers=['peer0.' + org],
            args=args,
            cc_name=CC_NAME,
            cc_version=CC_VERSION,
            cc_endorsement_policy=policy,
            wait_for_event=True)
        logger.info(
            "E2E: Chaincode instantiation response {}".format(response))
        policy = {
            'version':
            0,
            'rule': {
                'n_out_of': {
                    'n': 1,
                    'rules': [
                        {
                            'signed_by': 0
                        },
                        # {'signed_by': 1}
                    ]
                }
            },
            'identities': [
                {
                    'principal_classification': 'ROLE',
                    'principal': {
                        'msp_identifier': 'Org1MSP',
                        'role': 'MEMBER'
                    }
                },
                # {
                #     'principal_classification': 'ROLE',
                #     'principal': {
                #         'msp_identifier': 'Org1MSP',
                #         'role': 'ADMIN'
                #     }
                # },
            ]
        }
        self.assertEqual(response['name'], CC_NAME)
        self.assertEqual(response['version'], CC_VERSION)
        self.assertEqual(response['policy'], policy)
        logger.info("E2E: chaincode instantiation done")

    async def chaincode_invoke(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode invoke start")

        orgs = ["org1.example.com"]
        args = ['a', 'b', '100']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.chaincode_invoke(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer1.' + org],
                args=args,
                cc_name=CC_NAME,
                wait_for_event=True,
                cc_pattern="^invoked*"  # for chaincode event
            )
            self.assertEqual(response, '400')

        logger.info("E2E: chaincode invoke done")

    async def chaincode_invoke_fail(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode invoke fail start")

        orgs = ["org2.example.com"]
        args = ['a', 'b', '100']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            with self.assertRaises(Exception) as e:
                await self.client.chaincode_invoke(
                    requestor=org_admin,
                    channel_name=self.channel_name,
                    peers=['peer1.' + org],
                    args=args,
                    cc_name=CC_NAME,
                    wait_for_event=True,
                    wait_for_event_timeout=120,
                    cc_pattern="^invoked*"  # for chaincode event
                )
            self.assertEqual(e.exception.args[0],
                             ['ENDORSEMENT_POLICY_FAILURE'])

        logger.info("E2E: chaincode invoke fail done")

    async def chaincode_channel_event_hub(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode Channel Event Hub test start")

        def onEvent(cc_event, block_number, tx_id, tx_status):
            self.ceh.unregisterChaincodeEvent(self.cr1)
            self.ceh.unregisterChaincodeEvent(self.cr2)
            self.ceh.unregisterChaincodeEvent(self.cr3)
            self.ceh.disconnect()

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            # register extra chaincode event
            channel = self.client.get_channel(self.channel_name)
            target_peer = self.client.get_peer('peer1.' + org)
            self.ceh = channel.newChannelEventHub(target_peer, org_admin)
            stream = self.ceh.connect()
            self.cr1 = self.ceh.registerChaincodeEvent(CC_NAME, 'invoked')
            self.cr2 = self.ceh.registerChaincodeEvent(CC_NAME, 'invoked')
            self.cr3 = self.ceh.registerChaincodeEvent(CC_NAME,
                                                       'invoked',
                                                       onEvent=onEvent)

            await asyncio.wait_for(asyncio.gather(stream,
                                                  return_exceptions=True),
                                   timeout=120)

        logger.info("E2E: Chaincode Channel Event Hub test done")

    async def chaincode_query(self, orgs=None):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode query start")

        if orgs is None:
            orgs = ["org1.example.com"]

        args = ['b']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.chaincode_query(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                args=args,
                cc_name=CC_NAME)
            self.assertEqual(response, '400')  # 300 + 100

        logger.info("E2E: chaincode query done")

    async def query_installed_chaincodes(self):
        """
        Test query installed chaincodes on peer

        :return:
        """
        logger.info("E2E: Query installed chaincode start")

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            responses = await self.client.query_installed_chaincodes(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(responses[0].chaincodes[0].name, CC_NAME,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].version, CC_VERSION,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].path, CC_PATH,
                             "Query failed")

        logger.info("E2E: Query installed chaincode done")

    async def query_channels(self):
        """
        Test querying channel

        :return:
        """
        logger.info("E2E: Query channel start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.query_channels(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(response.channels[0].channel_id,
                             self.channel_name, "Query failed")

        logger.info("E2E: Query channel done")

    async def query_info(self):
        """
        Test querying information on the state of the Channel

        :return:
        """
        logger.info("E2E: Query info start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(response.height, 4, "Query failed")

        logger.info("E2E: Query info done")

    async def query_block_by_txid(self):
        """
        Test querying block by tx id

        :return:
        """
        logger.info("E2E: Query block by tx id start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            response = await self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=response.currentBlockHash)

            tx_id = response.get('data').get('data')[0].get('payload').get(
                'header').get('channel_header').get('tx_id')

            response = await self.client.query_block_by_txid(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                tx_id=tx_id)

            self.assertEqual(
                response.get('data').get('data')[0].get('payload').get(
                    'header').get('channel_header').get('tx_id'), tx_id,
                "Query failed")

        logger.info("E2E: Query block by tx id done")

    async def query_block_by_hash(self):
        """
        Test querying block by block hash

        :return:
        """
        logger.info("E2E: Query block by block hash start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            previous_block_hash = response.previousBlockHash
            current_block_hash = response.currentBlockHash
            response = await self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=current_block_hash)

            self.assertEqual(
                response['header']['previous_hash'].decode('utf-8'),
                previous_block_hash.hex(), "Query failed")

        logger.info("E2E: Query block by block hash done")

    async def query_block(self):
        """
        Test querying block by block number

        :return:
        """
        logger.info("E2E: Query block by block number start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.query_block(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_number='0')
            self.assertEqual(response['header']['number'], 0, "Query failed")
            self.blockheader = response['header']

        logger.info("E2E: Query block by block number done")

    async def query_transaction(self):
        """
        Test querying transaction by tx id

        :return:
        """
        logger.info("E2E: Query transaction by tx id start")
        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            response = await self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=response.currentBlockHash)

            tx_id = response.get('data').get('data')[0].get('payload').get(
                'header').get('channel_header').get('tx_id')

            response = await self.client.query_transaction(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                tx_id=tx_id)

            self.assertEqual(
                response.get('transaction_envelope').get('payload').get(
                    'header').get('channel_header').get('channel_id'),
                self.channel_name, "Query failed")

        logger.info("E2E: Query transaction by tx id done")

    async def query_instantiated_chaincodes(self):
        """
        Test query instantiated chaincodes on peer

        :return:
        """
        logger.info("E2E: Query instantiated chaincode start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            responses = await self.client.query_instantiated_chaincodes(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org])
            self.assertTrue(len(responses) >= 1)
            self.assertEqual(responses[0].chaincodes[0].name, CC_NAME,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].version, CC_VERSION,
                             "Query failed")
            self.assertEqual(responses[0].chaincodes[0].path, CC_PATH,
                             "Query failed")

        logger.info("E2E: Query installed chaincode done")

    async def get_channel_config(self):
        """
        Test get channel config on peer

        :return:
        """
        logger.info(f"E2E: Get channel {self.channel_name} config start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['peers']['peer0.' + org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            responses = await self.client.get_channel_config(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org])
            self.assertEqual(responses[0].config.sequence, 1,
                             "Get Config Failed")

        logger.info("E2E: Query installed chaincode done")

    async def get_channel_config_with_orderer(self,
                                              chname=SYSTEM_CHANNEL_NAME):
        """
        Test get channel config on orderer
         :return:
        """
        logger.info(f"E2E: Get channel {chname} config start")

        orgs = ["orderer.example.com"]

        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            node_info = self.network_info['orderers'][org]
            set_tls = self.client.set_tls_client_cert_and_key(
                node_info['clientKey']['path'],
                node_info['clientCert']['path'])
            self.assertTrue(set_tls)

            response = await self.client.get_channel_config_with_orderer(
                orderer='orderer.example.com',
                requestor=org_admin,
                channel_name=chname,
            )
            self.assertEqual(response['config']['sequence'], '0',
                             "Get Config Failed")

        logger.info(f"E2E: Get channel {chname} config done")

    def onFilteredEvent(self, block):
        self.filtered_blocks.append(block)

    async def get_filtered_block_events(self):

        org = 'org1.example.com'
        peer = self.client.get_peer('peer0.' + org)

        node_info = self.network_info['peers']['peer0.' + org]
        set_tls = self.client.set_tls_client_cert_and_key(
            node_info['clientKey']['path'], node_info['clientCert']['path'])
        self.assertTrue(set_tls)

        org_admin = self.client.get_user(org, 'Admin')
        channel = self.client.get_channel(self.channel_name)
        channel_event_hub = channel.newChannelEventHub(peer, org_admin)
        stream = channel_event_hub.connect(filtered=True,
                                           start='oldest',
                                           stop='newest')

        self.filtered_blocks = []
        channel_event_hub.registerBlockEvent(unregister=False,
                                             onEvent=self.onFilteredEvent)

        try:
            await shield(stream)
        except Exception:
            pass

        channel_event_hub.disconnect()

        self.assertEqual(len(self.filtered_blocks), 4)

        block = self.filtered_blocks[0]
        self.assertEqual(block['number'], 0)
        self.assertEqual(block['channel_id'], self.channel_name)

        filtered_transaction = block['filtered_transactions'][0]
        self.assertEqual(filtered_transaction['tx_validation_code'], 'VALID')
        self.assertEqual(filtered_transaction['txid'], '')
        self.assertEqual(filtered_transaction['type'], 'CONFIG')

    def onFullEvent(self, block):
        self.blocks.append(block)

    async def get_full_block_events(self):

        org = 'org1.example.com'
        peer = self.client.get_peer('peer0.' + org)

        node_info = self.network_info['peers']['peer0.' + org]
        set_tls = self.client.set_tls_client_cert_and_key(
            node_info['clientKey']['path'], node_info['clientCert']['path'])
        self.assertTrue(set_tls)

        org_admin = self.client.get_user(org, 'Admin')
        channel = self.client.get_channel(self.channel_name)
        channel_event_hub = channel.newChannelEventHub(peer, org_admin)
        stream = channel_event_hub.connect(filtered=False,
                                           start='oldest',
                                           stop='newest')

        self.blocks = []
        channel_event_hub.registerBlockEvent(unregister=False,
                                             onEvent=self.onFullEvent)

        try:
            await shield(stream)
        except Exception:
            pass

        channel_event_hub.disconnect()

        self.assertEqual(len(self.blocks), 4)

        block = self.blocks[0]
        self.assertEqual(block['header']['number'], 0)

        block = self.blocks[2]
        self.assertEqual(block['header']['number'], 2)
        action = block['data']['data'][0]['payload']['data']['actions'][0]
        ppl_r_p = action['payload']['action']['proposal_response_payload']
        events_obj = ppl_r_p['extension']['events']
        self.assertEqual(events_obj['event_name'], 'invoked')
        self.assertEqual(events_obj['chaincode_id'], CC_NAME)
        self.assertEqual(events_obj['payload'], b'400')

    def onTxEvent(self, tx_id, status, block_number):

        o = {'status': status, 'block_number': block_number}

        if tx_id == 'all':
            if tx_id not in self.txs:
                self.txs[tx_id] = []
            self.txs[tx_id] += [o]
        else:
            self.txs[tx_id] = o

    async def get_tx_events(self):

        org = 'org1.example.com'
        peer = self.client.get_peer('peer0.' + org)

        org_admin = self.client.get_user(org, 'Admin')
        channel = self.client.get_channel(self.channel_name)
        channel_event_hub = channel.newChannelEventHub(peer, org_admin)
        stream = channel_event_hub.connect(start='oldest',
                                           stop='newest',
                                           filtered=False)

        self.txs = {}
        channel_event_hub.registerTxEvent('all', onEvent=self.onTxEvent)

        try:
            await shield(stream)
        except Exception:
            pass

        channel_event_hub.disconnect()

        self.assertEqual(len(self.txs['all']), 4)

    def test_in_sequence(self):

        loop = asyncio.get_event_loop()

        logger.info("\n\nE2E testing started...")

        self.client.new_channel(SYSTEM_CHANNEL_NAME)

        loop.run_until_complete(self.get_channel_config_with_orderer())

        loop.run_until_complete(self.channel_create())

        loop.run_until_complete(self.channel_join())

        loop.run_until_complete(self.get_channel_config())

        loop.run_until_complete(self.chaincode_install())

        self.chaincode_install_fail()

        loop.run_until_complete(self.query_installed_chaincodes())

        loop.run_until_complete(self.chaincode_instantiate())

        loop.run_until_complete(self.query_instantiated_chaincodes())

        loop.run_until_complete(self.chaincode_invoke())

        loop.run_until_complete(self.chaincode_invoke_fail())

        loop.run_until_complete(self.chaincode_channel_event_hub())

        loop.run_until_complete(self.chaincode_query())

        loop.run_until_complete(self.query_channels())

        loop.run_until_complete(self.query_info())

        loop.run_until_complete(self.query_block_by_txid())

        loop.run_until_complete(self.query_block_by_hash())

        loop.run_until_complete(self.query_block())

        loop.run_until_complete(self.query_transaction())

        loop.run_until_complete(self.get_filtered_block_events())

        loop.run_until_complete(self.get_full_block_events())

        loop.run_until_complete(self.get_tx_events())

        logger.info("E2E all test cases done\n\n")
Esempio n. 6
0
class E2eTest(BaseTestCase):

    def setUp(self):
        self.gopath_bak = os.environ.get('GOPATH', '')
        gopath = os.path.normpath(os.path.join(os.path.dirname(__file__),
                                               "../fixtures/chaincode"))
        os.environ['GOPATH'] = os.path.abspath(gopath)
        self.channel_tx = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel.tx']
        self.compose_file_path = \
            E2E_CONFIG['test-network']['docker']['compose_file_mutual_tls']

        self.config_yaml = \
            E2E_CONFIG['test-network']['channel-artifacts']['config_yaml']
        self.channel_profile = \
            E2E_CONFIG['test-network']['channel-artifacts']['channel_profile']
        self.client = Client('test/fixtures/network-mutual-tls.json')
        self.channel_name = "businesschannel"  # default application channel
        self.user = self.client.get_user('org1.example.com', 'Admin')
        self.assertIsNotNone(self.user, 'org1 admin should not be None')

        # Boot up the testing network
        self.shutdown_test_env()
        self.start_test_env()
        time.sleep(1)

    def tearDown(self):
        super(E2eTest, self).tearDown()

    async def channel_create(self):
        """
        Create an channel for further testing.

        :return:
        """
        logger.info("E2E: Channel creation start: name={}".format(
            self.channel_name))

        # By default, self.user is the admin of org1
        response = await self.client.channel_create(
            'orderer.example.com',
            self.channel_name,
            self.user,
            config_yaml=self.config_yaml,
            channel_profile=self.channel_profile)

        self.assertTrue(response)

        logger.info("E2E: Channel creation done: name={}".format(
            self.channel_name))

    async def channel_join(self):
        """
        Join peers of two orgs into an existing channels

        :return:
        """

        logger.info("E2E: Channel join start: name={}".format(
            self.channel_name))

        # channel must already exist when to join
        channel = self.client.get_channel(self.channel_name)
        self.assertIsNotNone(channel)

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, 'Admin')
            response = await self.client.channel_join(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                orderer='orderer.example.com'
            )
            self.assertTrue(response)
            # Verify the ledger exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer0_container = dc.containers.get(peer + '.' + org)
                code, output = peer0_container.exec_run(
                    'test -f '
                    '/var/hyperledger/production/ledgersData/chains/chains/{}'
                    '/blockfile_000000'.format(self.channel_name))
                self.assertEqual(code, 0, "Local ledger not exists")

        logger.info("E2E: Channel join done: name={}".format(
            self.channel_name))

    async def chaincode_install(self):
        """
        Test installing an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode install start")
        cc = f'/var/hyperledger/production/chaincodes/{CC_NAME}.{CC_VERSION}'

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            responses = await self.client.chaincode_install(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
                cc_path=CC_PATH,
                cc_name=CC_NAME,
                cc_version=CC_VERSION
            )
            self.assertTrue(responses)
            # Verify the cc pack exists now in the peer node
            dc = docker.from_env()
            for peer in ['peer0', 'peer1']:
                peer0_container = dc.containers.get(peer + '.' + org)
                code, output = peer0_container.exec_run(f'test -f {cc}')
                self.assertEqual(code, 0, "chaincodes pack not exists")

        logger.info("E2E: chaincode install done")

    def chaincode_install_fail(self):
        pass

    async def chaincode_instantiate(self):
        """
        Test instantiating an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode instantiation start")

        orgs = ["org1.example.com"]
        args = ['a', '200', 'b', '300']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.chaincode_instantiate(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                args=args,
                cc_name=CC_NAME,
                cc_version=CC_VERSION,
                wait_for_event=True
            )
            logger.info(
                "E2E: Chaincode instantiation response {}".format(response))
            self.assertTrue(response)
        logger.info("E2E: chaincode instantiation done")

    async def chaincode_invoke(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode invoke start")

        orgs = ["org1.example.com"]
        args = ['a', 'b', '100']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.chaincode_invoke(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer1.' + org],
                args=args,
                cc_name=CC_NAME,
                cc_version=CC_VERSION,
                wait_for_event=True,
                cc_pattern="^invoked*"  # for chaincode event
            )
            self.assertEqual(response, '400')

        logger.info("E2E: chaincode invoke done")

    async def chaincode_query(self):
        """
        Test invoking an example chaincode to peer

        :return:
        """
        logger.info("E2E: Chaincode query start")

        orgs = ["org1.example.com"]
        args = ['b']
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.chaincode_query(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org],
                args=args,
                cc_name=CC_NAME,
                cc_version=CC_VERSION
            )
            self.assertEqual(response, '400')  # 300 + 100

        logger.info("E2E: chaincode query done")

    async def query_installed_chaincodes(self):
        """
        Test query installed chaincodes on peer

        :return:
        """
        logger.info("E2E: Query installed chaincode start")

        orgs = ["org1.example.com", "org2.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.query_installed_chaincodes(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(
                response.chaincodes[0].name, CC_NAME, "Query failed")
            self.assertEqual(
                response.chaincodes[0].version, CC_VERSION, "Query failed")
            self.assertEqual(
                response.chaincodes[0].path, CC_PATH, "Query failed")

        logger.info("E2E: Query installed chaincode done")

    async def query_channels(self):
        """
        Test querying channel

        :return:
        """
        logger.info("E2E: Query channel start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.query_channels(
                requestor=org_admin,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(
                response.channels[0].channel_id,
                'businesschannel',
                "Query failed")

        logger.info("E2E: Query channel done")

    async def query_info(self):
        """
        Test querying information on the state of the Channel

        :return:
        """
        logger.info("E2E: Query info start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )
            self.assertEqual(
                response.height,
                3,
                "Query failed")

        logger.info("E2E: Query info done")

    async def query_block_by_txid(self):
        """
        Test querying block by tx id

        :return:
        """
        logger.info("E2E: Query block by tx id start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            response = await self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=response.currentBlockHash
            )

            tx_id = response.get('data').get('data')[0].get(
                'payload').get('header').get(
                'channel_header').get('tx_id')

            response = await self.client.query_block_by_txid(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                tx_id=tx_id
            )

            self.assertEqual(
                response.get('data').get('data')[0].get(
                    'payload').get('header').get(
                    'channel_header').get('tx_id'),
                tx_id,
                "Query failed")

        logger.info("E2E: Query block by tx id done")

    async def query_block_by_hash(self):
        """
        Test querying block by block hash

        :return:
        """
        logger.info("E2E: Query block by block hash start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            previous_block_hash = response.previousBlockHash
            current_block_hash = response.currentBlockHash
            response = await self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=current_block_hash
            )

            self.assertEqual(
                response['header']['previous_hash'].decode('utf-8'),
                previous_block_hash.hex(),
                "Query failed")

        logger.info("E2E: Query block by block hash done")

    async def query_block(self):
        """
        Test querying block by block number

        :return:
        """
        logger.info("E2E: Query block by block number start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.query_block(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_number='0'
            )
            self.assertEqual(
                response['header']['number'],
                0,
                "Query failed")
            self.blockheader = response['header']

        logger.info("E2E: Query block by block number done")

    async def query_transaction(self):
        """
        Test querying transaction by tx id

        :return:
        """
        logger.info("E2E: Query transaction by tx id start")
        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")

            response = await self.client.query_info(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
            )

            response = await self.client.query_block_by_hash(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                block_hash=response.currentBlockHash
            )

            tx_id = response.get('data').get('data')[0].get(
                'payload').get('header').get(
                'channel_header').get('tx_id')

            response = await self.client.query_transaction(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org],
                tx_id=tx_id
            )

            self.assertEqual(
                response.get('transaction_envelope').get('payload').get(
                    'header').get('channel_header').get('channel_id'),
                self.channel_name,
                "Query failed")

        logger.info("E2E: Query transaction by tx id done")

    async def query_instantiated_chaincodes(self):
        """
        Test query instantiated chaincodes on peer

        :return:
        """
        logger.info("E2E: Query instantiated chaincode start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            responses = await self.client.query_instantiated_chaincodes(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org]
            )
            self.assertTrue(len(responses) >= 1)
            self.assertEqual(
                responses[0].chaincodes[0].name, CC_NAME, "Query failed")
            self.assertEqual(
                responses[0].chaincodes[0].version, CC_VERSION, "Query failed")
            self.assertEqual(
                responses[0].chaincodes[0].path, CC_PATH, "Query failed")

        logger.info("E2E: Query installed chaincode done")

    async def get_channel_config(self):
        """
        Test get channel config on peer

        :return:
        """
        logger.info("E2E: Get channel config start")

        orgs = ["org1.example.com"]
        for org in orgs:
            org_admin = self.client.get_user(org, "Admin")
            response = await self.client.get_channel_config(
                requestor=org_admin,
                channel_name=self.channel_name,
                peers=['peer0.' + org, 'peer1.' + org]
            )
            self.assertEqual(response.config.sequence,
                             1, "Get Config Failed")

        logger.info("E2E: Query installed chaincode done")

    def onFilteredEvent(self, block):
        self.filtered_blocks.append(block)

    async def get_filtered_block_events(self):

        org = 'org1.example.com'
        peer = self.client.get_peer('peer0.' + org)

        org_admin = self.client.get_user(org, 'Admin')
        channel = self.client.get_channel(self.channel_name)
        channel_event_hub = channel.newChannelEventHub(peer, org_admin)
        stream = channel_event_hub.connect(filtered=True, start=0, stop=None)

        self.filtered_blocks = []
        channel_event_hub.registerBlockEvent(unregister=False,
                                             onEvent=self.onFilteredEvent)
        await stream  # will wait until empty block

        self.assertEqual(len(self.filtered_blocks), 4)

        block = self.filtered_blocks[0]
        self.assertEqual(block['number'], 0)
        self.assertEqual(block['channel_id'], self.channel_name)

        filtered_transaction = block['filtered_transactions'][0]
        self.assertEqual(filtered_transaction['tx_validation_code'], 'VALID')
        self.assertEqual(filtered_transaction['txid'], '')
        self.assertEqual(filtered_transaction['type'], 'CONFIG')

        # test missing block is present
        data = {'channel_id': '', 'filtered_transactions': [], 'number': 0}
        filtered_block = self.filtered_blocks[len(self.filtered_blocks) - 1]
        self.assertEqual(filtered_block, data)

    def onFullEvent(self, block):
        self.blocks.append(block)

    async def get_full_block_events(self):

        org = 'org1.example.com'
        peer = self.client.get_peer('peer0.' + org)

        org_admin = self.client.get_user(org, 'Admin')
        channel = self.client.get_channel(self.channel_name)
        channel_event_hub = channel.newChannelEventHub(peer, org_admin)
        stream = channel_event_hub.connect(start=0, stop=None, filtered=False)

        self.blocks = []
        channel_event_hub.registerBlockEvent(unregister=False,
                                             onEvent=self.onFullEvent)
        await stream

        self.assertEqual(len(self.blocks), 4)

        block = self.blocks[0]
        self.assertEqual(block['header']['number'], 0)

        block = self.blocks[2]
        self.assertEqual(block['header']['number'], 2)
        action = block['data']['data'][0]['payload']['data']['actions'][0]
        ppl_r_p = action['payload']['action']['proposal_response_payload']
        events_obj = ppl_r_p['extension']['events']
        self.assertEqual(events_obj['event_name'], 'invoked')
        self.assertEqual(events_obj['chaincode_id'], CC_NAME)
        self.assertEqual(events_obj['payload'], b'400')

        # test missing block is present
        data = {
            'header': {
                'number': 0,
                'previous_hash': b'',
                'data_hash': b''
            },
            'data': {'data': []},
            'metadata': {'metadata': []}
        }
        block = self.blocks[len(self.blocks) - 1]
        self.assertEqual(block, data)

    def test_in_sequence(self):

        loop = asyncio.get_event_loop()

        logger.info("\n\nE2E testing started...")

        loop.run_until_complete(self.channel_create())

        loop.run_until_complete(self.channel_join())

        loop.run_until_complete(self.chaincode_install())

        self.chaincode_install_fail()

        loop.run_until_complete(self.chaincode_instantiate())

        loop.run_until_complete(self.query_instantiated_chaincodes())

        loop.run_until_complete(self.chaincode_invoke())

        loop.run_until_complete(self.chaincode_query())

        loop.run_until_complete(self.query_installed_chaincodes())

        loop.run_until_complete(self.query_channels())

        loop.run_until_complete(self.query_info())

        loop.run_until_complete(self.query_block_by_txid())

        loop.run_until_complete(self.query_block_by_hash())

        loop.run_until_complete(self.query_block())

        loop.run_until_complete(self.query_transaction())

        loop.run_until_complete(self.get_channel_config())

        loop.run_until_complete(self.get_filtered_block_events())

        loop.run_until_complete(self.get_full_block_events())

        logger.info("E2E all test cases done\n\n")
Esempio n. 7
0
class BaseTestCase(unittest.TestCase):
    """
    Base class for test cases.
    All test cases can feel free to implement this.
    """
    def setUp(self, wipe_all):
        self.gopath_bak = os.environ.get('GOPATH', '')
        gopath = os.path.normpath(
            os.path.join(os.path.dirname(__file__),
                         "../test/fixtures/chaincode"))

        os.environ['GOPATH'] = os.path.abspath(gopath)
        if "LOCAL_DEPLOY" in os.environ:
            LOCAL_DEPLOY = os.environ["LOCAL_DEPLOY"] == "True"
        GCP_DEPLOY = not LOCAL_DEPLOY

        self.channel_tx = \
            E2E_CONFIG[NETWORK_NAME]['channel-artifacts']['channel.tx']
        self.compose_file_path = \
            E2E_CONFIG[NETWORK_NAME]['docker']['compose_file_trustas_gcp'] if GCP_DEPLOY else \
            E2E_CONFIG[NETWORK_NAME]['docker']['compose_file_trustas_localhost']
        self.config_yaml = \
            E2E_CONFIG[NETWORK_NAME]['channel-artifacts']['config_yaml']
        self.channel_profile = \
            E2E_CONFIG[NETWORK_NAME]['channel-artifacts']['channel_profile']
        self.client =   Client('test/fixtures/trustas_net_gcp.json') if GCP_DEPLOY else \
                        Client('test/fixtures/network.json')
        # Client('test/fixtures/local-10peers.json')
        self.channel_name = "businesschannel"  # default application channel
        self.user = self.client.get_user('org1.example.com', 'Admin')
        self.assertIsNotNone(self.user, 'org1 admin should not be None')

        global ALIVE
        ALIVE = True

        # Boot up the testing network
        self.start_test_env(wipe_all)
        return HOST, NAME

    def tearDown(self, keep_network=False):
        if not keep_network:
            self.shutdown_test_env()
        global ALIVE
        ALIVE = False

    # Logs Hyperledger network output
    def __log_network(self):
        # capture logs
        output, _, _ = cli_call(
            ["docker-compose", "-f", self.compose_file_path, "logs", "-f"])
        output = output.decode()

        # remove color encoding
        ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
        output = ansi_escape.sub('', output)

        # create output dir if it does not exist
        mkdir_p('/'.join(LOG_FILE.split('/')[:-1]))

        # write log
        with open(LOG_FILE, "w+") as fp:
            fp.write(output)

    # Logs Docker network traffic
    def __network_traffic(self):
        global ALIVE
        command = [
            "docker", "stats", "--no-stream", "--all", "--format",
            "{{.Name}},{{.NetIO}}"
        ]
        mkdir_p(NET_STATS_DIR)
        filename = os.path.join(NET_STATS_DIR, str(time.time()) + ".csv")
        while ALIVE:
            netstats, _, _ = cli_call(command)
            netstats = netstats.decode()
            measurement = str(time.time())
            lines = []
            for line in netstats.split('\n'):
                columns = line.split(',')
                if not line or len(columns) < 2:
                    lines.append('\n')
                    continue
                # individual, agregado / input, output / peers, orderer

                # from 3rd column, remove whitespaces and separate ingress and egress traffic
                val = columns[1].replace(" ", "").split('/')
                if len(val) < 2:
                    lines.append('\n')
                    continue

                # convert B, KB, MB, ... into numbers only
                ingress = human_to_bytes(val[0])
                egress = human_to_bytes(val[1])

                # join everything to the line
                line = ','.join([measurement] + columns +
                                [str(ingress), str(egress)])
                lines.append(line)

            netstats = '\n'.join(lines)
            with open(filename, "a") as f:
                f.write(netstats)
            # TODO: ver como timestamp varia com 100 peers
            time.sleep(1)

    def start_test_env(self, wipe_all):

        if wipe_all:
            print(" > Wiping old assets")
            # Remove unwanted containers, images, and files
            cli_call(["./cleanup.sh"])

        if "LOCAL_DEPLOY" in os.environ:
            LOCAL_DEPLOY = os.environ["LOCAL_DEPLOY"] == "True"
        GCP_DEPLOY = not LOCAL_DEPLOY

        # GCP environment
        if GCP_DEPLOY:

            HOST, _, _ = cli_call([
                "curl", "--ssl", "-sH", "Metadata-Flavor: Google",
                "http://metadata.google.internal/computeMetadata/v1/instance/hostname"
            ])
            NAME, _, _ = cli_call([
                "curl", "--ssl", "-sH", "Metadata-Flavor: Google",
                "http://metadata.google.internal/computeMetadata/v1/instance/name"
            ])
            HOST = HOST.decode()
            NAME = NAME.decode()

            os.environ["GCP_HOST"] = HOST
            os.environ["GCP_NAME"] = NAME

            service = NAME + ".org1.example.com" if NAME.startswith(
                "peer") else NAME + ".example.com"
            print(" > Starting service {}".format(service))
            cli_call([
                "docker-compose", "-f", self.compose_file_path, "up",
                "--no-start"
            ])
            cli_call([
                "docker-compose", "-f", self.compose_file_path, "start",
                service
            ])

        # local environment
        else:
            host = "localhost"
            name = "localhost"
            print(" > Setting network... see it with \"docker stats\"")
            cli_call([
                "docker-compose", "-f", self.compose_file_path, "up", "-d",
                "--scale", "cli=0"
            ])

        time.sleep(1)
        network_logs = threading.Thread(target=self.__log_network)
        network_logs.start()
        print(" > Logging Network output to \"{}\"".format(LOG_FILE))

        network_traffic = threading.Thread(target=self.__network_traffic)
        network_traffic.start()
        print(" > Logging Network Traffic".format(LOG_FILE))

    def shutdown_test_env(self):
        print(" > Shutting down network")

        # Get network down
        cli_call([
            "docker-compose", "-f", self.compose_file_path, "down", "--volumes"
        ])
Esempio n. 8
0
class ChannelEventHubTest(unittest.TestCase):
    def setUp(self):
        super(ChannelEventHubTest, self).setUp()
        self.client = Client('test/fixtures/network.json')
        self.channel_name = "businesschannel"  # default application channel
        self.channel = self.client.new_channel(self.channel_name)
        self.blocks = []
        self.org = 'org1.example.com'
        self.peer = self.client.get_peer('peer0.' + self.org)
        self.org_admin = self.client.get_user(self.org, 'Admin')

        self.loop = asyncio.get_event_loop()

    def onEvent(self, block):
        self.blocks.append(block)

    def test_start_twice(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        channel_event_hub.registerBlockEvent(start=0)

        with self.assertRaises(Exception) as e:
            channel_event_hub.connect(start=0)
        self.assertEqual(
            'Not able to connect with start/stop block when a'
            ' registered listener has those options.', str(e.exception))

    def test_start_twice_from_listener(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        s = channel_event_hub.connect(start=0, stop='newest')

        with self.assertRaises(Exception) as e:
            channel_event_hub.registerBlockEvent(start=0)

        try:
            self.loop.run_until_complete(s)  # will fail as no peer is running
        except Exception:
            pass

        channel_event_hub.disconnect()
        self.assertEqual(
            'The registration with a start/stop block must be'
            ' done before calling connect()', str(e.exception))

    def test_registered_before(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        channel_event_hub.registerChaincodeEvent('foo', 'bar')

        with self.assertRaises(Exception) as e:
            channel_event_hub.registerBlockEvent(start=0)
        self.assertEqual(
            'Only one event registration is allowed when'
            ' start/stop block are used.', str(e.exception))

    def test_start_bad_connect(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        with self.assertRaises(Exception) as e:
            channel_event_hub.connect(start='foo')
        self.assertEqual(
            'start value must be: last_seen, oldest, newest or'
            ' an integer', str(e.exception))

    def test_start_bad_listener(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        with self.assertRaises(Exception) as e:
            channel_event_hub.registerBlockEvent(start='foo')
        self.assertEqual('start must be an integer', str(e.exception))

    def test_stop_bad_listener(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        with self.assertRaises(Exception) as e:
            channel_event_hub.registerBlockEvent(stop='foo')
        self.assertEqual('stop must be an integer, newest or sys.maxsize',
                         str(e.exception))

    def test_start_greater_connect(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        with self.assertRaises(Exception) as e:
            channel_event_hub.connect(start=20, stop=10)
        self.assertEqual('start cannot be greater than stop', str(e.exception))

    def test_start_greater_listener(self):
        channel_event_hub = self.channel.newChannelEventHub(
            self.peer, self.org_admin)

        with self.assertRaises(Exception) as e:
            channel_event_hub.registerBlockEvent(start=20, stop=10)
        self.assertEqual('start cannot be greater than stop', str(e.exception))
Esempio n. 9
0
class BaseTestCase(unittest.TestCase):
    """
    Base class for test cases.
    All test cases can feel free to implement this.
    """
    def setUp(self):
        self.gopath_bak = os.environ.get('GOPATH', '')
        gopath = os.path.normpath(
            os.path.join(os.path.dirname(__file__), "../fixtures/chaincode"))
        os.environ['GOPATH'] = os.path.abspath(gopath)
        self.channel_tx = \
            NET_CONFIG['channel-artifacts']['channel.tx']
        self.compose_file_path = \
            NET_CONFIG['docker']['compose_file_tls']

        self.config_yaml = \
            NET_CONFIG['channel-artifacts']['config_yaml']
        self.channel_profile = \
            NET_CONFIG['channel-artifacts']['channel_profile']
        self.client = Client('test/fixtures/trustas-net.json')
        self.channel_name = "businesschannel"  # application channel
        self.user = self.client.get_user('org1.example.com', 'Admin')
        self.assertIsNotNone(self.user, 'org1 admin should not be None')

        global ALIVE
        ALIVE = True

        # Boot up the testing network
        self.start_test_env()

    def tearDown(self):
        time.sleep(1)
        self.shutdown_test_env()
        global ALIVE
        ALIVE = False

    def check_logs(self):
        cli_call([
            "docker-compose", "-f", self.compose_file_path, "logs",
            "--tail=200"
        ])

    def start_test_env(self):

        cli_call(["docker-compose", "-f", self.compose_file_path, "up", "-d"])
        time.sleep(1)

        if FABRIC_LOGS:
            network_logs = threading.Thread(target=self.__log_network)
            network_logs.start()
            print(" > Logging Network output to \"{}\"".format(LOG_FILE))

        network_traffic = threading.Thread(target=self.__network_traffic)
        network_traffic.start()
        print(" > Logging Network Traffic")

    def shutdown_test_env(self):
        cli_call(["docker-compose", "-f", self.compose_file_path, "down"])

    # Logs Hyperledger network output
    def __log_network(self):
        # capture logs
        output, _, _ = cli_call(
            ["docker-compose", "-f", self.compose_file_path, "logs", "-f"])
        output = output.decode()

        # remove color encoding
        ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]')
        output = ansi_escape.sub('', output)

        # create output dir if it does not exist
        mkdir_p('/'.join(LOG_FILE.split('/')[:-1]))

        # write log
        with open(LOG_FILE, "w+") as fp:
            fp.write(output)

    # Logs Docker network traffic
    def __network_traffic(self):
        global ALIVE
        command = [
            "docker", "stats", "--no-stream", "--all", "--format",
            "{{.Name}},{{.NetIO}}"
        ]
        mkdir_p(NET_STATS_DIR)
        filename = os.path.join(NET_STATS_DIR, str(time.time()) + ".csv")
        while ALIVE:
            netstats, _, _ = cli_call(command)
            netstats = netstats.decode()
            measurement = str(time.time())
            lines = []
            for line in netstats.split('\n'):
                columns = line.split(',')
                if not line or len(columns) < 2:
                    lines.append('\n')
                    continue
                # individual, agregado / input, output / peers, orderer

                # from 3rd column, remove whitespaces and separate ingress and egress traffic
                val = columns[1].replace(" ", "").split('/')
                if len(val) < 2:
                    lines.append('\n')
                    continue

                # convert B, KB, MB, ... into numbers only
                ingress = human_to_bytes(val[0])
                egress = human_to_bytes(val[1])

                # join everything to the line
                line = ','.join([measurement] + columns +
                                [str(ingress), str(egress)])
                lines.append(line)

            netstats = '\n'.join(lines)
            with open(filename, "a") as f:
                f.write(netstats)