class AbstractTestCommunity(AbstractServer):

    # We have to initialize Dispersy and the tunnel community on the reactor thread

    @inlineCallbacks
    def setUp(self):
        yield super(AbstractTestCommunity, self).setUp()
        self.dispersy = Dispersy(ManualEnpoint(0), self.getStateDir())
        self.dispersy._database.open()
        self.master_member = DummyMember(self.dispersy, 1, "a" * 20)
        self.member = self.dispersy.get_new_member(u"curve25519")

    @inlineCallbacks
    def tearDown(self):
        for community in self.dispersy.get_communities():
            yield community.unload_community()

        self.master_member = None
        self.member = None
        yield super(AbstractTestCommunity, self).tearDown()
Example #2
0
class TestCircuitDebugEndpoint(AbstractApiTest):
    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield super(TestCircuitDebugEndpoint,
                    self).setUp(autoload_discovery=autoload_discovery)

        self.dispersy = Dispersy(ManualEnpoint(0), self.getStateDir())
        self.dispersy._database.open()
        master_member = DummyMember(self.dispersy, 1, "a" * 20)
        member = self.dispersy.get_new_member(u"curve25519")

        self.tunnel_community = HiddenTunnelCommunity(self.dispersy,
                                                      master_member, member)
        self.dispersy.get_communities = lambda: [self.tunnel_community]
        self.session.get_dispersy_instance = lambda: self.dispersy

    def setUpPreSession(self):
        super(TestCircuitDebugEndpoint, self).setUpPreSession()
        self.config.set_tunnel_community_enabled(True)

    @deferred(timeout=10)
    def test_get_circuit_no_community(self):
        """
        Testing whether the API returns error 404 if no tunnel community is loaded
        """
        self.dispersy.get_communities = lambda: []
        return self.do_request('debug/circuits', expected_code=404)

    @deferred(timeout=10)
    def test_get_circuits(self):
        """
        Testing whether the API returns the correct circuits
        """
        mock_hop = MockObject()
        mock_hop.host = 'somewhere'
        mock_hop.port = 4242

        mock_circuit = MockObject()
        mock_circuit.state = 'TESTSTATE'
        mock_circuit.goal_hops = 42
        mock_circuit.bytes_up = 200
        mock_circuit.bytes_down = 400
        mock_circuit.creation_time = 1234
        mock_circuit.hops = [mock_hop]

        self.tunnel_community.circuits = {'abc': mock_circuit}

        def verify_response(response):
            response_json = json.loads(response)
            self.assertEqual(len(response_json['circuits']), 1)
            self.assertEqual(response_json['circuits'][0]['state'],
                             'TESTSTATE')
            self.assertEqual(response_json['circuits'][0]['bytes_up'], 200)
            self.assertEqual(response_json['circuits'][0]['bytes_down'], 400)
            self.assertEqual(len(response_json['circuits'][0]['hops']), 1)
            self.assertEqual(response_json['circuits'][0]['hops'][0]['host'],
                             'somewhere:4242')

        self.should_check_equality = False
        return self.do_request('debug/circuits',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_open_files(self):
        """
        Test whether the API returns open files
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['open_files']), 1)

        self.should_check_equality = False
        return self.do_request('debug/open_files',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_open_sockets(self):
        """
        Test whether the API returns open sockets
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['open_sockets']), 1)

        self.should_check_equality = False
        return self.do_request('debug/open_sockets',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_threads(self):
        """
        Test whether the API returns open threads
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['threads']), 1)

        self.should_check_equality = False
        return self.do_request('debug/threads',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_cpu_history(self):
        """
        Test whether the API returns the cpu history
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['cpu_history']), 1)

        self.session.lm.resource_monitor.check_resources()
        self.should_check_equality = False
        return self.do_request('debug/cpu/history',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_memory_history(self):
        """
        Test whether the API returns the memory history
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['memory_history']), 1)

        self.session.lm.resource_monitor.check_resources()
        self.should_check_equality = False
        return self.do_request('debug/memory/history',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=60)
    def test_dump_memory(self):
        """
        Test whether the API returns a memory dump
        """
        def verify_response(response):
            self.assertTrue(response)

        self.should_check_equality = False
        return self.do_request('debug/memory/dump',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_debug_pane_core_logs(self):
        """
        Test whether the API returns the logs
        """

        test_core_log_message = "This is the core test log message"
        max_lines = 100

        # Log directory
        log_dir = SessionStartupConfig.load().get_log_dir()
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        # Fill logging files with statements
        core_info_log_file_path = os.path.join(log_dir,
                                               'tribler-core-info.log')

        # write 100 test lines which is used to test for its presence in the response
        with open(core_info_log_file_path, "w") as core_info_log_file:
            for log_index in xrange(max_lines):
                core_info_log_file.write("%s %d\n" %
                                         (test_core_log_message, log_index))

        def verify_log_exists(response):
            json_response = json.loads(response)
            logs = json_response['content'].strip().split("\n")

            # Check number of logs returned is correct
            self.assertEqual(len(logs), max_lines)

            # Check if test log message is present in the logs, at least once
            log_exists = any(
                (True for log in logs if test_core_log_message in log))
            self.assertTrue(log_exists,
                            "Test log not found in the debug log response")

        self.should_check_equality = False
        return self.do_request('debug/log?process=core&max_lines=%d' % max_lines, expected_code=200)\
            .addCallback(verify_log_exists)\

    @deferred(timeout=10)
    def test_debug_pane_default_num_logs(self):
        """
        Test whether the API returns the last 100 logs when no max_lines parameter is not provided
        """
        test_core_log_message = "This is the gui test log message"
        expected_num_lines = 100

        # Log directory
        log_dir = SessionStartupConfig.load().get_log_dir()
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
        gui_info_log_file_path = os.path.join(log_dir, 'tribler-gui-info.log')

        # write 200 (greater than expected_num_lines) test logs in file
        with open(gui_info_log_file_path, "w") as core_info_log_file:
            for log_index in xrange(200):  # write more logs
                core_info_log_file.write("%s %d\n" %
                                         (test_core_log_message, log_index))

        # Check number of logs returned is as expected
        def verify_max_logs_returned(response):
            json_response = json.loads(response)
            logs = json_response['content'].strip().split("\n")
            self.assertEqual(len(logs), expected_num_lines)

        self.should_check_equality = False
        return self.do_request('debug/log?process=gui&max_lines=', expected_code=200)\
            .addCallback(verify_max_logs_returned)
Example #3
0
class TestCircuitDebugEndpoint(AbstractApiTest):
    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield super(TestCircuitDebugEndpoint,
                    self).setUp(autoload_discovery=autoload_discovery)

        self.dispersy = Dispersy(ManualEnpoint(0), self.getStateDir())
        self.dispersy._database.open()
        master_member = DummyMember(self.dispersy, 1, "a" * 20)
        member = self.dispersy.get_new_member(u"curve25519")

        self.tunnel_community = HiddenTunnelCommunity(self.dispersy,
                                                      master_member, member)
        self.dispersy.get_communities = lambda: [self.tunnel_community]
        self.session.get_dispersy_instance = lambda: self.dispersy

    def setUpPreSession(self):
        super(TestCircuitDebugEndpoint, self).setUpPreSession()
        self.config.set_tunnel_community_enabled(True)

    @deferred(timeout=10)
    def test_get_circuit_no_community(self):
        """
        Testing whether the API returns error 404 if no tunnel community is loaded
        """
        self.dispersy.get_communities = lambda: []
        return self.do_request('debug/circuits', expected_code=404)

    @deferred(timeout=10)
    def test_get_circuits(self):
        """
        Testing whether the API returns the correct circuits
        """
        mock_hop = MockObject()
        mock_hop.host = 'somewhere'
        mock_hop.port = 4242

        mock_circuit = MockObject()
        mock_circuit.state = 'TESTSTATE'
        mock_circuit.goal_hops = 42
        mock_circuit.bytes_up = 200
        mock_circuit.bytes_down = 400
        mock_circuit.creation_time = 1234
        mock_circuit.hops = [mock_hop]

        self.tunnel_community.circuits = {'abc': mock_circuit}

        def verify_response(response):
            response_json = json.loads(response)
            self.assertEqual(len(response_json['circuits']), 1)
            self.assertEqual(response_json['circuits'][0]['state'],
                             'TESTSTATE')
            self.assertEqual(response_json['circuits'][0]['bytes_up'], 200)
            self.assertEqual(response_json['circuits'][0]['bytes_down'], 400)
            self.assertEqual(len(response_json['circuits'][0]['hops']), 1)
            self.assertEqual(response_json['circuits'][0]['hops'][0]['host'],
                             'somewhere:4242')

        self.should_check_equality = False
        return self.do_request('debug/circuits',
                               expected_code=200).addCallback(verify_response)
Example #4
0
class TestMultichainStatsEndpoint(AbstractApiTest):
    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield super(TestMultichainStatsEndpoint,
                    self).setUp(autoload_discovery=autoload_discovery)

        self.dispersy = Dispersy(ManualEnpoint(0), self.getStateDir())
        self.dispersy._database.open()
        master_member = DummyMember(self.dispersy, 1, "a" * 20)
        self.member = self.dispersy.get_new_member(u"curve25519")

        self.mc_community = MultiChainCommunity(self.dispersy, master_member,
                                                self.member)
        self.dispersy.get_communities = lambda: [self.mc_community]
        self.session.get_dispersy_instance = lambda: self.dispersy

    @deferred(timeout=10)
    def test_get_circuit_no_community(self):
        """
        Testing whether the API returns error 404 if no multichain community is loaded
        """
        self.dispersy.get_communities = lambda: []
        return self.do_request('multichain/statistics', expected_code=404)

    @deferred(timeout=10)
    def test_get_statistics(self):
        """
        Testing whether the API returns the correct statistics
        """
        mock_block = MockObject()
        mock_block.public_key_requester = self.member.public_key
        mock_block.public_key_responder = "deadbeef".decode("HEX")
        mock_block.up = 42
        mock_block.down = 8
        mock_block.total_up_requester = 1024
        mock_block.total_down_requester = 2048
        mock_block.sequence_number_requester = 3
        mock_block.previous_hash_requester = "cafebabe".decode("HEX")
        mock_block.hash_requester = "b19b00b5".decode("HEX")
        mock_block.signature_requester = "deadbabe".decode("HEX")
        mock_block.total_up_responder = 512
        mock_block.total_down_responder = 256
        mock_block.sequence_number_responder = 15
        mock_block.previous_hash_responder = "cafef00d".decode("HEX")
        mock_block.hash_responder = "baadf00d".decode("HEX")
        mock_block.signature_responder = "deadf00d".decode("HEX")
        self.mc_community.persistence.add_block(mock_block)

        def verify_response(response):
            response_json = json.loads(response)
            self.assertTrue("statistics" in response_json)
            stats = response_json["statistics"]
            self.assertEqual(
                stats["self_id"],
                base64.encodestring(self.member.public_key).strip())
            self.assertEqual(stats["self_total_blocks"], 3)
            self.assertEqual(stats["self_total_up_mb"], 1024)
            self.assertEqual(stats["self_total_down_mb"], 2048)
            self.assertNotEqual(stats["latest_block_insert_time"], "")
            self.assertEqual(
                stats["latest_block_id"],
                base64.encodestring("b19b00b5".decode("HEX")).strip())
            self.assertEqual(
                stats["latest_block_requester_id"],
                base64.encodestring(self.member.public_key).strip())
            self.assertEqual(
                stats["latest_block_responder_id"],
                base64.encodestring("deadbeef".decode("HEX")).strip())
            self.assertEqual(stats["latest_block_up_mb"], "42")
            self.assertEqual(stats["latest_block_down_mb"], "8")

        self.should_check_equality = False
        return self.do_request('multichain/statistics',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_statistics_no_data(self):
        """
        Testing whether the API returns the correct statistics
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertTrue("statistics" in response_json)
            stats = response_json["statistics"]
            self.assertEqual(
                stats["self_id"],
                base64.encodestring(self.member.public_key).strip())
            self.assertEqual(stats["self_total_blocks"], -1)
            self.assertEqual(stats["self_total_up_mb"], 0)
            self.assertEqual(stats["self_total_down_mb"], 0)
            self.assertEqual(stats["latest_block_insert_time"], "")
            self.assertEqual(stats["latest_block_id"], "")
            self.assertEqual(stats["latest_block_requester_id"], "")
            self.assertEqual(stats["latest_block_responder_id"], "")
            self.assertEqual(stats["latest_block_up_mb"], "")
            self.assertEqual(stats["latest_block_down_mb"], "")

        self.should_check_equality = False
        return self.do_request('multichain/statistics',
                               expected_code=200).addCallback(verify_response)
class TestCircuitDebugEndpoint(AbstractApiTest):
    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield super(TestCircuitDebugEndpoint,
                    self).setUp(autoload_discovery=autoload_discovery)

        self.dispersy = Dispersy(ManualEnpoint(0), self.getStateDir())
        self.dispersy._database.open()
        master_member = DummyMember(self.dispersy, 1, "a" * 20)
        member = self.dispersy.get_new_member(u"curve25519")

        self.tunnel_community = HiddenTunnelCommunity(self.dispersy,
                                                      master_member, member)
        self.dispersy.get_communities = lambda: [self.tunnel_community]
        self.session.get_dispersy_instance = lambda: self.dispersy

    def setUpPreSession(self):
        super(TestCircuitDebugEndpoint, self).setUpPreSession()
        self.config.set_tunnel_community_enabled(True)

    @deferred(timeout=10)
    def test_get_circuit_no_community(self):
        """
        Testing whether the API returns error 404 if no tunnel community is loaded
        """
        self.dispersy.get_communities = lambda: []
        return self.do_request('debug/circuits', expected_code=404)

    @deferred(timeout=10)
    def test_get_circuits(self):
        """
        Testing whether the API returns the correct circuits
        """
        mock_hop = MockObject()
        mock_hop.host = 'somewhere'
        mock_hop.port = 4242

        mock_circuit = MockObject()
        mock_circuit.state = 'TESTSTATE'
        mock_circuit.goal_hops = 42
        mock_circuit.bytes_up = 200
        mock_circuit.bytes_down = 400
        mock_circuit.creation_time = 1234
        mock_circuit.hops = [mock_hop]

        self.tunnel_community.circuits = {'abc': mock_circuit}

        def verify_response(response):
            response_json = json.loads(response)
            self.assertEqual(len(response_json['circuits']), 1)
            self.assertEqual(response_json['circuits'][0]['state'],
                             'TESTSTATE')
            self.assertEqual(response_json['circuits'][0]['bytes_up'], 200)
            self.assertEqual(response_json['circuits'][0]['bytes_down'], 400)
            self.assertEqual(len(response_json['circuits'][0]['hops']), 1)
            self.assertEqual(response_json['circuits'][0]['hops'][0]['host'],
                             'somewhere:4242')

        self.should_check_equality = False
        return self.do_request('debug/circuits',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_open_files(self):
        """
        Test whether the API returns open files
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['open_files']), 1)

        self.should_check_equality = False
        return self.do_request('debug/open_files',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_open_sockets(self):
        """
        Test whether the API returns open sockets
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['open_sockets']), 1)

        self.should_check_equality = False
        return self.do_request('debug/open_sockets',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_threads(self):
        """
        Test whether the API returns open threads
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['threads']), 1)

        self.should_check_equality = False
        return self.do_request('debug/threads',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_cpu_history(self):
        """
        Test whether the API returns the cpu history
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['cpu_history']), 1)

        self.session.lm.resource_monitor.check_resources()
        self.should_check_equality = False
        return self.do_request('debug/cpu/history',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_memory_history(self):
        """
        Test whether the API returns the memory history
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertGreaterEqual(len(response_json['memory_history']), 1)

        self.session.lm.resource_monitor.check_resources()
        self.should_check_equality = False
        return self.do_request('debug/memory/history',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_dump_memory(self):
        """
        Test whether the API returns a memory dump
        """
        def verify_response(response):
            self.assertTrue(response)

        self.should_check_equality = False
        return self.do_request('debug/memory/dump',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_debug_pane_logs(self):
        """
        Test whether the API returns the logs
        """

        test_log_message = "This is the test log message"
        max_lines = 100

        import Tribler
        project_root_dir = os.path.abspath(
            os.path.join(os.path.dirname(Tribler.__file__), ".."))
        log_config = os.path.join(project_root_dir, "logger.conf")

        # State directory for logs
        state_log_dir = os.path.join(self.session.config.get_state_dir(),
                                     'logs')
        if not os.path.exists(state_log_dir):
            os.makedirs(state_log_dir)

        # Setup logging
        logging.info_log_file = os.path.join(state_log_dir, 'tribler-info.log')
        logging.error_log_file = os.path.join(state_log_dir,
                                              'tribler-error.log')
        logging.config.fileConfig(log_config, disable_existing_loggers=False)

        def verify_log_exists(response):
            json_response = json.loads(response)
            logs = json_response['content'].strip().split("\n")

            # Check number of logs returned is correct
            self.assertEqual(len(logs), max_lines)

            # Check if test log message is present in the logs, at least once
            log_exists = any((True for log in logs if test_log_message in log))
            self.assertTrue(log_exists,
                            "Test log not found in the debug log response")

        # write 100 test logs which is used to test for its presence in the response
        for log_index in xrange(100):
            logging.error("%s [%d]", test_log_message, log_index)

        self.should_check_equality = False
        return self.do_request(
            'debug/log?max_lines=%d' % max_lines,
            expected_code=200).addCallback(verify_log_exists)
Example #6
0
class TestTrustchainStatsEndpoint(AbstractApiTest):
    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield super(TestTrustchainStatsEndpoint,
                    self).setUp(autoload_discovery=autoload_discovery)

        self.dispersy = Dispersy(ManualEnpoint(0), self.getStateDir())
        self.dispersy._database.open()
        master_member = DummyMember(self.dispersy, 1, "a" * 20)
        self.member = self.dispersy.get_new_member(u"curve25519")

        self.tc_community = TriblerChainCommunity(self.dispersy, master_member,
                                                  self.member)
        self.dispersy.get_communities = lambda: [self.tc_community]
        self.session.get_dispersy_instance = lambda: self.dispersy

    @deferred(timeout=10)
    def test_get_statistics_no_community(self):
        """
        Testing whether the API returns error 404 if no trustchain community is loaded
        """
        dummy_master_member = DummyMember(self.dispersy, 1, "b" * 20)
        Community.__abstractmethods__ = frozenset()
        self.dispersy.get_communities = lambda: [
            Community(self.dispersy, dummy_master_member, self.member),
            Community(self.dispersy, dummy_master_member, self.member)
        ]
        return self.do_request('trustchain/statistics', expected_code=404)

    @deferred(timeout=10)
    def test_get_statistics(self):
        """
        Testing whether the API returns the correct statistics
        """
        block = TrustChainBlock()
        block.public_key = self.member.public_key
        block.link_public_key = "deadbeef".decode("HEX")
        block.link_sequence_number = 21
        block.transaction = {
            "up": 42,
            "down": 8,
            "total_up": 1024,
            "total_down": 2048
        }
        block.sequence_number = 3
        block.previous_hash = "babecafe".decode("HEX")
        block.signature = "babebeef".decode("HEX")
        self.tc_community.persistence.add_block(block)

        def verify_response(response):
            response_json = json.loads(response)
            self.assertTrue("statistics" in response_json)
            stats = response_json["statistics"]
            self.assertEqual(stats["id"], self.member.public_key.encode("HEX"))
            self.assertEqual(stats["total_blocks"], 3)
            self.assertEqual(stats["total_up"], 1024)
            self.assertEqual(stats["total_down"], 2048)
            self.assertEqual(stats["peers_that_pk_helped"], 1)
            self.assertEqual(stats["peers_that_helped_pk"], 1)
            self.assertIn("latest_block", stats)
            self.assertNotEqual(stats["latest_block"]["insert_time"], "")
            self.assertEqual(stats["latest_block"]["hash"],
                             block.hash.encode("HEX"))
            self.assertEqual(stats["latest_block"]["link_public_key"],
                             "deadbeef")
            self.assertEqual(stats["latest_block"]["link_sequence_number"], 21)
            self.assertEqual(stats["latest_block"]["up"], 42)
            self.assertEqual(stats["latest_block"]["down"], 8)

        self.should_check_equality = False
        return self.do_request('trustchain/statistics',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_statistics_no_data(self):
        """
        Testing whether the API returns the correct statistics
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertTrue("statistics" in response_json)
            stats = response_json["statistics"]
            self.assertEqual(stats["id"], self.member.public_key.encode("HEX"))
            self.assertEqual(stats["total_blocks"], 0)
            self.assertEqual(stats["total_up"], 0)
            self.assertEqual(stats["total_down"], 0)
            self.assertEqual(stats["peers_that_pk_helped"], 0)
            self.assertEqual(stats["peers_that_helped_pk"], 0)
            self.assertNotIn("latest_block", stats)

        self.should_check_equality = False
        return self.do_request('trustchain/statistics',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_blocks_no_community(self):
        """
        Testing whether the API returns error 404 if no trustchain community is loaded when requesting blocks
        """
        self.dispersy.get_communities = lambda: []
        return self.do_request('trustchain/blocks/aaaaa', expected_code=404)

    @deferred(timeout=10)
    def test_get_blocks(self):
        """
        Testing whether the API returns the correct blocks
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertEqual(len(response_json["blocks"]), 1)

        test_block = TestBlock()
        self.tc_community.persistence.add_block(test_block)
        self.should_check_equality = False
        return self.do_request('trustchain/blocks/%s?limit=10' %
                               test_block.public_key.encode("HEX"),
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_blocks_bad_limit_too_many(self):
        """
        Testing whether the API takes large values for the limit
        """
        self.should_check_equality = False
        return self.do_request('trustchain/blocks/%s?limit=10000000' %
                               TestBlock().public_key.encode("HEX"),
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_blocks_bad_limit_negative(self):
        """
        Testing whether the API takes negative values for the limit
        """
        self.should_check_equality = False
        return self.do_request('trustchain/blocks/%s?limit=-10000000' %
                               TestBlock().public_key.encode("HEX"),
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_blocks_bad_limit_nan(self):
        """
        Testing whether the API takes odd values for the limit
        """
        self.should_check_equality = False
        return self.do_request('trustchain/blocks/%s?limit=bla' %
                               TestBlock().public_key.encode("HEX"),
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_blocks_bad_limit_nothing(self):
        """
        Testing whether the API takes no values for the limit
        """
        self.should_check_equality = False
        return self.do_request('trustchain/blocks/%s?limit=' %
                               TestBlock().public_key.encode("HEX"),
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_blocks_unlimited(self):
        """
        Testing whether the API takes no limit argument
        """
        self.should_check_equality = False
        return self.do_request('trustchain/blocks/%s' %
                               TestBlock().public_key.encode("HEX"),
                               expected_code=200)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_no_community(self):
        """
        Testing whether the API returns error 404 if no trustchain community is loaded when bootstrapping a new identity
        """
        self.dispersy.get_communities = lambda: []
        return self.do_request('trustchain/bootstrap', expected_code=404)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_all_tokens(self):
        """
        Testing whether the API return all available credit when no argument is supplied
        """
        transaction = {'up': 100, 'down': 0, 'total_up': 100, 'total_down': 0}
        transaction2 = {'up': 100, 'down': 0}

        def verify_response(response):
            response_json = json.loads(response)
            self.assertEqual(response_json['transaction'], transaction2)

        test_block = TestBlock(transaction=transaction,
                               key=self.tc_community.my_member.private_key)
        self.tc_community.persistence.add_block(test_block)

        self.should_check_equality = False
        return self.do_request('trustchain/bootstrap',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_partial_tokens(self):
        """
        Testing whether the API return partial available credit when argument is supplied
        """
        transaction = {'up': 100, 'down': 0, 'total_up': 100, 'total_down': 0}
        transaction2 = {'up': 50, 'down': 0}

        def verify_response(response):
            response_json = json.loads(response)
            self.assertEqual(response_json['transaction'], transaction2)

        test_block = TestBlock(transaction=transaction,
                               key=self.tc_community.my_member.private_key)
        self.tc_community.persistence.add_block(test_block)

        self.should_check_equality = False
        return self.do_request('trustchain/bootstrap?amount=50',
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_not_enough_tokens(self):
        """
        Testing whether the API returns error 400 if bandwidth is to low when bootstrapping a new identity
        """
        transaction = {'up': 100, 'down': 0, 'total_up': 100, 'total_down': 0}
        test_block = TestBlock(transaction=transaction,
                               key=self.tc_community.my_member.private_key)
        self.tc_community.persistence.add_block(test_block)

        self.should_check_equality = False
        return self.do_request('trustchain/bootstrap?amount=200',
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_not_enough_tokens_2(self):
        """
        Testing whether the API returns error 400 if bandwidth is to low when bootstrapping a new identity
        """
        transaction = {'up': 0, 'down': 100, 'total_up': 0, 'total_down': 100}
        test_block = TestBlock(transaction=transaction,
                               key=self.tc_community.my_member.private_key)
        self.tc_community.persistence.add_block(test_block)

        self.should_check_equality = False
        return self.do_request('trustchain/bootstrap?amount=10',
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_zero_amount(self):
        """
        Testing whether the API returns error 400 if amount is zero when bootstrapping a new identity
        """
        self.should_check_equality = False
        return self.do_request('trustchain/bootstrap?amount=0',
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_negative_amount(self):
        """
        Testing whether the API returns error 400 if amount is negative when bootstrapping a new identity
        """
        self.should_check_equality = False
        return self.do_request('trustchain/bootstrap?amount=-1',
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_bootstrap_identity_string(self):
        """
        Testing whether the API returns error 400 if amount is string when bootstrapping a new identity
        """
        self.should_check_equality = False
        return self.do_request('trustchain/bootstrap?amount=aaa',
                               expected_code=400)
class TestMultichainStatsEndpoint(AbstractApiTest):

    @blocking_call_on_reactor_thread
    @inlineCallbacks
    def setUp(self, autoload_discovery=True):
        yield super(TestMultichainStatsEndpoint, self).setUp(autoload_discovery=autoload_discovery)

        self.dispersy = Dispersy(ManualEnpoint(0), self.getStateDir())
        self.dispersy._database.open()
        master_member = DummyMember(self.dispersy, 1, "a" * 20)
        self.member = self.dispersy.get_new_member(u"curve25519")

        self.mc_community = MultiChainCommunity(self.dispersy, master_member, self.member)
        self.dispersy.get_communities = lambda: [self.mc_community]
        self.session.get_dispersy_instance = lambda: self.dispersy

    @deferred(timeout=10)
    def test_get_statistics_no_community(self):
        """
        Testing whether the API returns error 404 if no multichain community is loaded
        """
        dummy_master_member = DummyMember(self.dispersy, 1, "b" * 20)
        Community.__abstractmethods__ = frozenset()
        self.dispersy.get_communities = lambda: [Community(self.dispersy, dummy_master_member, self.member),
                                                 Community(self.dispersy, dummy_master_member, self.member)]
        return self.do_request('multichain/statistics', expected_code=404)

    @deferred(timeout=10)
    def test_get_statistics(self):
        """
        Testing whether the API returns the correct statistics
        """
        block = MultiChainBlock()
        block.public_key = self.member.public_key
        block.link_public_key = "deadbeef".decode("HEX")
        block.link_sequence_number = 21
        block.up = 42
        block.down = 8
        block.total_up = 1024
        block.total_down = 2048
        block.sequence_number = 3
        block.previous_hash = "babecafe".decode("HEX")
        block.signature = "babebeef".decode("HEX")
        self.mc_community.persistence.add_block(block)

        def verify_response(response):
            response_json = json.loads(response)
            self.assertTrue("statistics" in response_json)
            stats = response_json["statistics"]
            self.assertEqual(stats["id"], self.member.public_key.encode("HEX"))
            self.assertEqual(stats["total_blocks"], 3)
            self.assertEqual(stats["total_up"], 1024)
            self.assertEqual(stats["total_down"], 2048)
            self.assertEqual(stats["peers_that_pk_helped"], 1)
            self.assertEqual(stats["peers_that_helped_pk"], 1)
            self.assertIn("latest_block", stats)
            self.assertNotEqual(stats["latest_block"]["insert_time"], "")
            self.assertEqual(stats["latest_block"]["hash"], block.hash.encode("HEX"))
            self.assertEqual(stats["latest_block"]["link_public_key"], "deadbeef")
            self.assertEqual(stats["latest_block"]["link_sequence_number"], 21)
            self.assertEqual(stats["latest_block"]["up"], 42)
            self.assertEqual(stats["latest_block"]["down"], 8)

        self.should_check_equality = False
        return self.do_request('multichain/statistics', expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_statistics_no_data(self):
        """
        Testing whether the API returns the correct statistics
        """

        def verify_response(response):
            response_json = json.loads(response)
            self.assertTrue("statistics" in response_json)
            stats = response_json["statistics"]
            self.assertEqual(stats["id"], self.member.public_key.encode("HEX"))
            self.assertEqual(stats["total_blocks"], 0)
            self.assertEqual(stats["total_up"], 0)
            self.assertEqual(stats["total_down"], 0)
            self.assertEqual(stats["peers_that_pk_helped"], 0)
            self.assertEqual(stats["peers_that_helped_pk"], 0)
            self.assertNotIn("latest_block", stats)

        self.should_check_equality = False
        return self.do_request('multichain/statistics', expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_blocks_no_community(self):
        """
        Testing whether the API returns error 404 if no multichain community is loaded when requesting blocks
        """
        self.dispersy.get_communities = lambda: []
        return self.do_request('multichain/blocks/aaaaa', expected_code=404)

    @deferred(timeout=10)
    def test_get_blocks(self):
        """
        Testing whether the API returns the correct blocks
        """
        def verify_response(response):
            response_json = json.loads(response)
            self.assertEqual(len(response_json["blocks"]), 1)

        test_block = TestBlock()
        self.mc_community.persistence.add_block(test_block)
        self.should_check_equality = False
        return self.do_request('multichain/blocks/%s?limit=10' % test_block.public_key.encode("HEX"),
                               expected_code=200).addCallback(verify_response)

    @deferred(timeout=10)
    def test_get_blocks_bad_limit_too_many(self):
        """
        Testing whether the API takes large values for the limit
        """
        self.should_check_equality = False
        return self.do_request('multichain/blocks/%s?limit=10000000' % TestBlock().public_key.encode("HEX"),
                               expected_code=400)


    @deferred(timeout=10)
    def test_get_blocks_bad_limit_negative(self):
        """
        Testing whether the API takes negative values for the limit
        """
        self.should_check_equality = False
        return self.do_request('multichain/blocks/%s?limit=-10000000' % TestBlock().public_key.encode("HEX"),
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_blocks_bad_limit_nan(self):
        """
        Testing whether the API takes odd values for the limit
        """
        self.should_check_equality = False
        return self.do_request('multichain/blocks/%s?limit=bla' % TestBlock().public_key.encode("HEX"),
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_blocks_bad_limit_nothing(self):
        """
        Testing whether the API takes no values for the limit
        """
        self.should_check_equality = False
        return self.do_request('multichain/blocks/%s?limit=' % TestBlock().public_key.encode("HEX"),
                               expected_code=400)

    @deferred(timeout=10)
    def test_get_blocks_unlimited(self):
        """
        Testing whether the API takes no limit argument
        """
        self.should_check_equality = False
        return self.do_request('multichain/blocks/%s' % TestBlock().public_key.encode("HEX"),
                               expected_code=200)