presents
Testing with Fastly
Workshop
Cassandra Dixon, Fastly
Leon Brocard, Fastly
Testing with Fastly
https://should-i-test.freetls.fastly.net/
New service
A crucial step for continuous integration and
continuous delivery with Fastly is testing the service
configuration to provide confidence in changes.
This workshop will cover unit-testing VCL,
component testing a service as a black box,
systems testing a service end-to-end and
stakeholder acceptance testing.
—Us
Workshop, not
a presentation
Task
Visit https://www.fastly.com/
Check
the
Wi-Fi
Answer
You should have seen:
Check
the
Wi-FI
Testing with Fastly
Reduce
risk
Increase
confidence
Increase
agility
Testing with Fastly
Repetitive
tasks
Laziness CI/CD
Testing with Fastly
Service
Configuration
VCL
State machine
Fastly is...
User
to Fastly
to origin
Fastly service
configuration
VCL
Testing with Fastly
Testing VCL
Testing with Fastly
We’re going to use Fastly Fiddle during this presentation
https://fiddle.fastlydemo.net/
Warning: This tool is an experiment. There may be
instability or data loss, and it may be withdrawn at any
time. Any data entered into this tool can be viewed by
anyone on the internet.
Please use Chrome today.
Introduction to Fiddle
Task
https://fiddle.fastlydemo.net/
Run an empty Fiddle, using the default
https://httpbin.org as an origin, which is a simple
HTTP request & response service
“Click to set title” and give it a name, perhaps “<Your
Name> Test”
Run
Visit
Fiddle
Answer
You should end up with:
https://fiddle.fastlydemo.net/fiddle/f30d75b9
HTTP/1.1 200 OK
Visit
Fiddle
Task
https://fiddle.fastlydemo.net/
Let’s make a small fiddle
Type in recv section:
set req.url = "/status/418";
Send a request options: Purge first
Run
Create
a
fiddle
Answer
You should end up with:
https://fiddle.fastlydemo.net/fiddle/7335a9ee
HTTP/1.1 418 I'M A TEAPOT
-=[ teapot ]=-
_...._
.' _ _ `.
| ."` ^ `". _,
_;`"---"`|//
| ;/
_ _/
`"""`
Create
a
fiddle
Task
Clone:
https://fiddle.fastlydemo.net/fiddle/aa247598
Change the synthetic in the error section to:
synthetic "The user agent header is: "
+ req.http.user-agent;
Clone
a
fiddle
Answer
You should end up with:
https://fiddle.fastlydemo.net/fiddle/e4240e94
The user agent header is: Mozilla/5.0 (Macintosh; Intel
Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/67.0.3396.99 Safari/537.36
Clone
a
fiddle
Testing with Fastly
Now we’re going to test some VCL
We’re going to extract the functionality into a VCL
function
Set a input, call it and inspect the output
Test using assertions
Test a VCL function
Task
Replace multiple //// in URL path with a single one
https://fiddle.fastlydemo.net/fiddle/c3c6f137
Clone, run, add more tests in recv.Test a
VCL
function
Input Expected
// /
//blog /blog
////photos////animals///pets/// /photos/animals/pets/
Answer
You should end up with:
https://fiddle.fastlydemo.net/fiddle/1ff8d290
All tests passed.
Test a
VCL
function
Task
Clone
https://fiddle.fastlydemo.net/fiddle/8777be33
Add to transform() one of:
set req.http.output = regsub(req.http.output, "/$", "");
set req.http.output = regsub(req.http.output, "./$", "");
set req.http.output = regsub(req.http.output, "(?<=.)/$", "");
TDD
Answer
You should end up with
https://fiddle.fastlydemo.net/fiddle/85e9ed41
All tests passed.
TDD
Testing with Fastly
Good: tests near code
Good: can test in production
Bad: VCL has limited support for testing so it is verbose
Test VCL with VCL
Testing with Fastly
TAP, the Test Anything Protocol, is a simple text-based
interface between testing modules in a test harness.
There are implementations for many languages and
applications.
1..4
ok 1 - Input file opened
not ok 2 - First line of the input valid
ok 3 - Read the rest of the file
not ok 4 - Summarized correctly # TODO Not written yet
Test Anything Protocol in VCL
Task Clone
https://fiddle.fastlydemo.net/fiddle/e610db71
Add more test cases in recv section:
Bonus: add to transform() to make the failing test no
longer fail.
TAP
in
VCL
Input Expected
/status/200 req.http.origin0
/status/404 req.http.origin0
/blog/ req.http.origin2
Answer
You should end up with:
https://fiddle.fastlydemo.net/fiddle/bf28d00c
1..4
ok 1 - / went to F_origin_1
ok 2 - /status/200 went to F_origin_0
ok 3 - /status/404 went to F_origin_0
not ok 4 - /blog/ went to F_origin_0 instead of F_origin_2
TAP
in
VCL
Answer
Bonus: make the failing test pass.
You should end up with:
https://fiddle.fastlydemo.net/fiddle/687b37a0
1..4
ok 1 - / went to F_origin_1
ok 2 - /status/200 went to F_origin_0
ok 3 - /status/404 went to F_origin_0
ok 4 - /blog/ went to F_origin_2
TAP
in
VCL
Testing with Fastly
Good: tests near code
Good: can test in production
Good: standardized, so Jenkins can consume it
Bad: VCL has limited support for testing so it is verbose
Test Anything Protocol in VCL
Testing with Fastly
Inputs and output of a function could be HTTP
Test a VCL function over HTTP
Task
Run https://fiddle.fastlydemo.net/fiddle/d3e72f51
Notice custom header
Visit https://uap-vcl.freetls.fastly.net/
Run:
curl https://uap-vcl.freetls.fastly.net/  -
Haccept:application/json
VCL
over
HTTP
Answer
You should end up with:
{
"ua_family": "Chrome",
"ua_major": "68",
"ua_minor": "0",
"ua_patch": "3440"
}
{
"ua_family": "curl",
"ua_major": "7",
"ua_minor": "50",
"ua_patch": "3"
}
VCL
over
HTTP
Testing with Fastly
Good: can test in production
Good: standardized, so can throw into Jenkins
Good: HTTP & JSON are well supported by many tools
Bad: tests far from code
Test a VCL function over HTTP
Testing with Fastly
Break: back in
10 minutes!
Testing with Fastly
Testing a service
Testing with Fastly
Make the request through Fastly, but not to the origin
Return what the request to origin would have been
As JSON
Fastly-Debug-Trace in Fiddle
Fastly service configuration
Task
Clone Fastly-Debug-Trace in Fiddle:
https://fiddle.fastlydemo.net/fiddle/951bb2b9
Change URL to:
/status/200?fastly-debug-trace
/200?fastly-debug-trace
/429?fastly-debug-trace
Debug
trac
e
Answer
You should end up with, for /200?fastly-debug-trace:
{
"backend": "F_origin_0",
"method": "GET",
"host": "httpbin.org",
"sub": "miss",
"url": "/status/200",
"version": "26"
}
Debug
trace
Testing with Fastly
Live service
Under test
Fastly service configuration: HTTP
Task
Visit https://fdb.freetls.fastly.net/200?fastly-debug-
trace
Debug
trace
HTTP
Answer
You should end up with:
{
"backend": "F_httpbin_org",
"method": "GET",
"host": "httpbin.org",
"sub": "miss",
"url": "/status/200",
"version": "10"
}
Debug
trace
HTTP
Testing with Fastly
Good: can test in production
Good: can test entire configuration without origin
Good: HTTP & JSON are well supported by many tools
Bad: tests far from code
Fastly service configuration
Testing with Fastly
Testing end-to-end
Testing with Fastly
Behaviour Driven Development
Cucumber
Headless browser via Webdriver
User to Fastly to Origin
Testing with Fastly
Scenario: Visit the Fastly homepage over HTTP
Given the browser visits the homepage over HTTP
Then it was redirected to https
And the status code is 200
And the response is gzipped
And the content type is HTML
And the page is cached by an edge node
And the page is not cached by the browser
And the title is "Edge Cloud Platform | Fastly"
And the heading is "Fastly powers fast, secure, and scalable digital experiences."
And the body contains "We add value to every request"
Cucumber
Testing with Fastly
Then('the response is gzipped', function() {
expect(this.contentEncoding()).to.eql('gzip');
});
And the response is gzipped
Testing with Fastly
async launchChrome() {
this.browser = await puppeteer.launch();
this.page = await this.browser.newPage();
this.page.setViewport({
width: 1280,
height: 720
});
}
Headless browser
Testing with Fastly
1) Scenario: Visit some CSS # features/homepage.feature:38
✔ Before # features/support/steps.js:4
✔ Given the browser visits some CSS # features/support/steps.js:41
✔ Then the page was served over https # features/support/steps.js:51
✔ And the status code is 200 # features/support/steps.js:60
✔ And the response is gzipped # features/support/steps.js:64
✔ And the content type is CSS # features/support/steps.js:76
✖ And the page is cached by an edge node # features/support/steps.js:80
AssertionError: expected 'MISS, HIT' to match /^HIT/
at CustomWorld.<anonymous> (features/support/steps.js:81:28)
- And the page is cached by the browser # features/support/steps.js:84
✔ After # features/support/steps.js:8
Output
Testing with Fastly
Good: can test in production
Good: can test entire configuration including the origin
Good: real (headless) web browser
Bad: tests far from code
Bad: bit slow
Bad: cucumber-js lacks TAP generator
User to Fastly to Origin
Testing with Fastly
Other tests
Testing with Fastly
User performance, accessibility and user experience:
https://developers.google.com/web/tools/lighthouse/
Lighthouse by Google
Testing with Fastly
Security headers
https://observatory.mozilla.org/
Observatory by Mozilla
Testing with Fastly
Contact us first
Security scans and load tests
The headers we want
https://www.fastly.com/blog/headers-we-want
The headers we don't want
https://www.fastly.com/blog/headers-we-dont-want
ABCD: always be continuously deploying
https://vimeo.com/212667453
Testing Fastly services on every PR
https://medium.com/usa-today-network/f7e2cc744179
Testing with Fastly
Summary
Testing with Fastly
Testing
Fiddle
VCL
Fastly service configuration
Test Anything Protocol
User to Fastly to origin
As part of CI/CD
Summary of workshop
Testing with Fastly
https://should-i-test.freetls.fastly.net/?test
https://should-i-test.freetls.fastly.net/
New service
Testing with Fastly
Questions?
Testing with Fastly
Logging at the edge with
Fastly, Google Cloud Storage,
and BigQuery
Second floor
Seth Vargo, Google
Chris Jackel, Fastly
Next: break until 3:30PM
How I Learned to Stop Worrying
and Love Video: building a video
delivery workflow
First floor
Chris Buckley, Fastly
Jim Hall, Fastly

Altitude San Francisco 2018: Testing with Fastly Workshop