diff --git a/ULib/README.md b/ULib/README.md
new file mode 100644
index 00000000000..5827ffe91be
--- /dev/null
+++ b/ULib/README.md
@@ -0,0 +1,107 @@
+#ULib Benchmarking Test
+
+This is the ULib portion of a [benchmarking test suite](https://github.com/TechEmpower/FrameworkBenchmarks) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+
+* [JSON test source](src/json.usp)
+
+### Data-Store/Database Mapping Test
+
+* [Database test source](src/db.usp)
+
+### Variable Query Test
+
+* [Variable Query test source](src/queries.usp)
+
+### Fortune Query Test
+
+* [Fortune Query test source](src/fortunes.usp)
+
+### Variable Query (update) Test
+
+* [Variable Query (update) test source](src/updates.usp)
+
+### Plaintext Test
+
+* [Plaintext test source](src/plaintext.usp)
+
+## Infrastructure Software Versions
+The tests were run with:
+
+* [ULib Version 1.4.1](https://github.com/stefanocasazza/ULib/archive/v1.4.1.tar.gz)
+
+Output
+======
+
+[/json](http://www.techempower.com/benchmarks/#section=json)
+-----
+```
+HTTP/1.1 200 OK
+Date: Thu, 03 Jul 2014 10:11:10 GMT
+Server: ULib
+Content-Length: 27
+Content-Type: application/json; charset=UTF-8
+
+{"message":"Hello, World!"}
+```
+
+[/db](http://www.techempower.com/benchmarks/#section=db)
+---
+```
+HTTP/1.1 200 OK
+Date: Thu, 03 Jul 2014 10:14:51 GMT
+Server: ULib
+Content-Length: 31
+Content-Type: application/json; charset=UTF-8
+
+{"id":6227,"randomNumber":8489}
+```
+
+[/queries?queries=10](http://www.techempower.com/benchmarks/#section=query)
+-------------------
+```
+HTTP/1.1 200 OK
+Date: Thu, 03 Jul 2014 10:14:51 GMT
+Server: ULib
+Content-Length: 320
+Content-Type: application/json; charset=UTF-8
+
+[{"id":6851,"randomNumber":7598},{"id":3968,"randomNumber":7325},{"id":8159,"randomNumber":348},{"id":9560,"randomNumber":7333},{"id":9938,"randomNumber":9080},{"id":1598,"randomNumber":1623},{"id":3280,"randomNumber":8707},{"id":4521,"randomNumber":6063},{"id":8173,"randomNumber":3690},{"id":3648,"randomNumber":8803}]
+```
+
+[/fortunes](http://www.techempower.com/benchmarks/#section=fortune)
+---------
+```
+HTTP/1.1 200 OK
+Date: Thu, 03 Jul 2014 10:14:51 GMT
+Server: ULib
+Content-Type: text/html; charset=UTF-8
+Content-Length: 1111
+
+
Fortunes| id | message |
|---|
| 11 | <script>alert("This should not be displayed in a browser alert box.");</script> |
| 4 | A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1 |
| 5 | A computer program does what you tell it to do, not what you want it to do. |
| 2 | A computer scientist is someone who fixes things that aren't broken. |
| 8 | A list is only as strong as its weakest link. ¿ Donald Knuth |
| 3 | After enough decimal places, nobody gives a damn. |
| 7 | Any program that runs right is obsolete. |
| 10 | Computers make very fast, very accurate mistakes. |
| 6 | Emacs is a nice operating system, but I prefer UNIX. ¿ Tom Christaensen |
| 9 | Feature: A bug with seniority. |
| 1 | fortune: No such file or directory |
| 12 | ¿?¿?¿?¿?¿?¿?¿?¿?¿?¿?¿?¿?¿?¿? |
+```
+
+[/updates?queries=10](http://www.techempower.com/benchmarks/#section=update)
+-------------------
+```
+HTTP/1.1 200 OK
+Date: Thu, 03 Jul 2014 10:14:51 GMT
+Server: ULib
+Content-Length: 319
+Content-Type: application/json; charset=UTF-8
+
+[{"id":7171,"randomNumber":351},{"id":6019,"randomNumber":9725},{"id":8118,"randomNumber":4023},{"id":7965,"randomNumber":1388},{"id":7797,"randomNumber":2249},{"id":112,"randomNumber":1108},{"id":6127,"randomNumber":4323},{"id":2597,"randomNumber":7509},{"id":2978,"randomNumber":7883},{"id":1111,"randomNumber":2228}]
+```
+
+[/plaintext](http://www.techempower.com/benchmarks/#section=plaintext)
+----------
+```
+HTTP/1.1 200 OK
+Date: Thu, 03 Jul 2014 10:14:51 GMT
+Server: ULib
+Content-Type: text/plain; charset=UTF-8
+Content-Length: 13
+
+Hello, World!
+```
diff --git a/ULib/__init__.py b/ULib/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/ULib/bash_profile.sh b/ULib/bash_profile.sh
new file mode 100644
index 00000000000..5d23199a8d9
--- /dev/null
+++ b/ULib/bash_profile.sh
@@ -0,0 +1,20 @@
+if [ -z "${FWROOT}" ]; then
+ export FWROOT=${HOME}/FrameworkBenchmarks
+fi
+#------------------------------------------------------------ --------------------------------------------
+# IROOT - Path of this test's install directory ($FWROOT/installs or $FWROOT/installs/pertest/)
+#------------------------------------------------------------ --------------------------------------------
+if [ -z "${IROOT}" ]; then
+ export IROOT=${FWROOT}/installs
+fi
+
+# Set the root of our ULib installation
+export ULIB_ROOT=${IROOT}/ULib
+
+# Where to find the userver_tcp executable
+export PATH="${ULIB_ROOT}/bin:$PATH"
+
+export ULIB_VERSION=1.4.1
+export ULIB_DOCUMENT_ROOT=${ULIB_ROOT}/ULIB_DOCUMENT_ROOT
+export ULIB_BUILD_OUTPUT=${ULIB_ROOT}/ULIB_BUILD_OUTPUT.txt
+export ULIB_SERVER_OUTPUT=${ULIB_ROOT}/ULIB_SERVER_OUTPUT.txt
diff --git a/ULib/benchmark_config b/ULib/benchmark_config
new file mode 100644
index 00000000000..8449636f6e4
--- /dev/null
+++ b/ULib/benchmark_config
@@ -0,0 +1,28 @@
+{
+ "framework": "ULib",
+ "tests": [{
+ "default": {
+ "setup_file": "setup",
+ "json_url": "/json",
+ "db_url": "/db",
+ "query_url": "/queries?queries=",
+ "fortune_url": "/fortunes",
+ "update_url": "/updates?queries=",
+ "plaintext_url": "/plaintext",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "Fullstack",
+ "database": "MySQL",
+ "framework": "ULib",
+ "language": "C++",
+ "orm": "Micro",
+ "platform": "ULib",
+ "webserver": "None",
+ "os": "Linux",
+ "database_os": "Linux",
+ "display_name": "ULib",
+ "notes": "",
+ "versus": ""
+ }
+ }]
+}
diff --git a/ULib/install.sh b/ULib/install.sh
new file mode 100755
index 00000000000..46572800905
--- /dev/null
+++ b/ULib/install.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+#----------------------------------------------------------------------------------------------------
+# toolset/run-tests.py --install server --install-strategy pertest --name ULib --test ULib --type all
+#----------------------------------------------------------------------------------------------------
+
+source ${HOME}/FrameworkBenchmarks/ULib/bash_profile.sh
+
+cat <${ULIB_ROOT}/benchmark.cfg
+userver {
+ PORT 8080
+ PREFORK_CHILD 8
+ LISTEN_BACKLOG 16384
+ MAX_KEEP_ALIVE 16384
+ DOCUMENT_ROOT ${ULIB_DOCUMENT_ROOT}
+ PID_FILE ${ULIB_ROOT}/userver_tcp.pid
+}
+EOF
+
+RET1=$(fw_exists ${ULIB_ROOT}/bin/userver_tcp)
+RET2=$(fw_exists ${ULIB_DOCUMENT_ROOT}/db.so)
+
+if [ "$RET1" == 0 ] && [ "$RET2" == 0 ]; then
+ return 0;
+fi
+
+# 1. Download ULib
+wget -nc --no-check-certificate --trust-server-names -O v${ULIB_VERSION}.tar.gz https://github.com/stefanocasazza/ULib/archive/v${ULIB_VERSION}.tar.gz
+
+# 2. Compile application (userver_tcp)
+fw_untar v${ULIB_VERSION}.tar.gz
+
+cd ULib-$ULIB_VERSION
+# ======================================================================================================
+# TO AVOID configure: error: newly created file is older than distributed files! Check your system clock
+# ======================================================================================================
+find . -exec touch {} \;
+# ======================================================================================================
+
+LIBS="-lssl -lcrypto -lz" \
+./configure --prefix=$ULIB_ROOT \
+ --disable-static \
+ --with-mysql \
+ --without-ssl --without-pcre --without-expat \
+ --without-libz --without-libuuid --without-magic \
+ --enable-static-orm-driver=mysql --enable-static-server-plugin=http >$ULIB_BUILD_OUTPUT 2>&1
+
+make -j1 install >>$ULIB_BUILD_OUTPUT 2>&1
+
+# 3. Compile usp pages for benchmark
+cd src/ulib/net/server/plugin/usp
+make -j1 db.la fortunes.la json.la plaintext.la queries.la updates.la >>$ULIB_BUILD_OUTPUT 2>&1
+
+if [ ! -e .libs/db.so ]; then
+ return 1;
+fi
+
+mkdir -p $ULIB_DOCUMENT_ROOT
+cp .libs/db.so .libs/fortunes.so .libs/json.so .libs/plaintext.so .libs/queries.so .libs/updates.so $ULIB_DOCUMENT_ROOT
diff --git a/ULib/setup.py b/ULib/setup.py
new file mode 100644
index 00000000000..3a9c959a969
--- /dev/null
+++ b/ULib/setup.py
@@ -0,0 +1,88 @@
+# -------------------------------------------------------
+# toolset/run-tests.py --name ULib --test ULib --type all
+# -------------------------------------------------------
+import os
+import sys
+import time
+#import logging
+import setup_util
+import subprocess
+import multiprocessing
+
+#log = logging.getLogger('framework_test')
+
+subprocess.call("source ${HOME}/FrameworkBenchmarks/ULib/bash_profile.sh", shell=True, executable='/bin/bash')
+
+ulib_root = subprocess.check_output('printf "$ULIB_ROOT" 2>/dev/null', shell=True, executable='/bin/bash')
+ulib_document_root = subprocess.check_output('printf "$ULIB_DOCUMENT_ROOT" 2>/dev/null', shell=True, executable='/bin/bash')
+
+fcfg = ulib_root + "/benchmark.cfg"
+fprg = ulib_root + "/bin/userver_tcp"
+fusp = ulib_document_root + "/db.so"
+
+script = """
+if [ -x "${ULIB_ROOT}/bin/userver_tcp" ] && [ -e "${ULIB_DOCUMENT_ROOT}/db.so" ] && [ -f "${ULIB_ROOT}/benchmark.cfg" ]; then
+ return 0;
+fi
+return 1;
+"""
+
+p = subprocess.Popen(['sh'], stdin=subprocess.PIPE)
+p.communicate(script)
+if p.returncode != 0:
+# log.critical('ULib install script FAILED')
+ print('ULib install script FAILED')
+ if not os.path.exists(fprg):
+# log.critical("ULib server program " + fprg + " NOT EXIST")
+ print("ULib server program " + fprg + " NOT EXIST")
+ if not os.path.exists(fusp):
+# log.critical("ULib usp page " + fusp + " NOT EXIST")
+ print("ULib usp page " + fusp + " NOT EXIST")
+ if not os.path.exists(fcfg):
+# log.critical("ULib configuration file " + fcfg + " NOT EXIST")
+ print("ULib configuration file " + fcfg + " NOT EXIST")
+# log.critical('Aborting')
+ print('Aborting')
+ exit(1)
+
+##############
+# start(args)
+##############
+def start(args, logfile, errfile):
+ try:
+ # 1. Change ULib Server configuration
+ #threads = str(args.max_threads)
+ PROCS = str(multiprocessing.cpu_count())
+ setup_util.replace_text(fcfg, "PREFORK_CHILD *", "PREFORK_CHILD " + PROCS)
+
+ # 2. Start ULib Server (userver_tcp)
+# log.info("trying to start ULib server " + fprg + " -c " + fcfg)
+ print("trying to start ULib server " + fprg + " -c " + fcfg)
+
+ os.putenv("ORM_DRIVER","mysql")
+ os.putenv("ORM_OPTION","host=" + args.database_host + " user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world")
+ os.putenv("UMEMPOOL", "1583,1507,-19,45,16458,523,-27,-14,27")
+
+ # Run in the background, but keep stdout/stderr for easy debugging
+ subprocess.Popen(fprg + " -c " + fcfg + " >$ULIB_SERVER_OUTPUT 2>&1", shell=True, stdout=logfile, stderr=errfile)
+ return 0
+ except subprocess.CalledProcessError:
+ return 1
+
+##############
+# stop()
+##############
+def stop(logfile, errfile):
+ try:
+ # Stop ULib Server (userver_tcp)
+ subprocess.check_call("kill -TERM $( cat " + iroot + "/userver_tcp.pid )", shell=True, stderr=errfile, stdout=logfile)
+ time.sleep(2);
+ p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+ out, err = p.communicate()
+ for line in out.splitlines():
+ if 'userver_tcp' in line:
+ pid = int(line.split(None, 2)[1])
+ os.kill(pid, 9)
+ return 0
+ except subprocess.CalledProcessError:
+ return 1
diff --git a/ULib/source_code b/ULib/source_code
new file mode 100644
index 00000000000..6a204e85618
--- /dev/null
+++ b/ULib/source_code
@@ -0,0 +1,8 @@
+./src/db.usp
+./src/world.h
+./src/json.usp
+./src/fortune.h
+./src/queries.usp
+./src/updates.usp
+./src/fortunes.usp
+./src/plaintext.usp
diff --git a/ULib/src/db.usp b/ULib/src/db.usp
new file mode 100644
index 00000000000..9e0475a3513
--- /dev/null
+++ b/ULib/src/db.usp
@@ -0,0 +1,120 @@
+
+
+
+
diff --git a/ULib/src/fortune.h b/ULib/src/fortune.h
new file mode 100644
index 00000000000..cf51aa896ad
--- /dev/null
+++ b/ULib/src/fortune.h
@@ -0,0 +1,123 @@
+// fortune.h
+
+#ifndef FORTUNE_H
+#define FORTUNE_H 1
+
+#include
+#include
+
+class Fortune {
+public:
+ // Check for memory error
+ U_MEMORY_TEST
+
+ // Allocator e Deallocator
+ U_MEMORY_ALLOCATOR
+ U_MEMORY_DEALLOCATOR
+
+ int id;
+ UString message;
+
+ // CONSTRUCTOR
+
+ Fortune()
+ {
+ U_TRACE_REGISTER_OBJECT(5, Fortune, "")
+ }
+
+ Fortune(int _id, const UString& _message) : id(_id), message(_message)
+ {
+ U_TRACE_REGISTER_OBJECT(5, Fortune, "%d,%.*S", _id, U_STRING_TO_TRACE(_message))
+ }
+
+ Fortune(const Fortune& f) : id(f.id), message((void*)U_STRING_TO_PARAM(f.message))
+ {
+ U_TRACE_REGISTER_OBJECT(5, Fortune, "%p", &f)
+
+ U_MEMORY_TEST_COPY(f)
+ }
+
+ ~Fortune()
+ {
+ U_TRACE_UNREGISTER_OBJECT(5, Fortune)
+ }
+
+ // SERVICE
+
+ bool operator<(const Fortune& other) const { return cmp_obj(&message, &other.message); }
+
+ static int cmp_obj(const void* a, const void* b)
+ {
+ U_TRACE(5, "Fortune::cmp_obj(%p,%p)", a, b)
+
+ return (*(const Fortune**)a)->message.compare((*(const Fortune**)b)->message);
+ }
+
+#ifdef DEBUG
+ const char* dump(bool breset) const
+ {
+ *UObjectIO::os << "id " << id << '\n'
+ << "message (UString " << (void*)&message << ')';
+
+ if (breset)
+ {
+ UObjectIO::output();
+
+ return UObjectIO::buffer_output;
+ }
+
+ return 0;
+ }
+#endif
+
+private:
+ Fortune& operator=(const Fortune&) { return *this; }
+};
+
+// ORM TEMPLATE SPECIALIZATIONS
+
+template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base {
+public:
+ explicit UOrmTypeHandler(Fortune& val) : UOrmTypeHandler_Base(&val) {}
+
+ void bindParam(UOrmStatement* stmt) const
+ {
+ U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt)
+
+ stmt->bindParam(U_ORM_TYPE_HANDLER(Fortune, id, int));
+ stmt->bindParam(U_ORM_TYPE_HANDLER(Fortune, message, UString));
+ }
+
+ void bindResult(UOrmStatement* stmt)
+ {
+ U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt)
+
+ stmt->bindResult(U_ORM_TYPE_HANDLER(Fortune, id, int));
+ stmt->bindResult(U_ORM_TYPE_HANDLER(Fortune, message, UString));
+ }
+};
+
+// JSON TEMPLATE SPECIALIZATIONS
+
+template <> class U_EXPORT UJsonTypeHandler : public UJsonTypeHandler_Base {
+public:
+ explicit UJsonTypeHandler(Fortune& val) : UJsonTypeHandler_Base(&val) {}
+
+ void toJSON(UValue& json)
+ {
+ U_TRACE(0, "UJsonTypeHandler::toJSON(%p)", &json)
+
+ json.toJSON(U_JSON_TYPE_HANDLER(Fortune, id, int));
+ json.toJSON(U_JSON_TYPE_HANDLER(Fortune, message, UString));
+ }
+
+ void fromJSON(UValue& json)
+ {
+ U_TRACE(0, "UJsonTypeHandler::fromJSON(%p)", &json)
+
+ json.fromJSON(U_JSON_TYPE_HANDLER(Fortune, id, int));
+ json.fromJSON(U_JSON_TYPE_HANDLER(Fortune, message, UString));
+ }
+};
+
+#endif
diff --git a/ULib/src/fortunes.usp b/ULib/src/fortunes.usp
new file mode 100644
index 00000000000..7c0cb31963e
--- /dev/null
+++ b/ULib/src/fortunes.usp
@@ -0,0 +1,152 @@
+
+
+Fortunes
diff --git a/ULib/src/json.usp b/ULib/src/json.usp
new file mode 100644
index 00000000000..98c1d49ba37
--- /dev/null
+++ b/ULib/src/json.usp
@@ -0,0 +1,81 @@
+
+
+
+
diff --git a/ULib/src/plaintext.usp b/ULib/src/plaintext.usp
new file mode 100644
index 00000000000..abb0d69fe69
--- /dev/null
+++ b/ULib/src/plaintext.usp
@@ -0,0 +1,51 @@
+
+Hello, World!
diff --git a/ULib/src/queries.usp b/ULib/src/queries.usp
new file mode 100644
index 00000000000..f2fa31b651f
--- /dev/null
+++ b/ULib/src/queries.usp
@@ -0,0 +1,161 @@
+
+
+
+
+
diff --git a/ULib/src/updates.usp b/ULib/src/updates.usp
new file mode 100644
index 00000000000..7dcf9160d7e
--- /dev/null
+++ b/ULib/src/updates.usp
@@ -0,0 +1,184 @@
+
+
+
+
+
diff --git a/ULib/src/world.h b/ULib/src/world.h
new file mode 100644
index 00000000000..895f5eaf8ad
--- /dev/null
+++ b/ULib/src/world.h
@@ -0,0 +1,106 @@
+// world.h
+
+#ifndef WORLD_H
+#define WORLD_H 1
+
+#include
+#include
+
+class World {
+public:
+ // Check for memory error
+ U_MEMORY_TEST
+
+ // Allocator e Deallocator
+ U_MEMORY_ALLOCATOR
+ U_MEMORY_DEALLOCATOR
+
+ int id, randomNumber;
+
+ // CONSTRUCTOR
+
+ World()
+ {
+ U_TRACE_REGISTER_OBJECT(5, World, "")
+ }
+
+ World(const World& w) : id(w.id), randomNumber(w.randomNumber)
+ {
+ U_TRACE_REGISTER_OBJECT(5, World, "%p", &w)
+
+ U_MEMORY_TEST_COPY(w)
+ }
+
+ ~World()
+ {
+ U_TRACE_UNREGISTER_OBJECT(5, World)
+ }
+
+#ifdef DEBUG
+ const char* dump(bool breset) const
+ {
+ *UObjectIO::os << "id " << id << '\n'
+ << "randomNumber " << randomNumber;
+
+ if (breset)
+ {
+ UObjectIO::output();
+
+ return UObjectIO::buffer_output;
+ }
+
+ return 0;
+ }
+#endif
+
+private:
+ World& operator=(const World&) { return *this; }
+};
+
+// ORM TEMPLATE SPECIALIZATIONS
+
+template <> class U_EXPORT UOrmTypeHandler : public UOrmTypeHandler_Base {
+public:
+ explicit UOrmTypeHandler(World& val) : UOrmTypeHandler_Base(&val) {}
+
+ void bindParam(UOrmStatement* stmt) const
+ {
+ U_TRACE(0, "UOrmTypeHandler::bindParam(%p)", stmt)
+
+ stmt->bindParam(U_ORM_TYPE_HANDLER(World, id, int));
+ stmt->bindParam(U_ORM_TYPE_HANDLER(World, randomNumber, int));
+ }
+
+ void bindResult(UOrmStatement* stmt)
+ {
+ U_TRACE(0, "UOrmTypeHandler::bindResult(%p)", stmt)
+
+ stmt->bindResult(U_ORM_TYPE_HANDLER(World, id, int));
+ stmt->bindResult(U_ORM_TYPE_HANDLER(World, randomNumber, int));
+ }
+};
+
+// JSON TEMPLATE SPECIALIZATIONS
+
+template <> class U_EXPORT UJsonTypeHandler : public UJsonTypeHandler_Base {
+public:
+ explicit UJsonTypeHandler(World& val) : UJsonTypeHandler_Base(&val) {}
+
+ void toJSON(UValue& json)
+ {
+ U_TRACE(0, "UJsonTypeHandler::toJSON(%p)", &json)
+
+ json.toJSON(U_JSON_TYPE_HANDLER(World, id, int));
+ json.toJSON(U_JSON_TYPE_HANDLER(World, randomNumber, int));
+ }
+
+ void fromJSON(UValue& json)
+ {
+ U_TRACE(0, "UJsonTypeHandler::fromJSON(%p)", &json)
+
+ json.fromJSON(U_JSON_TYPE_HANDLER(World, id, int));
+ json.fromJSON(U_JSON_TYPE_HANDLER(World, randomNumber, int));
+ }
+};
+
+#endif
diff --git a/WeberFramework/__init__.py b/WeberFramework/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/evhttp-sharp/__init__.py b/evhttp-sharp/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/nawak/__init__.py b/nawak/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/php-yii2/__init__.py b/php-yii2/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/play-activate-mysql/__init__.py b/play-activate-mysql/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/pyramid/__init__.py b/pyramid/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/toolset/benchmark/benchmarker.py b/toolset/benchmark/benchmarker.py
index 95949a2246e..96302ed82cc 100644
--- a/toolset/benchmark/benchmarker.py
+++ b/toolset/benchmark/benchmarker.py
@@ -1,4 +1,6 @@
from setup.linux.installer import Installer
+from setup.linux import setup_util
+
from benchmark import framework_test
import os
@@ -238,6 +240,35 @@ def warning_file(self, test_name, test_type):
# End warning_file
############################################################
+ ############################################################
+ # get_stats_file(test_name, test_type)
+ # returns the stats file name for this test_name and
+ # test_type timestamp/test_type/test_name/raw
+ ############################################################
+ def get_stats_file(self, test_name, test_type):
+ return os.path.join(self.result_directory, self.timestamp, test_type, test_name, "stats")
+ ############################################################
+ # End get_stats_file
+ ############################################################
+
+
+ ############################################################
+ # stats_file(test_name, test_type)
+ # returns the stats file for this test_name and test_type
+ # timestamp/test_type/test_name/raw
+ ############################################################
+ def stats_file(self, test_name, test_type):
+ path = self.get_stats_file(test_name, test_type)
+ try:
+ os.makedirs(os.path.dirname(path))
+ except OSError:
+ pass
+ return path
+ ############################################################
+ # End stats_file
+ ############################################################
+
+
############################################################
# full_results_directory
############################################################
@@ -347,6 +378,16 @@ def __gather_tests(self):
tests.append(atest)
tests.sort(key=lambda x: x.name)
+
+ # If the tests have been interrupted somehow, then we want to resume them where we left
+ # off, rather than starting from the beginning
+ if os.path.isfile('current_benchmark.txt'):
+ with open('current_benchmark.txt', 'r') as interrupted_benchmark:
+ interrupt_bench = interrupted_benchmark.read()
+ for index, atest in enumerate(tests):
+ if atest.name == interrupt_bench:
+ tests = tests[index:]
+ break
return tests
############################################################
# End __gather_tests
@@ -476,6 +517,8 @@ def __run_tests(self, tests):
if self.os.lower() == 'windows':
logging.debug("Executing __run_tests on Windows")
for test in tests:
+ with open('current_benchmark.txt', 'w') as benchmark_resume_file:
+ benchmark_resume_file.write(test.name)
self.__run_test(test)
else:
logging.debug("Executing __run_tests on Linux")
@@ -487,13 +530,17 @@ def __run_tests(self, tests):
Running Test: {name} ...
-----------------------------------------------------
""".format(name=test.name))
+ with open('current_benchmark.txt', 'w') as benchmark_resume_file:
+ benchmark_resume_file.write(test.name)
test_process = Process(target=self.__run_test, args=(test,))
test_process.start()
test_process.join(self.run_test_timeout_seconds)
+ self.__load_results() # Load intermediate result from child process
if(test_process.is_alive()):
logging.debug("Child process for {name} is still alive. Terminating.".format(name=test.name))
self.__write_intermediate_results(test.name,"__run_test timeout (="+ str(self.run_test_timeout_seconds) + " seconds)")
test_process.terminate()
+ os.remove('current_benchmark.txt')
logging.debug("End __run_tests.")
############################################################
@@ -571,7 +618,8 @@ def __run_test(self, test):
p.communicate("""
sudo restart mysql
sudo restart mongodb
- sudo /etc/init.d/postgresql restart
+ sudo service redis-server restart
+ sudo /etc/init.d/postgresql restart
""")
time.sleep(10)
@@ -828,6 +876,13 @@ def __write_intermediate_results(self,test_name,status_message):
# End __write_intermediate_results
############################################################
+ def __load_results(self):
+ try:
+ with open(os.path.join(self.latest_results_directory, 'results.json')) as f:
+ self.results = json.load(f)
+ except (ValueError, IOError):
+ pass
+
############################################################
# __finish
############################################################
@@ -861,6 +916,9 @@ def __init__(self, args):
if self.database_host == None: self.database_host = self.client_host
if self.database_identity_file == None: self.database_identity_file = self.client_identity_file
+ # Remember root directory
+ self.fwroot = setup_util.get_fwroot()
+
# setup results and latest_results directories
self.result_directory = os.path.join("results", self.name)
self.latest_results_directory = self.latest_results_directory()
@@ -968,8 +1026,8 @@ def __init__(self, args):
if self.client_identity_file != None:
self.client_ssh_string = self.client_ssh_string + " -i " + self.client_identity_file
- if self.install_software:
- install = Installer(self)
+ if self.install is not None:
+ install = Installer(self, self.install_strategy)
install.install_software()
############################################################