Skip to content

Commit 470880a

Browse files
committed
Merge remote-tracking branch 'upstream/master' into zstd
# Conflicts: # contrib/docker/ubuntu/noble/Dockerfile # plugins/compress/configuration.cc # plugins/compress/configuration.h
2 parents 03e647a + 7f1c000 commit 470880a

File tree

1,133 files changed

+86284
-23129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,133 files changed

+86284
-23129
lines changed

.cursor/rules/writing-autests.mdc

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
---
2+
description: When working with or adding autests, the end to end tests for the project
3+
alwaysApply: false
4+
---
5+
This rule describes writing of end to end autests
6+
7+
Apache Traffic Server (ATS) has two types of tests: catch tests for unit tests and the autest framework for end-to-end testing. autests are declarative rather than imperative, using a specific Python framework syntax. Tests reside in `tests/gold_tests/` with `.test.py` extensions. For autest framework documentation, see: https://autestsuite.bitbucket.io/index.html
8+
9+
File Structure and Naming:
10+
- Place tests in appropriate subdirectories under `tests/gold_tests/` (e.g., `cache/`, `pluginTest/<plugin_name>`, `tls/`, etc.)
11+
- Use descriptive names with `.test.py` extension (e.g., `cache-auth.test.py`, `stats_over_http.test.py`)
12+
- Organize related tests in feature-specific subdirectories
13+
- autest, a general testing framework, is extended to add ATS testing support via `.test.ext` files in `tests/gold_tests/autest-site`
14+
15+
Running Autests:
16+
If ATS cmake build is properly configured, tests can be run with:
17+
```bash
18+
cmake --build build
19+
cmake --install build
20+
cd build/tests
21+
pipenv install
22+
./autest.sh --sandbox /tmp/sbcursor --clean=none -f <test_name_without_test_py_extension>
23+
```
24+
25+
For example, to run `cache-auth.test.py`:
26+
```bash
27+
./autest.sh --sandbox /tmp/sbcursor --clean=none -f cache-auth
28+
```
29+
30+
Test File Template Structure
31+
32+
Always start a test file with:
33+
34+
```python
35+
'''
36+
Brief description of what the test validates
37+
'''
38+
# Licensed to the Apache Software Foundation (ASF) under one
39+
# or more contributor license agreements. See the NOTICE file
40+
# distributed with this work for additional information
41+
# regarding copyright ownership. The ASF licenses this file
42+
# to you under the Apache License, Version 2.0 (the
43+
# "License"); you may not use this file except in compliance
44+
# with the License. You may obtain a copy of the License at
45+
#
46+
# http://www.apache.org/licenses/LICENSE-2.0
47+
#
48+
# Unless required by applicable law or agreed to in writing, software
49+
# distributed under the License is distributed on an "AS IS" BASIS,
50+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51+
# See the License for the specific language governing permissions and
52+
# limitations under the License.
53+
```
54+
55+
Test Configuration:
56+
57+
Set global test properties:
58+
59+
```python
60+
Test.Summary = 'Brief description of test purpose'
61+
Test.ContinueOnFail = True # Usually set to True for multi-step tests
62+
```
63+
64+
65+
Class-Based Test Organization
66+
67+
Prefer organizing tests as Python classes and use Python type hints:
68+
69+
```python
70+
class YourTestClass:
71+
"""
72+
Docstring explaining the test purpose and any relevant documentation links
73+
"""
74+
75+
def __init__(self):
76+
self._setupOriginServer() # or self.setupServers()
77+
self._setupTS() # or self.setupATS()
78+
79+
def _setupOriginServer(self):
80+
# Create origin server(s)
81+
self._server = Test.MakeOriginServer("server")
82+
# OR for replay-based tests:
83+
# self.server = Test.MakeVerifierServerProcess("server-name", "replay/file.replay.yaml")
84+
85+
def _setupTS(self):
86+
# Create ATS process
87+
self._ts = Test.MakeATSProcess("ts")
88+
89+
# Configure records.config
90+
self._ts.Disk.records_config.update({
91+
"proxy.config.diags.debug.enabled": 1,
92+
"proxy.config.diags.debug.tags": "relevant_debug_tags",
93+
# Add other configuration as needed
94+
})
95+
96+
# Configure remap.config if needed
97+
self._ts.Disk.remap_config.AddLine(
98+
f"map / http://127.0.0.1:{self.server.Variables.http_port}/"
99+
)
100+
101+
# Configure plugins if needed
102+
# self._ts.Disk.plugin_config.AddLine('plugin_name.so plugin_args')
103+
104+
# Set up log validation if needed
105+
# self._ts.Disk.diags_log.Content += Testers.ContainsExpression(
106+
# "expected log message", "Description of what this validates"
107+
# )
108+
109+
def run(self):
110+
# Execute test scenarios
111+
self._testScenario1()
112+
self._testScenario2()
113+
# etc.
114+
115+
def testScenario1(self):
116+
tr = Test.AddTestRun('Description of this test scenario')
117+
118+
# Start processes
119+
tr.Processes.Default.StartBefore(self._server)
120+
tr.Processes.Default.StartBefore(self._ts)
121+
122+
# Execute test command
123+
# Option 1: curl command
124+
tr.MakeCurlCommand(f"-vs --http1.1 http://127.0.0.1:{self._ts.Variables.port}/path", ts=self._ts)
125+
126+
# Option 2: custom command
127+
# tr.Processes.Default.Command = "your_command_here"
128+
129+
# Option 3: verifier client for replay tests
130+
# tr.AddVerifierClientProcess("client-name", "replay/file.replay.yaml",
131+
# http_ports=[self._ts.Variables.port])
132+
133+
# Set expectations
134+
tr.Processes.Default.ReturnCode = 0
135+
tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
136+
'expected_output', 'Description of what this validates'
137+
)
138+
# Optionally compare output to a gold file.
139+
# tr.Processes.Default.Streams.stderr = "gold/expected_stderr.gold"
140+
tr.Processes.Default.TimeOut = 5
141+
142+
# Keep processes running for subsequent tests
143+
tr.StillRunningAfter = self._server
144+
tr.StillRunningAfter = self._ts
145+
146+
# Execute the test
147+
YourTestClass().run()
148+
```
149+
150+
Key Framework Objects and Methods
151+
152+
Test Configuration
153+
- `Test.Summary`: Brief test description
154+
- `Test.ContinueOnFail`: Whether to continue after failures
155+
- `Test.SkipUnless()`: Conditional test execution
156+
- `Test.AddTestRun()`: Create new test run. Each test contains one or more of these.
157+
158+
Process Creation
159+
- `tr.MakeATSProcess` or `Test.MakeATSProcess("name")`: Create an ATS instance for a test run or a global one.
160+
- `tr.MakeOriginServer("name")` or `Test.MakeOriginServer("name")`: Create an origin server for a test run or a global one.
161+
- `tr.AddVerifierServerProcess` or `Test.MakeVerifierServerProcess("name", "replay_file")`: Create replay-based server
162+
- Note that every process, except for the Default process for each TestRun, takes a name and the name has to be unique across all Process names in the test.py file.
163+
164+
Proxy Verifier Client and Server
165+
- `tr.MakeoriginServer` is the legacy server type. It just sets up a server. Typically client HTTP traffic is generated using curl. New tests should use `AddVerifierServerProcess`
166+
- `tr.AddVerifierServerProcess` is paired with `tr.AddVerifierClientProcess` which both use the same external replay config yaml file. These two processes then exchange traffic to test ATS per the replay yaml file that has verification rules.
167+
- For proxy-verifier documentation, see: https://github.com/yahoo/proxy-verifier
168+
169+
Here's an example for how the server can be configured:
170+
171+
```python
172+
def _configure_server(self, tr: 'TestRun'):
173+
"""Configure the server.
174+
175+
:param tr: The TestRun object to associate the server process with.
176+
"""
177+
server = tr.AddVerifierServerProcess(f"server_{Test_ip_allow.server_counter}", self.replay_file)
178+
Test_ip_allow.server_counter += 1
179+
self._server = server
180+
```
181+
182+
Here's an example of how the client is configured:
183+
184+
```python
185+
tr.Processes.Default.StartBefore(self._server)
186+
tr.Processes.Default.StartBefore(self._ts)
187+
188+
tr.AddVerifierClientProcess(
189+
f'client-{Test_ip_allow.client_counter}',
190+
self.replay_file,
191+
http_ports=[self._ts.Variables.proxy_protocol_port],
192+
https_ports=[self._ts.Variables.ssl_port],
193+
http3_ports=[self._ts.Variables.ssl_port],
194+
keys=self.replay_keys)
195+
```
196+
197+
ATS Configuration
198+
- `ts.Disk.records_config.update`: Basic ATS configuration
199+
- `ts.Disk.remap_config.AddLine()`: Add a remap rule.
200+
- `ts.Disk.remap_config.AddLines()`: Add multiple remap rules.
201+
- `ts.Variables.port`, `ts.Variables.ssl_port`: Access ATS HTTP or HTTPS port
202+
203+
ATS HTTPS Configuration
204+
Many tests require testing HTTPS. This requires some specific configuration:
205+
- `ts.addDefaultSSLFiles` Copy the default SSL certs for ATS to use.
206+
- `ts.Disk.ssl_multicert_config.AddLine("dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key")` configure ATS to use the certs
207+
208+
Also for HTTP, add these configurations to the records_config.update:
209+
210+
```python
211+
"proxy.config.ssl.server.cert.path": f"{self.ts.Variables.SSLDir}",
212+
"proxy.config.ssl.server.private_key.path": f"{self.ts.Variables.SSLDir}",
213+
```
214+
215+
Plugin testing considerations:
216+
Some tests verify plugin behavior. Follow these guidelines when testing a plugin:
217+
- `ts.Disk.plugin_config.AddLine()`: Configure plugins. This must be done for any plugin under test.
218+
- Add `Test.SkipUnless(Condition.PluginExists('plugin_name.so'))` at the top of the test to only run if the plugin is installed.
219+
220+
Traffic Generation
221+
- `tr.Processes.Default.Command`: Set custom command. Sometimes a test has an adhoc Python script to generate traffic, for example.
222+
- `tr.MakeCurlCommand()`: Execute curl command. This sets tr.Processes.Default.Command to run a curl command.
223+
- `tr.AddVerifierClientProcess()`: This also sets tr.Processes.Default.Command to use the Proxy Verifier replay client to generate traffic. This takes, among other parameters, the name of a replay file.
224+
- `tr.Processes.Default.StartBefore()`: Start process before the client starts. This must be done for ats and all servers before the client starts. Although, if there are global servers, they can only be started once by the first Default process of the first TestRun.
225+
226+
Validation
227+
- `Testers.ContainsExpression(pattern, description)`: Validate output contains pattern. Generally += these.
228+
- `tr.Processes.Default.ReturnCode`: Expected exit code. By default it is 0, but certain negative tests should expect 1.
229+
- `tr.Processes.Default.Streams.all`: Stream validation
230+
- `tr.Processes.Default.TimeOut`: Test timeout
231+
- `tr.StillRunningAfter`: Ensure the server is still running after the client finishes.
232+
- For VerifierClient and VerifierServer, much validation is done in the replay files themselves. The test.py should add output verification that each transaction happened as expected.
233+
234+
Here's an example Verifier replay file:
235+
236+
```yaml
237+
# Licensed to the Apache Software Foundation (ASF) under one
238+
# or more contributor license agreements. See the NOTICE file
239+
# distributed with this work for additional information
240+
# regarding copyright ownership. The ASF licenses this file
241+
# to you under the Apache License, Version 2.0 (the
242+
# "License"); you may not use this file except in compliance
243+
# with the License. You may obtain a copy of the License at
244+
#
245+
# http://www.apache.org/licenses/LICENSE-2.0
246+
#
247+
# Unless required by applicable law or agreed to in writing, software
248+
# distributed under the License is distributed on an "AS IS" BASIS,
249+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
250+
# See the License for the specific language governing permissions and
251+
# limitations under the License.
252+
253+
sessions:
254+
255+
- transactions:
256+
257+
- client-request:
258+
method: GET
259+
url: /
260+
version: '1.1'
261+
headers:
262+
fields:
263+
- [ Host, fqdn1 ]
264+
- [ uuid, 1 ]
265+
266+
proxy-response:
267+
status: 200
268+
headers:
269+
fields:
270+
- [ Content-Length, { value: 19, as: equal } ]
271+
- [ Cache-Control, { value: no-cache, as: equal } ]
272+
- [ Content-Type, { value: text/plain, as: equal } ]
273+
- [ Server, { value: ATS, as: contains } ]
274+
content:
275+
encoding: plain
276+
data: |
277+
small body content
278+
verify: { as: equal }
279+
280+
- client-request:
281+
method: GET
282+
url: /path
283+
version: '1.1'
284+
headers:
285+
fields:
286+
- [ Host, fqdn1 ]
287+
- [ uuid, 2 ]
288+
289+
proxy-response:
290+
status: 404
291+
headers:
292+
fields:
293+
- [ Cache-Control, { value: no-store, as: equal } ]
294+
- [ Content-Type, { value: text/html, as: equal } ]
295+
- [ Server, { value: ATS, as: contains } ]
296+
content:
297+
encoding: plain
298+
data: Error
299+
verify: { as: contains }
300+
```
301+
302+
Replay Yaml Notes:
303+
- Each transaction will have a client-request and a server-response which each generate the HTTP request and response, respectively.
304+
- Each transaction's client-request has a uuid header whose value uniquely identifies the transaction.
305+
- proxy-request and proxy-response nodes do not generate traffic but rather verify content. See their value: and as: content above.
306+
- The proxy-response status: node verifies the status. This is generally important for verifying a 200 or some other HTTP response from ATS.
307+
308+
Best Practices:
309+
- **Class Organization**: Use classes to group related test scenarios
310+
- **Separation of Concerns**: Separate server setup, ATS setup, and test execution as separate functions in the class.
311+
- **Descriptive Names**: Use clear, descriptive names for test runs and processes. Pass a descriptive name to `tr.AddTestRun('<concise test run description>')`
312+
- **Documentation**: Include docstrings explaining test purpose and setup as well as type hints.
313+
- **Gold Files**: Use gold files for complex expected outputs in subdirectories. These can be slow, so prefer ContainsExpression/ExcludesExpressions.
314+
- **Debug Configuration**: Enable relevant debug tags for troubleshooting.
315+
- **Cache IO**: if testing the ATS cache, one transaction has to populate the cache. If using VerifierClient, put a `delay: 100ms` in the client-request for the following transaction to make a 100ms delay for the cache to finish IO.
316+
317+
318+
When generating autests, follow these patterns and adapt the template to the specific testing scenario while maintaining the declarative, configuration-driven approach that characterizes the autest framework.

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,10 @@ check_symbol_exists(SSL_set1_verify_cert_store "openssl/ssl.h" TS_HAS_VERIFY_CER
503503
check_symbol_exists(SSL_get_shared_curve "openssl/ssl.h" HAVE_SSL_GET_SHARED_CURVE)
504504
check_symbol_exists(SSL_get_curve_name "openssl/ssl.h" HAVE_SSL_GET_CURVE_NAME)
505505
check_symbol_exists(SSL_get0_group_name "openssl/ssl.h" HAVE_SSL_GET0_GROUP_NAME)
506+
check_symbol_exists(SSL_get_negotiated_group "openssl/ssl.h" HAVE_SSL_GET_NEGOTIATED_GROUP)
506507
check_symbol_exists(SSL_get_group_id "openssl/ssl.h" HAVE_SSL_GET_GROUP_ID)
507508
check_symbol_exists(SSL_get_group_name "openssl/ssl.h" HAVE_SSL_GET_GROUP_NAME)
509+
check_symbol_exists(SSL_group_to_name "openssl/ssl.h" HAVE_SSL_GROUP_TO_NAME)
508510
check_symbol_exists(SSL_set_max_early_data "openssl/ssl.h" HAVE_SSL_SET_MAX_EARLY_DATA)
509511
check_symbol_exists(SSL_read_early_data "openssl/ssl.h" HAVE_SSL_READ_EARLY_DATA)
510512
check_symbol_exists(SSL_write_early_data "openssl/ssl.h" HAVE_SSL_WRITE_EARLY_DATA)

CMakePresets.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,19 @@
357357
"inherits": ["branch"],
358358
"cacheVariables": {
359359
"ENABLE_AUTEST": "ON",
360-
"ENABLE_EXAMPLE": "ON"
360+
"ENABLE_EXAMPLE": "ON",
361+
"ENABLE_CRIPTS": "ON"
362+
}
363+
},
364+
{
365+
"name": "branch-autest-uds",
366+
"displayName": "CI branch autest",
367+
"inherits": ["branch"],
368+
"cacheVariables": {
369+
"ENABLE_AUTEST": "ON",
370+
"ENABLE_AUTEST_UDS": "ON",
371+
"ENABLE_EXAMPLE": "ON",
372+
"ENABLE_CRIPTS": "ON"
361373
}
362374
},
363375
{

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fosx%2F&label=macOS)](https://ci.trafficserver.apache.org/job/master/job/osx/)
1010
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fosx-m1%2F&label=macOS%20arm64)](https://ci.trafficserver.apache.org/job/master/job/osx-m1/)
1111
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fos-rockylinux_8%2F&label=Rocky%20Linux%208)](https://ci.trafficserver.apache.org/job/master/job/os-rockylinux_8/)
12-
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fos-rockylinux_8%2F&label=Rocky%20Linux%209)](https://ci.trafficserver.apache.org/job/master/job/os-rockylinux_9/)
12+
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fos-rockylinux_9%2F&label=Rocky%20Linux%209)](https://ci.trafficserver.apache.org/job/master/job/os-rockylinux_9/)
1313
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fos-ubuntu_20.04%2F&label=Ubuntu%2020.04)](https://ci.trafficserver.apache.org/job/master/job/os-ubuntu_20.04/)
1414
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fos-ubuntu_22.04%2F&label=Ubuntu%2022.04)](https://ci.trafficserver.apache.org/job/master/job/os-ubuntu_22.04/)
1515
[![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fci.trafficserver.apache.org%2Fjob%2Fmaster%2Fjob%2Fos-ubuntu_23.04%2F&label=Ubuntu%2023.04)](https://ci.trafficserver.apache.org/job/master/job/os-ubuntu_23.04/)

ci/rat-regex.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ port\.h
6666
^override.css$
6767
^catch[.]hpp$
6868
^configuru.hpp$
69+
^Catch2$
6970
^yamlcpp$
7071
^systemtap$
7172
^swoc$

cmake/ExperimentalPlugins.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ auto_option(
8787
${_DEFAULT}
8888
)
8989
auto_option(RATE_LIMIT FEATURE_VAR BUILD_RATE_LIMIT DEFAULT ${_DEFAULT})
90+
auto_option(REALIP FEATURE_VAR BUILD_REALIP DEFAULT ${_DEFAULT})
9091
auto_option(REDO_CACHE_LOOKUP FEATURE_VAR BUILD_REDO_CACHE_LOOKUP DEFAULT ${_DEFAULT})
9192
auto_option(SSLHEADERS FEATURE_VAR BUILD_SSLHEADERS DEFAULT ${_DEFAULT})
9293
auto_option(STALE_RESPONSE FEATURE_VAR BUILD_STALE_RESPONSE DEFAULT ${_DEFAULT})

0 commit comments

Comments
 (0)