rhmessaging commits: r3360 - mgmt/trunk/cumin/python/cumin.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-05-06 15:04:57 -0400 (Wed, 06 May 2009)
New Revision: 3360
Modified:
mgmt/trunk/cumin/python/cumin/widgets.py
mgmt/trunk/cumin/python/cumin/widgets.strings
Log:
Added default animation for deferred rending of widgets
Modified: mgmt/trunk/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/widgets.py 2009-05-06 19:03:44 UTC (rev 3359)
+++ mgmt/trunk/cumin/python/cumin/widgets.py 2009-05-06 19:04:57 UTC (rev 3360)
@@ -1268,3 +1268,7 @@
def render_open_display(self, session, *args):
return self.input.get(session) and "block" or "none"
+
+class Wait(Widget):
+ pass
+
Modified: mgmt/trunk/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/widgets.strings 2009-05-06 19:03:44 UTC (rev 3359)
+++ mgmt/trunk/cumin/python/cumin/widgets.strings 2009-05-06 19:04:57 UTC (rev 3360)
@@ -719,3 +719,6 @@
Last update was <span id="updateTime"></span>
</div>
</div>{start_stop_script}
+
+[Wait.html]
+ <div class="loading" style="visibility:visible;"><span>Loading...</span></div>
16 years, 12 months
rhmessaging commits: r3359 - mgmt/trunk/wooly/python/wooly.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-05-06 15:03:44 -0400 (Wed, 06 May 2009)
New Revision: 3359
Modified:
mgmt/trunk/wooly/python/wooly/__init__.py
mgmt/trunk/wooly/python/wooly/__init__.strings
mgmt/trunk/wooly/python/wooly/pages.py
mgmt/trunk/wooly/python/wooly/pages.strings
Log:
Added ability to defer the render of a widget
Modified: mgmt/trunk/wooly/python/wooly/__init__.py
===================================================================
--- mgmt/trunk/wooly/python/wooly/__init__.py 2009-05-06 18:31:00 UTC (rev 3358)
+++ mgmt/trunk/wooly/python/wooly/__init__.py 2009-05-06 19:03:44 UTC (rev 3359)
@@ -103,6 +103,7 @@
# Configuration
self.html_class = "_"
self.update_enabled = False
+ self.defer_enabled = False
# These are set in the init() pass
self.ancestors = None
@@ -111,6 +112,7 @@
self.frame = None
self.__main_tmpl = Template(self, "html")
+ self.__defer_tmpl = Template(self, "deferred_html")
def init(self):
#print "Initializing %s" % str(self)
@@ -251,6 +253,9 @@
args = self.get_args(session)
string = self.do_render(session, *args)
+ if self.defer_enabled:
+ self.page.enable_defer(session, self)
+
if string is None:
string = ""
@@ -266,9 +271,14 @@
return string
def do_render(self, session, *args):
- writer = Writer()
- self.__main_tmpl.render(writer, session, *args)
- return writer.to_string()
+ if self.defer_enabled and not getattr(session, "background", None):
+ writer = Writer()
+ self.__defer_tmpl.render(writer, session, *args)
+ return writer.to_string()
+ else:
+ writer = Writer()
+ self.__main_tmpl.render(writer, session, *args)
+ return writer.to_string()
def render_id(self, session, *args):
return self.path
Modified: mgmt/trunk/wooly/python/wooly/__init__.strings
===================================================================
--- mgmt/trunk/wooly/python/wooly/__init__.strings 2009-05-06 18:31:00 UTC (rev 3358)
+++ mgmt/trunk/wooly/python/wooly/__init__.strings 2009-05-06 19:03:44 UTC (rev 3359)
@@ -1,6 +1,9 @@
[Widget.html]
{content}
+[Widget.deferred_html]
+<div id="{id}"></div>
+
[Page.html]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
Modified: mgmt/trunk/wooly/python/wooly/pages.py
===================================================================
--- mgmt/trunk/wooly/python/wooly/pages.py 2009-05-06 18:31:00 UTC (rev 3358)
+++ mgmt/trunk/wooly/python/wooly/pages.py 2009-05-06 19:03:44 UTC (rev 3359)
@@ -83,9 +83,16 @@
self.updates = self.UpdatesAttribute(app, "updates")
self.add_attribute(self.updates)
+ self.defers = self.UpdatesAttribute(app, "defers")
+ self.add_attribute(self.defers)
+
self.update_script = UpdateScript(app, "update_script", self)
self.add_child(self.update_script)
+ self.defer_script = DeferScript(app, "defer_script", self)
+ self.defer_script.interval = 0
+ self.add_child(self.defer_script)
+
self.update_page = UpdatePage(app, self.base_name + ".update", self)
self.app.add_page(self.update_page)
@@ -111,6 +118,9 @@
self.updates.get(session).append(widget)
+ def enable_defer(self, session, widget):
+ self.defers.get(session).append(widget)
+
def get_update_url(self, session, widgets):
sess = Session(self.page.update_page)
@@ -126,20 +136,35 @@
def get_default(self, session):
return list()
-class UpdateScript(Widget):
+class AjaxScript(Widget):
def __init__(self, app, name, html_page):
- super(UpdateScript, self).__init__(app, name)
+ super(AjaxScript, self).__init__(app, name)
self.html_page = html_page
+ self.interval = 3000
def do_render(self, session):
- if self.html_page.updates.get(session):
- return super(UpdateScript, self).do_render(session)
+ if self.get_widget_list(session):
+ return super(AjaxScript, self).do_render(session)
def render_url(self, session):
- updates = self.html_page.updates.get(session)
- return self.html_page.get_update_url(session, updates)
+ widgets = self.get_widget_list(session)
+ return self.html_page.get_update_url(session, widgets)
+ def get_widget_list(self, session):
+ pass
+
+ def render_interval(self, session):
+ return self.interval
+
+class DeferScript(AjaxScript):
+ def get_widget_list(self, session):
+ return self.html_page.defers.get(session)
+
+class UpdateScript(AjaxScript):
+ def get_widget_list(self, session):
+ return self.html_page.updates.get(session)
+
class UpdatePage(Page):
def __init__(self, app, name, html_page):
super(UpdatePage, self).__init__(app, name)
Modified: mgmt/trunk/wooly/python/wooly/pages.strings
===================================================================
--- mgmt/trunk/wooly/python/wooly/pages.strings 2009-05-06 18:31:00 UTC (rev 3358)
+++ mgmt/trunk/wooly/python/wooly/pages.strings 2009-05-06 19:03:44 UTC (rev 3359)
@@ -22,12 +22,13 @@
<body class="{class}">
{content}
</body>
+ {defer_script}
</html>
-[UpdateScript.html]
+[AjaxScript.html]
<script type="text/javascript">
// <![CDATA[
- wooly.setIntervalUpdate('{url}', wooly.updatePage, 3000);
+ wooly.setIntervalUpdate('{url}', wooly.updatePage, {interval});
// ]]>
</script>
@@ -36,6 +37,7 @@
<!DOCTYPE widgets [
<!ELEMENT widgets (#PCDATA)>
<!ENTITY ndash "–">
+ <!ENTITY nbsp " ">
]>
<widgets>{widgets}</widgets>
16 years, 12 months
rhmessaging commits: r3358 - mgmt/trunk/notes.
by rhmessaging-commits@lists.jboss.org
Author: eallen
Date: 2009-05-06 14:31:00 -0400 (Wed, 06 May 2009)
New Revision: 3358
Added:
mgmt/trunk/notes/deferred rendered widgets.txt
Log:
New "how-to" note for deferred rendering of a widget.
Added: mgmt/trunk/notes/deferred rendered widgets.txt
===================================================================
--- mgmt/trunk/notes/deferred rendered widgets.txt (rev 0)
+++ mgmt/trunk/notes/deferred rendered widgets.txt 2009-05-06 18:31:00 UTC (rev 3358)
@@ -0,0 +1,55 @@
+How to defer the rendering of a widget until the page has loaded
+
+Some widgets rely on method calls that can potentially be lengthy. Getting the Job Ads is an example.
+In these cases it is desirable to render the containing page immediately, and then after the page has displayed,
+render the widget that relies on the method call.
+
+To accomplish this, take these steps:
+1. in the __init__ method of the widget add self.defer_enabled = True
+2. in the html for the widget, make sure the containing tag has an id attribute
+
+For example, to defer the rendering of the JobAdsViewer:
+<jobs.py>
+class JobAdsViewer(JobAdsSet):
+ def __init__(self, app, name):
+ super(JobAdsViewer, self).__init__(app, name)
+
+ self.defer_enabled = True
+
+ def render_deferred_job_ads(self, session, *args):
+ """ this won't be called until after the page has loaded """
+ return "Job Ads"
+
+<jobs.strings>
+[JobAdsViewer.html]
+<div id="{id}">
+ {deferred_job_ads}
+</div>
+
+
+In the above example, the page is loaded and instead of displaying "Job Ads", a Loading animation is displayed.
+Then as soon as the page has loaded, an ajax call is made to fetch the html for the job ad.
+
+To prevent the loading animation, or to contain the widget in something other than a <div>,
+override the .deferred_html for the widget. In this next example, the limit count on a tab is deferred.
+<limit.py>
+class LimitCount(Widget):
+ def __init__(self, app, name):
+ super(LimitCount, self).__init__(app, name)
+ self.defer_enabled = True
+
+ def render_count(self, session):
+ """ this won't be called until after the page has loaded """
+ """ stuff to get the count goes here """
+ pass
+
+<limit.strings>
+[LimitCount.html]
+<span id="{id}">Limits <span class="count">({count})</span></span>
+
+[LimitCount.deferred_html]
+<span id="{id}">Limits <span class="count">(?)</span></span>
+
+Multiple widgets on a page can be deferred.
+Deferred rendering can be used at the same time as background updating of the same widget(s).
+
16 years, 12 months
rhmessaging commits: r3357 - store/trunk/cpp/tests.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2009-05-06 12:58:58 -0400 (Wed, 06 May 2009)
New Revision: 3357
Modified:
store/trunk/cpp/tests/Makefile.am
store/trunk/cpp/tests/run_python_tests
Log:
Switched over to using the new python test framework broker start and stop in preparation for adding cluster tests
Modified: store/trunk/cpp/tests/Makefile.am
===================================================================
--- store/trunk/cpp/tests/Makefile.am 2009-05-05 19:52:38 UTC (rev 3356)
+++ store/trunk/cpp/tests/Makefile.am 2009-05-06 16:58:58 UTC (rev 3357)
@@ -78,6 +78,7 @@
TESTS_ENVIRONMENT = \
QPID_DIR=$(QPID_DIR) \
+ QPIDD=$(QPID_DIR)/cpp/src/qpidd \
VALGRIND=$(VALGRIND) \
abs_srcdir=$(abs_srcdir) \
LIBBDBSTORE=$(abs_builddir)/../lib/.libs/msgstore.so \
Modified: store/trunk/cpp/tests/run_python_tests
===================================================================
--- store/trunk/cpp/tests/run_python_tests 2009-05-05 19:52:38 UTC (rev 3356)
+++ store/trunk/cpp/tests/run_python_tests 2009-05-06 16:58:58 UTC (rev 3357)
@@ -56,25 +56,11 @@
echo "WARNING: Path(s) in ${PYTHONPATH} not found - skipping python tests."
exit 1
else
- # 1. Start broker
- echo -n "Starting broker... "
- ${abs_srcdir}/start_broker "$@" ${BROKER_OPTS} || { echo "FAIL broker start"; exit 1; }
- if ! test -f qpidd.port; then
- echo "FAIL no qpidd.port file found - broker may have failed to start"
- exit 1
- fi
- port=`cat qpidd.port`
- echo "port=${port} ok"
-
- # 2. Run all python tests
+ # Run all python tests
pwdir=$(pwd)
cd ${QPID_PYTHON_DIR}
- ./run-tests --skip-self-test -v -s ${AMQP_SPEC} -I ${FAILING_PYTHON_TESTS} -b localhost:${port} ${PYTHON_TESTS} || { echo "FAIL python tests for ${SPEC}"; fail=1; }
+ ./run-tests --skip-self-test -v -s ${AMQP_SPEC} -I ${FAILING_PYTHON_TESTS} -B "${BROKER_OPTS}" ${PYTHON_TESTS} || { echo "FAIL python tests for ${AMQP_SPEC}"; fail=1; }
cd ${pwdir}
- #3. Stop broker
- echo -n "Stopping broker on port ${port}... "
- ${abs_srcdir}/stop_broker || { echo "FAIL broker stop"; fail=1; }
- echo "ok"
exit ${fail}
fi
16 years, 12 months
rhmessaging commits: r3356 - store/trunk/cpp/tests/cluster.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2009-05-05 15:52:38 -0400 (Tue, 05 May 2009)
New Revision: 3356
Modified:
store/trunk/cpp/tests/cluster/
Log:
Set svn:ignore on tests/cluster dir
Property changes on: store/trunk/cpp/tests/cluster
___________________________________________________________________
Name: svn:ignore
+ Makefile
Makefile.in
.valgrindrc
.valgrind.supp
16 years, 12 months
rhmessaging commits: r3355 - in store/trunk/cpp/tests: cluster and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2009-05-05 15:07:47 -0400 (Tue, 05 May 2009)
New Revision: 3355
Added:
store/trunk/cpp/tests/cluster/
store/trunk/cpp/tests/cluster/Makefile.am
store/trunk/cpp/tests/cluster/run_cluster_tests
Log:
Added missing cluster test dir
Added: store/trunk/cpp/tests/cluster/Makefile.am
===================================================================
--- store/trunk/cpp/tests/cluster/Makefile.am (rev 0)
+++ store/trunk/cpp/tests/cluster/Makefile.am 2009-05-05 19:07:47 UTC (rev 3355)
@@ -0,0 +1,57 @@
+# Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+#
+# This file is part of the Qpid async store library msgstore.so.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+# USA
+#
+# The GNU Lesser General Public License is available in the file COPYING.
+
+
+abs_builddir=@abs_builddir@
+abs_srcdir=@abs_srcdir@
+
+if HAVE_LIBCPG
+
+
+AM_CXXFLAGS = $(WARNING_CFLAGS) -pthread -DBOOST_TEST_DYN_LINK
+
+INCLUDES=-I$(top_srcdir)/lib $(QPID_CXXFLAGS)
+
+TMPDIR=$(abs_srcdir)/test_tmp
+
+QPID_TEST_DIR = $(QPID_DIR)/cpp/src/tests
+
+all-local: .valgrindrc .valgrind.supp
+.valgrindrc: $(top_srcdir)/tests/.valgrindrc
+ cp $^ .
+.valgrind.supp: $(top_srcdir)/tests/.valgrind.supp
+ cp $^ .
+
+TESTS = run_cluster_tests
+
+TESTS_ENVIRONMENT = \
+ BOOST_TEST_SHOW_PROGRESS=yes \
+ STORE_ENABLE=1 \
+ QPID_DIR=$(QPID_DIR) \
+ VALGRIND=$(VALGRIND) \
+ LIBSTORE=$(abs_builddir)/../../lib/.libs/msgstore.so \
+ TMPDIR=$(TMPDIR) \
+ abs_srcdir=$(abs_srcdir)
+
+EXTRA_DIST = \
+ run_cluster_tests
+
+endif
\ No newline at end of file
Added: store/trunk/cpp/tests/cluster/run_cluster_tests
===================================================================
--- store/trunk/cpp/tests/cluster/run_cluster_tests (rev 0)
+++ store/trunk/cpp/tests/cluster/run_cluster_tests 2009-05-05 19:07:47 UTC (rev 3355)
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+# Copyright (c) 2008, 2009 Red Hat, Inc.
+#
+# This file is part of the Qpid async store library msgstore.so.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+# USA
+#
+# The GNU Lesser General Public License is available in the file COPYING.
+
+srcdir=`dirname $0`
+
+# Check AIS requirements and run tests if found.
+id -nG | grep '\<ais\>' >/dev/null || \
+ NOGROUP="You are not a member of the ais group."
+ps -u root | grep 'aisexec\|corosync' >/dev/null || \
+ NOAISEXEC="The aisexec or corosync daemon is not running as root"
+
+if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then
+ cat <<EOF
+
+ =========== WARNING: NOT RUNNING AIS TESTS ==============
+
+ Tests that depend on the openais library (used for clustering)
+ will not be run because:
+
+ $NOGROUP
+ $NOAISEXEC
+
+ ==========================================================
+
+EOF
+ exit 0; # A warning, not a failure.
+fi
+
+# Execute command with the ais group set.
+with_ais_group() {
+ id -nG | grep '\<ais\>' >/dev/null || { echo "You are not a member of the ais group."; exit 1; }
+ echo $* | newgrp ais
+}
+
+CLUSTER_EXEC=cluster_test
+if test -d ${QPID_DIR}; then
+ CLUSTER_DIR=${QPID_DIR}/cpp/src/tests
+else
+ CLUSTER_PATH=`which ${CLUSTER_EXEC}`
+ if test -z ${CLUSTER_PATH} ; then
+ echo "No executable \"${CLUSTER_EXEC}\" found in path"
+ exit 1
+ else
+ CLUSTER_DIR=${CLUSTER_PATH%/*}
+ fi
+fi
+
+# Run the tests
+srcdir=`dirname $0`
+cd ${CLUSTER_DIR}
+pwd
+with_ais_group ./${CLUSTER_EXEC} || ERROR=1
+exit $ERROR
Property changes on: store/trunk/cpp/tests/cluster/run_cluster_tests
___________________________________________________________________
Name: svn:executable
+ *
16 years, 12 months
rhmessaging commits: r3354 - in store/trunk/cpp: tests and 1 other directory.
by rhmessaging-commits@lists.jboss.org
Author: kpvdr
Date: 2009-05-05 14:24:25 -0400 (Tue, 05 May 2009)
New Revision: 3354
Modified:
store/trunk/cpp/configure.ac
store/trunk/cpp/tests/Makefile.am
Log:
Added external cluster test to make check
Modified: store/trunk/cpp/configure.ac
===================================================================
--- store/trunk/cpp/configure.ac 2009-04-30 15:41:55 UTC (rev 3353)
+++ store/trunk/cpp/configure.ac 2009-05-05 18:24:25 UTC (rev 3354)
@@ -178,7 +178,49 @@
# If rpmlint is available we'll run it when building RPMs.
AC_CHECK_PROG([RPMLINT], [rpmlint], [rpmlint])
AM_CONDITIONAL([HAS_RPMLINT], [test -n "$RPMLINT"])
+
+# Check for optional cluster requirements.
+tmp_LIBS=$LIBS
+LDFLAGS="$LDFLAGS -L/usr/lib/openais -L/usr/lib64/openais -L/usr/lib/corosync -L/usr/lib64/corosync"
+AC_CHECK_LIB([cpg],[cpg_local_get],[have_libcpg=yes],)
+AC_CHECK_HEADERS([openais/cpg.h corosync/cpg.h],[have_cpg_h=yes],)
+AC_ARG_WITH([cpg],
+ [AS_HELP_STRING([--with-cpg], [Build with CPG support for clustering.])],
+ [case "${withval}" in
+ yes) # yes - require dependencies
+ test x$have_libcpg = xyes || AC_MSG_ERROR([libcpg not found, install openais-devel or corosync-devel])
+ test x$have_cpg_h = xyes || AC_MSG_ERROR([cpg.h not found, install openais-devel or corosync-devel])
+ with_cpg=yes
+ ;;
+ no) with_cpg=no ;;
+ *) AC_MSG_ERROR([Bad value ${withval} for --with-cpg option]) ;;
+ esac],
+ [ # not specified - use if present
+ test x$have_libcpg = xyes -a x$have_cpg_h = xyes && with_cpg=yes
+ ]
+)
+AM_CONDITIONAL([HAVE_LIBCPG], [test x$with_cpg = xyes])
+AC_CHECK_LIB([cman],[cman_is_quorate],have_libcman=yes,)
+AC_CHECK_HEADERS([libcman.h],have_libcman_h=yes,)
+AC_ARG_WITH([libcman],
+ [AS_HELP_STRING([--with-libcman], [Integration with libcman quorum service.])],
+ [case "${withval}" in
+ yes) # yes - require dependencies
+ test x$have_libcman = xyes || AC_MSG_ERROR([libcman not found, install cman-devel or cmanlib-devel])
+ test x$have_libcman_h = xyes || AC_MSG_ERROR([libcman.h not found, install cman-devel or cmanlib-devel])
+ with_libcman=yes
+ ;;
+ no) with_libcman=no ;;
+ *) AC_MSG_ERROR([Bad value ${withval} for --with-libcman option]) ;;
+ esac],
+ [ # not specified - use if present and we're using with_cpg
+ test x$have_libcman = xyes -a x$have_libcman_h = xyes -a x$with_cpg = xyes && with_libcman=yes
+ ]
+)
+AM_CONDITIONAL([HAVE_LIBCMAN], [test x$with_libcman = xyes])
+LIBS=$tmp_LIBS
+
# Also doxygen for documentation...
AC_CHECK_PROG([do_doxygen], [doxygen], [yes])
AM_CONDITIONAL([DOXYGEN], [test x$do_doxygen = xyes])
@@ -186,6 +228,7 @@
AC_CONFIG_FILES([
Makefile
tests/Makefile
+ tests/cluster/Makefile
tests/jrnl/Makefile
tests/jrnl/jtt/Makefile
lib/Makefile
Modified: store/trunk/cpp/tests/Makefile.am
===================================================================
--- store/trunk/cpp/tests/Makefile.am 2009-04-30 15:41:55 UTC (rev 3353)
+++ store/trunk/cpp/tests/Makefile.am 2009-05-05 18:24:25 UTC (rev 3354)
@@ -28,7 +28,7 @@
TMPDIR=$(abs_srcdir)/test_tmp
-SUBDIRS = jrnl .
+SUBDIRS = jrnl cluster .
TESTS = \
SimpleTest \
@@ -76,10 +76,10 @@
.valgrindrc \
.valgrind.supp
-TESTS_ENVIRONMENT = \
- QPID_DIR=$(QPID_DIR) \
- VALGRIND=$(VALGRIND) \
- abs_srcdir=$(abs_srcdir) \
- LIBBDBSTORE=$(abs_builddir)/../lib/.libs/msgstore.so \
+TESTS_ENVIRONMENT = \
+ QPID_DIR=$(QPID_DIR) \
+ VALGRIND=$(VALGRIND) \
+ abs_srcdir=$(abs_srcdir) \
+ LIBBDBSTORE=$(abs_builddir)/../lib/.libs/msgstore.so \
TMPDIR=$(TMPDIR) \
$(srcdir)/run_test
16 years, 12 months