Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
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
13 changes: 6 additions & 7 deletions .github/workflows/run_release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,11 @@ jobs:
needs: [should_release]
uses: ./.github/workflows/_version_conflict_check.yaml

# tmp disabled due to instability
# integration_tests:
# name: Integration tests
# needs: [should_release]
# uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
# secrets: inherit
integration_tests:
name: Integration tests
needs: [should_release]
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
secrets: inherit

publish_to_pypi:
name: Publish to PyPI
Expand All @@ -81,7 +80,7 @@ jobs:
unit_tests,
changelog_entry_check,
version_conflict_check,
# integration_tests, # tmp disabled due to instability
integration_tests,
]
runs-on: ubuntu-latest
permissions:
Expand Down
58 changes: 54 additions & 4 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sys
import textwrap
from pathlib import Path
from typing import TYPE_CHECKING, Callable, Protocol, cast
from typing import TYPE_CHECKING, Any, Callable, Coroutine, Protocol, cast

import pytest
from filelock import FileLock
Expand Down Expand Up @@ -56,6 +56,53 @@ def apify_client_async() -> ApifyClientAsync:
return ApifyClientAsync(api_token, api_url=api_url)


class RunActorFunction(Protocol):
"""A type for the `run_actor` fixture."""

def __call__(
self,
actor: ActorClientAsync,
*,
run_input: Any = None,
) -> Coroutine[None, None, dict]:
"""Initiate an Actor run and wait for its completion.

Args:
actor: Actor async client, in testing context usually created by `make_actor` fixture.
run_input: Optional input for the Actor run.

Returns:
Actor run result.
"""


@pytest.fixture
async def run_actor(apify_client_async: ApifyClientAsync) -> RunActorFunction:
"""Fixture for calling an Actor run and waiting for its completion.

This fixture returns a function that initiates an Actor run with optional run input, waits for its completion,
and retrieves the final result. It uses the `wait_for_finish` method with a timeout of 10 minutes.

Returns:
A coroutine that initiates an Actor run and waits for its completion.
"""

async def _run_actor(actor: ActorClientAsync, *, run_input: Any = None) -> dict:
call_result = await actor.call(run_input=run_input)

assert isinstance(call_result, dict), 'The result of ActorClientAsync.call() is not a dictionary.'
assert 'id' in call_result, 'The result of ActorClientAsync.call() does not contain an ID.'

run_client = apify_client_async.run(call_result['id'])
run_result = await run_client.wait_for_finish(wait_secs=600)

assert isinstance(run_result, dict), 'The result of RunClientAsync.wait_for_finish() is not a dictionary.'
assert 'status' in run_result, 'The result of RunClientAsync.wait_for_finish() does not contain a status.'
return run_result

return _run_actor


# Build the package wheel if it hasn't been built yet, and return the path to the wheel
@pytest.fixture(scope='session')
def sdk_wheel_path(tmp_path_factory: pytest.TempPathFactory, testrun_uid: str) -> Path:
Expand Down Expand Up @@ -130,7 +177,7 @@ def actor_base_source_files(sdk_wheel_path: Path) -> dict[str, str | bytes]:
# Just a type for the make_actor result, so that we can import it in tests
class ActorFactory(Protocol):
def __call__(
self: ActorFactory,
self,
actor_label: str,
*,
main_func: Callable | None = None,
Expand Down Expand Up @@ -242,9 +289,12 @@ async def _make_actor(
actor_client = apify_client_async.actor(created_actor['id'])

print(f'Building Actor {actor_name}...')
build = await actor_client.build(version_number='0.0', wait_for_finish=300)
build_result = await actor_client.build(version_number='0.0')
build_client = apify_client_async.build(build_result['id'])
build_client_result = await build_client.wait_for_finish(wait_secs=600)

assert build['status'] == ActorJobStatus.SUCCEEDED
assert build_client_result is not None
assert build_client_result['status'] == ActorJobStatus.SUCCEEDED

# We only mark the client for cleanup if the build succeeded,
# so that if something goes wrong here,
Expand Down
Loading