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

shinrich 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 4d5d377  Make double* and openclose* reliably wait for stats to be 
ready
4d5d377 is described below

commit 4d5d377a785bec291a67a52b5186ff4c6d733459
Author: shinrich <shinr...@unknown-192-168-122-x.yahoo.com>
AuthorDate: Thu Nov 8 14:51:06 2018 -0500

    Make double* and openclose* reliably wait for stats to be ready
---
 tests/gold_tests/continuations/double.test.py      | 137 +++++++++++----------
 tests/gold_tests/continuations/double_h2.test.py   |  92 +++++++-------
 tests/gold_tests/continuations/openclose.test.py   |  73 ++++++-----
 .../gold_tests/continuations/openclose_h2.test.py  | 136 ++++++++++----------
 tests/tools/plugins/continuations_verify.cc        |  55 ++++++---
 tests/tools/plugins/ssntxnorder_verify.cc          |  35 +++---
 6 files changed, 282 insertions(+), 246 deletions(-)

diff --git a/tests/gold_tests/continuations/double.test.py 
b/tests/gold_tests/continuations/double.test.py
index b3f98d0..f6ba705 100644
--- a/tests/gold_tests/continuations/double.test.py
+++ b/tests/gold_tests/continuations/double.test.py
@@ -17,112 +17,125 @@
 #  limitations under the License.
 
 import os
+import subprocess
 Test.Summary = '''
-Test transactions and sessions, making sure two continuations catch the same 
number of hooks.
+Test transactions and sessions for http1, making sure the two continuations 
catch the same number of hooks.
 '''
