Skip to content

Cloudfront Integration Tests#4440

Merged
wjordan merged 6 commits into
cdo-cloudfrontfrom
cloudfront-tests-ngrok
Oct 9, 2015
Merged

Cloudfront Integration Tests#4440
wjordan merged 6 commits into
cdo-cloudfrontfrom
cloudfront-tests-ngrok

Conversation

@wjordan

@wjordan wjordan commented Oct 8, 2015

Copy link
Copy Markdown
Contributor

This addon-PR adds CloudFront integration tests to the cdo-cloudfront work (PR #4207). It adds a new cdo-varnish Test Kitchen test suite cloudfront that uses substantially the same test suite currently running against Varnish, with a few differences:

  • Runs ngrok to tunnel localhost:80 to cdo.ngrok.io, exposing the Varnish server at the public endpoint.
  • Requires a deployed CloudFront distribution at https://integration-studio.code.org, using cdo.ngrok.io as its origin server.
  • Runs a suite of http-cache tests against the CloudFront distribution, checking for X-Cache: [Miss|Hit] from cloudfront headers instead of the X-Varnish-Cache: [Miss|Hit] headers returned by Varnish.
  • Two key differences in support functionality between Varnish and CloudFront are noted in comments, and the related tests are skipped:
    • Language-header normalization (Varnish contains functionality to normalize the Accept-Language header based on available languages, so Accept-Language: fr and Accept-Language: da, x-random;q=0.8, fr;q=0.7 would return the same cached response)
    • Our Varnish config will avoid stripping cookies from uncached PUT or POST requests despite the path-based config not whitelisting those cookies whitelisted, but this behavior is not supported by CloudFront.

A successful CircleCI integration test run can be found here. I've added the NGROK_TOKEN environment variable to the CircleCI configuration in order to configure the ngrok tunnel correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like mock.jar is written by a chef recipe. Is this integration test something that can only be run on chef-manage instances (i.e. not my laptop?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a little unusual to drop a file in ~ and run it from there; will this work in all of the test running environments that we might care about?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. The integration test can run on your laptop, if Test Kitchen and Docker are installed locally. I've documented this in cdo-varnish/README.md:

Running Tests

The integration tests run using Test Kitchen.
See test/cookbooks/varnish_test/README.md for more details.

To test the cookbook, first make sure Docker is installed and running locally,
then run:

  • chef exec kitchen create to create the machine image
  • chef exec kitchen converge to install Chef and converge the cookbook in the
    platform environment
  • chef exec kitchen verify to run the integration test suite

I can clarify this documentation to add that test-kitchen, kitchen-docker and berkshelf all need to be available to the Ruby environment (either installed globally via gem install test-kitchen, provided by Bundler through the provided Gemfile after a bundle install via bundle exec kitchen, or provided by ChefDK via chef exec kitchen).

  1. This will only work in the provisioned, isolated environment created by Test Kitchen. The actual test_default.rb code is run within the environment via Busser using the busser-minitest runner plugin, after the cookbooks and runlists specified in .kitchen.yml have been applied to the environment. This is all described in the Test Kitchen documentation.

Let me know if you have any suggestions on how to clarify any of these points within the documentation here.

@philbogle

Copy link
Copy Markdown
Contributor

My big top-level comment is that as an integration test this should test the integrated CloudFront + Varnish system we have in production, rather than testing them in isolation (e.g. CloudFront without Varnish). This would also let you test some of the functionality that is provided by Varnish but not Cloudfront like the language normalization. (Speaking of which: I would really like to see hard data on the language header diversity.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be restored if the test is changed to hit CloudFront + Varnish.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test will succeed on a CloudFront + Varnish request only if we check the Varnish X-Varnish-Cache header for Hit, rather than the CloudFront X-Cache one. To distinguish this test as specifically checking the Varnish cache header, I'll add a new method assert_varnish_cache.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds fine. Or you could have a generic cache method that is happy
if either varnish or cloudfront gets a hit. (That way, if we make
CloudFront smarter down the road, the test doesn't break needlessly, since
we're still getting the desired hit.)

On Thu, Oct 8, 2015 at 4:53 PM, Will Jordan notifications@github.com
wrote:

In
cookbooks/cdo-varnish/test/integration/cloudfront/minitest/test_default.rb
#4440 (comment)
:

  • assert_miss response
  • assert_equal text_en, last_line(response)
  • Ensure that Vary response header is de-normalized

  • assert_nil /X-Varnish-Accept-Language/.match(response)
  • refute_nil /Accept-Language/.match(response)
  • assert_hit proxy_request url, en
  • Ensure that language is separately cached

  • fr = {'Accept-Language' => 'fr'}
  • response = proxy_request url, fr
  • assert_miss response
  • assert_equal text_fr, last_line(response)
  • assert_hit proxy_request url, fr
  • Language-header normalization not implemented in CloudFront.

This test will succeed on a CloudFront + Varnish request only if we check
the Varnish X-Varnish-Cache header for Hit, rather than the CloudFront
X-Cache one. To distinguish this test as specifically checking the
Varnish cache header, I'll add a new method assert_varnish_cache.


Reply to this email directly or view it on GitHub
https://github.com/code-dot-org/code-dot-org/pull/4440/files#r41584705.

@philbogle

Copy link
Copy Markdown
Contributor

Done with my first pass. Thanks for doing this; it will be very valuable to have tests for this.

@wjordan

wjordan commented Oct 8, 2015

Copy link
Copy Markdown
Contributor Author

Just to clarify, this cloudfront test suite does run tests on an integrated CloudFront + Varnish infrastructure, none of the tests currently run against CloudFront in isolation without the Varnish layer (though we could add that as a third test suite if desired, if we ever wanted to consider a CloudFront-only cache configuration in the future).

@wjordan

wjordan commented Oct 8, 2015

Copy link
Copy Markdown
Contributor Author

However, I've separated the tests so that the cloudfront suite only checks the Cloudfront caching headers, while the default suite only checks the Varnish caching headers. In my next refactoring pass I can update some of the tests in cloudfront to check both layers at the same time for the two cases that CloudFront doesn't handle, if that would make the actual production behavior more clear.

@philbogle

Copy link
Copy Markdown
Contributor

Looking at the tests which are currently skipped, it seems like they don't
really depend on Varnish vs. Cloudfront doing the (e.g.) cookie stripping
or https redirection, so can we not enable those now?

On Thu, Oct 8, 2015 at 3:15 PM, Will Jordan notifications@github.com
wrote:

However, I've separated the tests so that the cloudfront suite only
checks the Cloudfront caching headers, while the default suite only
checks the Varnish caching headers. In my next refactoring pass I can
update some of the tests in cloudfront to check both layers at the same
time for the two cases that CloudFront doesn't handle, if that would make
the actual production behavior more clear.


Reply to this email directly or view it on GitHub
#4440 (comment)
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants