Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Commit

Permalink
Locking test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kleijnweb committed Feb 21, 2016
1 parent 2190dd4 commit d2552d8
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 35 deletions.
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -38,7 +38,8 @@ The query part of the URL is treated as the last path segment:

The default child invalidation constraint is a negated regular expression: `\/[0-9]+$`. This means a POST to `/animals/rabbits` will by default not invalidate `/animals/rabbits/1` or any paths below it, but will invalidate `/animals/rabbits/findByName`.

NOTE: The store and retrieve calls are not yet fully optimized and get pretty chatty when using network based caches. You can probably expect best performance from APCu. It won't use that much memory.
*NOTE:* When concurrency control is turned on, you cannot POST to without the correct E-Tag either.
*NOTE:* The store and retrieve calls are not yet fully optimized and get pretty chatty when using network based caches. You can probably expect best performance from APCu. It won't use that much memory.

## Install And Configure

Expand All @@ -50,6 +51,7 @@ Concurrency control is enabled by default. To disable:
rest_e_tags:
concurrency_control: false
```

The bundle will work with any Doctrine cache. Use the 'cache' config option to reference the service to be used:

```yml
Expand Down
5 changes: 5 additions & 0 deletions src/EventListener/ResponseListener.php
Expand Up @@ -38,7 +38,12 @@ public function onKernelResponse(FilterResponseEvent $event)
return;
}
$request = $event->getRequest();

$response = $event->getResponse();
if (substr((string)$response->getStatusCode(), 0, 1) !== '2') {
// TODO UT this
return;
}

if (RequestListener::isModifyingMethodRequest($request)) {
$version = $this->cacheAdapter->update($request, (string)microtime(true));
Expand Down
70 changes: 36 additions & 34 deletions src/Tests/Functional/FunctionalTest.php
Expand Up @@ -46,46 +46,15 @@ public function willReturnNotModifiedResponseWhenUsingETag()
*/
public function willInvalidateWhenPostingToParent()
{
$client = self::createClient();
$client->disableReboot();
$childUrl = '/foo/bar/doh';
$client->request('GET', $childUrl);
$response = $client->getResponse();
$originalEtag = $response->getEtag();
$this->assertNotEmpty($originalEtag);

// Sanity check
$client->request('GET', $childUrl, [], [], ['HTTP_IF_NONE_MATCH' => $originalEtag]);
$response = $client->getResponse();
$this->assertSame(Response::HTTP_NOT_MODIFIED, $response->getStatusCode());

// Validate that when we post to what should be the parent, the resource is marked as modified
$client->request('POST', '/foo/bar');
$client->request('GET', $childUrl, [], [], ['HTTP_IF_NONE_MATCH' => $originalEtag]);
$this->assertNotSame(Response::HTTP_NOT_MODIFIED, $response->getStatusCode());
$this->assertWillInvalidateWhenPostingToParent('/foo/bar', '/foo/bar/doh');
}

/**
* @test
*/
public function willTreatQueryAsASegment()
{
$client = self::createClient();
$client->disableReboot();
$client->request('GET', '/foo/bar?doh=1');
$response = $client->getResponse();
$originalEtag = $response->getEtag();
$this->assertNotEmpty($originalEtag);

// Sanity check
$client->request('GET', '/foo/bar?doh=1', [], [], ['HTTP_IF_NONE_MATCH' => $originalEtag]);
$response = $client->getResponse();
$this->assertSame(Response::HTTP_NOT_MODIFIED, $response->getStatusCode());

// Validate that when we post to what should be the parent, the resource is marked as modified
$client->request('POST', '/foo/bar');
$client->request('GET', '/foo/bar?doh=1', [], [], ['HTTP_IF_NONE_MATCH' => $originalEtag]);
$this->assertNotSame(Response::HTTP_NOT_MODIFIED, $response->getStatusCode());
$this->assertWillInvalidateWhenPostingToParent('/foo/bar', '/foo/bar?doh=1');
}

/**
Expand All @@ -112,8 +81,41 @@ public function willDoResourceLocking()
$client->disableReboot();
$client->request('POST', '/foo/bar');
$staleETag = (string)$client->getResponse()->getEtag();
$client->request('POST', '/foo/bar');
$client->request('POST', '/foo/bar', [], [], ['HTTP_IF_MATCH' => $staleETag]);
$this->assertSame(Response::HTTP_OK, $client->getResponse()->getStatusCode());
$client->request('POST', '/foo/bar', [], [], ['HTTP_IF_MATCH' => $staleETag]);
$this->assertSame(Response::HTTP_PRECONDITION_FAILED, $client->getResponse()->getStatusCode());
}

/**
* @param string $parentUrl
* @param string $childUrl
*/
public function assertWillInvalidateWhenPostingToParent($parentUrl, $childUrl)
{
$client = self::createClient();
$client->disableReboot();
$client->request('GET', $childUrl);
$response = $client->getResponse();
$originalEtag = $response->getEtag();
$this->assertNotEmpty($originalEtag);

// Sanity check
$client->request('GET', $childUrl, [], [], ['HTTP_IF_NONE_MATCH' => $originalEtag]);
$response = $client->getResponse();
$this->assertSame(Response::HTTP_NOT_MODIFIED, $response->getStatusCode());

// Validate that when we post to what should be the parent, the resource is marked as modified
// Strict concurrency control is turned on, so we always need to pass the current E-Tag.
// Since we just registered a child path, the correct key is the same
$client->request('POST', $parentUrl, [], [], ['HTTP_IF_MATCH' => $originalEtag]);

// Sanity check
$response = $client->getResponse();
$this->assertSame(Response::HTTP_OK, $response->getStatusCode());

// Now validate the child is re-evaluated
$client->request('GET', $childUrl, [], [], ['HTTP_IF_NONE_MATCH' => $originalEtag]);
$this->assertSame(Response::HTTP_OK, $response->getStatusCode());
}
}

0 comments on commit d2552d8

Please sign in to comment.