Пример #1
0
    def test_regular_command(self):
        """
    Sending a non-sandbox command to the node.
    """
        adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

        expected_result = {
            'message': 'Hello, IOTA!',
        }

        mocked_response = create_http_response(json.dumps(expected_result))
        mocked_sender = Mock(return_value=mocked_response)

        payload = {'command': 'helloWorld'}

        # noinspection PyUnresolvedReferences
        with patch.object(adapter, '_send_http_request', mocked_sender):
            result = adapter.send_request(payload)

        self.assertEqual(result, expected_result)

        mocked_sender.assert_called_once_with(
            payload=json.dumps(payload),
            url=adapter.node_url,

            # Auth token automatically added to the HTTP request.
            headers={
                'Authorization': 'token ACCESS-TOKEN',
                'Content-type': 'application/json',
            },
        )
Пример #2
0
  def test_regular_command(self):
    """
    Sending a non-sandbox command to the node.
    """
    adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

    expected_result = {
      'message': 'Hello, IOTA!',
    }

    mocked_response = create_http_response(json.dumps(expected_result))
    mocked_sender = mock.Mock(return_value=mocked_response)

    payload = {'command': 'helloWorld'}

    # noinspection PyUnresolvedReferences
    with mock.patch.object(adapter, '_send_http_request', mocked_sender):
      result = adapter.send_request(payload)

    self.assertEqual(result, expected_result)

    mocked_sender.assert_called_once_with(
      payload = json.dumps(payload),
      url     = adapter.node_url,

      # Auth token automatically added to the HTTP request.
      headers = {
        'Authorization':      'token ACCESS-TOKEN',
        'Content-type':       'application/json',
        'X-IOTA-API-Version': API_VERSION,
      },
    )
Пример #3
0
    def test_error_non_200_response(self):
        """
    The node sends back a non-200 response.
    """
        adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

        decoded_response = {
            'message': 'You have reached maximum request limit.',
        }

        mocked_sender = Mock(return_value=create_http_response(
            status=429,
            content=json.dumps(decoded_response),
        ))

        # noinspection PyUnresolvedReferences
        with patch.object(adapter, '_send_http_request', mocked_sender):
            with self.assertRaises(BadApiResponse) as context:
                adapter.send_request({'command': 'helloWorld'})

        self.assertEqual(
            text_type(context.exception),
            '429 response from node: {decoded}'.format(
                decoded=decoded_response),
        )
Пример #4
0
    def test_regular_command_null_token(self):
        """
    Sending commands to a sandbox that doesn't require authorization.

    This is generally not recommended, but the sandbox node may use
    other methods to control access (e.g., listen only on loopback
    interface, use IP address whitelist, etc.).
    """
        # No access token.
        adapter = SandboxAdapter('https://localhost', None)

        expected_result = {
            'message': 'Hello, IOTA!',
        }

        mocked_response = create_http_response(json.dumps(expected_result))
        mocked_sender = Mock(return_value=mocked_response)

        payload = {'command': 'helloWorld'}

        # noinspection PyUnresolvedReferences
        with patch.object(adapter, '_send_http_request', mocked_sender):
            result = adapter.send_request(payload)

        self.assertEqual(result, expected_result)

        mocked_sender.assert_called_once_with(
            payload=json.dumps(payload),
            url=adapter.node_url,
            headers={
                # No auth token, so no Authorization header.
                # 'Authorization':  'token ACCESS-TOKEN',
                'Content-type': 'application/json',
            },
        )
Пример #5
0
 def test_error_auth_token_wrong_type(self):
     """
 ``auth_token`` is not a string.
 """
     with self.assertRaises(TypeError):
         # Nope; it has to be a unicode string.
         SandboxAdapter('https://localhost', b'not valid')
Пример #6
0
 def test_error_auth_token_empty(self):
     """
 ``auth_token`` is an empty string.
 """
     with self.assertRaises(ValueError):
         # If the node does not require authorization, use ``None``.
         SandboxAdapter('https://localhost', '')
