From 4d25b8c03b7a01f841a6fd97dfaf72bcd89e6c44 Mon Sep 17 00:00:00 2001 From: Jan Segre Date: Thu, 1 Jul 2021 18:15:09 -0300 Subject: [PATCH] chore(ci): run tests on Windows, do not continue on error --- .github/workflows/main.yml | 19 ++++++++----------- hathor/cli/top.py | 8 ++++++-- tests/cli/test_shell.py | 10 ++++++++++ tests/p2p/test_connections.py | 5 +++++ tests/p2p/test_protocol.py | 3 +++ tests/resources/test_profiler.py | 3 +++ tests/simulation/test_simulator.py | 4 ++++ tests/tx/test_prometheus.py | 4 ++++ tests/utils.py | 14 ++++++++++++-- 9 files changed, 55 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dec0e0dd9..09b2d6747 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,23 +20,21 @@ jobs: python: - 3.6 - 3.7 + - 3.8 + - 3.9 os: - ubuntu-latest - macos-latest - tier: [1] include: - - os: ubuntu-latest - python: 3.8 - tier: 1 - # - os: macos-latest - # python: 3.8 - # tier: 1 - os: windows-latest python: 3.6 - tier: 2 - os: windows-latest python: 3.7 - tier: 2 + # these still have some errors: + # - os: windows-latest + # python: 3.8 + # - os: windows-latest + # python: 3.9 steps: - name: Checkout uses: actions/checkout@v2 @@ -73,7 +71,6 @@ jobs: run: poetry run make check - name: Run tests run: poetry run make tests - continue-on-error: ${{ matrix.tier > 1 }} - name: Upload coverage uses: codecov/codecov-action@v1 - if: matrix.python == 3.6 && matrix.os == 'ubuntu-latest' + if: matrix.python == 3.7 && matrix.os == 'ubuntu-latest' diff --git a/hathor/cli/top.py b/hathor/cli/top.py index 540f4238b..396e493ae 100644 --- a/hathor/cli/top.py +++ b/hathor/cli/top.py @@ -13,8 +13,6 @@ # limitations under the License. import asyncio -import curses -import curses.ascii import datetime import signal import sys @@ -26,6 +24,12 @@ from math import floor from typing import Any, Callable, DefaultDict, Dict, List, Optional, Tuple +try: + import curses + import curses.ascii +except ModuleNotFoundError: + pass + from aiohttp import ClientSession Key = Tuple[str, ...] diff --git a/tests/cli/test_shell.py b/tests/cli/test_shell.py index bda156d98..5704f1cc1 100644 --- a/tests/cli/test_shell.py +++ b/tests/cli/test_shell.py @@ -1,8 +1,17 @@ import tempfile +import pytest + from hathor.cli.shell import Shell from tests import unittest +try: + import rocksdb # noqa: F401 +except ImportError: + HAS_ROCKSDB = False +else: + HAS_ROCKSDB = True + class ShellTest(unittest.TestCase): # In this case we just want to go through the code to see if it's okay @@ -11,6 +20,7 @@ def test_shell_execution_memory_storage(self): shell = Shell(argv=['--memory-storage']) self.assertTrue(shell is not None) + @pytest.mark.skipif(not HAS_ROCKSDB, reason='requires python-rocksdb') def test_shell_execution_default_storage(self): temp_data = tempfile.TemporaryDirectory() shell = Shell(argv=['--data', temp_data.name]) diff --git a/tests/p2p/test_connections.py b/tests/p2p/test_connections.py index 8fab394fc..4a75c4a98 100644 --- a/tests/p2p/test_connections.py +++ b/tests/p2p/test_connections.py @@ -1,6 +1,9 @@ import shutil +import sys import tempfile +import pytest + from hathor.manager import HathorManager from hathor.transaction.storage import TransactionMemoryStorage from hathor.wallet import Wallet @@ -9,6 +12,8 @@ class ConnectionsTest(unittest.TestCase): + + @pytest.mark.skipif(sys.platform == 'win32', reason='run_server is very finicky on Windows') def test_connections(self): process = run_server() process2 = run_server(listen=8006, status=8086, bootstrap='tcp://127.0.0.1:8005') diff --git a/tests/p2p/test_protocol.py b/tests/p2p/test_protocol.py index 9a1c2bfdd..840fbcd1b 100644 --- a/tests/p2p/test_protocol.py +++ b/tests/p2p/test_protocol.py @@ -1,5 +1,7 @@ import json +import sys +import pytest import twisted.names.client from twisted.internet.defer import inlineCallbacks from twisted.python.failure import Failure @@ -155,6 +157,7 @@ def test_valid_hello(self): self.assertFalse(self.conn.tr1.disconnecting) self.assertFalse(self.conn.tr2.disconnecting) + @pytest.mark.skipif(sys.platform == 'win32', reason='resolver._parseCall not defined on Windows') @inlineCallbacks def test_invalid_peer_id(self): self.conn.run_one_step() # HELLO diff --git a/tests/resources/test_profiler.py b/tests/resources/test_profiler.py index f961705aa..2e9197384 100644 --- a/tests/resources/test_profiler.py +++ b/tests/resources/test_profiler.py @@ -1,8 +1,10 @@ import os import re import shutil +import sys import tempfile +import pytest from twisted.internet.defer import inlineCallbacks from hathor.profiler.resources import ProfilerResource @@ -14,6 +16,7 @@ def setUp(self): super().setUp() self.web = StubSite(ProfilerResource(self.manager)) + @pytest.mark.skipif(sys.platform == 'win32', reason='shutil.rmtree fails on Windows') @inlineCallbacks def test_post(self): # Options diff --git a/tests/simulation/test_simulator.py b/tests/simulation/test_simulator.py index 5944bd904..1b50ea5cf 100644 --- a/tests/simulation/test_simulator.py +++ b/tests/simulation/test_simulator.py @@ -1,10 +1,14 @@ import random +import sys from typing import Optional +import pytest + from hathor.simulator import FakeConnection, MinerSimulator, RandomTransactionGenerator, Simulator from tests import unittest +@pytest.mark.skipif(sys.platform == 'win32', reason='set_seed fails on Windows') class HathorSimulatorTestCase(unittest.TestCase): seed_config: Optional[int] = None diff --git a/tests/tx/test_prometheus.py b/tests/tx/test_prometheus.py index a792b44dc..981ea153f 100644 --- a/tests/tx/test_prometheus.py +++ b/tests/tx/test_prometheus.py @@ -1,7 +1,10 @@ import os import shutil +import sys import tempfile +import pytest + from hathor.prometheus import PrometheusMetricsExporter from tests import unittest from tests.utils import add_new_blocks, add_new_transactions @@ -14,6 +17,7 @@ def setUp(self): self.network = 'testnet' self.manager = self.create_peer(self.network, unlock_wallet=True) + @pytest.mark.skipif(sys.platform == 'win32', reason='set_new_metrics fails on Windows') def test_wallet(self): tmpdir = tempfile.mkdtemp() tmpfile = tempfile.NamedTemporaryFile(dir=tmpdir, suffix='.prom', delete=False) diff --git a/tests/utils.py b/tests/utils.py index 64a133d28..d9c028970 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,4 +1,5 @@ import base64 +import os import random import subprocess import time @@ -192,7 +193,7 @@ def add_blocks_unlock_reward(manager): return add_new_blocks(manager, settings.REWARD_SPEND_MIN_BLOCKS, advance_clock=1, address=BURN_ADDRESS) -def run_server(hostname='localhost', listen=8005, status=8085, bootstrap=None, tries=100): +def run_server(hostname='localhost', listen=8005, status=8085, bootstrap=None, tries=100, alive_for_at_least_sec=3): """ Starts a full node in a subprocess running the cli command :param hostname: Hostname used to be accessed by other peers @@ -229,12 +230,21 @@ def run_server(hostname='localhost', listen=8005, status=8085, bootstrap=None, t if bootstrap: command = '{} --bootstrap {}'.format(command, bootstrap) - process = subprocess.Popen(command.split()) + process = subprocess.Popen(command.split(), env=os.environ) + + # check that the process doesn't close in the first few seconds + for _ in range(alive_for_at_least_sec): + exit_code = process.poll() + if exit_code is not None: + raise RuntimeError(f'remote process died with {exit_code}') partial_url = 'http://{}:{}'.format(hostname, status) url = urllib.parse.urljoin(partial_url, '/wallet/balance/') while True: try: + exit_code = process.poll() + if exit_code is not None: + raise RuntimeError(f'remote process died with {exit_code}') requests.get(url) break except requests.exceptions.ConnectionError: