Skip to content

Commit 4c5fd62

Browse files
authored
esi_nested_include test updates (#12471)
Some updates to the esi_nested_include autest. This uses Proxy Verifier and adds type hints.
1 parent c168b13 commit 4c5fd62

2 files changed

Lines changed: 126 additions & 81 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
sessions:
18+
19+
- transactions:
20+
21+
# Initial request for the main ESI document
22+
- client-request:
23+
method: GET
24+
url: /main.php
25+
version: '1.1'
26+
headers:
27+
fields:
28+
- [ Host, www.example.com ]
29+
- [ Accept, "*/*" ]
30+
31+
server-response:
32+
status: 200
33+
headers:
34+
fields:
35+
- [ X-Esi, "1" ]
36+
- [ Cache-Control, "private" ]
37+
- [ Content-Type, "text/html" ]
38+
- [ Connection, "close" ]
39+
- [ Transfer-Encoding, "chunked" ]
40+
content:
41+
encoding: plain
42+
data: "<head>\n<title>Main ESI Document</title>\n</head>\n<body>\n<esi:include src=\"http://www.example.com/esi-nested-include.html\"/>\n</body>\n"
43+
44+
# This is what the client receives /after/ ESI processing and fetching.
45+
# Note: since the maximum inclusion depth is reached, the ESI include is
46+
# not expanded.
47+
proxy-response:
48+
status: 200
49+
headers:
50+
fields:
51+
- [ Content-Type, { value: "text/html", as: equal } ]
52+
content:
53+
encoding: plain
54+
data: "<esi:include src=\"http://www.example.com/esi-nested-include.html\"/>"
55+
verify: { as: contains }
56+
57+
# ESI nested include requests for the ATS-generated ESI include.
58+
- client-request:
59+
method: GET
60+
url: /esi-nested-include.html
61+
version: '1.1'
62+
headers:
63+
fields:
64+
- [ Host, www.example.com ]
65+
66+
server-response:
67+
status: 200
68+
headers:
69+
fields:
70+
- [ X-Esi, "1" ]
71+
- [ Cache-Control, "private" ]
72+
- [ Content-Type, "text/html" ]
73+
- [ Connection, "close" ]
74+
- [ Transfer-Encoding, "chunked" ]
75+
content:
76+
encoding: plain
77+
data: "<esi:include src=\"http://www.example.com/esi-nested-include.html\"/>"

tests/gold_tests/pluginTest/esi/esi_nested_include.test.py

Lines changed: 49 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
# See the License for the specific language governing permissions and
1818
# limitations under the License.
1919

20-
import os
21-
2220
Test.Summary = '''
2321
Test nested include for the ESI plugin.
2422
'''
@@ -31,107 +29,77 @@ class EsiTest():
3129
A class that encapsulates the configuration and execution of a set of ESI
3230
test cases.
3331
"""
34-
""" static: The same server Process is used across all tests. """
35-
_server = None
36-
""" static: A counter to keep the ATS process names unique across tests. """
37-
_ts_counter = 0
38-
""" static: A counter to keep any output file names unique across tests. """
39-
_output_counter = 0
40-
""" The ATS process for this set of test cases. """
41-
_ts = None
42-
43-
def __init__(self, plugin_config):
44-
"""
45-
Args:
46-
plugin_config (str): The config line to place in plugin.config for
47-
the ATS process.
48-
"""
49-
if EsiTest._server is None:
50-
EsiTest._server = EsiTest._create_server()
5132

52-
self._ts = EsiTest._create_ats(self, plugin_config)
33+
_replay_file: str = "esi_nested_include.replay.yaml"
5334

54-
@staticmethod
55-
def _create_server():
35+
def __init__(self, plugin_config) -> None:
5636
"""
57-
Create and start a server process.
37+
:param plugin_config: esi.so configuration for plugin.config.
5838
"""
59-
# Configure our server.
60-
server = Test.MakeOriginServer("server", lookup_key="{%uuid}")
61-
62-
# Generate the set of ESI responses.
63-
request_header = {
64-
"headers": "GET /esi-nested-include.php HTTP/1.1\r\n" + "Host: www.example.com\r\n" + "Content-Length: 0\r\n\r\n",
65-
"timestamp": "1469733493.993",
66-
"body": ""
67-
}
68-
esi_body = r'''<p>
69-
<esi:include src="http://www.example.com/esi-nested-include.html"/>
70-
</p>
71-
'''
72-
response_header = {
73-
"headers":
74-
"HTTP/1.1 200 OK\r\n" + "X-Esi: 1\r\n" + "Cache-Control: private\r\n" + "Content-Type: text/html\r\n" +
75-
"Connection: close\r\n" + "Content-Length: {}\r\n".format(len(esi_body)) + "\r\n",
76-
"timestamp": "1469733493.993",
77-
"body": esi_body
78-
}
79-
server.addResponse("sessionfile.log", request_header, response_header)
80-
81-
# Create a run to start the server.
82-
tr = Test.AddTestRun("Start the server.")
83-
tr.Processes.Default.StartBefore(server)
84-
tr.Processes.Default.Command = "echo starting the server"
85-
tr.Processes.Default.ReturnCode = 0
86-
tr.StillRunningAfter = server
39+
tr = Test.AddTestRun("Request the ESI generated document")
40+
self._create_server(tr)
41+
self._create_ats(tr, plugin_config)
42+
self._create_client(tr)
43+
44+
def _create_server(self, tr: 'TestRun') -> 'Process':
45+
""" Create and start a server process.
46+
:param tr: The test run to add the server to.
47+
:return: The server process.
48+
"""
49+
# Configure our server using proxy verifier.
50+
server = tr.AddVerifierServerProcess("server", self._replay_file, other_args='--format "{url}"')
51+
self._server = server
52+
53+
# Validate server traffic
54+
server.Streams.All += Testers.ContainsExpression('GET /main.php', 'Verify the server received the initial request.')
55+
server.Streams.All += Testers.ContainsExpression(
56+
'GET /esi-nested-include.html', 'Verify the server received the nested include request.')
8757

8858
return server
8959

90-
@staticmethod
91-
def _create_ats(self, plugin_config):
92-
"""
93-
Create and start an ATS process.
60+
def _create_ats(self, tr: 'TestRun', plugin_config: str) -> 'Process':
61+
""" Create and start an ATS process.
62+
:param tr: The test run to add the ATS to.
63+
:param plugin_config: The plugin configuration to use.
64+
:return: The ATS process.
9465
"""
95-
EsiTest._ts_counter += 1
96-
9766
# Configure ATS with a vanilla ESI plugin configuration.
98-
ts = Test.MakeATSProcess("ts{}".format(EsiTest._ts_counter))
67+
ts = tr.MakeATSProcess(f"ts")
68+
self._ts = ts
9969
ts.Disk.records_config.update({
10070
'proxy.config.diags.debug.enabled': 1,
10171
'proxy.config.diags.debug.tags': 'http|plugin_esi',
10272
})
103-
ts.Disk.remap_config.AddLine(f'map http://www.example.com/ http://127.0.0.1:{EsiTest._server.Variables.Port}')
73+
server_port = self._server.Variables.http_port
74+
ts.Disk.remap_config.AddLine(f'map http://www.example.com/ http://127.0.0.1:{server_port}')
10475
ts.Disk.plugin_config.AddLine(plugin_config)
10576

10677
ts.Disk.diags_log.Content = Testers.ContainsExpression(
10778
r'The current esi inclusion depth \(3\) is larger than or equal to the max \(3\)',
10879
'Verify the ESI error concerning the max inclusion depth')
109-
110-
# Create a run to start the ATS process.
111-
tr = Test.AddTestRun("Start the ATS process.")
112-
tr.Processes.Default.StartBefore(ts)
113-
tr.Processes.Default.Command = "echo starting ATS"
114-
tr.Processes.Default.ReturnCode = 0
115-
tr.StillRunningAfter = ts
11680
return ts
11781

118-
def run_test(self):
119-
# Test 1: Verify basic ESI functionality without processing internal txn.
120-
tr = Test.AddTestRun("First request")
121-
tr.MakeCurlCommand(
122-
f'http://127.0.0.1:{self._ts.Variables.port}/main.php -H"Host: www.example.com" '
123-
'-H"Accept: */*" --verbose',
124-
ts=self._ts)
125-
tr.Processes.Default.ReturnCode = 0
126-
tr.Processes.Default.Streams.stdout = "gold/nested_include_body.gold"
127-
tr.StillRunningAfter = self._server
128-
tr.StillRunningAfter = self._ts
82+
def _create_client(self, tr: 'TestRun') -> None:
83+
""" Create and start a client process to generate the request.
84+
:param tr: The test run to add the client to.
85+
"""
86+
# Note, just request the main.php file. Otherwise the client will do the
87+
# ESI requests in the replay file as well.
88+
p = tr.AddVerifierClientProcess(
89+
"client", self._replay_file, http_ports=[self._ts.Variables.port], other_args='--format "{url}" --keys /main.php')
90+
p.ReturnCode = 0
91+
p.StartBefore(self._server)
92+
p.StartBefore(self._ts)
93+
94+
# Double check that the client received the response.
95+
p.Streams.stdout += Testers.ContainsExpression(
96+
'Received an HTTP/1 chunked body', 'Verify the client received the response.')
97+
98+
p.Streams.stdout += Testers.ContainsExpression(
99+
'esi:include src="http://www.example.com/esi-nested-include.html"/>', 'Verify the ATS received the esi include.')
129100

130101

131102
#
132103
# Configure and run the test cases.
133104
#
134-
135-
# Run the tests with ESI configured with private response.
136-
first_test = EsiTest(plugin_config='esi.so')
137-
first_test.run_test()
105+
EsiTest(plugin_config='esi.so')

0 commit comments

Comments
 (0)