Пример #7
0
def generate_api():
    return Iota(
        adapter=SandboxAdapter(uri='https://nodes.devnet.iota.org:443',
                               auth_token=None),
        seed=
        '9JJCOGBBWONXNV9TEVCQQMKYIGKBBSJZOSXEWQEPIRYPYLQYBCUDHKFKSLRW9HZKALHUYXDLVETTDIMFD'
    )
Пример #8
0
 def test_max_polls_too_small(self):
     """
 ``max_polls`` is < 1.
 """
     with self.assertRaises(ValueError):
         # noinspection PyTypeChecker
         SandboxAdapter('https://localhost', 'token', max_polls=0)
Пример #9
0
 def test_error_max_polls_null(self):
     """
 ``max_polls`` is None.
 """
     with self.assertRaises(TypeError):
         # noinspection PyTypeChecker
         SandboxAdapter('https://localhost', 'token', max_polls=None)
Пример #10
0
 def test_error_poll_interval_wrong_type(self):
     """
 ``poll_interval`` is not an int or float.
 """
     with self.assertRaises(TypeError):
         # ``poll_interval`` must be an int.
         # noinspection PyTypeChecker
         SandboxAdapter('https://localhost', 'token', 42.0)
Пример #11
0
 def test_max_polls_wrong_type(self):
     """
 ``max_polls`` is not an int.
 """
     with self.assertRaises(TypeError):
         # ``max_polls`` must be an int.
         # noinspection PyTypeChecker
         SandboxAdapter('https://localhost', 'token', max_polls=2.0)
Пример #12
0
    def test_error_poll_interval_null(self):
        """
    ``poll_interval`` is ``None``.

    The implications of allowing this are cool to think about...
    but not implemented yet.
    """
        with self.assertRaises(TypeError):
            # noinspection PyTypeChecker
            SandboxAdapter('https://localhost', 'token', None)
Пример #13
0
  def test_regular_command_null_token(self):
    """
    Sending commands to a sandbox that doesn't require authorization.

    This is generally not recommended, but the sandbox node may use
    other methods to control access (e.g., listen only on loopback
    interface, use IP address whitelist, etc.).
    """
    # No access token.
    adapter = SandboxAdapter('https://localhost', None)

    expected_result = {
      'message': 'Hello, IOTA!',
    }

    mocked_response = create_http_response(json.dumps(expected_result))
    mocked_sender = mock.Mock(return_value=mocked_response)

    payload = {'command': 'helloWorld'}

    # noinspection PyUnresolvedReferences
    with mock.patch.object(adapter, '_send_http_request', mocked_sender):
      result = adapter.send_request(payload)

    self.assertEqual(result, expected_result)

    mocked_sender.assert_called_once_with(
      payload = json.dumps(payload),
      url     = adapter.node_url,

      headers = {
        # No auth token, so no Authorization header.
        # 'Authorization':  'token ACCESS-TOKEN',
        'Content-type':       'application/json',
        'X-IOTA-API-Version': API_VERSION,
      },
    )
Пример #14
0
  def test_error_non_200_response(self):
    """
    The node sends back a non-200 response.
    """
    adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

    decoded_response = {
      'message': 'You have reached maximum request limit.',
    }

    mocked_sender = mock.Mock(return_value=create_http_response(
      status  = 429,
      content = json.dumps(decoded_response),
    ))

    # noinspection PyUnresolvedReferences
    with mock.patch.object(adapter, '_send_http_request', mocked_sender):
      with self.assertRaises(BadApiResponse) as context:
        adapter.send_request({'command': 'helloWorld'})

    self.assertEqual(
      text_type(context.exception),
      '429 response from node: {decoded}'.format(decoded=decoded_response),
    )
Пример #15
0
 def test_sandbox_adapter(self):
     """
     Test if local_pow feature works with SandboxAdapter.
     """
     # Note that we need correct return value to pass the
     # response filter.
     with patch('pow.ccurl_interface.attach_to_tangle',
                 MagicMock(return_value=self.bundle)) as mocked_ccurl:
         api = Iota(SandboxAdapter('https://sandbox.iota:14265/api/v1/', auth_token=None),
                    local_pow=True)
         result = api.attach_to_tangle(
             self.trunk,
             self.branch,
             self.bundle,
             self.mwm)
         self.assertTrue(mocked_ccurl.called)
         self.assertEqual(result['trytes'], self.bundle)