-Test.SkipIf(Condition.true('This test errors frequently, and so it is 
disabled.'))
+
 Test.SkipUnless(
-    Condition.HasProgram("curl", "Curl needs to be installed on system for 
this test to work")
+    Condition.HasProgram("curl", "Curl needs to be installed on system for 
this test to work"),
 )
 Test.ContinueOnFail = True
 # Define default ATS
-ts = Test.MakeATSProcess("ts", command="traffic_manager")
-
+ts = Test.MakeATSProcess("ts", select_ports=False, command="traffic_manager")
 server = Test.MakeOriginServer("server")
+server2 = Test.MakeOriginServer("server2")
 
 Test.testName = ""
-request_header = {"headers": "GET / HTTP/1.1\r\nHost: double.test\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
+request_header = {"headers": "GET / HTTP/1.1\r\nHost: double_h2.test\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\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
-
-Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir, 'plugins', 
'continuations_verify.cc'), ts)
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\nContent-Length:0\r\n\r\n",
+                   "timestamp": "1469733493.993", "body": ""}
 
 # add response to the server dictionary
 server.addResponse("sessionfile.log", request_header, response_header)
+
+# add port and remap rule
+ts.Disk.remap_config.AddLine(
+    'map / http://127.0.0.1:{0}'.format(server.Variables.Port)
+)
+
 ts.Disk.records_config.update({
     'proxy.config.diags.debug.enabled': 1,
     'proxy.config.diags.debug.tags': 'continuations_verify.*',
-    'proxy.config.http.cache.http' : 0, #disable cache to simply the test.
-    'proxy.config.cache.enable_read_while_writer' : 0
+    'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.ssl.server.private_key.path': 
'{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.http.cache.http': 0,  # disable cache to simply the test.
+    'proxy.config.cache.enable_read_while_writer': 0,
+    'proxy.config.ssl.client.verify.server':  0,
+    'proxy.config.ssl.server.cipher_suite': 
'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2',
+    'proxy.config.http2.max_concurrent_streams_in': 65535
 })
-ts.Disk.remap_config.AddLine(
-    'map http://double.test:{0} 
http://127.0.0.1:{1}'.format(ts.Variables.port, server.Variables.Port)
-)
 
-cmd = 'curl -vs http://127.0.0.1:{0}'.format(ts.Variables.port)
-numberOfRequests = 25
+# add plugin to assist with test metrics
+Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir,
+                                 'plugins', 'continuations_verify.cc'), ts)
+
+comparator_command = '''
+if test "`traffic_ctl metric get continuations_verify.{0}.close.1 | cut -d ' ' 
-f 2`" -eq "`traffic_ctl metric get continuations_verify.{0}.close.2 | cut -d ' 
' -f 2`" ; then\
+     echo yes;\
+    else \
+    echo no; \
+    fi; \
+    traffic_ctl metric match continuations_verify
+    '''
+
+cmd = 'curl -vs http://127.0.0.1:{0}/'.format(ts.Variables.port)
+numberOfRequests = 55
 
 tr = Test.AddTestRun()
 
 # Create a bunch of curl commands to be executed in parallel. Default.Process 
is set in SpawnCommands.
-ps = tr.SpawnCommands(cmdstr=cmd,  count=numberOfRequests)
+# On Fedora 28/29, it seems that curl will occaisionally timeout after a 
couple seconds and return exitcode 2
+# Examinig the packet capture shows that Traffic Server dutifully sends the 
response
+ps = tr.SpawnCommands(cmdstr=cmd, count=numberOfRequests, retcode=Any(0,2))
 tr.Processes.Default.Env = ts.Env
+tr.Processes.Default.ReturnCode = Any(0,2)
 
 # Execution order is: ts/server, ps(curl cmds), Default Process.
 tr.Processes.Default.StartBefore(
     server, ready=When.PortOpen(server.Variables.Port))
 # Adds a delay once the ts port is ready. This is because we cannot test the 
ts state.
-tr.Processes.Default.StartBefore(ts, ready=10)
+tr.Processes.Default.StartBefore(Test.Processes.ts, 
ready=When.PortOpen(ts.Variables.port))
 ts.StartAfter(*ps)
 server.StartAfter(*ps)
 tr.StillRunningAfter = ts
 
-comparator_command = '''
-if test "`traffic_ctl metric get continuations_verify.{0}.close.1 | cut -d ' ' 
-f 2`" -eq "`traffic_ctl metric get continuations_verify.{0}.close.2 | cut -d ' 
' -f 2`" ; then\
-     echo yes;\
-    else \
-    echo no; \
-    fi;
-    '''
+# Signal that all the curl processes have completed
+tr = Test.AddTestRun("Curl Done")
+tr.Processes.Default.Command = "traffic_ctl plugin msg done done"
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Env = ts.Env
+tr.StillRunningAfter = ts
 
-records = ts.Disk.File(os.path.join(ts.Variables.RUNTIMEDIR, "records.snap"))
+# Parking this as a ready tester on a meaningless process
+# To stall the test runs that check for the stats until the
+# stats have propagated and are ready to read.
+def make_done_stat_ready(tsenv): 
+  def done_stat_ready(process, hasRunFor, **kw):
+    retval = subprocess.run("traffic_ctl metric get 
continuations_verify.test.done > done  2> /dev/null", shell=True, env=tsenv)
+    if retval.returncode == 0:
+      retval = subprocess.run("grep 1 done > /dev/null", shell = True, 
env=tsenv)
+    return retval.returncode == 0
 
+  return done_stat_ready
+  
 # number of sessions/transactions opened and closed are equal
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
+tr = Test.AddTestRun("Check Ssn")
+server2.StartupTimeout = 60
+# Again, here the imporant thing is the ready function not the server2 process
+tr.Processes.Default.StartBefore(server2, ready=make_done_stat_ready(ts.Env))
 tr.Processes.Default.Command = comparator_command.format('ssn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression("yes", 
'should verify contents')
+# Session and Txn's should be non-zero
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.ssn.close.1 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.ssn.close.2 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.txn.close.1 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.txn.close.2 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
+    "continuations_verify.txn.close.1 {}".format(numberOfRequests), 'should be 
the number of transactions we made')
+tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
+    "continuations_verify.txn.close.2 {}".format(numberOfRequests), 'should be 
the number of transactions we made')
 tr.StillRunningAfter = ts
-# for debugging session number
-ssn1 = tr.Processes.Process("session1", 'traffic_ctl metric get 
continuations_verify.ssn.close.1 > ssn1')
-ssn2 = tr.Processes.Process("session2", 'traffic_ctl metric get 
continuations_verify.ssn.close.2 > ssn2')
-ssn1.Env = ts.Env
-ssn2.Env = ts.Env
-tr.Processes.Default.StartBefore(ssn1)
-tr.Processes.Default.StartBefore(ssn2)
+tr.StillRunningAfter = server2
 
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
+tr = Test.AddTestRun("Check Txn")
 tr.Processes.Default.Command = comparator_command.format('txn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression("yes", 
'should verify contents')
 tr.StillRunningAfter = ts
-# for debugging transaction number
-txn1 = tr.Processes.Process("transaction1", 'traffic_ctl metric get 
continuations_verify.txn.close.1 > txn1')
-txn2 = tr.Processes.Process("transaction2", 'traffic_ctl metric get 
continuations_verify.txn.close.2 > txn2')
-txn1.Env = ts.Env
-txn2.Env = ts.Env
-tr.Processes.Default.StartBefore(txn1)
-tr.Processes.Default.StartBefore(txn2)
-
-# session count is positive,
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
-tr.Processes.Default.Command = "traffic_ctl metric get 
continuations_verify.ssn.close.1"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ExcludesExpression(" 0", 'should 
be nonzero')
-tr.StillRunningAfter = ts
+tr.StillRunningAfter = server2
 
-# and we receive the same number of transactions as we asked it to make
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
-tr.Processes.Default.Command = "traffic_ctl metric get 
continuations_verify.txn.close.1"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
-    "continuations_verify.txn.close.1 {}".format(numberOfRequests), 'should be 
the number of transactions we made')
-tr.StillRunningAfter = ts
diff --git a/tests/gold_tests/continuations/double_h2.test.py 
b/tests/gold_tests/continuations/double_h2.test.py
index 61da07d..86aace4 100644
--- a/tests/gold_tests/continuations/double_h2.test.py
+++ b/tests/gold_tests/continuations/double_h2.test.py
@@ -17,6 +17,7 @@
 #  limitations under the License.
 
 import os
+import subprocess
 Test.Summary = '''
 Test transactions and sessions for http2, making sure the two continuations 
catch the same number of hooks.
 '''
@@ -28,11 +29,12 @@ Test.ContinueOnFail = True
 # Define default ATS
 ts = Test.MakeATSProcess("ts", select_ports=False, command="traffic_manager")
 server = Test.MakeOriginServer("server")
+server2 = Test.MakeOriginServer("server2")
 
 Test.testName = ""
 request_header = {"headers": "GET / HTTP/1.1\r\nHost: double_h2.test\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\n\r\n",
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\nContent-Length:0\r\n\r\n",
                    "timestamp": "1469733493.993", "body": ""}
 
 # add response to the server dictionary
@@ -45,7 +47,7 @@ ts.addSSLfile("ssl/server.key")
 # add port and remap rule
 ts.Variables.ssl_port = 4443
 ts.Disk.remap_config.AddLine(
-    'map http://double_h2.test:{0} 
http://127.0.0.1:{1}'.format(ts.Variables.port, server.Variables.Port)
+    'map / http://127.0.0.1:{0}'.format(server.Variables.Port)
 )
 
 ts.Disk.ssl_multicert_config.AddLine(
@@ -54,7 +56,7 @@ ts.Disk.ssl_multicert_config.AddLine(
 
 ts.Disk.records_config.update({
     'proxy.config.diags.debug.enabled': 1,
-    'proxy.config.diags.debug.tags': 'continuations_verify.*',
+    'proxy.config.diags.debug.tags': 'continuations_verify',
     'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
     'proxy.config.ssl.server.private_key.path': 
'{0}'.format(ts.Variables.SSLDir),
     'proxy.config.http.cache.http': 0,  # disable cache to simply the test.
@@ -75,7 +77,8 @@ if test "`traffic_ctl metric get 
continuations_verify.{0}.close.1 | cut -d ' ' -
      echo yes;\
     else \
     echo no; \
-    fi;
+    fi; \
+    traffic_ctl metric match continuations_verify
     '''
 
 # curl with http2
@@ -85,69 +88,66 @@ numberOfRequests = 25
 tr = Test.AddTestRun()
 
 # Create a bunch of curl commands to be executed in parallel. Default.Process 
is set in SpawnCommands.
-ps = tr.SpawnCommands(cmdstr=cmd, count=numberOfRequests)
+# On Fedora 28/29, it seems that curl will occaisionally timeout after a 
couple seconds and return exitcode 2
+# Examinig the packet capture shows that Traffic Server dutifully sends the 
response
+ps = tr.SpawnCommands(cmdstr=cmd, count=numberOfRequests, retcode=Any(0,2))
 tr.Processes.Default.Env = ts.Env
+tr.Processes.Default.ReturnCode = Any(0,2)
 
 # Execution order is: ts/server, ps(curl cmds), Default Process.
 tr.Processes.Default.StartBefore(
     server, ready=When.PortOpen(server.Variables.Port))
 # Adds a delay once the ts port is ready. This is because we cannot test the 
ts state.
-tr.Processes.Default.StartBefore(ts, ready=10)
+tr.Processes.Default.StartBefore(Test.Processes.ts, 
ready=When.PortOpen(ts.Variables.ssl_port))
 ts.StartAfter(*ps)
 server.StartAfter(*ps)
 tr.StillRunningAfter = ts
 
-# Watch the records snapshot file.
-records = ts.Disk.File(os.path.join(ts.Variables.RUNTIMEDIR, "records.snap"))
+# Signal that all the curl processes have completed
+tr = Test.AddTestRun("Curl Done")
+tr.Processes.Default.Command = "traffic_ctl plugin msg done done"
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Env = ts.Env
+tr.StillRunningAfter = ts
 
+# Parking this as a ready tester on a meaningless process
+# To stall the test runs that check for the stats until the
+# stats have propagated and are ready to read.
+def make_done_stat_ready(tsenv): 
+  def done_stat_ready(process, hasRunFor, **kw):
+    retval = subprocess.run("traffic_ctl metric get 
continuations_verify.test.done > done  2> /dev/null", shell=True, env=tsenv)
+    if retval.returncode == 0:
+      retval = subprocess.run("grep 1 done > /dev/null", shell = True, 
env=tsenv)
+    return retval.returncode == 0
+
+  return done_stat_ready
+  
 # number of sessions/transactions opened and closed are equal
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
+tr = Test.AddTestRun("Check Ssn")
+server2.StartupTimeout = 60
+# Again, here the imporant thing is the ready function not the server2 process
+tr.Processes.Default.StartBefore(server2, ready=make_done_stat_ready(ts.Env))
 tr.Processes.Default.Command = comparator_command.format('ssn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression("yes", 
'should verify contents')
+# Session and Txn's should be non-zero
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.ssn.close.1 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.ssn.close.2 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.txn.close.1 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += 
Testers.ExcludesExpression("continations_verify.txn.close.2 0", 'should be 
nonzero')
+tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
+    "continuations_verify.txn.close.1 {}".format(numberOfRequests), 'should be 
the number of transactions we made')
+tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
+    "continuations_verify.txn.close.2 {}".format(numberOfRequests), 'should be 
the number of transactions we made')
 tr.StillRunningAfter = ts
+tr.StillRunningAfter = server2
 
-# for debugging session number
-ssn1 = tr.Processes.Process("session1", 'traffic_ctl metric get 
continuations_verify.ssn.close.1 > ssn1')
-ssn2 = tr.Processes.Process("session2", 'traffic_ctl metric get 
continuations_verify.ssn.close.2 > ssn2')
-ssn1.Env = ts.Env
-ssn2.Env = ts.Env
-tr.Processes.Default.StartBefore(ssn1)
-tr.Processes.Default.StartBefore(ssn2)
-
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
+tr = Test.AddTestRun("Check Txn")
 tr.Processes.Default.Command = comparator_command.format('txn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression("yes", 
'should verify contents')
 tr.StillRunningAfter = ts
+tr.StillRunningAfter = server2
 
-# for debugging transaction number
-txn1 = tr.Processes.Process("transaction1", 'traffic_ctl metric get 
continuations_verify.txn.close.1 > txn1')
-txn2 = tr.Processes.Process("transaction2", 'traffic_ctl metric get 
continuations_verify.txn.close.2 > txn2')
-txn1.Env = ts.Env
-txn2.Env = ts.Env
-tr.Processes.Default.StartBefore(txn1)
-tr.Processes.Default.StartBefore(txn2)
-
-# session count is positive,
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
-tr.Processes.Default.Command = "traffic_ctl metric get 
continuations_verify.ssn.close.1"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ExcludesExpression(" 0", 'should 
be nonzero')
-tr.StillRunningAfter = ts
-
-# and we receive the same number of transactions as we asked it to make
-tr = Test.AddTestRun()
-tr.DelayStart = 10 # wait for stats to be updated
-tr.Processes.Default.Command = "traffic_ctl metric get 
continuations_verify.txn.close.1"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
-    "continuations_verify.txn.close.1 {}".format(numberOfRequests), 'should be 
the number of transactions we made')
-tr.StillRunningAfter = ts
diff --git a/tests/gold_tests/continuations/openclose.test.py 
b/tests/gold_tests/continuations/openclose.test.py
index 32d45bd..452ea13 100644
--- a/tests/gold_tests/continuations/openclose.test.py
+++ b/tests/gold_tests/continuations/openclose.test.py
@@ -17,6 +17,7 @@
 #  limitations under the License.
 
 import os
+import subprocess
 Test.Summary = '''
 Test transactions and sessions, making sure they open and close in the proper 
order.
 '''
@@ -29,12 +30,13 @@ Test.SkipUnless(
 ts = Test.MakeATSProcess("ts", command="traffic_manager")
 
 server = Test.MakeOriginServer("server")
+server2 = Test.MakeOriginServer("server2")
 
 Test.testName = ""
 request_header = {"headers": "GET / HTTP/1.1\r\nHost: oc.test\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\n\r\n",
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\nContent-Length:0\r\n\r\n",
                    "timestamp": "1469733493.993", "body": ""}
 
 Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir,
@@ -59,8 +61,11 @@ numberOfRequests = 25
 
 tr = Test.AddTestRun()
 # Create a bunch of curl commands to be executed in parallel. Default.Process 
is set in SpawnCommands.
-ps = tr.SpawnCommands(cmdstr=cmd,  count=numberOfRequests)
+# On Fedora 28/29, it seems that curl will occaisionally timeout after a 
couple seconds and return exitcode 2
+# Examinig the packet capture shows that Traffic Server dutifully sends the 
response
+ps = tr.SpawnCommands(cmdstr=cmd,  count=numberOfRequests, retcode=Any(0,2))
 tr.Processes.Default.Env = ts.Env
+tr.Processes.Default.ReturnCode = Any(0,2)
 
 # Execution order is: ts/server, ps(curl cmds), Default Process.
 tr.Processes.Default.StartBefore(
@@ -71,13 +76,30 @@ ts.StartAfter(*ps)
 server.StartAfter(*ps)
 tr.StillRunningAfter = ts
 
-# Watch the records snapshot file.
-records = ts.Disk.File(os.path.join(ts.Variables.RUNTIMEDIR, "records.snap"))
+# Signal that all the curl processes have completed
+tr = Test.AddTestRun("Curl Done")
+tr.Processes.Default.Command = "traffic_ctl plugin msg done done"
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Env = ts.Env
+tr.StillRunningAfter = ts
 
-# Check our work on traffic_ctl
-# no errors happened,
-tr = Test.AddTestRun()
-tr.DelayStart = 10
+# Parking this as a ready tester on a meaningless process
+# To stall the test runs that check for the stats until the
+# stats have propagated and are ready to read.
+def make_done_stat_ready(tsenv): 
+  def done_stat_ready(process, hasRunFor, **kw):
+    retval = subprocess.run("traffic_ctl metric get 
ssntxnorder_verify.test.done > done  2> /dev/null", shell=True, env=tsenv)
+    if retval.returncode == 0:
+      retval = subprocess.run("grep 1 done > /dev/null", shell = True, 
env=tsenv)
+    return retval.returncode == 0
+
+  return done_stat_ready
+  
+# number of sessions/transactions opened and closed are equal
+tr = Test.AddTestRun("Check Ssn order errors")
+server2.StartupTimeout = 60
+# Again, here the imporant thing is the ready function not the server2 process
+tr.Processes.Default.StartBefore(server2, ready=make_done_stat_ready(ts.Env))
 tr.Processes.Default.Command = 'traffic_ctl metric get ssntxnorder_verify.err'
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
@@ -91,48 +113,33 @@ if test "`traffic_ctl metric get 
ssntxnorder_verify.{0}.start | cut -d ' ' -f 2`
      echo yes;\
     else \
     echo no; \
-    fi;
+    fi; \
+    traffic_ctl metric match ssntxnorder_verify
     '''
 
 # number of sessions/transactions opened and closed are equal
-tr = Test.AddTestRun()
-tr.DelayStart = 10
+tr = Test.AddTestRun("Check for ssn open/close")
 tr.Processes.Default.Command = comparator_command.format('ssn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
     "yes", 'should verify contents')
+tr.Processes.Default.Streams.stdout += Testers.ExcludesExpression(
+    "ssntxnorder_verify.ssn.start 0", 'should be nonzero')
 tr.StillRunningAfter = ts
 tr.StillRunningAfter = server
 
-tr = Test.AddTestRun()
-tr.DelayStart = 10
+tr = Test.AddTestRun("Check for txn/open/close")
 tr.Processes.Default.Command = comparator_command.format('txn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
     "yes", 'should verify contents')
-tr.StillRunningAfter = ts
-tr.StillRunningAfter = server
-
-# session count is positive,
-tr = Test.AddTestRun()
-tr.DelayStart = 10
-tr.Processes.Default.Command = "traffic_ctl metric get 
ssntxnorder_verify.ssn.start"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ExcludesExpression(
-    " 0", 'should be nonzero')
-tr.StillRunningAfter = ts
-tr.StillRunningAfter = server
-
+tr.Processes.Default.Streams.stdout += Testers.ExcludesExpression(
+    "ssntxnorder_verify.txn.start 0", 'should be nonzero')
 # and we receive the same number of transactions as we asked it to make
-tr = Test.AddTestRun()
-tr.DelayStart = 10
-tr.Processes.Default.Command = "traffic_ctl metric get 
ssntxnorder_verify.txn.start"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
+tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
     "ssntxnorder_verify.txn.start {}".format(numberOfRequests), 'should be the 
number of transactions we made')
 tr.StillRunningAfter = ts
 tr.StillRunningAfter = server
+
diff --git a/tests/gold_tests/continuations/openclose_h2.test.py 
b/tests/gold_tests/continuations/openclose_h2.test.py
index f14db70..07aec81 100644
--- a/tests/gold_tests/continuations/openclose_h2.test.py
+++ b/tests/gold_tests/continuations/openclose_h2.test.py
@@ -17,75 +17,67 @@
 #  limitations under the License.
 
 import os
+import subprocess
 Test.Summary = '''
-Test transactions and sessions for http2, making sure they open and close in 
the proper order.
+Test transactions and sessions over http2, making sure they open and close in 
the proper order.
 '''
 
-Test.SkipIf(Condition.true('This test errors frequently, and so it is 
disabled.'))
 Test.SkipUnless(
     Condition.HasProgram("curl", "Curl needs to be installed on system for 
this test to work"),
     Condition.HasCurlFeature('http2')
 )
-Test.ContinueOnFail = True
+
 # Define default ATS
 ts = Test.MakeATSProcess("ts", select_ports=False, command="traffic_manager")
+ts.Variables.ssl_port = 4443
+
 server = Test.MakeOriginServer("server")
+server2 = Test.MakeOriginServer("server2")
 
 Test.testName = ""
-request_header = {"headers": "GET / HTTP/1.1\r\nHost: oc_h2.test\r\n\r\n", 
"timestamp": "1469733493.993", "body": ""}
+request_header = {"headers": "GET / HTTP/1.1\r\nHost: oc.test\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\n\r\n",
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: 
close\r\nContent-Length:0\r\n\r\n",
                    "timestamp": "1469733493.993", "body": ""}
 
-# add response to the server dictionary
-server.addResponse("sessionfile.log", request_header, response_header)
-
+# add ssl materials like key, certificates for the server
 ts.addSSLfile("ssl/server.pem")
 ts.addSSLfile("ssl/server.key")
 
-ts.Variables.ssl_port = 4443
-ts.Disk.remap_config.AddLine(
-    'map http://oc_h2.test:{0} http://127.0.0.1:{1}'.format(ts.Variables.port, 
server.Variables.Port)
-)
-
-ts.Disk.ssl_multicert_config.AddLine(
-    'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key'
-)
+Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir,
+                                'plugins', 'ssntxnorder_verify.cc'), ts)
 
+# add response to the server dictionary
+server.addResponse("sessionfile.log", request_header, response_header)
 ts.Disk.records_config.update({
     'proxy.config.diags.debug.enabled': 1,
-    'proxy.config.diags.debug.tags': 'ssntxnorder_verify.*',
-    'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
-    'proxy.config.ssl.server.private_key.path': 
'{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.diags.debug.tags': 'ssntxnorder_verify',
     'proxy.config.http.cache.http': 0,  # disable cache to simply the test.
     'proxy.config.cache.enable_read_while_writer': 0,
-     # enable ssl port
+    'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.ssl.server.private_key.path': 
'{0}'.format(ts.Variables.SSLDir),
     'proxy.config.http.server_ports': '{0} 
{1}:proto=http2;http:ssl'.format(ts.Variables.port, ts.Variables.ssl_port),
-    'proxy.config.ssl.client.verify.server':  0,
-    'proxy.config.ssl.server.cipher_suite': 
'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2',
-    'proxy.config.http2.max_concurrent_streams_in': 65535
 })
 
-# add plugin to assist with test metrics
-Test.PreparePlugin(os.path.join(Test.Variables.AtsTestToolsDir,
-                                'plugins', 'ssntxnorder_verify.cc'), ts)
-
-comparator_command = '''
-if test "`traffic_ctl metric get ssntxnorder_verify.{0}.start | cut -d ' ' -f 
2`" -eq "`traffic_ctl metric get ssntxnorder_verify.{0}.close | cut -d ' ' -f 
2`" ; then\
-     echo yes;\
-    else \
-    echo no; \
-    fi;
-    '''
+ts.Disk.remap_config.AddLine(
+    'map http://oc.test:{0} http://127.0.0.1:{1}'.format(
+        ts.Variables.port, server.Variables.Port)
+)
+ts.Disk.ssl_multicert_config.AddLine(
+    'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key'
+)
 
-# curl with http2
-cmd = 'curl --http2 -k -vs 
https://127.0.0.1:{0}/'.format(ts.Variables.ssl_port)
+cmd = 'curl -k --http2 -vs https://127.0.0.1:{0}'.format(ts.Variables.ssl_port)
 numberOfRequests = 25
 
 tr = Test.AddTestRun()
 # Create a bunch of curl commands to be executed in parallel. Default.Process 
is set in SpawnCommands.
-ps = tr.SpawnCommands(cmdstr=cmd, count=numberOfRequests)
+# On Fedora 28/29, it seems that curl will occaisionally timeout after a 
couple seconds and return exitcode 2
+# Examinig the packet capture shows that Traffic Server dutifully sends the 
response
+ps = tr.SpawnCommands(cmdstr=cmd,  count=numberOfRequests, retcode=Any(0,2))
 tr.Processes.Default.Env = ts.Env
+tr.Processes.Default.ReturnCode = Any(0,2)
 
 # Execution order is: ts/server, ps(curl cmds), Default Process.
 tr.Processes.Default.StartBefore(
@@ -96,13 +88,30 @@ ts.StartAfter(*ps)
 server.StartAfter(*ps)
 tr.StillRunningAfter = ts
 
-# Watch the records snapshot file.
-records = ts.Disk.File(os.path.join(ts.Variables.RUNTIMEDIR, "records.snap"))
+# Signal that all the curl processes have completed
+tr = Test.AddTestRun("Curl Done")
+tr.Processes.Default.Command = "traffic_ctl plugin msg done done"
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Env = ts.Env
+tr.StillRunningAfter = ts
 
-# Check our work on traffic_ctl
-# no errors happened,
-tr = Test.AddTestRun()
-tr.DelayStart = 10
+# Parking this as a ready tester on a meaningless process
+# To stall the test runs that check for the stats until the
+# stats have propagated and are ready to read.
+def make_done_stat_ready(tsenv): 
+  def done_stat_ready(process, hasRunFor, **kw):
+    retval = subprocess.run("traffic_ctl metric get 
ssntxnorder_verify.test.done > done  2> /dev/null", shell=True, env=tsenv)
+    if retval.returncode == 0:
+      retval = subprocess.run("grep 1 done > /dev/null", shell = True, 
env=tsenv)
+    return retval.returncode == 0
+
+  return done_stat_ready
+  
+# number of sessions/transactions opened and closed are equal
+tr = Test.AddTestRun("Check Ssn order errors")
+server2.StartupTimeout = 60
+# Again, here the imporant thing is the ready function not the server2 process
+tr.Processes.Default.StartBefore(server2, ready=make_done_stat_ready(ts.Env))
 tr.Processes.Default.Command = 'traffic_ctl metric get ssntxnorder_verify.err'
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
@@ -111,45 +120,38 @@ tr.Processes.Default.Streams.All = 
Testers.ContainsExpression(
 tr.StillRunningAfter = ts
 tr.StillRunningAfter = server
 
+comparator_command = '''
+if test "`traffic_ctl metric get ssntxnorder_verify.{0}.start | cut -d ' ' -f 
2`" -eq "`traffic_ctl metric get ssntxnorder_verify.{0}.close | cut -d ' ' -f 
2`" ; then\
+     echo yes;\
+    else \
+    echo no; \
+    fi; \
+    traffic_ctl metric match ssntxnorder_verify
+    '''
+
 # number of sessions/transactions opened and closed are equal
-tr = Test.AddTestRun()
-tr.DelayStart = 10
+tr = Test.AddTestRun("Check for ssn open/close")
 tr.Processes.Default.Command = comparator_command.format('ssn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
     "yes", 'should verify contents')
+tr.Processes.Default.Streams.stdout += Testers.ExcludesExpression(
+    "ssntxnorder_verify.ssn.start 0", 'should be nonzero')
 tr.StillRunningAfter = ts
 tr.StillRunningAfter = server
 
-tr = Test.AddTestRun()
-tr.DelayStart = 10
+tr = Test.AddTestRun("Check for txn/open/close")
 tr.Processes.Default.Command = comparator_command.format('txn')
 tr.Processes.Default.ReturnCode = 0
 tr.Processes.Default.Env = ts.Env
 tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
     "yes", 'should verify contents')
-tr.StillRunningAfter = ts
-tr.StillRunningAfter = server
-
-# session count is positive,
-tr = Test.AddTestRun()
-tr.DelayStart = 10
-tr.Processes.Default.Command = "traffic_ctl metric get 
ssntxnorder_verify.ssn.start"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ExcludesExpression(
-    " 0", 'should be nonzero')
-tr.StillRunningAfter = ts
-tr.StillRunningAfter = server
-
+tr.Processes.Default.Streams.stdout += Testers.ExcludesExpression(
+    "ssntxnorder_verify.txn.start 0", 'should be nonzero')
 # and we receive the same number of transactions as we asked it to make
-tr = Test.AddTestRun()
-tr.DelayStart = 10
-tr.Processes.Default.Command = "traffic_ctl metric get 
ssntxnorder_verify.txn.start"
-tr.Processes.Default.ReturnCode = 0
-tr.Processes.Default.Env = ts.Env
-tr.Processes.Default.Streams.stdout = Testers.ContainsExpression(
+tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
     "ssntxnorder_verify.txn.start {}".format(numberOfRequests), 'should be the 
number of transactions we made')
 tr.StillRunningAfter = ts
 tr.StillRunningAfter = server
+
diff --git a/tests/tools/plugins/continuations_verify.cc 
b/tests/tools/plugins/continuations_verify.cc
index d87fd51..d452968 100644
--- a/tests/tools/plugins/continuations_verify.cc
+++ b/tests/tools/plugins/continuations_verify.cc
@@ -23,35 +23,46 @@
   limitations under the License.
 */
 
-#define __STDC_FORMAT_MACROS 1 // for inttypes.h
-#include <inttypes.h>          // for PRIu64
-#include <iostream>
 #include <stdlib.h> // for abort
-#include <string.h> // for NULL macro
 #include <ts/ts.h>  // for debug
 
-// TODO Is LIFECYCLE_MSG enabled in 6.2.0, or 7.0.0, might require push
-// with version rework
-
 // debug messages viewable by setting 'proxy.config.diags.debug.tags'
 // in 'records.config'
 
 // debug messages during one-time initialization
 static const char DEBUG_TAG_INIT[] = "continuations_verify.init";
+static const char DEBUG_TAG_MSG[]  = "continuations_verify.msg";
+static const char DEBUG_TAG_HOOK[] = "continuations_verify.hook";
 
 // plugin registration info
 static char plugin_name[]   = "continuations_verify";
-static char vendor_name[]   = "Yahoo! Inc.";
-static char support_email[] = "ats-de...@yahoo-inc.com";
-
-static TSMutex order_mutex_1; // lock on global data
-static TSMutex order_mutex_2; // lock on global data
+static char vendor_name[]   = "apache";
+static char support_email[] = "shinr...@apache.org";
 
 // Statistics provided by the plugin
 static int stat_ssn_close_1 = 0; // number of TS_HTTP_SSN_CLOSE hooks caught 
by the first continuation
 static int stat_ssn_close_2 = 0; // number of TS_HTTP_SSN_CLOSE hooks caught 
by the second continuation
 static int stat_txn_close_1 = 0; // number of TS_HTTP_TXN_CLOSE hooks caught 
by the first continuation
 static int stat_txn_close_2 = 0; // number of TS_HTTP_TXN_CLOSE hooks caught 
by the second continuation
+static int stat_test_done   = 0; // Incremented when receiving a traffic_ctl 
message
+
+static int
+handle_msg(TSCont contp, TSEvent event, void *edata)
+{
+  if (event == TS_EVENT_LIFECYCLE_MSG) { // External trigger, such as 
traffic_ctl
+    TSDebug(DEBUG_TAG_MSG, "event TS_EVENT_LIFECYCLE_MSG");
+    // Send to a ET net thread just to be sure.
+    // Turns out the msg is sent to a task thread, but task
+    // threads do not get their thread local copy of the stats
+    // merged in.  So externally, test.done was stuck at 0 without
+    // the Schedule to a NET thread
+    TSContSchedule(contp, 0, TS_THREAD_POOL_NET);
+  } else {
+    TSDebug(DEBUG_TAG_MSG, "event %d", event);
+    TSStatIntIncrement(stat_test_done, 1);
+  }
+  return 0;
+}
 
 /**
     This function is called on every request and logs session and transaction
@@ -64,6 +75,8 @@ handle_order_1(TSCont contp, TSEvent event, void *edata)
   TSHttpSsn ssnp; // session data
   TSHttpTxn txnp; // transaction data
 
+  TSDebug(DEBUG_TAG_HOOK, "order_1 event %d", event);
+
   // Find the event that happened
   switch (event) {
   case TS_EVENT_HTTP_TXN_CLOSE: // End of transaction
@@ -92,6 +105,8 @@ handle_order_2(TSCont contp, TSEvent event, void *edata)
   TSHttpSsn ssnp; // session data
   TSHttpTxn txnp; // transaction data
 
+  TSDebug(DEBUG_TAG_HOOK, "order_2 event %d", event);
+
   // Find the event that happened
   switch (event) {
   case TS_EVENT_HTTP_TXN_CLOSE: // End of transaction
@@ -142,14 +157,11 @@ TSPluginInit(int argc, const char *argv[])
     TSError("[%s] Plugin registration failed. \n", plugin_name);
   }
 
-  order_mutex_1 = TSMutexCreate();
-  TSCont contp_1;
-  order_mutex_2 = TSMutexCreate();
-  TSCont contp_2;
+  TSCont contp_1 = TSContCreate(handle_order_1, TSMutexCreate());
+  TSCont contp_2 = TSContCreate(handle_order_2, TSMutexCreate());
+  TSCont contp   = TSContCreate(handle_msg, TSMutexCreate());
 
-  contp_1 = TSContCreate(handle_order_1, order_mutex_1);
-  contp_2 = TSContCreate(handle_order_2, order_mutex_2);
-  if (contp_1 == NULL || contp_2 == NULL) {
+  if (contp_1 == nullptr || contp_2 == nullptr || contp == nullptr) {
     // Continuation initialization failed. Unrecoverable, report and exit.
     TSError("[%s] could not create continuation", plugin_name);
     abort();
@@ -164,6 +176,8 @@ TSPluginInit(int argc, const char *argv[])
       TSStatCreate("continuations_verify.txn.close.2", TS_RECORDDATATYPE_INT, 
TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM);
     stat_ssn_close_2 =
       TSStatCreate("continuations_verify.ssn.close.2", TS_RECORDDATATYPE_INT, 
TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM);
+    stat_test_done =
+      TSStatCreate("continuations_verify.test.done", TS_RECORDDATATYPE_INT, 
TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM);
 
     // Add all hooks.
     TSHttpHookAdd(TS_HTTP_TXN_CLOSE_HOOK, contp_1);
@@ -171,5 +185,8 @@ TSPluginInit(int argc, const char *argv[])
 
     TSHttpHookAdd(TS_HTTP_TXN_CLOSE_HOOK, contp_2);
     TSHttpHookAdd(TS_HTTP_SSN_CLOSE_HOOK, contp_2);
+
+    // Respond to a traffic_ctl message
+    TSLifecycleHookAdd(TS_LIFECYCLE_MSG_HOOK, contp);
   }
 }
diff --git a/tests/tools/plugins/ssntxnorder_verify.cc 
b/tests/tools/plugins/ssntxnorder_verify.cc
index e2889d8..9ff16ae 100644
--- a/tests/tools/plugins/ssntxnorder_verify.cc
+++ b/tests/tools/plugins/ssntxnorder_verify.cc
@@ -22,19 +22,13 @@
   See the License for the specific language governing permissions and
   limitations under the License.
 */
-
-#define __STDC_FORMAT_MACROS 1 // for inttypes.h
-#include <inttypes.h>          // for PRIu64
 #include <iostream>
-#include <map>
 #include <set>
 #include <sstream>
-#include <stdlib.h> // for abort
-#include <string.h> // for NULL macro
-#include <ts/ts.h>  // for debug
-
-// TODO Is LIFECYCLE_MSG enabled in 6.2.0, or 7.0.0, might require push
-// with version rework
+#include <stdlib.h>   // for abort
+#include <ts/ts.h>    // for debug
+#include <inttypes.h> // for PRIu64
+#include <string.h>
 
 // debug messages viewable by setting 'proxy.config.diags.debug.tags'
 // in 'records.config'
@@ -47,10 +41,8 @@ static const char DEBUG_TAG_HOOK[] = 
"ssntxnorder_verify.hook";
 
 // plugin registration info
 static char plugin_name[]   = "ssntxnorder_verify";
-static char vendor_name[]   = "Yahoo! Inc.";
-static char support_email[] = "ats-de...@yahoo-inc.com";
-
-static TSMutex order_mutex; // lock on global data
+static char vendor_name[]   = "Apache";
+static char support_email[] = "shinr...@apache.org";
 
 // List of started sessions, SSN_START seen, SSN_CLOSE not seen yet.
 static std::set<TSHttpSsn> started_ssns;
@@ -84,6 +76,7 @@ static int stat_ssn_start = 0; // number of TS_HTTP_SSN_START 
hooks caught
 static int stat_txn_close = 0; // number of TS_HTTP_TXN_CLOSE hooks caught
 static int stat_txn_start = 0; // number of TS_HTTP_TXN_START hooks caught
 static int stat_err       = 0; // number of inaccuracies encountered
+static int stat_test_done = 0; // Set to 1 when the test is done
 
 // IPC information
 static char *ctl_tag         = plugin_name; // name is a convenient identifier
@@ -255,12 +248,18 @@ handle_order(TSCont contp, TSEvent event, void *edata)
     // Verify message is with the appropriate tag
     if (!strcmp(ctl_tag, msgp->tag) && strncmp(ctl_dump, 
reinterpret_cast<const char *>(msgp->data), strlen(ctl_dump)) == 0) {
       dump_tables();
+    } else {
+      TSContSchedule(contp, 0, TS_THREAD_POOL_NET);
     }
 
     break;
   }
 #endif
 
+  case TS_EVENT_IMMEDIATE:
+    TSStatIntIncrement(stat_test_done, 1);
+    break;
+
   // Just release the lock for all other states and do nothing
   default:
     break;
@@ -297,11 +296,8 @@ TSPluginInit(int argc, const char *argv[])
     TSError("[%s] Plugin registration failed. \n", plugin_name);
   }
 
-  order_mutex = TSMutexCreate();
-  TSCont contp;
-
-  contp = TSContCreate(handle_order, order_mutex);
-  if (contp == NULL) {
+  TSCont contp = TSContCreate(handle_order, TSMutexCreate());
+  if (contp == nullptr) {
     // Continuation initialization failed. Unrecoverable, report and exit.
     TSError("[%s] could not create continuation", plugin_name);
     abort();
@@ -313,6 +309,7 @@ TSPluginInit(int argc, const char *argv[])
     stat_txn_start = TSStatCreate("ssntxnorder_verify.txn.start", 
TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM);
     stat_txn_close = TSStatCreate("ssntxnorder_verify.txn.close", 
TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM);
     stat_err       = TSStatCreate("ssntxnorder_verify.err", 
TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM);
+    stat_test_done = TSStatCreate("ssntxnorder_verify.test.done", 
TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM);
 
     // Add all hooks.
     TSHttpHookAdd(TS_HTTP_SSN_START_HOOK, contp);

Reply via email to