diff --git a/.circleci/config.yml b/.circleci/config.yml index 35590fdf..cac57801 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -244,14 +244,21 @@ jobs: -f test-engineering/contract-tests/docker-compose.yml \ up --abort-on-container-exit --force-recreate - run: - name: 'Run "204" contract tests' + name: Run "tiles cache" contract tests + command: | + docker-compose \ + -f test-engineering/contract-tests/docker-compose.yml \ + -f test-engineering/contract-tests/docker-compose.tiles_cache.yml \ + up --abort-on-container-exit --force-recreate + - run: + name: Run "204" contract tests command: | docker-compose \ -f test-engineering/contract-tests/docker-compose.yml \ -f test-engineering/contract-tests/docker-compose.204.yml \ up --abort-on-container-exit --force-recreate - run: - name: 'Run "init_error" contract tests' + name: Run "init_error" contract tests command: | set +e # We need this so that the run doesn't exit after docker-compose docker-compose \ diff --git a/test-engineering/contract-tests/README.md b/test-engineering/contract-tests/README.md index cea74a96..b64bb975 100644 --- a/test-engineering/contract-tests/README.md +++ b/test-engineering/contract-tests/README.md @@ -11,7 +11,7 @@ The contract test suite is designed to be set up as a `docker-compose` CI workflow. The following sections as well as the sequence diagram below describe the individual components of the suite. -**Test Scenario: success_windows_desktop** +**Test Scenario: success_tiles_cached_for_identical_proxy_params** ![Sequence diagram of the integration tests][sequence_diagram] To run the contract tests locally, execute the following from the repository root: diff --git a/test-engineering/contract-tests/docker-compose.tiles_cache.yml b/test-engineering/contract-tests/docker-compose.tiles_cache.yml new file mode 100644 index 00000000..e922a4ef --- /dev/null +++ b/test-engineering/contract-tests/docker-compose.tiles_cache.yml @@ -0,0 +1,9 @@ +version: "3" + +services: + contile: + environment: + CONTILE_TILES_TTL: 900 # cached tiles will expire after 15 minutes + client: + environment: + SCENARIOS_FILE: /tmp/client/scenarios_tiles_cache.yml diff --git a/test-engineering/contract-tests/docker-compose.yml b/test-engineering/contract-tests/docker-compose.yml index 49be861c..1efa8076 100644 --- a/test-engineering/contract-tests/docker-compose.yml +++ b/test-engineering/contract-tests/docker-compose.yml @@ -39,6 +39,7 @@ services: CONTILE_HOST: 0.0.0.0 CONTILE_HUMAN_LOGS: 1 CONTILE_PORT: 8000 + CONTILE_TILES_TTL: 0 # cached tiles will always be expired RUST_LOG: main,contile=INFO expose: - "8000" diff --git a/test-engineering/contract-tests/sequence_diagram.png b/test-engineering/contract-tests/sequence_diagram.png index 0e777246..6e3d0a8e 100644 Binary files a/test-engineering/contract-tests/sequence_diagram.png and b/test-engineering/contract-tests/sequence_diagram.png differ diff --git a/test-engineering/contract-tests/volumes/client/scenarios.yml b/test-engineering/contract-tests/volumes/client/scenarios.yml index 2f87517f..79fdd037 100644 --- a/test-engineering/contract-tests/volumes/client/scenarios.yml +++ b/test-engineering/contract-tests/volumes/client/scenarios.yml @@ -408,3 +408,120 @@ scenarios: image_size: null impression_url: 'https://example.org/gb_desktop_linux?id=0002' url: 'https://www.example.org/gb_desktop_linux' + + - name: success_tiles_cache_expired + description: > + Test that Contile requests tiles from the partner, when its cached tiles are + expired + steps: + - request: + service: contile + method: GET + path: '/v1/tiles' + headers: + # Contile maps the User-Agent Header value to os-family and form-factor parameters + # The following value will result in os-family: windows and form-factor: desktop + - name: User-Agent + value: 'Mozilla/5.0 (Windows NT 10.0; rv:10.0) Gecko/20100101 Firefox/91.0' + # Contile looks up the IP address from this header value and maps it to proxy information. + # We use a random IP address from the range specified by the CIDR network notation "216.160.83.56/29" + # from https://github.com/maxmind/MaxMind-DB/blob/main/source-data/GeoLite2-City-Test.json + # The following value will result in country-code: US and region-code: WA + - name: X-Forwarded-For + value: '216.160.83.62' + response: + status_code: 200 + content: + tiles: + - id: 22345 + name: 'Example COM' + click_url: 'https://example.com/us_wa_desktop_windows?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/us_wa_desktop_windows01.jpg' + image_size: null + impression_url: 'https://example.com/us_wa_desktop_windows?id=0001' + url: 'https://www.example.com/us_wa_desktop_windows' + - id: 66789 + name: 'Example ORG' + click_url: 'https://example.org/us_wa_desktop_windows?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/us_wa_desktop_windows02.jpg' + image_size: null + impression_url: 'https://example.org/us_wa_desktop_windows?id=0002' + url: 'https://www.example.org/us_wa_desktop_windows' + - request: + service: contile + method: GET + path: '/v1/tiles' + headers: + # Contile maps the User-Agent Header value to os-family and form-factor parameters + # The following value will result in os-family: windows and form-factor: desktop + - name: User-Agent + value: 'Mozilla/5.0 (Windows NT 10.0; rv:10.0) Gecko/20100101 Firefox/91.0' + # Contile looks up the IP address from this header value and maps it to proxy information. + # We use a random IP address from the range specified by the CIDR network notation "216.160.83.56/29" + # from https://github.com/maxmind/MaxMind-DB/blob/main/source-data/GeoLite2-City-Test.json + # The following value will result in country-code: US and region-code: WA + - name: X-Forwarded-For + value: '216.160.83.62' + response: + status_code: 200 + content: + tiles: + - id: 22345 + name: 'Example COM' + click_url: 'https://example.com/us_wa_desktop_windows?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/us_wa_desktop_windows01.jpg' + image_size: null + impression_url: 'https://example.com/us_wa_desktop_windows?id=0001' + url: 'https://www.example.com/us_wa_desktop_windows' + - id: 66789 + name: 'Example ORG' + click_url: 'https://example.org/us_wa_desktop_windows?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/us_wa_desktop_windows02.jpg' + image_size: null + impression_url: 'https://example.org/us_wa_desktop_windows?id=0002' + url: 'https://www.example.org/us_wa_desktop_windows' + - request: + service: partner + method: GET + path: '/records/' + headers: + - name: 'accept' + value: '*/*' + response: + status_code: 200 + content: + records: + - count: 2 + record: + method: GET + headers: + - name: accept + value: '*/*' + - name: user-agent + value: 'contile/1.8.0' + - name: host + value: 'partner:5000' + path: '/tilesp/desktop' + query_parameters: + - name: partner + value: 'partner_id_test' + - name: sub1 + value: 'sub1_test' + - name: sub2 + value: 'newtab' + - name: country-code + value: 'US' + - name: region-code + value: 'WA' + - name: dma-code + value: '819' + - name: form-factor + value: 'desktop' + - name: os-family + value: 'windows' + - name: v + value: '1.0' + - name: out + value: 'json' + - name: results + value: '5' diff --git a/test-engineering/contract-tests/volumes/client/scenarios_tiles_cache.yml b/test-engineering/contract-tests/volumes/client/scenarios_tiles_cache.yml new file mode 100644 index 00000000..00854b2d --- /dev/null +++ b/test-engineering/contract-tests/volumes/client/scenarios_tiles_cache.yml @@ -0,0 +1,264 @@ +# Note: The scenarios in this file will be executed using a 'CONTILE_TILES_TTL' value +# greater than 0. As a result, requests made to Contile will be cached, impacting +# subsequent scenario executions. + +scenarios: + - name: success_tiles_cached_for_identical_proxy_params + description: > + Test that Contile will use tiles from its cache, instead of from the + partner, for requests that map to the same form-factor and region. + steps: + - request: + service: contile + method: GET + path: '/v1/tiles' + headers: + # The following 'User-Agent' header value will result in query values + # os-family: windows and form-factor: desktop + - name: User-Agent + value: 'Mozilla/5.0 (Windows NT 10.0; rv:10.0) Gecko/20100101 Firefox/91.0' + # The following 'X-Forwarded-For' header value will result in query values + # country-code: US, region-code: WA and dma-code: 819 + - name: X-Forwarded-For + value: '216.160.83.57' + response: + status_code: 200 + content: + tiles: + - id: 22345 + name: 'Example COM' + click_url: 'https://example.com/us_wa_desktop_windows?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/us_wa_desktop_windows01.jpg' + image_size: null + impression_url: 'https://example.com/us_wa_desktop_windows?id=0001' + url: 'https://www.example.com/us_wa_desktop_windows' + - id: 66789 + name: 'Example ORG' + click_url: 'https://example.org/us_wa_desktop_windows?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/us_wa_desktop_windows02.jpg' + image_size: null + impression_url: 'https://example.org/us_wa_desktop_windows?id=0002' + url: 'https://www.example.org/us_wa_desktop_windows' + - request: + service: contile + method: GET + path: '/v1/tiles' + headers: + # The following 'User-Agent' header value will result in query values + # os-family: windows and form-factor: desktop + - name: User-Agent + value: 'Mozilla/5.0 (Windows NT 10.0; rv:10.0) Gecko/20100101 Firefox/91.0' + # The following 'X-Forwarded-For' header value will result in query values + # country-code: US, region-code: WA and dma-code: 819 + - name: X-Forwarded-For + value: '216.160.83.62' + response: + status_code: 200 + content: + tiles: + - id: 22345 + name: 'Example COM' + click_url: 'https://example.com/us_wa_desktop_windows?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/us_wa_desktop_windows01.jpg' + image_size: null + impression_url: 'https://example.com/us_wa_desktop_windows?id=0001' + url: 'https://www.example.com/us_wa_desktop_windows' + - id: 66789 + name: 'Example ORG' + click_url: 'https://example.org/us_wa_desktop_windows?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/us_wa_desktop_windows02.jpg' + image_size: null + impression_url: 'https://example.org/us_wa_desktop_windows?id=0002' + url: 'https://www.example.org/us_wa_desktop_windows' + - request: + service: partner + method: GET + path: '/records/' + headers: + - name: 'accept' + value: '*/*' + response: + status_code: 200 + content: + records: + - count: 1 + record: + method: GET + headers: + - name: accept + value: '*/*' + - name: user-agent + value: 'contile/1.8.0' + - name: host + value: 'partner:5000' + path: '/tilesp/desktop' + query_parameters: + - name: partner + value: 'partner_id_test' + - name: sub1 + value: 'sub1_test' + - name: sub2 + value: 'newtab' + - name: country-code + value: 'US' + - name: region-code + value: 'WA' + - name: dma-code + value: '819' + - name: form-factor + value: 'desktop' + - name: os-family + value: 'windows' + - name: v + value: '1.0' + - name: out + value: 'json' + - name: results + value: '5' + + - name: success_tiles_cached_for_different_proxy_params + description: > + Test that Contile will use tiles from the partner, instead of from its cache, + for requests that map to different form-factors and regions. + steps: + - request: + service: contile + method: GET + path: '/v1/tiles' + headers: + # The following 'User-Agent' header value will result in query values + # os-family: linux and form-factor: desktop + - name: User-Agent + value: 'Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/91.0' + # The following 'X-Forwarded-For' header value will result in query values + # country-code: GB and region-code: ENG + - name: X-Forwarded-For + value: '81.2.69.204' + response: + status_code: 200 + content: + tiles: + - id: 32347 + name: 'Example COM' + click_url: 'https://example.com/gb_desktop_linux?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/gb_desktop_linux01.jpg' + image_size: null + impression_url: 'https://example.com/gb_desktop_linux?id=0001' + url: 'https://www.example.com/gb_desktop_linux' + - id: 76791 + name: 'Example ORG' + click_url: 'https://example.org/gb_desktop_linux?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/gb_desktop_linux02.jpg' + image_size: null + impression_url: 'https://example.org/gb_desktop_linux?id=0002' + url: 'https://www.example.org/gb_desktop_linux' + - request: + service: contile + method: GET + path: '/v1/tiles' + headers: + # The following 'User-Agent' header value will result in query values + # os-family: windows and form-factor: desktop + - name: User-Agent + value: 'Mozilla/5.0 (Windows NT 10.0; rv:10.0) Gecko/20100101 Firefox/91.0' + # The following 'X-Forwarded-For' header value will result in query values + # country-code: CN and region-code: 22 + - name: X-Forwarded-For + value: '175.16.199.0' + response: + status_code: 200 + content: + tiles: + - id: 14356 + name: 'Example COM' + click_url: 'https://example.com/cn_desktop_windows?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/cn_desktop_windows01.jpg' + image_size: null + impression_url: 'https://example.com/cn_desktop_windows?id=0001' + url: 'https://www.example.com/cn_desktop_windows' + - id: 24356 + name: 'Example ORG' + click_url: 'https://example.org/cn_desktop_windows?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/cn_desktop_windows02.jpg' + image_size: null + impression_url: 'https://example.org/cn_desktop_windows?id=0002' + url: 'https://www.example.org/cn_desktop_windows' + - request: + service: partner + method: GET + path: '/records/' + headers: + - name: 'accept' + value: '*/*' + response: + status_code: 200 + content: + records: + - count: 1 + record: + method: GET + headers: + - name: accept + value: '*/*' + - name: user-agent + value: 'contile/1.8.0' + - name: host + value: 'partner:5000' + path: '/tilesp/desktop' + query_parameters: + - name: partner + value: 'partner_id_test' + - name: sub1 + value: 'sub1_test' + - name: sub2 + value: 'newtab' + - name: country-code + value: 'GB' + - name: region-code + value: 'ENG' + - name: dma-code + value: '' + - name: form-factor + value: 'desktop' + - name: os-family + value: 'linux' + - name: v + value: '1.0' + - name: out + value: 'json' + - name: results + value: '5' + - count: 1 + record: + method: GET + headers: + - name: accept + value: '*/*' + - name: user-agent + value: 'contile/1.8.0' + - name: host + value: 'partner:5000' + path: '/tilesp/desktop' + query_parameters: + - name: partner + value: 'partner_id_test' + - name: sub1 + value: 'sub1_test' + - name: sub2 + value: 'newtab' + - name: country-code + value: 'CN' + - name: region-code + value: '22' + - name: dma-code + value: '' + - name: form-factor + value: 'desktop' + - name: os-family + value: 'windows' + - name: v + value: '1.0' + - name: out + value: 'json' + - name: results + value: '5' diff --git a/test-engineering/contract-tests/volumes/partner/CN/responses.yml b/test-engineering/contract-tests/volumes/partner/CN/responses.yml new file mode 100644 index 00000000..8100e82a --- /dev/null +++ b/test-engineering/contract-tests/volumes/partner/CN/responses.yml @@ -0,0 +1,56 @@ +# This file contains partner responses for CN for the /tilesp API endpoint. +# We use form-factor and os-family to determine which response to send to Contile. +desktop: + windows: + status_code: 200 + headers: [] + content: + tiles: + - id: 14356 + name: 'Example COM' + click_url: 'https://example.com/cn_desktop_windows?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/cn_desktop_windows01.jpg' + impression_url: 'https://example.com/cn_desktop_windows?id=0001' + advertiser_url: 'https://www.example.com/cn_desktop_windows' + - id: 24356 + name: 'Example ORG' + click_url: 'https://example.org/cn_desktop_windows?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/cn_desktop_windows02.jpg' + impression_url: 'https://example.org/cn_desktop_windows?id=0002' + advertiser_url: 'https://www.example.org/cn_desktop_windows' + + macos: + status_code: 200 + headers: [] + content: + tiles: + - id: 14357 + name: 'Example COM' + click_url: 'https://example.com/cn_desktop_macos?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/cn_desktop_macos01.jpg' + impression_url: 'https://example.com/cn_desktop_macos?id=0001' + advertiser_url: 'https://www.example.com/cn_desktop_macos' + - id: 24357 + name: 'Example ORG' + click_url: 'https://example.org/cn_desktop_macos?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/cn_desktop_macos02.jpg' + impression_url: 'https://example.org/cn_desktop_macos?id=0002' + advertiser_url: 'https://www.example.org/cn_desktop_macos' + + linux: + status_code: 200 + headers: [] + content: + tiles: + - id: 14358 + name: 'Example COM' + click_url: 'https://example.com/cn_desktop_linux?version=16.0.0&key=22.1&ci=6.2&ctag=1612376952400200000' + image_url: 'https://example.com/cn_desktop_linux01.jpg' + impression_url: 'https://example.com/cn_desktop_linux?id=0001' + advertiser_url: 'https://www.example.com/cn_desktop_linux' + - id: 24358 + name: 'Example ORG' + click_url: 'https://example.org/cn_desktop_linux?version=16.0.0&key=7.2&ci=8.9&ctag=E1DE38C8972D0281F5556659A' + image_url: 'https://example.org/cn_desktop_linux02.jpg' + impression_url: 'https://example.org/cn_desktop_linux?id=0002' + advertiser_url: 'https://www.example.org/cn_desktop_linux'