1''' 2''' 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, software 14# distributed under the License is distributed on an "AS IS" BASIS, 15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16# See the License for the specific language governing permissions and 17# limitations under the License. 18 19Test.Summary = ''' 20Test next hop selection using strategies.yaml with consistent hashing, with fallover 21''' 22 23# Define and populate MicroServer. 24# 25server = Test.MakeOriginServer("server") 26response_header = { 27 "headers": 28 "HTTP/1.1 200 OK\r\n" 29 "Connection: close\r\n" 30 "Cache-control: max-age=85000\r\n" 31 "\r\n", 32 "timestamp": "1469733493.993", 33 "body": "This is the body.\n" 34} 35num_objects = 32 36for i in range(num_objects): 37 request_header = { 38 "headers": 39 f"GET /obj{i} HTTP/1.1\r\n" 40 "Host: does.not.matter\r\n" # But cannot be omitted. 41 "\r\n", 42 "timestamp": "1469733493.993", 43 "body": "" 44 } 45 server.addResponse("sessionlog.json", request_header, response_header) 46 47dns = Test.MakeDNServer("dns") 48 49# Define next hop trafficserver instances. 50# 51num_nh = 8 52ts_nh = [] 53for i in range(num_nh): 54 ts = Test.MakeATSProcess(f"ts_nh{i}") 55 ts.Disk.records_config.update({ 56 'proxy.config.diags.debug.enabled': 1, 57 'proxy.config.diags.debug.tags': 'http|dns', 58 'proxy.config.dns.nameservers': f"127.0.0.1:{dns.Variables.Port}", 59 'proxy.config.dns.resolv_conf': "NULL", 60 }) 61 ts.Disk.remap_config.AddLine( 62 f"map / http://127.0.0.1:{server.Variables.Port}" 63 ) 64 ts_nh.append(ts) 65 66ts = Test.MakeATSProcess("ts", command="traffic_server 2> trace.log") 67 68ts.Disk.records_config.update({ 69 'proxy.config.diags.debug.enabled': 1, 70 'proxy.config.diags.debug.tags': 'http|dns|parent|next_hop|host_statuses|hostdb', 71 'proxy.config.dns.nameservers': f"127.0.0.1:{dns.Variables.Port}", # Only nameservers if resolv_conf NULL. 72 'proxy.config.dns.resolv_conf': "NULL", # This defaults to /etc/resvolv.conf (OS namesevers) if not NULL. 73 'proxy.config.http.cache.http': 0, 74 'proxy.config.http.uncacheable_requests_bypass_parent': 0, 75 'proxy.config.http.no_dns_just_forward_to_parent': 1, 76 'proxy.config.http.parent_proxy.mark_down_hostdb': 1, 77 'proxy.config.http.parent_proxy.self_detect': 0, 78}) 79 80ts.Disk.File(ts.Variables.CONFIGDIR + "/strategies.yaml", id="strategies", typename="ats:config") 81s = ts.Disk.strategies 82s.AddLine("groups:") 83s.AddLine(" - &g1") 84for i in range(num_nh): 85 dns.addRecords(records={f"next_hop{i}": ["127.0.0.1"]}) 86 s.AddLine(f" - host: next_hop{i}") 87 s.AddLine(f" protocol:") 88 s.AddLine(f" - scheme: http") 89 s.AddLine(f" port: {ts_nh[i].Variables.port}") 90 # The health check URL does not seem to be used currently. 91 # s.AddLine(f" health_check_url: http://next_hop{i}:{ts_nh[i].Variables.port}") 92 s.AddLine(f" weight: 1.0") 93s.AddLines([ 94 "strategies:", 95 " - strategy: the-strategy", 96 " policy: consistent_hash", 97 " hash_key: path", 98 " go_direct: false", 99 " parent_is_proxy: true", 100 " ignore_self_detect: true", 101 " groups:", 102 " - *g1", 103 " scheme: http" 104]) 105 106# Use default fallover config. 107# 108# s.AddLines([ 109# " fallover:", 110# " max_simple_retries: 2", 111# " ring_mode: exhaust_ring", 112# " response_codes:", 113# " - 404", 114# " health_check:", 115# " - passive" 116# ]) 117 118ts.Disk.remap_config.AddLine( 119 "map http://dummy.com http://not_used @strategy=the-strategy" 120) 121 122tr = Test.AddTestRun() 123tr.Processes.Default.StartBefore(server) 124tr.Processes.Default.StartBefore(dns) 125for i in range(num_nh): 126 if (i != 3) and (i != 6): 127 tr.Processes.Default.StartBefore(ts_nh[i]) 128tr.Processes.Default.StartBefore(Test.Processes.ts) 129tr.Processes.Default.Command = 'echo start TS, HTTP server, DNS server and all but 2 next hop TSes' 130tr.Processes.Default.ReturnCode = 0 131 132for i in range(num_objects): 133 tr = Test.AddTestRun() 134 tr.Processes.Default.Command = ( 135 f'curl --verbose --proxy 127.0.0.1:{ts.Variables.port} http://dummy.com/obj{i}' 136 ) 137 tr.Processes.Default.Streams.stdout = "body.gold" 138 tr.Processes.Default.ReturnCode = 0 139 140tr = Test.AddTestRun() 141tr.Processes.Default.StartBefore(ts_nh[3]) 142tr.Processes.Default.StartBefore(ts_nh[6]) 143tr.Processes.Default.Command = 'echo start the 2 unstarted next hop TSes' 144tr.Processes.Default.ReturnCode = 0 145 146for i in range(num_objects): 147 tr = Test.AddTestRun() 148 tr.Processes.Default.Command = ( 149 f'curl --verbose --proxy 127.0.0.1:{ts.Variables.port} http://dummy.com/obj{i}' 150 ) 151 tr.Processes.Default.Streams.stdout = "body.gold" 152 tr.Processes.Default.ReturnCode = 0 153 154tr = Test.AddTestRun() 155tr.Processes.Default.Command = ( 156 "grep -F PARENT_SPECIFIED trace.log | sed 's/^.*(next_hop) [^ ]* //' | sed 's/[.][0-9]*$$//'" 157) 158tr.Processes.Default.Streams.stdout = "trace.gold" 159tr.Processes.Default.ReturnCode = 0 160