def test_wallet_count(self): ''' Количество кошельков меняется, как минимум не равно 1 ''' wallet = FullWallet(RootWallet(), 666, APP.test_client()) APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(wallet))) response = APP.test_client().get('/') assert response.json['wallets'] >= 2
def test_wallet_ok(self): ''' Сервер возвращает содержимое кошелька ''' wallet = FakeWallet() APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(wallet))) response = APP.test_client().get('/wallet/%s' % wallet.id()) assert response.status_code == status.HTTP_200_OK
def test_incoming_transaction_bnf_is_sender(self): ''' Идентификатор корневого должен фигурировать в транзакции получателя ''' root_wallet = RootWallet() wallet = FullWallet(root_wallet, 1000, APP.test_client()) APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(wallet))) response = APP.test_client().get('/wallet/%s' % wallet.id()) assert root_wallet.id() in response.json['body']
def test_full_payout(self): ''' Cписание с кошелька последних средств ''' wallet = FullWallet(RootWallet(), 1000, APP.test_client()) self.put_wallet( TransactionWallet(wallet, FakeTransaction(wallet, FakeWallet(), -1000))) response = APP.test_client().get('/wallet/%s/balance' % wallet.id()) assert response.data == b'0'
def test_dst_wallet_from_wanted(self): ''' Кошельки получатели удаляются из списка tasks ''' wallet = FullWallet(RootWallet(), 1000, APP.test_client()) APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(wallet))) response = APP.test_client().get('/tasks') assert not any(t['id'] == wallet.id() for t in response.json['tasks'] if t['type'] == 'wanted')
def test_src_wallet_to_wanted(self): ''' Кошельки отправители помещаются в список tasks ''' src = FakeWallet() dst = IncomeWallet(src, 1500) APP.test_client().put('/wallet/%s' % dst.id(), data=str(WalletString(dst))) response = APP.test_client().get('/tasks') assert any(t['id'] == src.id() and t.get('who', None) == dst.id() for t in response.json['tasks'] if t['type'] == 'wanted')
def test_remotes_tasks(self): ''' В списке задач присутствуют задачи поиска кошелька ''' wallet = FakeWallet() APP.test_client().get( '/', headers={'X-Zold-Score': '3/3: %s' % WalletScore(wallet)}) response = APP.test_client().get('/tasks') assert response.status_code == status.HTTP_200_OK assert any(t['id'] == wallet.id() and t['prefix'] in wallet.public() for t in response.json['tasks'] if t['type'] == 'wanted')
def test_dst_wallet_to_wanted(self): ''' Кошельки получатели помещаются в список tasks ''' root = RootWallet() wallet = FullWallet(root, 1000, APP.test_client()) response = APP.test_client().get('/tasks') assert any( all((t['id'] == wallet.id(), t['prefix'] in wallet.public(), t.get('who', None) == root.id())) for t in response.json['tasks'] if t['type'] == 'wanted')
def test_wallet_mtime(self): ''' В отзыве сервера присутствует время последней модификации кошелька ''' root_wallet = RootWallet() wallet = FakeWallet() transaction = FakeTransaction(root_wallet, wallet, -555) APP.test_client().put( '/wallet/%s' % root_wallet.id(), data=str(WalletString(TransactionWallet(root_wallet, transaction)))) response = APP.test_client().get('/wallet/%s' % root_wallet.id()) assert response.json['mtime'] == str(transaction.time())
def test_remotes_not_need_tasks(self): ''' В списке задач отсутствую задачи поиска, если кошелек присутствует ''' wallet = FakeWallet() APP.test_client().get( '/', headers={'X-Zold-Score': '3/3: %s' % WalletScore(wallet)}) APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(wallet))) response = APP.test_client().get('/tasks') assert response.status_code == status.HTTP_200_OK assert not any(t['id'] == wallet.id() for t in response.json['tasks'] if t['type'] == 'wanted')
def test_wallet_balance(self): ''' Запрос баланса по кошельку ''' wallet = FullWallet(RootWallet(), 1000, APP.test_client()) APP.test_client().put('/wallet/%s' % wallet.id(), data=str( WalletString( TransactionWallet( wallet, FakeTransaction( wallet, FakeWallet(), -250))))) response = APP.test_client().get('/wallet/%s/balance' % wallet.id()) assert response.data == b'750'
def test_incoming_transaction_approved(self): ''' Входящая транзакций должна сразу появиться в кошельке получателе ''' root_wallet = RootWallet() wallet = FakeWallet() transaction = FakeTransaction(root_wallet, wallet, -777) APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(wallet))) APP.test_client().put( '/wallet/%s' % root_wallet.id(), data=str(WalletString(TransactionWallet(root_wallet, transaction)))) response = APP.test_client().get('/wallet/%s' % wallet.id()) assert root_wallet.id() in response.json['body']
def test_put_wallet_many_times(self): ''' При многократной загрузке, кошелек должен оставаться согласованным ''' src = FullWallet(RootWallet(), 1000, APP.test_client()) dst = FakeWallet() transaction = FakeTransaction(src, dst, -400) wallet = TransactionWallet(src, transaction) self.put_wallet(wallet) self.put_wallet(wallet) response = APP.test_client().get('/wallet/%s' % wallet.id()) assert len( list( OutgoingTransactions( StringWallet(response.json['body']).transactions()))) == 1
def test_src_wallet_from_wanted_anyway(self): ''' В случае загрузки кошелька он удаляется из поиска, даже если искомых транзакций там нет. ''' src = FakeWallet() dst = IncomeWallet(src, 555) APP.test_client().put('/wallet/%s' % dst.id(), data=str(WalletString(dst))) APP.test_client().put('/wallet/%s' % src.id(), data=str(WalletString(src))) response = APP.test_client().get('/tasks') assert not any(t['id'] == src.id() for t in response.json['tasks'] if t['type'] == 'wanted')
def test_mining_tasks(self): ''' В списке задач присутствуют задачи майнинга ''' with APP.app_context(): DB.session.query(Score).delete() response = APP.test_client().get('/tasks') assert response.status_code == status.HTTP_200_OK assert any(t['type'] == 'mining' for t in response.json['tasks'])
def test_src_wallet_wanted_once(self): ''' Известные отправители отправители помещаются в список tasks только один раз ''' src = FakeWallet() dst = IncomeWallet(src, 777) APP.test_client().put('/wallet/%s' % dst.id(), data=str(WalletString(dst))) APP.test_client().put('/wallet/%s' % dst.id(), data=str(WalletString(dst))) response = APP.test_client().get('/tasks') assert len([ t for t in response.json['tasks'] if t['type'] == 'wanted' and t['id'] == src.id() ]) == 1
def test_wrong_request(self): ''' Зaгрузка другого кошелька - это ошибка 400 ''' wallet = FakeWallet() self.put_wallet(wallet) response = APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(FakeWallet()))) assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_src_wallet_to_wanted_alone(self): ''' Ищем кошелек только один раз, не зависимо от того, для каких еще кошельков он нужен ''' src = FakeWallet() dst1 = IncomeWallet(src, 1500) APP.test_client().put('/wallet/%s' % dst1.id(), data=str(WalletString(dst1))) dst2 = IncomeWallet(src, 100) APP.test_client().put('/wallet/%s' % dst2.id(), data=str(WalletString(dst2))) response = APP.test_client().get('/tasks') assert len([ t for t in response.json['tasks'] if t['type'] == 'wanted' and t['id'] == src.id() ]) == 1
def test_remote_from_header_scores(self): ''' Тестируем, как сервер принимает информацию о новых ремотах через содержимое заголовка ''' with APP.app_context(): DB.session.query(Remote).delete() APP.test_client().get( '/', headers={ 'X-Zold-Score': '3/3: %s' % FakeScore(3, {'STRENGTH': 3}, host='5.4.3.2', port=2048) }) response = APP.test_client().get('/remotes') assert any((r['host'] == '5.4.3.2' and r['port'] == 2048 for r in response.json['all']))
def test_right_suffix(self): ''' Правильный суффикс принимается сервером и включается в отдачу Чтобы тест не зависео от времени - он должен сам майнить... это медленно, поэтому мы проверяем здесь и тот факт, что сервер зафиксировал у себя результат нашей работы. ''' info = APP.test_client().get('/') score = JsonScore(info.json.get('score')) prefix = str(ScoreHash(score, APP.config)) suffix = next( (xs for xs in (hex(s) for s in range(0xffffffffffffffff)) if hashlib.sha256((prefix + ' ' + xs).encode( 'ascii')).hexdigest().endswith('0' * APP.config['STRENGTH']))) response = APP.test_client().post('/score', json={'suffix': suffix}) assert response.status_code == status.HTTP_200_OK assert suffix in JsonScore( APP.test_client().get('/').json.get('score')).suffixes()
def test_wrong_key(self): ''' Зaгрузка кошелька с другим ключем - это ошибка 400 ''' wallet = FakeWallet() self.put_wallet(wallet) fake = FakeWallet() response = APP.test_client().put('/wallet/%s' % wallet.id(), data=str(WalletString(fake)).replace( fake.id(), wallet.id())) assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_put_wallet_negative_balance(self): ''' Загрузка кошелька с негативным балансом - не ошибка но избыточные транзакции не проверяем и не сохраняем ''' src_wallet = FakeWallet() dst_wallet = FakeWallet() transact = FakeTransaction(src_wallet, dst_wallet, -1000) wallet = TransactionWallet(src_wallet, transact) self.put_wallet(wallet) response = APP.test_client().get('/wallet/%s' % wallet.id()) assert response.status_code == status.HTTP_200_OK # Транзакция не возвращается, поскольку не прошла проверку. assert response.json['body'] == str(WalletString(src_wallet))
def test_put_root_wallet_import_all_valid(self): ''' Загрузка корневого кошелька На нем не бывает нехватки средств И все транзакции необходимо проверять и принимать ''' src_wallet = RootWallet() dst_wallet = FakeWallet() transact = FakeTransaction(src_wallet, dst_wallet, -1000) wallet = TransactionWallet(src_wallet, transact) self.put_wallet(wallet) response = APP.test_client().get('/wallet/%s' % wallet.id()) assert response.status_code == status.HTTP_200_OK # Там могут быть левые транзакции, поэтому ищем нашу assert str(TransactionString(transact)) in response.json['body']
def test_body_contents(self): ''' Тело реплая должно содержать определенные поля ''' json = APP.test_client().get('/').json assert 'cpus' in json assert 'hours_alive' in json assert 'load' in json assert 'memory' in json assert 'nscore' in json assert 'platform' in json assert 'protocol' in json assert 'remotes' in json assert 'threads' in json assert 'version' in json assert 'wallets' in json assert 'value' in json['score'] assert 'history_size' in json['entrance'] assert 'queue_age' in json['entrance'] assert 'queue' in json['entrance'] assert 'speed' in json['entrance']
def test_put_wallet_negative_balance_partial(self): ''' Загрузка кошелька с негативным балансом - не ошибка но избыточные транзакции не проверяем и не сохраняем Но хорошие принимаем ''' root_wallet = RootWallet() src_wallet = FakeWallet() self.put_wallet( TransactionWallet(root_wallet, FakeTransaction(root_wallet, src_wallet, -1500))) dst_wallet = FakeWallet() transaction1 = FakeTransaction(src_wallet, dst_wallet, -1000) transaction2 = FakeTransaction(src_wallet, dst_wallet, -600) self.put_wallet( TransactionWallet(src_wallet, transaction1, transaction2)) response = APP.test_client().get('/wallet/%s' % src_wallet.id()) assert response.status_code == status.HTTP_200_OK assert str(TransactionString(transaction1)) in response.json['body'] # Вторая транзакция не должна проходить assert str( TransactionString(transaction2)) not in response.json['body']
def test_src_wallet_from_wanted_trivial(self): ''' Кошелек убирается из поиска, простой случай ''' src = FullWallet(RootWallet(), 3000, APP.test_client()) dst = FakeWallet() transaction = FakeTransaction(src, dst, -777) APP.test_client().put( '/wallet/%s' % dst.id(), data=str( WalletString( TransactionWallet(dst, IncomingTransaction(src, transaction))))) APP.test_client().put( '/wallet/%s' % src.id(), data=str(WalletString(TransactionWallet(src, transaction)))) response = APP.test_client().get('/tasks') assert not any(t['id'] == src.id() for t in response.json['tasks'] if t['type'] == 'wanted')
def test_dst_wallet_from_wanted_if_not_match(self): ''' Кошельки получатели удаляются из списка tasks, даже если не совпадает префикс ''' src = FullWallet(RootWallet(), 1000, APP.test_client()) dst = FakeWallet() transaction = BadPrefixTransaction(src, dst, -100) APP.test_client().put( '/wallet/%s' % src.id(), data=str(WalletString(TransactionWallet(src, transaction)))) APP.test_client().put('/wallet/%s' % dst.id(), data=str(WalletString(dst))) response = APP.test_client().get('/tasks') assert not any(t['id'] in [src.id(), dst.id()] for t in response.json['tasks'] if t['type'] == 'wanted')
def test_known_src_wallet_not_wanted(self): ''' Известные отправители отправители не помещаются в список tasks ''' src_wallet = FullWallet(RootWallet(), 1000, APP.test_client()) wallet = FakeWallet() dst_wallet = FakeWallet() src_transaction = FakeTransaction(src_wallet, dst_wallet, -777) transaction = FakeTransaction(wallet, dst_wallet, -1500) APP.test_client().put( '/wallet/%s' % src_wallet.id(), data=str( WalletString(TransactionWallet(src_wallet, src_transaction)))) APP.test_client().put( '/wallet/%s' % dst_wallet.id(), data=str( WalletString( TransactionWallet( dst_wallet, IncomingTransaction(src_wallet, src_transaction), IncomingTransaction(wallet, transaction), )))) response = APP.test_client().get('/tasks') assert not any(t['id'] == src_wallet.id() for t in response.json['tasks'] if t['type'] == 'wanted')
def test_wallet_not_found(self): ''' Кошелек не найден на сервере ''' response = APP.test_client().get('/wallet/dead3a11ed000000') assert response.status_code == status.HTTP_404_NOT_FOUND
def test_version_format_is_text(self): ''' При запросе сервер возвращает свою версию в виде текста ''' response = APP.test_client().get('/version') assert response.status_code == status.HTTP_200_OK assert re.match(r'^\d+\.\d+\.\d+$', response.data.decode('ascii'))