Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Commit

Permalink
concent acceptance test: force accept after force download
Browse files Browse the repository at this point in the history
  • Loading branch information
etam committed Sep 26, 2019
1 parent 3b4dfad commit a8edec2
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 20 deletions.
6 changes: 3 additions & 3 deletions scripts/concent_acceptance_tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import calendar
import datetime
import functools
import logging
import os
import sys
import tempfile
Expand All @@ -13,6 +12,9 @@

from pathlib import Path

# this must be before any other ethereum imports
from .fix_logging import logging

from ethereum.utils import denoms
import golem_messages

Expand Down Expand Up @@ -67,8 +69,6 @@ def setUp(self):
self.variant = variables.CONCENT_CHOICES[concent_variant]
self.provider_keys = self._fake_keys()
self.requestor_keys = self._fake_keys()
from golem.core import common
common.config_logging(suffix='concent-acceptance')
logger.debug('Provider key: %s',
base64.b64encode(self.provider_pub_key).decode())
logger.debug('Requestor key: %s',
Expand Down
22 changes: 22 additions & 0 deletions scripts/concent_acceptance_tests/fix_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import logging

from ethereum import slogging


# Monkey patch for ethereum.slogging.
# SLogger aggressively mess up with python logger.
# This patch is to settle down this.
# It should be done before any SLogger is created.


orig_getLogger = slogging.SManager.getLogger


def monkey_patched_getLogger(*args, **kwargs):
orig_class = logging.getLoggerClass()
result = orig_getLogger(*args, **kwargs)
logging.setLoggerClass(orig_class)
return result


slogging.SManager.getLogger = monkey_patched_getLogger
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import datetime
import logging
import random
import uuid

from golem_messages import constants
from golem_messages import factories as msg_factories
Expand All @@ -21,19 +20,17 @@
moment = datetime.timedelta(seconds=2)


class RequestorDoesntSendTestCase(SCIBaseTest):
"""Requestor doesn't send Ack/Reject of SubtaskResults"""

def prepare_report_computed_task(self, mode, ttc_kwargs, rct_kwargs):
class TestBase(SCIBaseTest):
def prepare_report_computed_task(self, mode, ttc_kwargs, rct_kwargs, ttc=None):
"""Returns ReportComputedTask with open force acceptance window
Can be modified by delta
"""
_rct_kwargs = self.gen_rtc_kwargs()
_rct_kwargs.update(rct_kwargs)
report_computed_task = msg_factories.tasks.ReportComputedTaskFactory(
task_to_compute=(ttc if ttc else self.gen_ttc(**ttc_kwargs)),
**_rct_kwargs,
**{'task_to_compute': self.gen_ttc(**ttc_kwargs)},
)
# Difference between timestamp and deadline has to be constant
# because it's part of SVT formula
Expand Down Expand Up @@ -85,16 +82,21 @@ def prepare_report_computed_task(self, mode, ttc_kwargs, rct_kwargs):
return report_computed_task

def provider_send_force(
self, mode='within', ttc_kwargs=None, rct_kwargs=None, **kwargs):
self, mode='within', ttc_kwargs=None, ttc=None, rct_kwargs=None,
**kwargs):
ttc_kwargs = ttc_kwargs or {}
rct_kwargs = rct_kwargs or {}
price = random.randint(1 << 20, 10 << 20)
if ttc:
price = ttc.price
else:
price = random.randint(1 << 20, 10 << 20)
ttc_kwargs['price'] = price
self.requestor_put_deposit(helpers.requestor_deposit_amount(price)[0])
ttc_kwargs['price'] = price
report_computed_task = self.prepare_report_computed_task(
mode=mode,
ttc_kwargs=ttc_kwargs,
rct_kwargs=rct_kwargs,
ttc=ttc,
)
fsr = msg_factories.concents.ForceSubtaskResultsFactory(
ack_report_computed_task__report_computed_task=report_computed_task,
Expand Down Expand Up @@ -126,6 +128,7 @@ def provider_send_force(
),
)
fsr.sig = None # Will be signed in send_to_concent()
self.provider_fsr = fsr
response = self.provider_load_response(self.provider_send(fsr))
self.assertIn(
type(response),
Expand All @@ -137,6 +140,10 @@ def provider_send_force(
)
return response


class RequestorDoesntSendTestCase(TestBase):
"""Requestor doesn't send Ack/Reject of SubtaskResults"""

def test_provider_insufficient_funds(self):
# TODO implement when we actually implement
# the Concent communication fee
Expand Down Expand Up @@ -206,6 +213,7 @@ def test_requestor_responds_with_accept(self):
concent_public_key=self.variant['pubkey'],
),
)
assert self.provider_fsr.subtask_id == fsr.subtask_id
accept_msg = msg_factories.tasks.SubtaskResultsAcceptedFactory(
report_computed_task=fsr
.ack_report_computed_task
Expand Down Expand Up @@ -265,3 +273,36 @@ def test_requestor_responds_with_reject(self):
)
self.assertIsNone(received.subtask_results_accepted)
self.assertEqual(received.subtask_results_rejected, reject_msg)

