You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2010/01/22 20:25:10 UTC
svn commit: r902236 - in /incubator/trafficserver/traffic/branches/dev:
libinktomi++/DynArray.h libinktomi++/Regression.cc
libinktomi++/Regression.h proxy/Makefile.am proxy/RegressionSM.cc
proxy/RegressionSM.h
Author: jplevyak
Date: Fri Jan 22 19:25:10 2010
New Revision: 902236
URL: http://svn.apache.org/viewvc?rev=902236&view=rev
Log:
TS-115: This adds a new rperf() call to report performance results in regressions
This adds a sequential and parallel composition system for regression statemachines.
Added:
incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.cc
incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.h
Modified:
incubator/trafficserver/traffic/branches/dev/libinktomi++/DynArray.h
incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.cc
incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.h
incubator/trafficserver/traffic/branches/dev/proxy/Makefile.am
Modified: incubator/trafficserver/traffic/branches/dev/libinktomi++/DynArray.h
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libinktomi%2B%2B/DynArray.h?rev=902236&r1=902235&r2=902236&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libinktomi++/DynArray.h (original)
+++ incubator/trafficserver/traffic/branches/dev/libinktomi++/DynArray.h Fri Jan 22 19:25:10 2010
@@ -30,7 +30,7 @@
template<class T> class DynArray {
public:
- DynArray(const T * val, intptr_t initial_size = 0);
+ DynArray(const T * val = 0, intptr_t initial_size = 0);
~DynArray();
#ifndef __GNUC__
@@ -71,6 +71,7 @@
resize(i);
}
+
}
template<class T> inline DynArray<T>::~DynArray()
@@ -177,7 +178,8 @@
}
for (; i < new_size; i++) {
- new_data[i] = (T) * default_val;
+ if (default_val)
+ new_data[i] = (T) * default_val;
}
if (data) {
Modified: incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.cc
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libinktomi%2B%2B/Regression.cc?rev=902236&r1=902235&r2=902236&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.cc (original)
+++ incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.cc Fri Jan 22 19:25:10 2010
@@ -35,16 +35,12 @@
static RegressionTest *test = NULL;
static RegressionTest *exclusive_test = NULL;
-RegressionTest *
- RegressionTest::current = 0;
-int
- RegressionTest::ran_tests = 0;
-DFA
- RegressionTest::dfa;
-int
- regression_level = 0;
-int
- RegressionTest::final_status = REGRESSION_TEST_PASSED;
+RegressionTest *RegressionTest::current = 0;
+int RegressionTest::ran_tests = 0;
+DFA RegressionTest::dfa;
+int regression_level = 0;
+int RegressionTest::final_status = REGRESSION_TEST_PASSED;
+
char *
regression_status_string(int status)
{
@@ -55,7 +51,6 @@
RegressionTest::RegressionTest(const char *name_arg, TestFunction * function_arg, int aopt)
{
- // printf("<%s>\n",name_arg);
name = name_arg;
function = function_arg;
status = REGRESSION_TEST_NOT_RUN;
@@ -109,7 +104,6 @@
return run_some();
}
-
int
RegressionTest::run_some()
{
@@ -123,7 +117,6 @@
&SPACES[40 + strlen(current->name)], regression_status_string(current->status));
}
current = current->next;
-
}
for (; current; current = current->next) {
if ((dfa.match(current->name) >= 0)) {
@@ -180,7 +173,7 @@
}
int
-rprintf(RegressionTest * t, const char *format, ...)
+rprintf(RegressionTest *t, const char *format, ...)
{
int l;
char buffer[8192];
@@ -194,10 +187,21 @@
return (l);
}
+int
+rperf(RegressionTest *t, const char *tag, double val)
+{
+ int l;
+ char format2[8192];
+ l = snprintf(format2, sizeof(format2), "RPERF %s.%s %f\n", t->name, tag, val);
+ fputs(format2, stderr);
+ return (l);
+}
+
REGRESSION_TEST(Regression) (RegressionTest * t, int atype, int *status) {
(void) t;
(void) atype;
rprintf(t, "regression test\n");
+ rperf(t, "speed", 100.0);
if (!test)
*status = REGRESSION_TEST_FAILED;
else
Modified: incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.h
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/libinktomi%2B%2B/Regression.h?rev=902236&r1=902235&r2=902236&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.h (original)
+++ incubator/trafficserver/traffic/branches/dev/libinktomi++/Regression.h Fri Jan 22 19:25:10 2010
@@ -21,38 +21,32 @@
limitations under the License.
*/
-/****************************************************************************
-
- Regression.h
-
-
- ****************************************************************************/
-
#ifndef _Regression_h
#define _Regression_h
+
#include "inktomi++.h"
#include "Regex.h"
-//
-// Each module should provide one or more regression tests
+// Each module should provide one or more regression tests
//
-// An example:
+// An example:
//
-// REGRESSION_TEST(Addition)(RegressionTest *t, int atype, int *pstatus) {
-// if (1 + 1 != 2)
-// *pstatus = REGRESSION_TEST_FAILED;
-// if (atype > REGRESSION_TEST_NIGHTLY) // try again
-// if (1 + 1 != 2)
-// *pstatus = REGRESSION_TEST_FAILED;
-// rprintf(t, "it worked, 1+1 really is 2!");
-// *pstatus return REGRESSION_TEST_PASSED;
-// }
-//
-//
+// REGRESSION_TEST(Addition)(RegressionTest *t, int atype, int *pstatus) {
+// if (atype < REGRESSION_TEST_NIGHTLY) { // to expensive to do more than nightly
+// *pstatus = REGRESSION_TEST_NOT_RUN;
+// return;
+// }
+// if (1 + 1 != 2) {
+// rprintf(t, "drat, 1+1 isn't 2??");
+// *pstatus = REGRESSION_TEST_FAILED;
+// } else
+// *pstatus = REGRESSION_TEST_PASSED;
+// }
+
// status values
#define REGRESSION_TEST_PASSED 1
-#define REGRESSION_TEST_INPROGRESS 0
+#define REGRESSION_TEST_INPROGRESS 0 // initial value
#define REGRESSION_TEST_FAILED -1
#define REGRESSION_TEST_NOT_RUN -2
@@ -80,7 +74,7 @@
int printed;
int opt;
- RegressionTest(const char *name_arg, TestFunction * function_arg, int aopt);
+ RegressionTest(const char *name_arg, TestFunction * function_arg, int aopt);
static int final_status;
static int ran_tests;
@@ -102,6 +96,7 @@
void RegressionTest_##_f
int rprintf(RegressionTest * t, const char *format, ...);
+int rperf(RegressionTest *t, const char *tag, double val);
char *regression_status_string(int status);
extern int regression_level;
@@ -113,5 +108,4 @@
Warning(_buf); \
} \
-#define _Regression_h
#endif /* _Regression_h */
Modified: incubator/trafficserver/traffic/branches/dev/proxy/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/proxy/Makefile.am?rev=902236&r1=902235&r2=902236&view=diff
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/proxy/Makefile.am (original)
+++ incubator/trafficserver/traffic/branches/dev/proxy/Makefile.am Fri Jan 22 19:25:10 2010
@@ -109,6 +109,8 @@
Prefetch.cc \
Prefetch.h \
Raf.h \
+ RegressionSM.h \
+ RegressionSM.cc \
RemapAPI.h \
ReverseProxy.cc \
ReverseProxy.h \
Added: incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.cc
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.cc?rev=902236&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.cc (added)
+++ incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.cc Fri Jan 22 19:25:10 2010
@@ -0,0 +1,259 @@
+/** @file
+
+ A brief file description
+
+ @section license License
+
+ 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.
+ */
+
+#include "P_EventSystem.h"
+#include "RegressionSM.h"
+
+#define REGRESSION_SM_RETRY (100*HRTIME_MSECOND)
+
+void RegressionSM::set_status(int astatus) {
+ ink_assert(astatus != REGRESSION_TEST_INPROGRESS);
+ // INPROGRESS < NOT_RUN < PASSED < FAILED
+ if (status != REGRESSION_TEST_FAILED) {
+ if (status == REGRESSION_TEST_PASSED) {
+ if (astatus != REGRESSION_TEST_NOT_RUN)
+ status = astatus;
+ } else {
+ // INPROGRESS or NOT_RUN
+ status = astatus;
+ }
+ } // else FAILED is FAILED
+}
+
+void RegressionSM::done(int astatus) {
+ if (pending_action) {
+ pending_action->cancel();
+ pending_action = 0;
+ }
+ set_status(astatus);
+ if (pstatus) *pstatus = status;
+ if (parent) parent->child_done(status);
+}
+
+void RegressionSM::run(int *apstatus) {
+ pstatus = apstatus;
+ run();
+}
+
+void RegressionSM::xrun(RegressionSM *aparent) {
+ parent = aparent;
+ parent->nwaiting++;
+ run();
+}
+
+void RegressionSM::run_in(int *apstatus, ink_hrtime t) {
+ pstatus = apstatus;
+ SET_HANDLER(&RegressionSM::regression_sm_start);
+ eventProcessor.schedule_in(this, t);
+}
+
+void RegressionSM::child_done(int astatus) {
+ {
+ MUTEX_LOCK(l, mutex, this_ethread());
+ if (pending_action) {
+ pending_action->cancel();
+ pending_action = 0;
+ }
+ ink_assert(nwaiting > 0);
+ --nwaiting;
+ set_status(astatus);
+ }
+}
+
+int RegressionSM::regression_sm_waiting(int event, void *data) {
+ if (!nwaiting) {
+ done(REGRESSION_TEST_NOT_RUN);
+ delete this;
+ }
+ else
+ ((Event*)data)->schedule_in(REGRESSION_SM_RETRY);
+ return EVENT_CONT;
+}
+
+int RegressionSM::regression_sm_start(int event, void *data) {
+ run();
+ return EVENT_CONT;
+}
+
+RegressionSM *RegressionSM::do_sequential(RegressionSM *sm, ...) {
+ RegressionSM *new_sm = new RegressionSM(t);
+ va_list ap;
+ va_start(ap, sm);
+ new_sm->par = false;
+ new_sm->rep = false;
+ new_sm->ichild = 0;
+ new_sm->nchildren = 0;
+ new_sm->nwaiting = 0;
+ new_sm->children(new_sm->nchildren++) = sm;
+ while (1) {
+ RegressionSM *x = va_arg(ap, RegressionSM*);
+ if (!x) break;
+ new_sm->children(new_sm->nchildren++) = x;
+ }
+ new_sm->n = new_sm->nchildren;
+ va_end(ap);
+ return new_sm;
+}
+
+RegressionSM *RegressionSM::do_sequential(int an, RegressionSM *sm) {
+ RegressionSM *new_sm = new RegressionSM(t);
+ new_sm->par = false;
+ new_sm->rep = true;
+ new_sm->ichild = 0;
+ new_sm->nchildren = 1;
+ new_sm->children(0) = sm;
+ new_sm->nwaiting = 0;
+ new_sm->n = an;
+ return new_sm;
+}
+
+RegressionSM *RegressionSM::do_parallel(RegressionSM *sm, ...) {
+ RegressionSM *new_sm = new RegressionSM(t);
+ va_list ap;
+ va_start(ap, sm);
+ new_sm->par = true;
+ new_sm->rep = false;
+ new_sm->ichild = 0;
+ new_sm->nchildren = 0;
+ new_sm->nwaiting = 0;
+ new_sm->children(new_sm->nchildren++) = sm;
+ while (1) {
+ RegressionSM *x = va_arg(ap, RegressionSM*);
+ if (!x) break;
+ new_sm->children(new_sm->nchildren++) = x;
+ }
+ new_sm->n = new_sm->nchildren;
+ va_end(ap);
+ return new_sm;
+}
+
+RegressionSM *RegressionSM::do_parallel(int an, RegressionSM *sm) {
+ RegressionSM *new_sm = new RegressionSM(t);
+ new_sm->par = true;
+ new_sm->rep = true;
+ new_sm->ichild = 0;
+ new_sm->nchildren = 1;
+ new_sm->children(0) = sm;
+ new_sm->nwaiting = 0;
+ new_sm->n = an;
+ return new_sm;
+}
+
+void RegressionSM::run() {
+ {
+ MUTEX_TRY_LOCK(l, mutex, this_ethread());
+ if (!l || nwaiting)
+ pending_action = eventProcessor.schedule_in(this, REGRESSION_SM_RETRY);
+ RegressionSM *x = 0;
+ for (; ichild < n; ichild++) {
+ if (!rep)
+ x = children[ichild];
+ else {
+ if (ichild != n-1)
+ x = children[0]->clone();
+ else
+ x = children[0];
+ }
+ x->xrun(this);
+ if (!par && nwaiting)
+ goto Lretry;
+ }
+ }
+ if (!nwaiting) {
+ done(REGRESSION_TEST_NOT_RUN);
+ delete this;
+ return;
+ }
+Lretry:
+ SET_HANDLER(&RegressionSM::regression_sm_waiting);
+ pending_action = eventProcessor.schedule_in(this, REGRESSION_SM_RETRY);
+}
+
+void RegressionSM::do_run(RegressionSM *sm) {
+ par = false;
+ rep = true;
+ ichild = 0;
+ nchildren = 1;
+ children(0) = sm;
+ nwaiting = 0;
+ n = 1;
+ RegressionSM::run();
+}
+
+RegressionSM::RegressionSM(const RegressionSM &ao) {
+ RegressionSM &o = *(RegressionSM*)&ao;
+ t = o.t;
+ status = o.status;
+ pstatus = o.pstatus;
+ parent = &o;
+ nwaiting = o.nwaiting;
+ nchildren = o.nchildren;
+ for (int i = 0; i < nchildren; i++)
+ children(i) = o.children[i]->clone();
+ n = o.n;
+ ichild = o.ichild;
+ par = o.par;
+ rep = o.rep;
+ ink_assert(status == REGRESSION_TEST_INPROGRESS);
+ ink_assert(nwaiting == 0);
+ ink_assert(ichild == 0);
+ mutex = new_ProxyMutex();
+}
+
+struct ReRegressionSM1 : RegressionSM {
+ virtual void run() {
+ if (time(NULL) < 1) { // example test
+ rprintf(t,"impossible");
+ done(REGRESSION_TEST_FAILED);
+ } else
+ done(REGRESSION_TEST_PASSED);
+ }
+ ReRegressionSM1(RegressionTest *at) : RegressionSM(at) {}
+ virtual RegressionSM *clone() { return new ReRegressionSM1(*this); }
+ ReRegressionSM1(const ReRegressionSM1 &o) {
+ t = o.t;
+ }
+};
+
+struct ReRegressionSM2 : RegressionSM {
+ virtual void run() {
+ do_run(
+ do_sequential(
+ do_parallel(new ReRegressionSM1(t), new ReRegressionSM1(t), NULL),
+ do_sequential(new ReRegressionSM1(t), new ReRegressionSM1(t), NULL),
+ do_parallel(3, new ReRegressionSM1(t)),
+ do_sequential(3, new ReRegressionSM1(t)),
+ do_parallel(
+ do_sequential(2, new ReRegressionSM1(t)),
+ do_parallel(2, new ReRegressionSM1(t)),
+ NULL),
+ NULL));
+ }
+ ReRegressionSM2(RegressionTest *at) : RegressionSM(at) {}
+};
+
+REGRESSION_TEST(RegressionSM)(RegressionTest *t, int atype, int *pstatus) {
+ ReRegressionSM2 *sm = new ReRegressionSM2(t);
+ sm->run_in(pstatus, HRTIME_SECOND);
+}
+
Added: incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.h
URL: http://svn.apache.org/viewvc/incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.h?rev=902236&view=auto
==============================================================================
--- incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.h (added)
+++ incubator/trafficserver/traffic/branches/dev/proxy/RegressionSM.h Fri Jan 22 19:25:10 2010
@@ -0,0 +1,78 @@
+/** @file
+
+ A brief file description
+
+ @section license License
+
+ 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.
+ */
+
+#ifndef _RegressionSM_h
+#define _RegressionSM_h
+
+#include "I_EventSystem.h"
+
+/*
+ Regression Test Composition State Machine
+
+ See RegressionSM.cc at the end for an example
+*/
+
+struct RegressionSM : Continuation {
+
+ RegressionTest *t; // for use with rprint
+
+ virtual void run(); // replace with leaf regression
+ void done(int status = REGRESSION_TEST_NOT_RUN);
+ void run(int *pstatus);
+ void run_in(int *pstatus, ink_hrtime t);
+ void do_run(RegressionSM *sm);
+ RegressionSM *do_sequential(RegressionSM *sm, ...); // terminate list in NULL
+ RegressionSM *do_sequential(int n, RegressionSM *sm);
+ RegressionSM *do_parallel(RegressionSM *sm, ...); // terminate list in NULL
+ RegressionSM *do_parallel(int n, RegressionSM *sm);
+ virtual RegressionSM *clone() { return new RegressionSM(*this); } // for run_xxx(int n,...);
+
+ // Internal
+
+ int status;
+ int *pstatus;
+ RegressionSM *parent;
+ int nwaiting;
+ int nchildren;
+ DynArray<RegressionSM*> children;
+ int n, ichild;
+ bool par, rep;
+ Action *pending_action;
+
+ int regression_sm_start(int event, void *data);
+ int regression_sm_waiting(int event, void *data);
+ void set_status(int status);
+ void child_done(int status);
+ void xrun(RegressionSM *parent);
+
+ RegressionSM(RegressionTest *at = NULL) :
+ t(at), status(REGRESSION_TEST_INPROGRESS),
+ pstatus(0), parent(0), nwaiting(0), nchildren(0), children(0), ichild(0), par(false), rep(false),
+ pending_action(0)
+ {
+ mutex = new_ProxyMutex();
+ }
+ RegressionSM(const RegressionSM &);
+};
+
+#endif