Skip to content

Commit

Permalink
[6.x] DynamoDB in CI suite (#36749)
Browse files Browse the repository at this point in the history
* Set up DynamoDB testing

* env variable

* Random AWS keys

* AWS endpoint

* try different port

* Try localhost

* Dynamically create table

* Add provider

* uppercase

* KeySchema

* Update table

* Apply fixes from StyleCI (#36746)

* throughput

* exception message

* Switch env statement

* Remove directory
  • Loading branch information
driesvints authored Mar 25, 2021
1 parent ab703aa commit 5be0afe
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 25 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,20 @@ jobs:
max_attempts: 5
command: composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress

- name: Setup DynamoDB Local
uses: rrainn/dynamodb-action@v2.0.0
with:
port: 8888

- name: Execute tests
run: vendor/bin/phpunit --verbose
env:
DB_PORT: ${{ job.services.mysql.ports[3306] }}
DB_USERNAME: root
DYNAMODB_CACHE_TABLE: laravel_dynamodb_test
DYNAMODB_ENDPOINT: "http://localhost:8888"
AWS_ACCESS_KEY_ID: random_key
AWS_SECRET_ACCESS_KEY: random_secret

windows_tests:
runs-on: windows-latest
Expand Down
16 changes: 1 addition & 15 deletions src/Illuminate/Cache/CacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

namespace Illuminate\Cache;

use Aws\DynamoDb\DynamoDbClient;
use Closure;
use Illuminate\Contracts\Cache\Factory as FactoryContract;
use Illuminate\Contracts\Cache\Store;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Support\Arr;
use InvalidArgumentException;

/**
Expand Down Expand Up @@ -226,21 +224,9 @@ protected function createDatabaseDriver(array $config)
*/
protected function createDynamodbDriver(array $config)
{
$dynamoConfig = [
'region' => $config['region'],
'version' => 'latest',
'endpoint' => $config['endpoint'] ?? null,
];

if ($config['key'] && $config['secret']) {
$dynamoConfig['credentials'] = Arr::only(
$config, ['key', 'secret', 'token']
);
}

return $this->repository(
new DynamoDbStore(
new DynamoDbClient($dynamoConfig),
$this->app['cache.dynamodb.client'],
$config['table'],
$config['attributes']['key'] ?? 'key',
$config['attributes']['value'] ?? 'value',
Expand Down
17 changes: 16 additions & 1 deletion src/Illuminate/Cache/CacheServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Illuminate\Cache;

use Aws\DynamoDb\DynamoDbClient;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Cache\Adapter\Psr16Adapter;

Expand Down Expand Up @@ -30,6 +32,19 @@ public function register()
$this->app->singleton('memcached.connector', function () {
return new MemcachedConnector;
});

$this->app->singleton('cache.dynamodb.client', function ($app) {
$config = $app['config']->get('cache.stores.dynamodb');

return new DynamoDbClient([
'region' => $config['region'],
'version' => 'latest',
'endpoint' => $config['endpoint'] ?? null,
'credentials' => Arr::only(
$config, ['key', 'secret', 'token']
),
]);
});
}

/**
Expand All @@ -40,7 +55,7 @@ public function register()
public function provides()
{
return [
'cache', 'cache.store', 'cache.psr6', 'memcached.connector',
'cache', 'cache.store', 'cache.psr6', 'memcached.connector', 'cache.dynamodb.client',
];
}
}
68 changes: 59 additions & 9 deletions tests/Integration/Cache/DynamoDbStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Illuminate\Tests\Integration\Cache;

use Aws\DynamoDb\DynamoDbClient;
use Aws\Exception\AwsException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Orchestra\Testbench\TestCase;
Expand All @@ -13,11 +15,11 @@ class DynamoDbStoreTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();

if (! env('DYNAMODB_CACHE_TABLE')) {
$this->markTestSkipped('DynamoDB not configured.');
}

parent::setUp();
}

public function testItemsCanBeStoredAndRetrieved()
Expand Down Expand Up @@ -74,15 +76,63 @@ public function testLocksCanBeAcquired()
*/
protected function getEnvironmentSetUp($app)
{
if (! env('DYNAMODB_CACHE_TABLE')) {
$this->markTestSkipped('DynamoDB not configured.');
}

$app['config']->set('cache.default', 'dynamodb');

$app['config']->set('cache.stores.dynamodb', [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => 'us-east-1',
'table' => env('DYNAMODB_CACHE_TABLE', 'laravel_test'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
$config = $app['config']->get('cache.stores.dynamodb');

/** @var \Aws\DynamoDb\DynamoDbClient $client */
$client = $app['cache.dynamodb.client'];

if ($this->dynamoTableExists($client, $config['table'])) {
return;
}

$client->createTable([
'TableName' => $config['table'],
'KeySchema' => [
[
'AttributeName' => $config['attributes']['key'] ?? 'key',
'KeyType' => 'HASH',
],
],
'AttributeDefinitions' => [
[
'AttributeName' => $config['attributes']['key'] ?? 'key',
'AttributeType' => 'S',
],
],
'ProvisionedThroughput' => [
'ReadCapacityUnits' => 1,
'WriteCapacityUnits' => 1,
],
]);
}

/**
* Determine if the given DynamoDB table exists.
*
* @param \Aws\DynamoDb\DynamoDbClient $client
* @param string $table
* @return bool
*/
public function dynamoTableExists(DynamoDbClient $client, $table)
{
try {
$client->describeTable([
'TableName' => $table,
]);

return true;
} catch (AwsException $e) {
if (Str::contains($e->getAwsErrorMessage(), ['resource not found', 'Cannot do operations on a non-existent table'])) {
return false;
}

throw $e;
}
}
}

0 comments on commit 5be0afe

Please sign in to comment.