diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 35d220e..1fa9e71 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -72,6 +72,9 @@ jobs: run: composer run-script lint build-integration-test-containers: runs-on: ubuntu-latest + needs: + - lint + - unit-tests strategy: matrix: image: [ 'caddy', 'tests' ] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cc374a2 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ + +export GITHUB_SHA=latest +export DAPR_VERSION=1.3.0-rc.1 + +.PHONY: integration-tests +integration-tests: build + docker-compose down -v + docker-compose up & + sleep 10 + curl --silent --output /tmp/test-results.json --write-out "%{http_code}" http://localhost:9502/do_tests + docker-compose down -v + cat /tmp/test-results.json | jq . + +composer.lock: composer.json + composer update + +vendor/autoload.php: composer.lock + composer install + touch vendor/autoload.php + +.PHONY: build +build: build-caddy build-tests + +.PHONY: build-tests +build-tests: vendor/autoload.php + docker build -t tests:latest -f images/tests.Dockerfile . + +.PHONY: build-caddy +build-caddy: vendor/autoload.php + docker build -t caddy:latest -f images/caddy.Dockerfile . diff --git a/docker-compose.yml b/docker-compose.yml index dba3459..e601b48 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -# A Docker Compose file for spinning up integration tests in CI +# A Docker Compose file for spinning up integration tests in CI, you can run these locally by running `make` version: "3" services: placement: diff --git a/images/caddy.Dockerfile b/images/caddy.Dockerfile index 7588a2b..0b5a7cb 100644 --- a/images/caddy.Dockerfile +++ b/images/caddy.Dockerfile @@ -1,4 +1,3 @@ -# syntax=docker/dockerfile:labs FROM caddy AS base COPY images/Caddyfile /etc/caddy/Caddyfile COPY . /tests diff --git a/images/tests.Dockerfile b/images/tests.Dockerfile index c3d6881..3624c8b 100644 --- a/images/tests.Dockerfile +++ b/images/tests.Dockerfile @@ -1,5 +1,3 @@ -# syntax=docker/dockerfile:labs -# withinboredom/php-base-min == docker build --pull -t withinboredom/php-base-min --target base -f images/tests.Dockerfile . FROM php:8.0-fpm AS base COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ RUN apt-get update && apt-get install -y wget git unzip && apt-get clean diff --git a/src/index.php b/src/index.php index 0f407c3..57c59ec 100644 --- a/src/index.php +++ b/src/index.php @@ -1,5 +1,7 @@ get( '/do_tests', function (\Dapr\Client\DaprClient $client) { + while (true) { + sleep(1); + if ($client->isDaprHealthy()) { + $meta = $client->getMetadata(); + error_log(print_r($meta, true)); + if (!empty($meta->actors)) { + break; + } + } + } + $test_results = [ 'test/actors' => null, 'test/binding' => null, @@ -463,6 +476,13 @@ function (\Dapr\Client\DaprClient $client) { ]; } + $client->shutdown(afterRequest: false); + + while ($client->isDaprHealthy()) { + sleep(1); + error_log('waiting for daprd shutdown...'); + } + return new \Nyholm\Psr7\Response($has_failed ? 500 : 200, body: json_encode($test_results)); } ); diff --git a/src/lib/Client/DaprClient.php b/src/lib/Client/DaprClient.php index 29b2c2f..5e137f1 100644 --- a/src/lib/Client/DaprClient.php +++ b/src/lib/Client/DaprClient.php @@ -444,6 +444,20 @@ abstract public function getBulkSecret(string $storeName, array $metadata = []): */ abstract public function isDaprHealthy(): bool; + /** + * Retrieve metadata from the sidecar + * + * @return MetadataResponse + */ + abstract public function getMetadata(): MetadataResponse|null; + + /** + * Shutdown the Daprd sidecar + * + * @param bool $afterRequest If true, schedules a php shutdown function, otherwise fires the request immediately. + */ + abstract public function shutdown(bool $afterRequest = true): void; + /** * @param string $token * @return null|array{dapr-api-token: string} diff --git a/src/lib/Client/DaprHttpClient.php b/src/lib/Client/DaprHttpClient.php index 3b43205..eca7a6f 100644 --- a/src/lib/Client/DaprHttpClient.php +++ b/src/lib/Client/DaprHttpClient.php @@ -4,7 +4,6 @@ use Dapr\Deserialization\IDeserializer; use Dapr\Serialization\ISerializer; -use Dapr\State\StateItem; use GuzzleHttp\Client; use Psr\Log\LoggerInterface; @@ -49,7 +48,7 @@ public function isDaprHealthy(): bool { try { $result = $this->httpClient->get('/v1.0/healthz'); - if (200 === $result->getStatusCode()) { + if (204 === $result->getStatusCode()) { return true; } return false; @@ -57,4 +56,25 @@ public function isDaprHealthy(): bool return false; } } + + public function getMetadata(): MetadataResponse|null + { + try { + $result = $this->httpClient->get('/v1.0/metadata'); + return $this->deserializer->from_json(MetadataResponse::class, $result->getBody()->getContents()); + } catch (\Throwable $exception) { + return null; + } + } + + public function shutdown(bool $afterRequest = true): void + { + $shutdown = fn() => $this->httpClient->post('/v1.0/shutdown'); + if ($afterRequest) { + register_shutdown_function($shutdown); + return; + } + + $shutdown(); + } } diff --git a/src/lib/Client/MetadataResponse.php b/src/lib/Client/MetadataResponse.php new file mode 100644 index 0000000..1502898 --- /dev/null +++ b/src/lib/Client/MetadataResponse.php @@ -0,0 +1,47 @@ +get_http_client_stack( [ - new Response(200) + new Response(204) ] ); $client = $this->get_new_client_with_http($container->client); diff --git a/tests/MetadataTest.php b/tests/MetadataTest.php new file mode 100644 index 0000000..1a953b6 --- /dev/null +++ b/tests/MetadataTest.php @@ -0,0 +1,55 @@ +get_http_client_stack( + [ + new \GuzzleHttp\Psr7\Response( + 200, body: json_encode( + [ + 'id' => 'demo-actor', + 'actors' => [ + [ + 'type' => 'DemoActor', + 'count' => 1 + ] + ], + 'extended' => [ + 'cliPID' => '12301823', + 'appCommand' => 'uvicorn --port 3000 demo_actor_service:app' + ], + 'components' => [ + [ + 'name' => 'pubsub', + 'type' => 'pubsub.redis', + 'version' => '' + ] + ] + ] + ) + ) + ] + ); + $client = $this->get_new_client_with_http($stack->client); + $result = $client->getMetadata(); + $this->assertEquals( + new \Dapr\Client\MetadataResponse( + 'demo-actor', + [new \Dapr\Client\RegisteredActor('DemoActor', 1)], + [ + 'cliPID' => '12301823', + 'appCommand' => 'uvicorn --port 3000 demo_actor_service:app' + ], + [new \Dapr\Client\RegisteredComponent('pubsub', 'pubsub.redis', '')] + ), + $result + ); + } +}