def test_requestor_responds_with_invalid_reject_reason(self):
self.assertIsNone(self.provider_send_force())
fsr = self.requestor_receive()
self.assertTrue(
fsr.verify_owners(
provider_public_key=self.provider_pub_key,
requestor_public_key=self.requestor_pub_key,
concent_public_key=self.variant['pubkey'],
),
)
# the only allowed reasons are VerificationNegative and
# ForcedResourcesFailure
reject_msg = msg_factories.tasks.SubtaskResultsRejectedFactory(
report_computed_task=fsr
.ack_report_computed_task
.report_computed_task,
reason=message.tasks.SubtaskResultsRejected.REASON
.ConcentVerificationNegative,
)
reject_msg.sign_message(self.requestor_priv_key)
self.assertTrue(
reject_msg.verify_owners(
provider_public_key=self.provider_pub_key,
requestor_public_key=self.requestor_pub_key,
concent_public_key=self.variant['pubkey'],
),
)
fsrr = message.concents.ForceSubtaskResultsResponse(
subtask_results_rejected=reject_msg,
)
with self.assertRaises(concent_exceptions.ConcentRequestError):
self.requestor_send(fsrr)
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import datetime
import logging
import time

from golem_messages import message

from golem.network.concent.filetransfers import ConcentFileRequest

from .force_download.test_filetransfers import TestBase as ForceDownloadTestBase
from .force_accept.test_requestor_doesnt_send import TestBase \
as ForceAcceptTestBase

logger = logging.getLogger(__name__)


class Test(ForceDownloadTestBase, ForceAcceptTestBase):
def _test_upload_fail(self):
wrong_hash = "sha1:adeab1829629b4e1a19dc197f2e85603ee0b5cb4"
offset_seconds = 61
fgtr = self.get_fgtr(
ttc_kwargs={
'compute_task_def__deadline': int(time.time()) + offset_seconds
},
report_computed_task__size=self.size,
report_computed_task__package_hash=wrong_hash,
)
self.requestor_send(fgtr)
fgtru = self.provider_receive()
self.assertIsInstance(fgtru, message.concents.ForceGetTaskResultUpload)

ftt = fgtru.file_transfer_token
file_request = ConcentFileRequest(self.filename, ftt)
upload_response = self.provider_cfts.upload(file_request)
self._log_concent_response(upload_response)

self.assertEqual(upload_response.status_code, 400)
timeout = ftt.token_expiration_deadline + offset_seconds
logger.debug("timeout: %s", datetime.datetime.fromtimestamp(timeout))
fgtrf = None

# Currently concent treats wrong hash as an upload that didn't took
# place, so we have to wait for timeout.
while not fgtrf and time.time() < timeout:
fgtrf = self.requestor_receive()
time.sleep(60)

self.assertIsInstance(fgtrf, message.concents.ForceGetTaskResultFailed)
self.assertEqual(fgtrf.subtask_id, fgtru.subtask_id)
return fgtrf

def test_requestor_responds_with_fgtrf(self):
fgtrf = self._test_upload_fail()

response_to_force = self.provider_send_force(ttc=fgtrf.task_to_compute)
self.assertIsInstance(response_to_force,
message.concents.ServiceRefused)
self.assertEqual(
response_to_force.reason,
message.concents.ServiceRefused.REASON.DuplicateRequest
)
5 changes: 3 additions & 2 deletions scripts/concent_acceptance_tests/force_download/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@


class ForceDownloadBaseTest(ConcentBaseTest):
def get_fgtr(self, **kwargs):
def get_fgtr(self, ttc_kwargs={}, **kwargs):
return msg_factories.concents.ForceGetTaskResultFactory(
**self.gen_rtc_kwargs('report_computed_task__'),
**{'report_computed_task__task_to_compute': self.gen_ttc()},
**{'report_computed_task__task_to_compute':
self.gen_ttc(**ttc_kwargs)},
**kwargs,
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import tempfile
import time
import shutil
import unittest
from unittest import mock

import faker
Expand All @@ -24,9 +23,7 @@
logger = logging.getLogger(__name__)


class ForceGetTaskResultFiletransferTest(ForceDownloadBaseTest,
unittest.TestCase):

class TestBase(ForceDownloadBaseTest):
def setUp(self):
super().setUp()
file = tempfile.NamedTemporaryFile(delete=False)
Expand Down Expand Up @@ -68,6 +65,10 @@ def get_fgtru(self):
self.requestor_send(fgtr)
return self.provider_receive()


class ForceGetTaskResultFiletransferTest(TestBase):
# testing failing upload is a part of force_accept_after_force_download

def test_upload(self):
fgtru = self.get_fgtru()
self.assertIsInstance(fgtru, concent_msg.ForceGetTaskResultUpload)
Expand Down
3 changes: 3 additions & 0 deletions scripts/concent_acceptance_tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pytest]
log_cli=true
log_level=DEBUG
3 changes: 1 addition & 2 deletions scripts/concent_acceptance_tests/test_base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pickle
import unittest

from golem_messages import message
from golem_messages import factories as msg_factories
Expand All @@ -8,7 +7,7 @@
from .base import ConcentBaseTest


class ConcentBaseTestTest(ConcentBaseTest, unittest.TestCase):
class ConcentBaseTestTest(ConcentBaseTest):
def test_assert_methods(self):
requestor_keys = self._fake_keys()
provider_keys = self._fake_keys()
Expand Down

0 comments on commit a8edec2

Please # to comment.