Пример #16
0
 def test_error_poll_interval_too_small(self):
     """
 ``poll_interval`` is < 1.
 """
     with self.assertRaises(ValueError):
         SandboxAdapter('https://localhost', 'token', 0)
Пример #17
0
  def test_sandbox_command_fails(self):
    """
    A sandbox command fails after an interval.
    """
    adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

    error_message = "You didn't say the magic word!"

    # Simulate responses from the node.
    responses =\
      deque([
        # The first request creates the job.
        # Note that the response has a 202 status.
        create_http_response(status=202, content=json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'QUEUED',
          'createdAt':  1483574581,
          'startedAt':  None,
          'finishedAt': None,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },
        })),

        # The job is still running when we poll.
        create_http_response(json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'RUNNING',
          'createdAt':  1483574581,
          'startedAt':  1483574589,
          'finishedAt': None,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },
        })),

        # The job has finished by the next polling request.
        create_http_response(json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'FAILED',
          'createdAt':  1483574581,
          'startedAt':  1483574589,
          'finishedAt': 1483574604,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },

          'error': {
            'message': error_message,
          },
        })),
      ])

    # noinspection PyUnusedLocal
    def _send_http_request(*args, **kwargs):
      return responses.popleft()

    mocked_sender = mock.Mock(wraps=_send_http_request)
    mocked_waiter = mock.Mock()

    # noinspection PyUnresolvedReferences
    with mock.patch.object(adapter, '_send_http_request', mocked_sender):
      # mock.Mock ``_wait_to_poll`` so that it returns immediately, instead
      # of waiting for 15 seconds.  Bad for production, good for tests.
      # noinspection PyUnresolvedReferences
      with mock.patch.object(adapter, '_wait_to_poll', mocked_waiter):
        with self.assertRaises(BadApiResponse) as context:
          adapter.send_request({'command': 'helloWorld'})

    self.assertEqual(text_type(context.exception), error_message)
Пример #18
0
  def test_error_job_takes_too_long(self):
    """
    A job takes too long to complete, and we lose interest.
    """
    adapter =\
      SandboxAdapter(
        uri           = 'https://localhost',
        auth_token    = 'token',
        poll_interval = 15,
        max_polls     = 2,
      )

    responses =\
      deque([
        # The first request creates the job.
        create_http_response(status=202, content=json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'QUEUED',
          'createdAt':  1483574581,
          'startedAt':  None,
          'finishedAt': None,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },
        })),

        # The next two times we poll, the job is still in progress.
        create_http_response(json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'RUNNING',
          'createdAt':  1483574581,
          'startedAt':  1483574589,
          'finishedAt': None,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },
        })),

        create_http_response(json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'RUNNING',
          'createdAt':  1483574581,
          'startedAt':  1483574589,
          'finishedAt': None,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },
        })),
      ])

    # noinspection PyUnusedLocal
    def _send_http_request(*args, **kwargs):
      return responses.popleft()

    mocked_sender = mock.Mock(wraps=_send_http_request)
    mocked_waiter = mock.Mock()

    # noinspection PyUnresolvedReferences
    with mock.patch.object(adapter, '_send_http_request', mocked_sender):
      # mock.Mock ``_wait_to_poll`` so that it returns immediately, instead
      # of waiting for 15 seconds.  Bad for production, good for tests.
      # noinspection PyUnresolvedReferences
      with mock.patch.object(adapter, '_wait_to_poll', mocked_waiter):
        with self.assertRaises(BadApiResponse) as context:
          adapter.send_request({'command': 'helloWorld'})

    self.assertEqual(
      text_type(context.exception),

      '``helloWorld`` job timed out after 30 seconds '
      '(``exc.context`` has more info).',
    )
