Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 8 additions & 12 deletions examples/cloud/failureToMatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,14 @@
// Next we build the pipeline. We could additionally add extra engines and/or
// flowElements here before building.

// To stop having to construct the pipeline
// and re-make cloud API requests used during construction on every page load,
// we recommend caching the serialized pipeline to a database or disk.
// Below we are using PHP's serialize and writing to a file if it doesn't exist

$serializedPipelineFile = __DIR__ . "failure_to_match_pipeline.pipeline";
if(!file_exists($serializedPipelineFile)){
$pipeline = $builder->build();
file_put_contents($serializedPipelineFile, serialize($pipeline));
} else {
$pipeline = unserialize(file_get_contents($serializedPipelineFile));
}
// A site keeps the pipeline for the life of the process, or serializes it,
// so that the cloud requests made while it is built are not made on every
// page load. Anything kept that way has to be thrown away when the resource
// key changes, because a pipeline carries the properties of the key it was
// built with. This example builds it on every run, so the answer always
// belongs to the key the example was given.

$pipeline = $builder->build();

// Here we create a function that checks if a supplied User-Agent is a
// mobile device
Expand Down
83 changes: 83 additions & 0 deletions tests/ExampleTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,89 @@ static function ($line) { return strpos($line, "\t") === 0; }
}
}

/**
* The failure to match example is a script rather than a class, so it
* is run as its own process.
*
* It used to keep the pipeline it built in a file beside the examples
* and reuse it on the next run, so a run with one resource key answered
* with the properties of whichever key had run first. The file name was
* also built without a separator, so it landed outside the folder the
* example lives in. The example builds its pipeline on every run now,
* and this checks that it answers and leaves nothing behind.
*/
public function testFailureToMatchLeavesNoPipelineBehind()
{
$key = $this->getResourceKey();
$examples = __DIR__ . '/../examples';

foreach ($this->pipelineFilesUnder($examples) as $stale) {
unlink($stale);
}

$output = $this->runScript(
$examples . '/cloud/failureToMatch.php',
$key
);

$this->assertStringContainsString(
'represent a mobile device',
$output
);

$this->assertSame(
[],
$this->pipelineFilesUnder($examples),
'The example left a serialized pipeline behind, and the next run '
. 'would answer from whatever resource key wrote it'
);
}

/**
* Runs a PHP script with the resource key in its environment and
* returns everything it wrote.
*/
private function runScript(string $script, string $key): string
{
$environment = getenv();
$environment[Constants::RESOURCE_ENV_VAR] = $key;

$process = proc_open(
[PHP_BINARY, $script],
[1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
$pipes,
null,
$environment
);
$this->assertIsResource($process, 'Could not start ' . $script);

$output = stream_get_contents($pipes[1])
. stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

return $output;
}

/**
* Every serialized pipeline file in the examples folder, in the folders
* below it, and beside it, because a name built without a separator
* lands beside the folder rather than in it.
*
* @return string[]
*/
private function pipelineFilesUnder(string $folder): array
{
$found = array_merge(
(array) glob($folder . '/*.pipeline'),
(array) glob($folder . '/*/*.pipeline'),
(array) glob(dirname($folder) . '/*.pipeline')
);

return array_values(array_filter($found, 'is_file'));
}

private function getResourceKey()
{
$resourceKey = ResourceKeys::find(Constants::RESOURCE_ENV_VAR);
Expand Down
Loading