diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 25f47ee..70c23ef 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,18 +12,18 @@ jobs: - name: Setup Python uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: - python-version: 3.12 + python-version: 3.13 - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 build: runs-on: ubuntu-latest strategy: matrix: tox_env: - - py38 - py39 - py310 - py311 - py312 + - py313 - pypy3 steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 diff --git a/README.md b/README.md index 784f5cb..b95c5b5 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,11 @@ python setup.py install ### Supported Python versions in API v2.6.0 -- Python 3.8 - Python 3.9 - Python 3.10 - Python 3.11 - Python 3.12 +- Python 3.13 - PyPy3 **Python 2 has been deprecated** @@ -49,9 +49,9 @@ but are not able to get working, please [contact UpCloud support](https://upclou ```python import upcloud_api -from upcloud_api import Server, Storage, login_user_block +from upcloud_api import CloudManager, Server, Storage, login_user_block -manager = upcloud_api.CloudManager('api_user', 'password') +manager = CloudManager('api_user', 'password') manager.authenticate() @@ -248,10 +248,10 @@ tox ``` -The project also supplies a small test suite to test against the live API at `test/live_test.py`. -This suite is NOT run with `py.test` as it will permanently remove all resources related to an account. +The project also supplies a small test suite to test against the live API in `test/test_integration`. +This suite is NOT run with `py.test` dy default as it will permanently remove all resources related to an account. It should only be run with a throwaway dev-only account when preparing for a new release. It is not shipped with -PyPI releases. See source code on how to run the live test. +PyPI releases. To run the integration tests, append `--integration-tests` flag to the `py.test` command. ## Bugs, Issues, Problems, Ideas diff --git a/pyproject.toml b/pyproject.toml index a13ebdf..902b06b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [tool.black] line-length = 99 -target-version = ['py38'] +target-version = ['py39'] skip-string-normalization = true [tool.ruff] -target-version = "py38" +target-version = "py39" exclude = [ ".git", "ENV", diff --git a/requirements-dev.txt b/requirements-dev.txt index 4a179d3..f54d52b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,64 +1,67 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.9 # by the following command: # # pip-compile requirements-dev.in # -build==0.10.0 +build==1.2.2.post1 # via pip-tools -certifi==2023.7.22 +certifi==2024.8.30 # via requests -charset-normalizer==3.2.0 +charset-normalizer==3.4.0 # via requests -click==8.1.6 +click==8.1.7 # via pip-tools -coverage[toml]==7.2.7 +coverage[toml]==7.6.4 # via pytest-cov -exceptiongroup==1.2.1 +exceptiongroup==1.2.2 # via pytest -idna==3.7 +idna==3.10 # via requests +importlib-metadata==8.5.0 + # via build iniconfig==2.0.0 # via pytest mock==5.1.0 # via -r requirements-dev.in -packaging==23.1 +packaging==24.1 # via # build # pytest -pip-tools==6.14.0 +pip-tools==7.4.1 # via -r requirements-dev.in -pluggy==1.2.0 +pluggy==1.5.0 # via pytest -pyproject-hooks==1.0.0 - # via build -pytest==7.4.0 +pyproject-hooks==1.2.0 + # via + # build + # pip-tools +pytest==8.3.3 # via # -r requirements-dev.in # pytest-cov -pytest-cov==4.1.0 +pytest-cov==6.0.0 # via -r requirements-dev.in -pyyaml==6.0.1 +pyyaml==6.0.2 # via responses -requests==2.32.2 +requests==2.32.3 # via responses -responses==0.23.2 +responses==0.25.3 # via -r requirements-dev.in -tomli==2.0.1 +tomli==2.0.2 # via # build # coverage # pip-tools - # pyproject-hooks # pytest -types-pyyaml==6.0.12.11 - # via responses -urllib3==2.0.7 +urllib3==2.2.3 # via # requests # responses -wheel==0.41.0 +wheel==0.44.0 # via pip-tools +zipp==3.20.2 + # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/setup.cfg b/setup.cfg index 46b7c15..991522e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -11,7 +11,7 @@ packages=['upcloud_api', 'upcloud_api.cloud_manager'] license = MIT [options] -python_requires = >=3.8, <4 +python_requires = >=3.9, <4 setup_requires = setuptools install_requires = diff --git a/test/conftest.py b/test/conftest.py index 98fa3a5..c2f7991 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -10,8 +10,21 @@ sys.path.append(HELPERS_PATH) +def pytest_configure(config): + config.addinivalue_line( + "markers", "integration_tests: mark test to run only on if --integration-tests is passed" + ) + + def pytest_addoption(parser): - parser.addoption('--integration-tests', action='store_true', help='run integration tests') + parser.addoption( + '--integration-tests', action='store_true', default=False, help='run integration tests' + ) + + +def pytest_runtest_setup(item): + if 'integration_tests' in item.keywords and not item.config.getoption("--integration-tests"): + pytest.skip("need --integration-tests option to run this test") @pytest.fixture(scope='module') diff --git a/test/helpers/infra.py b/test/helpers/infra.py index ce6741e..53becf6 100644 --- a/test/helpers/infra.py +++ b/test/helpers/infra.py @@ -12,7 +12,7 @@ zone='uk-lon1', password_delivery='none', storage_devices=[ - Storage(os='01000000-0000-4000-8000-000030060200', size=10), + Storage(os='01000000-0000-4000-8000-000030240200', size=10), Storage(size=10, tier='maxiops'), ], ), @@ -23,7 +23,7 @@ zone='uk-lon1', password_delivery='none', storage_devices=[ - Storage(os='01000000-0000-4000-8000-000030060200', size=10), + Storage(os='01000000-0000-4000-8000-000030240200', size=10), Storage(size=10, tier='maxiops'), ], ip_addresses=[IPAddress(family='IPv6', access='public')], @@ -35,22 +35,18 @@ zone='uk-lon1', password_delivery='none', storage_devices=[ - Storage(os='01000000-0000-4000-8000-000050010300', size=10), - Storage(size=10), + Storage(os='01000000-0000-4000-8000-000150020100', size=10), + Storage(size=10, tier='standard'), ], - login_user=login_user_block( - 'testuser', ['ssh-rsa AAAAB3NzaC1yc2EAA[...]ptshi44x user@some.host'], True - ), + login_user=login_user_block('testuser', ['ssh-ed25519 AAAA'], False), ), 'lb': Server( plan='1xCPU-1GB', hostname='balancer.example.com', zone='uk-lon1', password_delivery='none', - storage_devices=[Storage(os='Debian 10.0', size=30)], - login_user=login_user_block( - 'testuser', ['ssh-rsa AAAAB3NzaC1yc2EAA[...]ptshi44x user@some.host'], True - ), + storage_devices=[Storage(os='01000000-0000-4000-8000-000020070100', size=30)], + login_user=login_user_block('testuser', ['ssh-ed25519 AAAA'], False), ), } diff --git a/test/helpers/infra_helpers.py b/test/helpers/infra_helpers.py index 9a4fc2f..996a2c4 100644 --- a/test/helpers/infra_helpers.py +++ b/test/helpers/infra_helpers.py @@ -47,7 +47,7 @@ def server_test(manager, server): storage = manager.create_storage(size=10, tier='maxiops', zone='uk-lon1') server.add_storage(storage) - server.start() + server.ensure_started() # sync new info from API and assert the changes from above have happened server.populate() diff --git a/test/test_integration/test_integration_test.py b/test/test_integration/test_integration_test.py index c1e1629..9aec7e7 100644 --- a/test/test_integration/test_integration_test.py +++ b/test/test_integration/test_integration_test.py @@ -10,12 +10,7 @@ USERNAME = os.environ.get('UPCLOUD_API_USER') PASSWORD = os.environ.get('UPCLOUD_API_PASSWD') - -integration_test = pytest.mark.skipif( - True, # TODO: not pytest.request.getoption('--integration-tests'), - reason='need --integration-tests option to run', -) - +integration_test = pytest.mark.integration_tests # globals to store created resources so we can cleanup after tests CREATED_SERVERS = [] diff --git a/tox.ini b/tox.ini index 31ea22a..e1b8a3c 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py38, py39, py310, py311, py312, pypy3 +envlist = py39, py310, py311, py312, py313, pypy3 skip_missing_interpreters = True [testenv]