Пример #19
0
    def test_sandbox_command_succeeds(self):
        """
    Sending a sandbox command to the node.
    """
        adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

        expected_result = {
            'message': 'Hello, IOTA!',
        }

        # Simulate responses from the node.
        responses =\
          deque([
            # The first request creates the job.
            # Note that the response has a 202 status.
            create_http_response(status=202, content=json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'QUEUED',
              'createdAt':  1483574581,
              'startedAt':  None,
              'finishedAt': None,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },
            })),

            # The job is still running when we poll.
            create_http_response(json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'RUNNING',
              'createdAt':  1483574581,
              'startedAt':  1483574589,
              'finishedAt': None,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },
            })),

            # The job has finished by the next polling request.
            create_http_response(json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'FINISHED',
              'createdAt':  1483574581,
              'startedAt':  1483574589,
              'finishedAt': 1483574604,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },

              'helloWorldResponse': expected_result,
            })),
          ])

        # noinspection PyUnusedLocal
        def _send_http_request(*args, **kwargs):
            return responses.popleft()

        mocked_sender = Mock(wraps=_send_http_request)
        mocked_waiter = Mock()

        # noinspection PyUnresolvedReferences
        with patch.object(adapter, '_send_http_request', mocked_sender):
            # Mock ``_wait_to_poll`` so that it returns immediately, instead
            # of waiting for 15 seconds.  Bad for production, good for tests.
            # noinspection PyUnresolvedReferences
            with patch.object(adapter, '_wait_to_poll', mocked_waiter):
                result = adapter.send_request({'command': 'helloWorld'})

        self.assertEqual(result, expected_result)
Пример #20
0
    def test_error_job_takes_too_long(self):
        """
    A job takes too long to complete, and we lose interest.
    """
        adapter =\
          SandboxAdapter(
            uri           = 'https://localhost',
            auth_token    = 'token',
            poll_interval = 15,
            max_polls     = 2,
          )

        responses =\
          deque([
            # The first request creates the job.
            create_http_response(status=202, content=json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'QUEUED',
              'createdAt':  1483574581,
              'startedAt':  None,
              'finishedAt': None,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },
            })),

            # The next two times we poll, the job is still in progress.
            create_http_response(json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'RUNNING',
              'createdAt':  1483574581,
              'startedAt':  1483574589,
              'finishedAt': None,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },
            })),

            create_http_response(json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'RUNNING',
              'createdAt':  1483574581,
              'startedAt':  1483574589,
              'finishedAt': None,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },
            })),
          ])

        # noinspection PyUnusedLocal
        def _send_http_request(*args, **kwargs):
            return responses.popleft()

        mocked_sender = mock.Mock(wraps=_send_http_request)
        mocked_waiter = mock.Mock()

        # noinspection PyUnresolvedReferences
        with mock.patch.object(adapter, '_send_http_request', mocked_sender):
            # mock.Mock ``_wait_to_poll`` so that it returns immediately, instead
            # of waiting for 15 seconds.  Bad for production, good for tests.
            # noinspection PyUnresolvedReferences
            with mock.patch.object(adapter, '_wait_to_poll', mocked_waiter):
                with self.assertRaises(BadApiResponse) as context:
                    adapter.send_request({'command': 'helloWorld'})

        self.assertEqual(
            text_type(context.exception),
            '``helloWorld`` job timed out after 30 seconds '
            '(``exc.context`` has more info).',
        )
Пример #21
0
    def test_sandbox_command_fails(self):
        """
    A sandbox command fails after an interval.
    """
        adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

        error_message = "You didn't say the magic word!"

        # Simulate responses from the node.
        responses =\
          deque([
            # The first request creates the job.
            # Note that the response has a 202 status.
            create_http_response(status=202, content=json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'QUEUED',
              'createdAt':  1483574581,
              'startedAt':  None,
              'finishedAt': None,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },
            })),

            # The job is still running when we poll.
            create_http_response(json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'RUNNING',
              'createdAt':  1483574581,
              'startedAt':  1483574589,
              'finishedAt': None,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },
            })),

            # The job has finished by the next polling request.
            create_http_response(json.dumps({
              'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
              'status':     'FAILED',
              'createdAt':  1483574581,
              'startedAt':  1483574589,
              'finishedAt': 1483574604,
              'command':    'helloWorld',

              'helloWorldRequest': {
                'command': 'helloWorld',
              },

              'error': {
                'message': error_message,
              },
            })),
          ])

        # noinspection PyUnusedLocal
        def _send_http_request(*args, **kwargs):
            return responses.popleft()

        mocked_sender = Mock(wraps=_send_http_request)
        mocked_waiter = Mock()

        # noinspection PyUnresolvedReferences
        with patch.object(adapter, '_send_http_request', mocked_sender):
            # Mock ``_wait_to_poll`` so that it returns immediately, instead
            # of waiting for 15 seconds.  Bad for production, good for tests.
            # noinspection PyUnresolvedReferences
            with patch.object(adapter, '_wait_to_poll', mocked_waiter):
                with self.assertRaises(BadApiResponse) as context:
                    adapter.send_request({'command': 'helloWorld'})

        self.assertEqual(text_type(context.exception), error_message)
Пример #22
0
# coding=utf-8
from __future__ import absolute_import, division, print_function, \
  unicode_literals

from iota import *
from iota.adapter.sandbox import SandboxAdapter

# Create the API object.
iota =\
  Iota(
    # To use sandbox mode, inject a ``SandboxAdapter``.
    adapter = SandboxAdapter(
      # URI of the sandbox node.
      uri = 'https://sandbox.iota.org/api/v1/',

      # Access token used to authenticate requests.
      # Contact the node maintainer to get an access token.
      auth_token = 'auth token goes here',
    ),

    # Seed used for cryptographic functions.
    # If null, a random seed will be generated.
    seed = b'SEED9GOES9HERE',
)

# Example of sending a transfer using the sandbox.
# For more information, see :py:meth:`Iota.send_transfer`.
# noinspection SpellCheckingInspection
iota.send_transfer(
    depth=100,
Пример #23
0
  def test_sandbox_command_succeeds(self):
    """
    Sending a sandbox command to the node.
    """
    adapter = SandboxAdapter('https://localhost', 'ACCESS-TOKEN')

    expected_result = {
      'message': 'Hello, IOTA!',
    }

    # Simulate responses from the node.
    responses =\
      deque([
        # The first request creates the job.
        # Note that the response has a 202 status.
        create_http_response(status=202, content=json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'QUEUED',
          'createdAt':  1483574581,
          'startedAt':  None,
          'finishedAt': None,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },
        })),

        # The job is still running when we poll.
        create_http_response(json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'RUNNING',
          'createdAt':  1483574581,
          'startedAt':  1483574589,
          'finishedAt': None,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },
        })),

        # The job has finished by the next polling request.
        create_http_response(json.dumps({
          'id':         '70fef55d-6933-49fb-ae17-ec5d02bc9117',
          'status':     'FINISHED',
          'createdAt':  1483574581,
          'startedAt':  1483574589,
          'finishedAt': 1483574604,
          'command':    'helloWorld',

          'helloWorldRequest': {
            'command': 'helloWorld',
          },

          'helloWorldResponse': expected_result,
        })),
      ])

    # noinspection PyUnusedLocal
    def _send_http_request(*args, **kwargs):
      return responses.popleft()

    mocked_sender = mock.Mock(wraps=_send_http_request)
    mocked_waiter = mock.Mock()

    # noinspection PyUnresolvedReferences
    with mock.patch.object(adapter, '_send_http_request', mocked_sender):
      # mock.Mock ``_wait_to_poll`` so that it returns immediately, instead
      # of waiting for 15 seconds.  Bad for production, good for tests.
      # noinspection PyUnresolvedReferences
      with mock.patch.object(adapter, '_wait_to_poll', mocked_waiter):
        result = adapter.send_request({'command': 'helloWorld'})

    self.assertEqual(result, expected_result)