Skip to content

Commit

Permalink
Use Rust FFI: Provider
Browse files Browse the repository at this point in the history
  • Loading branch information
tienvx committed May 5, 2023
1 parent 8e5fc21 commit 7b21436
Show file tree
Hide file tree
Showing 58 changed files with 1,667 additions and 1,793 deletions.
147 changes: 56 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Table of contents
- [Start API](#start-api)
- [Provider Verification](#provider-verification)
- [Verify From Pact Broker](#verify-from-pact-broker)
- [Verify All from Pact Broker](#verify-all-from-pact-broker)
- [Verify Files in Directory](#verify-files-in-directory)
- [Verify Files by Path](#verify-files-by-path)
- [Tips](#tips)
- [Starting API Asynchronously](#starting-api-asynchronously)
Expand Down Expand Up @@ -229,51 +229,57 @@ $config = new VerifierConfig();
$config
->setProviderName('someProvider') // Providers name to fetch.
->setProviderVersion('1.0.0') // Providers version.
->setProviderBranch('main') // Providers git branch name.
->setProviderBaseUrl(new Uri('http://localhost:58000')) // URL of the Provider.
->setBrokerUri(new Uri('http://localhost')) // URL of the Pact Broker to publish results.
->setPublishResults(true) // Flag the verifier service to publish the results to the Pact Broker.
->setProcessTimeout(60) // Set process timeout (optional) - default 60
->setProcessIdleTimeout(10) // Set process idle timeout (optional) - default 10
->setEnablePending(true) // Flag to enable pending pacts feature (check pact docs for further info)
->setIncludeWipPactSince('2020-01-30') //Start date of WIP Pacts (check pact docs for further info)
->setRequestFilter(
function (RequestInterface $r) {
return $r->withHeader('MY_SPECIAL_HEADER', 'my special value');
}
);
// Verify that the Consumer 'someConsumer' that is tagged with 'master' is valid.
->setProviderTags('prod' ,'dev')
->setProviderBranch('main')
->setScheme('http')
->setHost('localhost')
->setPort(58000)
->setBasePath('/')
->setStateChangeUrl(new Uri('http://localhost:58000/change-state'))
->setBuildUrl(new Uri('http://build.domain.com'))
->setFilterConsumerNames('someConsumer', 'otherConsumer')
->setFilterDescription('Send POST to create')
->setFilterNoState(true)
->setFilterState('state')
->setPublishResults(true)
->setDisableSslVerification(true)
->setStateChangeAsBody(false)
->setStateChangeTeardown(true)
->setRequestTimeout(500);

$verifier = new Verifier($config);
$verifier->verify('someConsumer', 'master'); // The tag is option. If no tag is set it will just grab the latest.

// This will not be reached if the PACT verifier throws an error, otherwise it was successful.
$this->assertTrue(true, 'Pact Verification has failed.');
$selectors = (new ConsumerVersionSelectors())
->addSelector('{"tag":"foo","latest":true}')
->addSelector('{"tag":"bar","latest":true}');

$broker = new Broker();
$broker
->setUrl(new Uri('http://localhost'))
->setUsername('user')
->setPassword('pass')
->setToken('token')
->setEnablePending(true)
->setIncludeWipPactSince('2020-01-30')
->setProviderTags(['prod'])
->setProviderBranch('main')
->setConsumerVersionSelectors($selectors)
->setConsumerVersionTags(['dev']);

$verifier->addBroker($broker);

$this->assertTrue($verifier->verify());
```

##### Verify All from Pact Broker
##### Verify Files in Directory

This will grab every Pact file associated with the given provider.
This allows local Pact file testing.

```php
public function testPactVerifyAll()
public function testPactVerifyFilesInDirectory()
{
$config = new VerifierConfig();
$config
->setProviderName('someProvider') // Providers name to fetch.
->setProviderVersion('1.0.0') // Providers version.
->setProviderBranch('main') // Providers git branch name.
->setProviderBaseUrl(new Uri('http://localhost:58000')) // URL of the Provider.
->setBrokerUri(new Uri('http://localhost')) // URL of the Pact Broker to publish results.
->setPublishResults(true) // Flag the verifier service to publish the results to the Pact Broker.
->setEnablePending(true) // Flag to enable pending pacts feature (check pact docs for further info)
->setIncludeWipPactSince('2020-01-30') //Start date of WIP Pacts (check pact docs for further info)

// Verify that all consumers of 'someProvider' are valid.
$verifier = new Verifier($config);
$verifier->verifyAll();

// This will not be reached if the PACT verifier throws an error, otherwise it was successful.
$this->assertTrue(true, 'Pact Verification has failed.');
$verifier->addDirectory('C:\SomePath');
$this->assertTrue($verifier->verify());
}
```

Expand All @@ -282,25 +288,10 @@ public function testPactVerifyAll()
This allows local Pact file testing.

```php
public function testPactVerifyAll()
public function testPactVerifyFiles()
{
$config = new VerifierConfig();
$config
->setProviderName('someProvider') // Providers name to fetch.
->setProviderVersion('1.0.0') // Providers version.
->setProviderBranch('main') // Providers git branch name.
->setProviderBaseUrl(new Uri('http://localhost:58000')) // URL of the Provider.
->setBrokerUri(new Uri('http://localhost')) // URL of the Pact Broker to publish results.
->setPublishResults(true); // Flag the verifier service to publish the results to the Pact Broker.
->setEnablePending(true) // Flag to enable pending pacts feature (check pact docs for further info)
->setIncludeWipPactSince('2020-01-30') //Start date of WIP Pacts (check pact docs for further info)

// Verify that the files in the array are valid.
$verifier = new Verifier($config);
$verifier->verifyFiles(['C:\SomePath\consumer-provider.json']);

// This will not be reached if the PACT verifier throws an error, otherwise it was successful.
$this->assertTrue(true, 'Pact Verification has failed.');
$verifier->addFile('C:\SomePath\consumer-provider.json');
$this->assertTrue($verifier->verify());
}
```

Expand Down Expand Up @@ -332,7 +323,6 @@ There is a separate repository with an end to end example for both the 2.X and 3
- [2.2.1 tag](https://github.com/mattermack/pact-php-example/tree/2.2.1) for 2.X examples

## Message support
This feature is preliminary as the Pact community as a whole is flushing this out.
The goal is not to test the transmission of an object over a bus but instead vet the contents of the message.
While examples included focus on a Rabbit MQ, the exact message queue is irrelevant. Initial comparisons require a certain
object type to be created by the Publisher/Producer and the Consumer of the message. This includes a metadata set where you
Expand Down Expand Up @@ -377,42 +367,17 @@ $this->assertTrue($builder->verify());


### Provider Side Message Validation
This may evolve as we work through this implementation. The provider relies heavily on callbacks.
Some of the complexity lies in a consumer and provider having many messages and states between the each other in a single pact.

For each message, one needs to provide a single provider state. The name of this provider state must be the key to run
a particular message callback on the provider side. See example\tests\MessageProvider

1. Create your callbacks and states wrapped in a callable object
1. The array key is a provider state / given() on the consumer side
1. It is helpful to wrap the whole thing in a lambda if you need to customize paramaters to be passed in
1. Choose your verification method
1. If nothing explodes, #winning

```php
Handle these requests on provider's proxy:

$callbacks = array();
1. POST /change-state
1. Set up your database to meet the expectations of the request
2. Reset the database to its original state.
2. POST /
1. Return message's content in body
2. Return message's metadata in header `PACT-MESSAGE-METADATA`
3. Proxy to provider app on other requests

// a hello message is a provider state / given() on the consumer side
$callbacks["a hello message"] = function() {
$content = new \stdClass();
$content->text ="Hello Mary";

$metadata = array();
$metadata['queue'] = "myKey";

$provider = (new ExampleMessageProvider())
->setContents($content)
->setMetadata($metadata);

return $provider->Build();
};

$verifier = (new MessageVerifier($config))
->setCallbacks($callbacks)
->verifyFiles([__DIR__ . '/../../output/test_consumer-test_provider.json']);

```
[Click here](/example/src/Provider/public/proxy.php) to see the full sample file.

## Usage for the optional `pact-stub-service`

Expand Down
42 changes: 42 additions & 0 deletions UPGRADE-9.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,45 @@ UPGRADE FROM 8.x to 9.0
* PACT_CORS
* PACT_MOCK_SERVER_HEALTH_CHECK_TIMEOUT
* PACT_MOCK_SERVER_HEALTH_CHECK_RETRY_SEC

* Verifier
* Different pacts sources can be configured via `addXxx` methods

Example Usage:
```php
$config = new VerifierConfig();
$config
->setPort(8000)
->setProviderName('someProvider')
->setProviderVersion('1.0.0');

$url = new Url();
$url
->setUrl(new Uri('http://localhost'))
->setProviderName('someProvider')
->setUsername('user')
->setPassword('pass')
->setToken('token');

$selectors = (new ConsumerVersionSelectors())
->addSelector('{"tag":"foo","latest":true}')
->addSelector('{"tag":"bar","latest":true}');

$broker = new Broker();
$broker
->setUrl(new Uri('http://localhost'))
->setProviderName('someProvider')
->setUsername('user')
->setPassword('pass')
->setToken('token')
->setConsumerVersionSelectors($selectors);

$verifier = new Verifier($config);
$verifier
->addFile('C:\SomePath\consumer-provider.json');
->addDirectory('C:\OtherPath');
->addUrl($url);
->addBroker($broker);

$this->assertTrue($verifier->verify());
```
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
},
"require-dev": {
"roave/security-advisories": "dev-latest",
"mockery/mockery": "^1.4.2",
"slim/slim": "^4.6",
"slim/psr7": "^1.2.0",
"friendsofphp/php-cs-fixer": "^3.0",
Expand All @@ -66,11 +65,14 @@
"MessageProvider\\": [
"example/src/MessageProvider",
"example/tests/MessageProvider"
],
"Provider\\": [
"example/src/Provider"
]
}
},
"scripts": {
"start-provider": "php -S localhost:58000 -t example/src/Provider/public/",
"start-provider": "php -S localhost:58000 -t example/src/Provider/public/ example/src/Provider/public/proxy.php",
"static-code-analysis": "phpstan",
"lint": "php-cs-fixer fix --dry-run",
"fix": "php-cs-fixer fix",
Expand Down
4 changes: 0 additions & 4 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ All examples could be run within tests.
## Consumer Tests for Message Processing

vendor/bin/phpunit -c example/phpunit.message.consumer.xml

## Provider Verification Tests for Message Processing

vendor/bin/phpunit -c example/phpunit.message.provider.xml

## All tests together

Expand Down
2 changes: 1 addition & 1 deletion example/pacts/someconsumer-someprovider.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"matchingRules": {
"$.body.message": {
"match": "regex",
"regex": "(Hello, )[A-Za-z]"
"regex": "(Hello, )[A-Za-z]+"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion example/pacts/test_consumer-test_provider.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
"version": "3.0.0"
}
}
}
3 changes: 0 additions & 3 deletions example/phpunit.all.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
<testsuite name="PhpPact Message Consumer Example Tests">
<directory>./tests/MessageConsumer</directory>
</testsuite>
<testsuite name="PhpPact Message Provider Example Tests">
<directory>./tests/MessageProvider</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="PhpPact\Consumer\Listener\PactTestListener">
Expand Down
8 changes: 0 additions & 8 deletions example/phpunit.message.provider.xml

This file was deleted.

16 changes: 0 additions & 16 deletions example/src/Consumer/publish_json_example.php

This file was deleted.

12 changes: 6 additions & 6 deletions example/src/MessageProvider/ExampleMessageProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
class ExampleMessageProvider
{
/** @var array */
private $metadata;
private array $metadata;

/**
* @var mixed
*/
private $contents;
private mixed $contents;

public function __construct($metadata = [])
public function __construct(array $metadata = [])
{
$this->metadata = $metadata;
}
Expand Down Expand Up @@ -40,7 +40,7 @@ public function setMetadata(array $metadata): self
/**
* @return mixed
*/
public function getContents()
public function getContents(): mixed
{
return $this->contents;
}
Expand All @@ -50,7 +50,7 @@ public function getContents()
*
* @return ExampleMessageProvider
*/
public function setContents($contents)
public function setContents(mixed $contents): self
{
$this->contents = $contents;

Expand All @@ -62,7 +62,7 @@ public function setContents($contents)
*
* @return string
*/
public function Build()
public function Build(): string
{
$obj = new \stdClass();
$obj->metadata = $this->metadata;
Expand Down
Loading

0 comments on commit 7b21436

Please sign in to comment.