You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bn...@apache.org on 2022/06/28 16:35:38 UTC

[trafficserver] branch master updated: proxy_serve_stale: Test updates (#8928)

This is an automated email from the ASF dual-hosted git repository.

bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 952bf25a3 proxy_serve_stale: Test updates (#8928)
952bf25a3 is described below

commit 952bf25a3940ba96a2184d6b40204a9e0b062482
Author: Brian Neradt <br...@gmail.com>
AuthorDate: Tue Jun 28 11:35:31 2022 -0500

    proxy_serve_stale: Test updates (#8928)
    
    This updates the proxy_serve_stale test to run more quickly (about 15
    seconds instead of about 2 minutes). While doing so, the test is also
    converted to use Proxy Verifier.
---
 .../proxy_protocol/gold/proxy_serve_stale.gold     |  58 ---------
 .../proxy_protocol/proxy_serve_stale.test.py       | 101 +++++++--------
 .../replay/proxy_serve_stale.replay.yaml           | 142 +++++++++++++++++++++
 3 files changed, 189 insertions(+), 112 deletions(-)

diff --git a/tests/gold_tests/proxy_protocol/gold/proxy_serve_stale.gold b/tests/gold_tests/proxy_protocol/gold/proxy_serve_stale.gold
deleted file mode 100644
index d3654629f..000000000
--- a/tests/gold_tests/proxy_protocol/gold/proxy_serve_stale.gold
+++ /dev/null
@@ -1,58 +0,0 @@
-``
-> GET / HTTP/1.1
-> Host: ``
-> User-Agent: curl/``
-> Accept: */*
-``
-< HTTP/1.1 200 OK
-< Server: ATS/{}
-< Accept-Ranges: bytes
-< Content-Length: 6
-< Cache-Control: public, max-age=5
-< Age: ``
-< Date: ``
-< Connection: keep-alive
-< Warning: ``
-``
-> GET / HTTP/1.1
-> Host: ``
-> User-Agent: curl/``
-> Accept: */*
-``
-< HTTP/1.1 200 OK
-< Server: ATS/{}
-< Accept-Ranges: bytes
-< Content-Length: 6
-< Cache-Control: public, max-age=5
-< Age: ``
-< Date: ``
-< Connection: keep-alive
-< Warning: ``
-``
-> GET / HTTP/1.1
-> Host: ``
-> User-Agent: curl/``
-> Accept: */*
-``
-< HTTP/1.1 200 OK
-< Server: ATS/{}
-< Accept-Ranges: bytes
-< Content-Length: 6
-< Cache-Control: public, max-age=5
-< Age: ``
-< Date: ``
-< Connection: keep-alive
-< Warning: ``
-``
-> GET / HTTP/1.1
-> Host: ``
-> User-Agent: curl/``
-> Accept: */*
-``
-< HTTP/1.1 502 Next Hop Connection Failed
-< Date: ``
-< Connection: keep-alive
-< Server: ATS/{}
-< Cache-Control: ``
-< Content-Length: ``
-``
diff --git a/tests/gold_tests/proxy_protocol/proxy_serve_stale.test.py b/tests/gold_tests/proxy_protocol/proxy_serve_stale.test.py
index ec25592f7..e012d394f 100644
--- a/tests/gold_tests/proxy_protocol/proxy_serve_stale.test.py
+++ b/tests/gold_tests/proxy_protocol/proxy_serve_stale.test.py
@@ -1,6 +1,6 @@
-'''
+"""
 Test child proxy serving stale content when parents are exhausted
-'''
+"""
 #  Licensed to the Apache Software Foundation (ASF) under one
 #  or more contributor license agreements.  See the NOTICE file
 #  distributed with this work for additional information
@@ -17,64 +17,57 @@ Test child proxy serving stale content when parents are exhausted
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
+
+Test.testName = "proxy_serve_stale"
 Test.ContinueOnFail = True
-# Set up hierarchical caching processes
-ts_child = Test.MakeATSProcess("ts_child")
-# Parent ATS process is not created to mock parent being "down"
-# but parent hostname is recognized in hostdb to match with child successfully
-ts_parent_hostname = "localhost:82"
-server = Test.MakeOriginServer("server")
 
-Test.testName = "STALE"
 
-# Request from client
-request_header = {"headers":
-                  "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n",
-                  "timestamp": "1469733493.993",
-                  "body": ""}
-# Expected response from the origin server
-response_header = {"headers":
-                   "HTTP/1.1 200 OK\r\nConnection: close\r\nCache-Control: max-age=5,public\r\n\r\n",
-                   "timestamp": "1469733493.993",
-                   "body": "CACHED"}
+class ProxyServeStaleTest:
+    """Verify that stale content is served when the parent is down."""
+
+    single_transaction_replay = "replay/proxy_serve_stale.replay.yaml"
+    ts_parent_hostname = "localhost:82"
+
+    def __init__(self):
+        """Initialize the test."""
+        self._configure_server()
+        self._configure_ts()
 
-# Add request/response
-server.addResponse("sessionlog.log", request_header, response_header)
+    def _configure_server(self):
+        self.server = Test.MakeVerifierServerProcess(
+            "server",
+            self.single_transaction_replay)
 
-# Config child proxy to route to parent proxy
-ts_child.Disk.records_config.update({
-    'proxy.config.http.parent_proxy.fail_threshold': 2,
-    'proxy.config.http.parent_proxy.total_connect_attempts': 1,
-    'proxy.config.http.cache.max_stale_age': 90,
-    'proxy.config.http.parent_proxy.self_detect': 0,
-})
-ts_child.Disk.parent_config.AddLine(
-    f'dest_domain=. parent="{ts_parent_hostname}" round_robin=consistent_hash go_direct=false'
-)
-ts_child.Disk.remap_config.AddLine(
-    f'map http://localhost:{ts_child.Variables.port} http://localhost:{server.Variables.Port}'
-)
+    def _configure_ts(self):
+        self.ts_child = Test.MakeATSProcess("ts_child")
+        # Config child proxy to route to parent proxy
+        self.ts_child.Disk.records_config.update({
+            'proxy.config.http.parent_proxy.fail_threshold': 2,
+            'proxy.config.http.parent_proxy.total_connect_attempts': 1,
+            'proxy.config.http.cache.max_stale_age': 10,
+            'proxy.config.http.parent_proxy.self_detect': 0,
+            'proxy.config.diags.debug.enabled': 1,
+            'proxy.config.diags.debug.tags': 'http|dns|parent_proxy',
+        })
+        self.ts_child.Disk.parent_config.AddLine(
+            f'dest_domain=. parent="{self.ts_parent_hostname}" round_robin=consistent_hash go_direct=false'
+        )
+        self.ts_child.Disk.remap_config.AddLine(
+            f'map / http://localhost:{self.server.Variables.http_port}'
+        )
 
-stale_output = "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: bytes\nContent-Length: 6\nCache-Control: public, max-age=5\n\nCACHED"
+    def run(self):
+        """Run the test cases."""
 
+        tr = Test.AddTestRun()
+        tr.AddVerifierClientProcess(
+            'client',
+            self.single_transaction_replay,
+            http_ports=[self.ts_child.Variables.port])
+        tr.Processes.Default.ReturnCode = 0
+        tr.StillRunningAfter = self.ts_child
+        tr.Processes.Default.StartBefore(self.server)
+        tr.Processes.Default.StartBefore(self.ts_child)
 
-# Testing scenarios
-# 1. Child proxy serves stale with warning header when parent returns invalid response
-# 2. Child proxy serves stale with warning header when parent failcount meets fail_threshold and parent is unavailable
-# 3. Child proxy does not serve stale when object is past the max_stale_age expiration date
-curl_request = (
-    f'curl -X PUSH -d "{stale_output}" "http://localhost:{ts_child.Variables.port}";'
-    f'sleep 10; curl -s -v http://localhost:{ts_child.Variables.port};'  # 1. serve stale with warning, failcount=1
-    f'curl -s -v http://localhost:{ts_child.Variables.port};'  # 1. serve stale with warning, failcount=2
-    f'curl -s -v http://localhost:{ts_child.Variables.port};'  # 2. serve stale with warning, parent unavailable
-    f'sleep 90; curl -v http://localhost:{ts_child.Variables.port}'  # 3. max_stale_age expires, stale content cannot be served
-)
 
-# Test case for when parent server is down but child proxy can serve cache object
-tr = Test.AddTestRun()
-tr.Processes.Default.Command = curl_request
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.StartBefore(server)
-tr.Processes.Default.StartBefore(ts_child)
-tr.Processes.Default.Streams.stderr = "gold/proxy_serve_stale.gold"
-tr.StillRunningAfter = ts_child
+ProxyServeStaleTest().run()
diff --git a/tests/gold_tests/proxy_protocol/replay/proxy_serve_stale.replay.yaml b/tests/gold_tests/proxy_protocol/replay/proxy_serve_stale.replay.yaml
new file mode 100644
index 000000000..9a04d86e2
--- /dev/null
+++ b/tests/gold_tests/proxy_protocol/replay/proxy_serve_stale.replay.yaml
@@ -0,0 +1,142 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+#
+# This replay file assumes that caching is enabled and
+# proxy.config.http.cache.ignore_client_cc_max_age is set to 0 so that we can
+# test max-age in the client requests.
+#
+
+meta:
+  version: "1.0"
+
+  blocks:
+
+  # All responses should be served out of the cache for this test, so this
+  # response from the origin should never been seen.
+  - origin_response: &origin_response
+      server-response:
+        status: 500
+        reason: "Internal Server Error"
+        headers:
+          fields:
+          - [ Content-Length, 16 ]
+          - [ X-Response, should_not_see ]
+
+
+sessions:
+- transactions:
+
+  # Use a PUSH to populate the cache with a max-age response of 2 seconds.
+  - client-request:
+      method: "PUSH"
+      version: "1.1"
+      url: /a/path
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, push ]
+        - [ X-Request, push ]
+        - [ Content-Length, 113 ]
+      content:
+        encoding: plain
+        data: "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: bytes\nContent-Length: 6\nCache-Control: public,max-age=2\n\nCACHED"
+
+    <<: *origin_response
+
+    # Verify that ATS confirmed that the PUSH was successful, which it does
+    # with a 201 response.
+    proxy-response:
+      status: 201
+
+  # Issue a GET request after the 2 second max-age. The test configures the
+  # parent ATS cache to be non-existent, so it appears as down to this ATS
+  # host. After this transaction, failcount == 1.
+  - client-request:
+      delay: 4s
+
+      method: "GET"
+      version: "1.1"
+      url: /a/path
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, first_stale ]
+        - [ X-Request, first_stale ]
+
+    <<: *origin_response
+
+    proxy-response:
+      status: 200
+      headers:
+        fields:
+          - [ Cache-Control, {value: max-age=2, as: contains } ]
+
+  # Request the stale resource a second time. After this transaction, failcount == 2.
+  - client-request:
+      method: "GET"
+      version: "1.1"
+      url: /a/path
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, second_stale ]
+        - [ X-Request, second_stale ]
+
+    <<: *origin_response
+
+    proxy-response:
+      status: 200
+
+  # Request the stale resource a third time. Here the failcount will exceed the
+  # fail_threshold of 2. ATS will still serve the stale entry, but it now
+  # considers the parent unavailable.
+  - client-request:
+      method: "GET"
+      version: "1.1"
+      url: /a/path
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, third_stale ]
+        - [ X-Request, third_stale ]
+
+    <<: *origin_response
+
+    proxy-response:
+      status: 200
+
+  # Request the stale resource after enough delay to guarantee that the cached
+  # object's age exceeds max_stale_age (10 seconds). Note that we already
+  # delayed 4 seconds in a previous transaction. ATS should not serve the stale
+  # entry anymore because it is too old.
+  - client-request:
+      delay: 8s
+
+      method: "GET"
+      version: "1.1"
+      url: /a/path
+      headers:
+        fields:
+        - [ Host, example.com ]
+        - [ uuid, past_max_age ]
+        - [ X-Request, past_max_age ]
+
+    <<: *origin_response
+
+    # At this point, ATS should respond with a 502 since max_stale_age is exceeded.
+    proxy-response:
+      status: 502