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 8, 2023
1 parent bf7830d commit d73729a
Show file tree
Hide file tree
Showing 59 changed files with 1,659 additions and 1,824 deletions.
159 changes: 67 additions & 92 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 @@ -230,51 +230,62 @@ $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);

$verifyResult = $verifier->verify();

$this->assertTrue($verifyResult);
```

##### 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');

$verifyResult = $verifier->verify();

$this->assertTrue($verifyResult);
}
```

Expand All @@ -283,25 +294,13 @@ 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');

$verifyResult = $verifier->verify();

$this->assertTrue($verifyResult);
}
```

Expand Down Expand Up @@ -333,7 +332,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 @@ -373,47 +371,24 @@ $consumerMessage = new ExampleMessageConsumer();
$callback = [$consumerMessage, 'ProcessSong'];
$builder->setCallback($callback);

$this->assertTrue($builder->verify());
$verifyResult = $verifier->verify();

$this->assertTrue($verifyResult);
```


### 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

$callbacks = array();
Handle these requests on provider's proxy:

// a hello message is a provider state / given() on the consumer side
$callbacks["a hello message"] = function() {
$content = new \stdClass();
$content->text ="Hello Mary";
1. POST /pact-change-state
1. Set up your database to meet the expectations of the request
2. Reset the database to its original state.
2. POST /pact-messages
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

$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
44 changes: 44 additions & 0 deletions UPGRADE-9.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,47 @@ 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);

$verifyResult = $verifier->verify();

$this->assertTrue($verifyResult);
```
14 changes: 4 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,14 @@
"composer/semver": "^1.4.0|^3.2.0",
"amphp/amp": "^2.5.1",
"amphp/byte-stream": "^1.8",
"amphp/dns": "^1.2.3",
"amphp/hpack": "^3.1.0",
"amphp/http-server": "^2.1",
"amphp/log": "^1.1",
"amphp/process": "^1.1.1",
"amphp/serialization": "^1.0",
"amphp/socket": "^1.1.3",
"amphp/sync": "^1.4.0",
"amphp/cache": "^1.4.0",
"amphp/windows-registry": "v0.3.3",
"guzzlehttp/guzzle": "^6.5.8|^7.4.5",
"phpunit/phpunit": ">=8.5.23 <10",
"tienvx/composer-downloads-plugin": "^1.1.0"
},
"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 +57,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.

Loading

0 comments on commit d73729a

Please sign in to comment.