Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2005c86
Added fixture waiting unti SaaS database is running
ckunki Apr 30, 2024
4e51522
fixed typo in changes file
ckunki Apr 30, 2024
6c274ef
Merge branch 'main' into feature/#14-fixture-operational_saas_databas…
ckunki Apr 30, 2024
7e1cb91
Fixed merge errors
ckunki Apr 30, 2024
de6a01f
Fixed review findings
ckunki May 6, 2024
dad0f11
Fixed review findings
ckunki May 6, 2024
ebef57c
Added user name to resources in Exasol Saas
ckunki May 6, 2024
97f44cc
fixed method call
ckunki May 6, 2024
8a400e4
fixed _timestamp_name()
ckunki May 6, 2024
0985a0d
replaced os.getlogin() by getpass.getuser()
ckunki May 6, 2024
bb93dda
shortened database name
ckunki May 6, 2024
6b328bf
Added log messages for deleting the database
ckunki May 6, 2024
b21c96a
Make pytest display log output of tests cases in CI build
ckunki May 6, 2024
2da0580
Added sleep before deleting the database
ckunki May 6, 2024
66026b0
Added log message for creating a database
ckunki May 6, 2024
26cf321
Excluded generated code from coverage
ckunki May 7, 2024
d822647
Fixed first batch of review findings
ckunki May 7, 2024
2b2b4a3
Refactored extracting minutes from timedelta for SaaS API
ckunki May 7, 2024
aace19e
Added parameter region for create_database()
ckunki May 7, 2024
5af0e1d
Moved limits into dedicated class
ckunki May 7, 2024
bd0fcc9
Use project short tag for saas resource
ckunki May 7, 2024
2534a4a
Renamed database limits to meet linter requirements
ckunki May 7, 2024
381e404
Fixed type check
ckunki May 7, 2024
fb30fa7
fixed import
ckunki May 7, 2024
db989b6
Made parameter project short tag for timestamp_name optional
ckunki May 7, 2024
3e23db0
Fixed review finding
ckunki May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/changes/changes_0.3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ This release adds integration tests for the most important calls to SaaS API.

* #21: Added integration test for operation "create database"
* #23: Added integration test for operation "add IP to whitelist"

## Feature

* #14: Added fixture waiting until SaaS database is running
* #25: Fixed transitive dependencies required by generated API client
4 changes: 2 additions & 2 deletions doc/developer_guide/developer_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ openapi-python-client reads the JSON specification of the SaaS API and generates
The easiest way is to make openapi-python-client create a dedicated file `pyproject.toml` and copy the transitive dependencies from there to SAPIPY's file `pyproject.toml`.

In order to create file `pyproject.toml`
* In file `noxfile.py` you need to replace mode `update` by `generate`
* Additionally in file `openapi_config.yml` you need to specify a non-existing top-level directory as `name` and a package that does not contain slashes, e.g.
* In file `noxfile.py`, function `generate_api` you need to replace mode `update` by `generate`.
* Additionally, in file `openapi_config.yml` you need to specify a non-existing top-level directory as `project_name_override` and a package that does not contain slashes, e.g.

```yaml
project_name_override: "generate"
Expand Down
16 changes: 15 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ python = ">=3.8.0,<4.0"
requests = "^2.31.0"
types-requests = "^2.31.0.6"
ifaddr = "^0.2.0"
tenacity = "^8.2.3"
# generated by openapi-python-client
httpx = ">=0.20.0,<0.28.0"
attrs = ">=21.3.0"
Expand Down
48 changes: 47 additions & 1 deletion test/integration/api_access.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
from typing import Iterable
from contextlib import contextmanager
from datetime import datetime
from datetime import datetime, timedelta
from tenacity.wait import wait_fixed
from tenacity.stop import stop_after_delay

from exasol.saas.client import openapi
from exasol.saas.client.openapi.models.status import Status
from exasol.saas.client.openapi.api.databases import (
create_database,
delete_database,
list_databases,
get_database,
)
from exasol.saas.client.openapi.api.security import (
list_allowed_i_ps,
add_allowed_ip,
delete_allowed_ip,
)
from tenacity import retry, TryAgain


def timestamp() -> str:
return f'{datetime.now().timestamp():.0f}'


class DatabaseStartupFailure(Exception):
"""
If a SaaS database instance during startup reports a status other than
transitional or successful.
"""


def create_saas_client(
host: str,
pat: str,
Expand Down Expand Up @@ -88,6 +100,40 @@ def database(
if not keep and db:
self.delete_database(db.id, ignore_delete_failure)

def get_database(self, database_id: str):
return get_database.sync(
self._account_id,
database_id,
client=self._client,
)

def wait_until_running(
self,
database_id: str,
timeout: timedelta = timedelta(minutes=30),
interval: timedelta = timedelta(minutes=2),
) -> str:
transitional = [
Status.TOCREATE,
Status.CREATING,
Status.SCALING,
]
success = [
Status.RUNNING,
]

@retry(wait=wait_fixed(interval), stop=stop_after_delay(timeout))
def poll_status():
db = self.get_database(database_id)
if db.status in transitional:
print(f'status = {db.status}')
raise TryAgain
return db.status

if poll_status() not in success:
raise DatabaseStartupFailure()


def list_allowed_ip_ids(self) -> Iterable[openapi.models.allowed_ip.AllowedIP]:
ips = list_allowed_i_ps.sync(
self._account_id,
Expand Down
7 changes: 7 additions & 0 deletions test/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,10 @@ def saas_database(api_access) -> openapi.models.database.Database:
"""
with api_access.database() as db:
yield db


@pytest.fixture(scope="session")
def operational_saas_database_id(api_access) -> str:
with api_access.database() as db:
api_access.wait_until_running(db.id)
yield db
14 changes: 14 additions & 0 deletions test/integration/databases_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import pytest
from exasol.saas.client import openapi
from tenacity import RetryError
from datetime import timedelta


def test_lifecycle(api_access):
Expand All @@ -24,3 +27,14 @@ def test_lifecycle(api_access):
# delete database and verify database is not listed anymore
testee.delete_database(db.id)
assert db.id not in testee.list_database_ids()


def test_poll(api_access):
with api_access.database() as db:
print(f'{db.status}')
with pytest.raises(RetryError):
api_access.wait_until_running(
db.id,
timeout=timedelta(seconds=3),
interval=timedelta(seconds=1),
)