浏览代码

Merge branch 'master' of https://github.com/LadyMozzarella/FrameworkBenchmarks into get-rack-rails-sinatra-running

Brittany Mazza 10 年之前
父节点
当前提交
69cb5b5e1a
共有 53 个文件被更改,包括 783 次插入397 次删除
  1. 1 1
      .travis.yml
  2. 3 3
      config/cassandra/cassandra.yaml
  3. 2 2
      deployment/vagrant-common/bootstrap.sh
  4. 4 0
      frameworks/C++/ULib/install.sh
  5. 2 2
      frameworks/C++/ULib/setup_mysql.sh
  6. 2 2
      frameworks/C++/ULib/setup_postgres.sh
  7. 2 2
      frameworks/C++/ULib/setup_sqlite.sh
  8. 0 1
      frameworks/C++/ULib/src/json.usp
  9. 19 4
      frameworks/C/lwan/benchmark_config
  10. 1 1
      frameworks/C/lwan/install.sh
  11. 3 0
      frameworks/Java/sabina/bash_profile.sh
  12. 10 8
      frameworks/Java/sabina/benchmark_config
  13. 3 0
      frameworks/Java/sabina/install.sh
  14. 135 0
      frameworks/Java/sabina/pom.xml
  15. 44 0
      frameworks/Java/sabina/readme.md
  16. 4 0
      frameworks/Java/sabina/setup.sh
  17. 4 0
      frameworks/Java/sabina/source_code
  18. 141 0
      frameworks/Java/sabina/src/main/java/sabina/benchmark/Application.java
  19. 9 0
      frameworks/Java/sabina/src/main/java/sabina/benchmark/Fortune.java
  20. 5 0
      frameworks/Java/sabina/src/main/java/sabina/benchmark/Message.java
  21. 5 0
      frameworks/Java/sabina/src/main/java/sabina/benchmark/World.java
  22. 20 0
      frameworks/Java/sabina/src/main/resources/sabina/view/fortunes.ftl
  23. 20 0
      frameworks/Java/sabina/src/main/resources/sabina/view/fortunes.html
  24. 25 0
      frameworks/Java/sabina/src/main/resources/server.properties
  25. 136 0
      frameworks/Java/sabina/src/test/java/sabina/benchmark/ApplicationTest.java
  26. 2 2
      frameworks/Java/servlet/pom.xml
  27. 22 0
      frameworks/Java/spring/src/main/java/com/techempower/spring/Common.java
  28. 50 18
      frameworks/Java/spring/src/main/java/com/techempower/spring/web/WorldDatabaseController.java
  29. 4 4
      frameworks/Java/undertow-edge/pom.xml
  30. 4 4
      frameworks/Java/undertow/pom.xml
  31. 0 9
      frameworks/PHP/php-silica/.gitignore
  32. 0 36
      frameworks/PHP/php-silica/README.md
  33. 0 9
      frameworks/PHP/php-silica/bash_profile.sh
  34. 0 6
      frameworks/PHP/php-silica/composer.json
  35. 0 136
      frameworks/PHP/php-silica/deploy/nginx.conf
  36. 0 9
      frameworks/PHP/php-silica/deploy/php-silica
  37. 0 3
      frameworks/PHP/php-silica/install.sh
  38. 0 13
      frameworks/PHP/php-silica/setup.sh
  39. 0 4
      frameworks/PHP/php-silica/source_code
  40. 0 8
      frameworks/PHP/php-silica/web/.htaccess
  41. 0 51
      frameworks/PHP/php-silica/web/app.php
  42. 4 1
      frameworks/PHP/php-slim/index.php
  43. 17 7
      frameworks/Perl/mojolicious/cpanfile.snapshot
  44. 1 1
      frameworks/Python/API-Hour/requirements.txt
  45. 31 17
      toolset/run-ci.py
  46. 3 1
      toolset/setup/linux/client.sh
  47. 26 17
      toolset/setup/linux/database.sh
  48. 3 2
      toolset/setup/linux/installer.py
  49. 5 4
      toolset/setup/linux/languages/mono.sh
  50. 2 2
      toolset/setup/linux/languages/perl.sh
  51. 3 2
      toolset/setup/linux/languages/python2.sh
  52. 3 2
      toolset/setup/linux/languages/python3.sh
  53. 3 3
      toolset/setup/linux/prerequisites.sh

+ 1 - 1
.travis.yml

@@ -69,6 +69,7 @@ env:
     - "TESTDIR=Java/servlet"
     - "TESTDIR=Java/servlet3-cass"
     - "TESTDIR=Java/spark"
+    - "TESTDIR=Java/sabina"
     - "TESTDIR=Java/spring"
     - "TESTDIR=Java/tapestry"
     - "TESTDIR=Java/undertow"
@@ -106,7 +107,6 @@ env:
     - "TESTDIR=PHP/php-pimf"
     - "TESTDIR=PHP/php-silex"
     - "TESTDIR=PHP/php-silex-orm"
-    - "TESTDIR=PHP/php-silica"
     - "TESTDIR=PHP/php-slim"
     - "TESTDIR=PHP/symfony2"
     - "TESTDIR=PHP/symfony2-stripped"

+ 3 - 3
config/cassandra/cassandra.yaml

@@ -224,7 +224,7 @@ seed_provider:
       parameters:
           # seeds is actually a comma-delimited list of addresses.
           # Ex: "<ip1>,<ip2>,<ip3>"
-          - seeds: "TFB_DATABASE_HOST"
+          - seeds: "127.0.0.1"
 
 # For workloads with more data than can fit in memory, Cassandra's
 # bottleneck will be reads that need to fetch data from
@@ -294,7 +294,7 @@ ssl_storage_port: 7001
 # address associated with the hostname (it might not be).
 #
 # Setting this to 0.0.0.0 is always wrong.
-listen_address: TFB_DATABASE_HOST
+listen_address: 127.0.0.1
 
 # Address to broadcast to other Cassandra nodes
 # Leaving this blank will set it to the same value as listen_address
@@ -332,7 +332,7 @@ start_rpc: true
 # Note that unlike ListenAddress above, it is allowed to specify 0.0.0.0
 # here if you want to listen on all interfaces, but that will break clients 
 # that rely on node auto-discovery.
-rpc_address: TFB_DATABASE_HOST
+rpc_address: 0.0.0.0
 # port for Thrift to listen for clients on
 rpc_port: 9160
 

+ 2 - 2
deployment/vagrant-common/bootstrap.sh

@@ -75,8 +75,8 @@ if [ ! -e "~/.firstboot" ]; then
   echo $CLIENT_IP TFB-client   | sudo tee --append /etc/hosts
   echo $SERVER_IP TFB-server   | sudo tee --append /etc/hosts
 
-  # Add other users:
-  sudo useradd -m testrunner
+  # Add user to run tests
+  sudo adduser --disabled-password --gecos "" testrunner
   # WARN: testrunner will NOT have sudo access by round 11
   #       please begin migrating scripts to not rely on sudo.
   sudo bash -c "echo 'testrunner ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-tfb-testrunner"

+ 4 - 0
frameworks/C++/ULib/install.sh

@@ -16,6 +16,10 @@
 #    . $FWROOT/ULib/install.sh (cwd=$FWROOT//installs)
 # --------------------------------------------------------------------------------------------------------
 
+ULIB_VERSION=1.4.2
+ULIB_ROOT=$IROOT/ULib
+ULIB_DOCUMENT_ROOT=${ULIB_ROOT}/ULIB_DOCUMENT_ROOT
+
 # Check if ULib is already installed
 ULIB_INSTALLED_FILE="${IROOT}/ULib-${ULIB_VERSION}.installed"
 RETCODE=$(fw_exists ${ULIB_INSTALLED_FILE})

+ 2 - 2
frameworks/C++/ULib/setup_mysql.sh

@@ -5,7 +5,7 @@ export ORM_DRIVER="mysql"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
 
 # 1. Change ULib Server configuration
-sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $ULIB_ROOT/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $IROOT/ULib/benchmark.cfg
 
 # 2. Start ULib Server (userver_tcp)
-$ULIB_ROOT/bin/userver_tcp -c $ULIB_ROOT/benchmark.cfg &
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 2 - 2
frameworks/C++/ULib/setup_postgres.sh

@@ -5,7 +5,7 @@ export ORM_DRIVER="pgsql"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8"
 
 # 1. Change ULib Server configuration
-sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $ULIB_ROOT/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $IROOT/ULib/benchmark.cfg
 
 # 2. Start ULib Server (userver_tcp)
-$ULIB_ROOT/bin/userver_tcp -c $ULIB_ROOT/benchmark.cfg &
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 2 - 2
frameworks/C++/ULib/setup_sqlite.sh

@@ -5,7 +5,7 @@ export ORM_DRIVER="sqlite"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=${ULIB_ROOT}/db/%.*s"
 
 # 1. Change ULib Server configuration
-sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" $ULIB_ROOT/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g" ${IROOT}/ULib/benchmark.cfg
 
 # 2. Start ULib Server (userver_tcp)
-$ULIB_ROOT/bin/userver_tcp -c $ULIB_ROOT/benchmark.cfg &
+${IROOT}/ULib/bin/userver_tcp -c ${IROOT}/ULib/benchmark.cfg &

+ 0 - 1
frameworks/C++/ULib/src/json.usp

@@ -43,5 +43,4 @@ const char* hello_str = json_object_to_json_string(hello);
 USP_PUTS_STRING(hello_str);
 json_object_put(hello);
 #endif
-U_ClientImage_request_nocache = true;
 -->

+ 19 - 4
frameworks/C/lwan/benchmark_config

@@ -1,13 +1,30 @@
 {
   "framework": "lwan",
   "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "plaintext_url": "/plaintext",
+      "json_url": "/json",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "None",
+      "framework": "lwan",
+      "language": "C",
+      "orm": "Raw",
+      "platform": "Lwan",
+      "webserver": "Lwan",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "Lwan",
+      "notes": "",
+      "versus": ""
+    },
     "sqlite": {
       "setup_file": "setup",
       "db_url": "/db",
       "query_url": "/queries?queries=",
       "fortune_url": "/fortunes",
-      "plaintext_url": "/plaintext",
-      "json_url": "/json",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",
@@ -28,8 +45,6 @@
       "db_url": "/db",
       "query_url": "/queries?queries=",
       "fortune_url": "/fortunes",
-      "plaintext_url": "/plaintext",
-      "json_url": "/json",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Platform",

+ 1 - 1
frameworks/C/lwan/install.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-REV='eb96604657dd940ecb70b56fef4279077e3f9c21'
+REV='8ae98d2b6e146948a7ed13e76141e0f69228d690'
 
 INSTALLED_FILE="${IROOT}/lwan-${REV}.installed"
 RETCODE=$(fw_exists ${INSTALLED_FILE})

+ 3 - 0
frameworks/Java/sabina/bash_profile.sh

@@ -0,0 +1,3 @@
+#@IgnoreInspection AddShebang
+
+export JAVA_HOME=/opt/java8

+ 10 - 8
frameworks/PHP/php-silica/benchmark_config → frameworks/Java/sabina/benchmark_config

@@ -1,24 +1,26 @@
 {
-  "framework": "silica",
+  "framework": "sabina",
   "tests": [{
-    "raw": {
+    "default": {
       "setup_file": "setup",
+      "json_url": "/json",
       "db_url": "/db",
       "query_url": "/db?queries=",
+      "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",
       "database": "MySQL",
-      "framework": "silica",
-      "language": "PHP",
+      "framework": "sabina",
+      "language": "Java",
       "orm": "Raw",
-      "platform": "PHP-FPM",
-      "webserver": "nginx",
+      "platform": "Servlet",
+      "webserver": "None",
       "os": "Linux",
       "database_os": "Linux",
-      "display_name": "silica",
+      "display_name": "Sabina",
       "notes": "",
-      "versus": "php"
+      "versus": "servlet"
     }
   }]
 }

+ 3 - 0
frameworks/Java/sabina/install.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+fw_depends java8 maven

+ 135 - 0
frameworks/Java/sabina/pom.xml

@@ -0,0 +1,135 @@
+<project
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>sabina</groupId>
+    <artifactId>sabina</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+
+    <name>Sabina benchmark project</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+        <maven.compiler.source>${java.specification.version}</maven.compiler.source>
+        <maven.compiler.target>${java.specification.version}</maven.compiler.target>
+        <maven.compiler.optimize>true</maven.compiler.optimize>
+        <maven.compiler.debug>false</maven.compiler.debug>
+
+        <db.host>localhost</db.host>
+        <web.port>8080</web.port>
+
+        <sabina-version>1.0.0</sabina-version>
+        <mysql-connector-version>5.1.28</mysql-connector-version>
+    </properties>
+
+    <repositories>
+        <repository>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <id>central</id>
+            <name>bintray</name>
+            <url>http://jcenter.bintray.com</url>
+        </repository>
+    </repositories>
+    <pluginRepositories>
+        <pluginRepository>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+            <id>central</id>
+            <name>bintray-plugins</name>
+            <url>http://jcenter.bintray.com</url>
+        </pluginRepository>
+    </pluginRepositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>sabina</groupId>
+            <artifactId>http</artifactId>
+            <version>${sabina-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>javax.servlet-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>sabina</groupId>
+            <artifactId>extra</artifactId>
+            <version>${sabina-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.spec.javax.servlet</groupId>
+            <artifactId>jboss-servlet-api_3.1_spec</artifactId>
+            <version>1.0.0.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>com.mchange</groupId>
+            <artifactId>c3p0</artifactId>
+            <version>0.9.2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>${mysql-connector-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>fluent-hc</artifactId>
+            <version>4.4</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+
+        <plugins>
+            <plugin>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>2.3</version>
+                <configuration>
+                    <createDependencyReducedPom>false</createDependencyReducedPom>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.5</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>sabina.benchmark.Application</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 44 - 0
frameworks/Java/sabina/readme.md

@@ -0,0 +1,44 @@
+
+# Sabina Benchmarking Test
+
+This is the Sabina portion of a [benchmarking test suite](../) comparing a variety of web
+development platforms. The test utilizes Sabina routes, Gson for JSON serialization and a custom
+OSIV pattern created with Sabina filters.
+
+
+## Tests
+
+* [Sabina application](/src/main/java/sabina/benchmark/Application.java)
+
+
+## Infrastructure Software Versions
+
+* [Sabina 1.0](http://there4.co/)
+
+
+## Different test setups
+
+* Local environment with Sabina's built in embedded Jetty (port=8080, context=/)
+ * Start application from [Application](/src/main/java/sabina/benchmark/Application.java)'s main method
+* Local environment with Sabina's built in embedded Undertow (port=8080, context=/)
+ * Start application from [Application](/src/main/java/sabina/benchmark/Application.java)'s main method
+
+
+## Test URLs
+
+### JSON Encoding Test
+
+http://localhost:8080/json
+
+### Data-Store/Database Mapping Test
+
+http://localhost:8080/db?queries=5
+
+### Plain Text Test
+
+http://localhost:8080/plaintext
+
+## TODO
+
+* Implement 'update' test
+* Implement 'fortunes' test

+ 4 - 0
frameworks/Java/sabina/setup.sh

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+mvn clean package -Ddb.host=${DBHOST}
+${JAVA_HOME}/bin/java -jar target/sabina-1.0.0-SNAPSHOT.jar &

+ 4 - 0
frameworks/Java/sabina/source_code

@@ -0,0 +1,4 @@
+./sabina/src/main/java/
+./sabina/src/main/java/Application.java
+./sabina/src/main/java/Message.java
+./sabina/src/main/java/World.java

+ 141 - 0
frameworks/Java/sabina/src/main/java/sabina/benchmark/Application.java

@@ -0,0 +1,141 @@
+package sabina.benchmark;
+
+import static java.lang.Integer.parseInt;
+import static sabina.Sabina.*;
+import static sabina.content.JsonContent.toJson;
+
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+import sabina.Exchange;
+import sabina.Request;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.Properties;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.sql.DataSource;
+
+/**
+ * When it is implemented, add this to benchmark_config
+ * "fortune_url": "/fortune",
+ * "update_url": "/update",
+ */
+final class Application {
+    private static final Properties CONFIG = loadConfig ();
+    private static final DataSource DS = createSessionFactory ();
+    private static final String QUERY = "select * from world where id = ?";
+
+    private static final int DB_ROWS = 10000;
+    private static final String MESSAGE = "Hello, World!";
+    private static final String CONTENT_TYPE_TEXT = "text/plain";
+
+    private static Properties loadConfig () {
+        try {
+            Properties config = new Properties ();
+            config.load (Class.class.getResourceAsStream ("/server.properties"));
+            return config;
+        }
+        catch (Exception ex) {
+            throw new RuntimeException (ex);
+        }
+    }
+
+    private static DataSource createSessionFactory () {
+        try {
+            ComboPooledDataSource cpds = new ComboPooledDataSource ();
+            cpds.setJdbcUrl (CONFIG.getProperty ("mysql.uri"));
+            cpds.setMinPoolSize (32);
+            cpds.setMaxPoolSize (256);
+            cpds.setCheckoutTimeout (1800);
+            cpds.setMaxStatements (50);
+            return cpds;
+        }
+        catch (Exception ex) {
+            throw new RuntimeException (ex);
+        }
+    }
+
+    private static int getQueries (final Request request) {
+        try {
+            String param = request.queryParams ("queries");
+            if (param == null)
+                return 1;
+
+            int queries = parseInt (param);
+            if (queries < 1)
+                return 1;
+            if (queries > 500)
+                return 500;
+
+            return queries;
+        }
+        catch (NumberFormatException ex) {
+            return 1;
+        }
+    }
+
+    private static Object getJson (Exchange it) {
+        it.response.type ("application/json");
+        return toJson (new Message ());
+    }
+
+    private static Object getDb (Exchange it) {
+        final int queries = getQueries (it.request);
+        final World[] worlds = new World[queries];
+
+        try (final Connection con = DS.getConnection ()) {
+            final Random random = ThreadLocalRandom.current ();
+            PreparedStatement stmt = con.prepareStatement (QUERY);
+
+            for (int i = 0; i < queries; i++) {
+                stmt.setInt (1, random.nextInt (DB_ROWS) + 1);
+                ResultSet rs = stmt.executeQuery ();
+                while (rs.next ()) {
+                    worlds[i] = new World ();
+                    worlds[i].id = rs.getInt (1);
+                    worlds[i].randomNumber = rs.getInt (2);
+                }
+            }
+        }
+        catch (SQLException e) {
+            e.printStackTrace ();
+        }
+
+        it.response.type ("application/json");
+        return toJson (it.request.queryParams ("queries") == null? worlds[0] : worlds);
+    }
+
+    private static Object getFortune (Exchange aExchange) {
+        throw new UnsupportedOperationException ();
+    }
+
+    private static Object getUpdate (Exchange aExchange) {
+        throw new UnsupportedOperationException ();
+    }
+
+    private static Object getPlaintext (Exchange it) {
+        it.response.type (CONTENT_TYPE_TEXT);
+        return MESSAGE;
+    }
+
+    private static void addCommonHeaders (Exchange it) {
+        it.header ("Server", "Undertow/1.1.2");
+        it.response.raw ().addDateHeader ("Date", new Date ().getTime ());
+    }
+
+    public static void main (String[] args) {
+        get ("/json", Application::getJson);
+        get ("/db", Application::getDb);
+        get ("/fortune", Application::getFortune);
+        get ("/update", Application::getUpdate);
+        get ("/plaintext", Application::getPlaintext);
+        after (Application::addCommonHeaders);
+
+        setIpAddress (CONFIG.getProperty ("web.host"));
+        start (parseInt (CONFIG.getProperty ("web.port")));
+    }
+}

+ 9 - 0
frameworks/Java/sabina/src/main/java/sabina/benchmark/Fortune.java

@@ -0,0 +1,9 @@
+package sabina.benchmark;
+
+/**
+ * TODO .
+ *
+ * @author jam
+ */
+public class Fortune {
+}

+ 5 - 0
frameworks/Java/sabina/src/main/java/sabina/benchmark/Message.java

@@ -0,0 +1,5 @@
+package sabina.benchmark;
+
+final class Message {
+    public final String message = "Hello, World!";
+}

+ 5 - 0
frameworks/Java/sabina/src/main/java/sabina/benchmark/World.java

@@ -0,0 +1,5 @@
+package sabina.benchmark;
+
+final class World {
+    public int id, randomNumber;
+}

+ 20 - 0
frameworks/Java/sabina/src/main/resources/sabina/view/fortunes.ftl

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Fortunes</title>
+</head>
+<body>
+<table>
+    <tr>
+        <th>id</th>
+        <th>message</th>
+    </tr>
+    {{#.}}
+      <tr>
+          <td>{{id}}</td>
+          <td>{{message}}</td>
+      </tr>
+    {{/.}}
+</table>
+</body>
+</html>

+ 20 - 0
frameworks/Java/sabina/src/main/resources/sabina/view/fortunes.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Fortunes</title>
+</head>
+<body>
+<table>
+    <tr>
+        <th>id</th>
+        <th>message</th>
+    </tr>
+    <#list fortunes as fortune>
+      <tr>
+          <td>${fortune.id}</td>
+          <td>${fortune.message!null}</td>
+      </tr>
+    </#list>
+</table>
+</body>
+</html>

+ 25 - 0
frameworks/Java/sabina/src/main/resources/server.properties

@@ -0,0 +1,25 @@
+web.port = ${web.port}
+web.host = 0.0.0.0
+
+mongodb.uri = ${db.host}:27017
+mongodb.name = hello_world
+
+mysql.uri = jdbc:mysql://${db.host}:3306/hello_world?\
+user=benchmarkdbuser&\
+password=benchmarkdbpass&\
+jdbcCompliantTruncation=false&\
+elideSetAutoCommits=true&\
+useLocalSessionState=true&\
+cachePrepStmts=true&\
+cacheCallableStmts=true&\
+alwaysSendSetIsolation=false&\
+prepStmtCacheSize=4096&\
+cacheServerConfiguration=true&\
+prepStmtCacheSqlLimit=2048&\
+zeroDateTimeBehavior=convertToNull&\
+traceProtocol=false&\
+useUnbufferedInput=false&\
+useReadAheadInput=false&\
+maintainTimeStats=false&\
+useServerPrepStmts&\
+cacheRSMetadata=true

+ 136 - 0
frameworks/Java/sabina/src/test/java/sabina/benchmark/ApplicationTest.java

@@ -0,0 +1,136 @@
+package sabina.benchmark;
+
+import static org.apache.http.client.fluent.Request.Get;
+import static org.junit.Assert.*;
+import static sabina.benchmark.Application.main;
+import static sabina.Sabina.stop;
+import static sun.misc.IOUtils.readFully;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.Gson;
+import org.apache.http.HttpResponse;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public final class ApplicationTest {
+    private static final String ENDPOINT = "http://localhost:8080";
+    private static final Gson GSON = new Gson ();
+
+    @BeforeClass public static void setup () {
+        main (null);
+    }
+
+    @AfterClass public static void close () {
+        stop ();
+    }
+
+    @Test public void json () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/json");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        assertEquals ("Hello, World!", GSON.fromJson (content, Map.class).get ("message"));
+    }
+
+    @Test public void plaintext () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/plaintext");
+        String content = getContent (response);
+
+        checkResponse (response, content, "text/plain");
+        assertEquals ("Hello, World!", content);
+    }
+
+    @Test public void no_query_parameter () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        Map<?, ?> resultsMap = GSON.fromJson (content, Map.class);
+        assertTrue (resultsMap.containsKey ("id") && resultsMap.containsKey ("randomNumber"));
+    }
+
+    @Test public void empty_query_parameter () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db?queries");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        checkResultItems (content, 1);
+    }
+
+    @Test public void text_query_parameter () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db?queries=text");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        checkResultItems (content, 1);
+    }
+
+    @Test public void zero_queries () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db?queries=0");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        checkResultItems (content, 1);
+    }
+
+    @Test public void one_thousand_queries () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db?queries=1000");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        checkResultItems (content, 500);
+    }
+
+    @Test public void one_query () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db?queries=1");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        checkResultItems (content, 1);
+    }
+
+    @Test public void ten_query () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db?queries=10");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        checkResultItems (content, 10);
+    }
+
+    @Test public void five_hundred_queries () throws IOException {
+        HttpResponse response = get (ENDPOINT + "/db?queries=500");
+        String content = getContent (response);
+
+        checkResponse (response, content, "application/json");
+        checkResultItems (content, 500);
+    }
+
+    private HttpResponse get (String uri) throws IOException {
+        return Get (uri).execute ().returnResponse ();
+    }
+
+    private String getContent (HttpResponse aResponse) throws IOException {
+        return new String (readFully (aResponse.getEntity ().getContent (), -1, true));
+    }
+
+    private void checkResponse (HttpResponse aRes, String aContent, String contentType) {
+        assertTrue (aRes.getFirstHeader ("Server") != null);
+        assertTrue (aRes.getFirstHeader ("Date") != null);
+        assertEquals (aContent.length (), aRes.getEntity ().getContentLength ());
+        assertEquals (contentType, aRes.getEntity ().getContentType ().getValue ());
+    }
+
+    private void checkResultItems (String result, int size) {
+        List<?> resultsList = GSON.fromJson (result, List.class);
+        assertEquals (size, resultsList.size ());
+
+        for (int ii = 0; ii < size; ii++) {
+            Map<?, ?> r = (Map)resultsList.get (ii);
+            assertTrue (r.containsKey ("id") && r.containsKey ("randomNumber"));
+        }
+    }
+}

+ 2 - 2
frameworks/Java/servlet/pom.xml

@@ -18,9 +18,9 @@
         </dependency>
 
 	<dependency>
-	    <groupId>postgresql</groupId>
+	    <groupId>org.postgresql</groupId>
 	    <artifactId>postgresql</artifactId>
-	    <version>9.1-901.jdbc4</version>
+	    <version>9.3-1102-jdbc41</version>
 	</dependency>
             
 

+ 22 - 0
frameworks/Java/spring/src/main/java/com/techempower/spring/Common.java

@@ -0,0 +1,22 @@
+package com.techempower.spring;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * User: Denis Baranov
+ * Date: 2/18/15
+ */
+public class Common {
+
+    private static final int cpuCount = Runtime.getRuntime().availableProcessors();
+
+    // todo: parameterize multipliers
+    public static ExecutorService EXECUTOR = new ThreadPoolExecutor(
+        cpuCount * 2, cpuCount * 25, 200, TimeUnit.MILLISECONDS,
+        new LinkedBlockingQueue<Runnable>(cpuCount * 100),
+        new ThreadPoolExecutor.CallerRunsPolicy());
+
+}

+ 50 - 18
frameworks/Java/spring/src/main/java/com/techempower/spring/web/WorldDatabaseController.java

@@ -3,9 +3,15 @@ package com.techempower.spring.web;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.concurrent.ThreadLocalRandom;
 
+import com.techempower.spring.Common;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
@@ -28,43 +34,70 @@ final class WorldDatabaseController {
 	}
 
 	@RequestMapping(value = "/queries", produces = "application/json")
+	@Transactional(readOnly = true)
 	List<World> multipleQueries(@RequestParam(value="queries", required=false, defaultValue="1") String rawQueryCount) {
 		Integer queryCount = boundQueryCount(rawQueryCount);
 
-		List<World> worlds = new ArrayList<World>(queryCount);
-		Random random = ThreadLocalRandom.current();
-
+		List<Future<World>> wfs = new ArrayList<>(queryCount);
+		// it gets better with Java 8, promise!
 		for (int i = 0; i < queryCount; i++) {
-			worlds.add(this.worldRepository.findOne(random.nextInt(DB_ROWS) + 1));
+			wfs.add(
+				Common.EXECUTOR.submit(
+					new Callable<World>() {
+						@Override
+						public World call() throws Exception {
+							return worldRepository.findOne(
+								ThreadLocalRandom.current().nextInt(DB_ROWS) + 1);
+						}
+					}));
 		}
 
-		return worlds;
+		return waitFor(wfs);
 	}
 
 	@RequestMapping(value = "/updates", produces = "application/json")
 	List<World> updateQueries(@RequestParam(value="queries", required=false, defaultValue="1") String rawQueryCount) {
 		Integer queryCount = boundQueryCount(rawQueryCount);
 
-		List<World> worlds = new ArrayList<World>(queryCount);
-		Random random = ThreadLocalRandom.current();
+		List<Future<World>> wfs = new ArrayList<>(queryCount);
 
 		for (int i = 0; i < queryCount; i++) {
-			World world = this.worldRepository.findOne(random.nextInt(DB_ROWS) + 1);
-			world.setRandomNumber(random.nextInt(DB_ROWS) + 1);
-			this.worldRepository.save(world);
-			worlds.add(world);
+			wfs.add(Common.EXECUTOR.submit(
+				new Callable<World>() {
+					@Override
+					@Transactional(propagation = Propagation.REQUIRES_NEW)
+					public World call() throws Exception {
+						Random random = ThreadLocalRandom.current();
+						World world = worldRepository.findOne(random.nextInt(DB_ROWS) + 1);
+						world.setRandomNumber(random.nextInt(DB_ROWS) + 1);
+						worldRepository.save(world);
+						return world;
+					}
+				}));
 		}
 
+		return waitFor(wfs);
+	}
+
+	private List<World> waitFor(List<Future<World>> wfs) {
+		List<World> worlds = new ArrayList<>(wfs.size());
+		for (Future<World> wf: wfs) {
+			try {
+				worlds.add(wf.get());
+			} catch (InterruptedException | ExecutionException e) {
+				throw new RuntimeException(e);
+			}
+		}
 		return worlds;
 	}
 
 	private Integer boundQueryCount(final String rawString) {
-                Integer raw;
-                try {
-                       raw = Integer.parseInt(rawString);
-                } catch (NumberFormatException e) {
-                       raw = null;
-                } 
+		Integer raw;
+		try {
+			raw = Integer.parseInt(rawString);
+		} catch (NumberFormatException e) {
+			raw = null;
+		}
 		if (raw == null || raw < 1) {
 			return 1;
 		} else if (raw > 500) {
@@ -73,5 +106,4 @@ final class WorldDatabaseController {
 
 		return raw;
 	}
-
 }

+ 4 - 4
frameworks/Java/undertow-edge/pom.xml

@@ -43,10 +43,10 @@
             <version>5.1.25</version>
         </dependency>
         <dependency>
-            <groupId>postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-            <version>9.0-801.jdbc4</version>
-        </dependency>
+            <groupId>org.postgresql</groupId>
+	    <artifactId>postgresql</artifactId>
+            <version>9.3-1102-jdbc41</version>
+	</dependency>
         <dependency>
             <groupId>org.mongodb</groupId>
             <artifactId>mongo-java-driver</artifactId>

+ 4 - 4
frameworks/Java/undertow/pom.xml

@@ -34,10 +34,10 @@
             <version>5.1.30</version>
         </dependency>
         <dependency>
-            <groupId>postgresql</groupId>
-            <artifactId>postgresql</artifactId>
-            <version>9.1-901-1.jdbc4</version>
-        </dependency>
+            <groupId>org.postgresql</groupId>
+	    <artifactId>postgresql</artifactId>
+            <version>9.3-1102-jdbc41</version>
+	</dependency>
         <dependency>
             <groupId>org.mongodb</groupId>
             <artifactId>mongo-java-driver</artifactId>

+ 0 - 9
frameworks/PHP/php-silica/.gitignore

@@ -1,9 +0,0 @@
-/app/cache
-/app/logs
-/bin
-/vendors
-/build
-/dist
-.DS_Store
-/tags
-.idea

+ 0 - 36
frameworks/PHP/php-silica/README.md

@@ -1,36 +0,0 @@
-# Silica Benchmarking Test
-
-This is the Silica PHP portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
-
-### JSON Encoding Test
-Uses the PHP standard [JSON encoder](http://www.php.net/manual/en/function.json-encode.php).
-
-* [JSON test controller](web/index.php)
-
-
-### Data-Store/Database Mapping Test
-Uses the Doctrine DBAL functionality.
-
-* [DB test controller](web/index.php)
-
-
-## Infrastructure Software Versions
-The tests were run with:
-
-* [Silica dev-master](https://github.com/changloong/Silica)
-* [PHP Version 5.5.17](http://www.php.net/) with FPM and APC
-* [nginx 1.4.0](http://nginx.org/)
-* [MySQL 5.5.29](https://dev.mysql.com/)
-
-## Test URLs
-### JSON Encoding Test
-
-http://localhost/json
-
-### Data-Store/Database Mapping Test
-
-http://localhost/db
-
-### Variable Query Test
-    
-http://localhost/db?queries=2

+ 0 - 9
frameworks/PHP/php-silica/bash_profile.sh

@@ -1,9 +0,0 @@
-#!/bin/bash
-
-export PHP_HOME=${IROOT}/php-5.5.17
-
-export PHP_FPM=$PHP_HOME/sbin/php-fpm
-
-export COMPOSER_HOME=${IROOT}/php-composer
-
-export NGINX_HOME=${IROOT}/nginx

+ 0 - 6
frameworks/PHP/php-silica/composer.json

@@ -1,6 +0,0 @@
-{
-    "require": {
-        "silica/silica": "dev-master"
-    }
-}
-

+ 0 - 136
frameworks/PHP/php-silica/deploy/nginx.conf

@@ -1,136 +0,0 @@
-#user  nobody;
-worker_processes  8;
-
-#error_log  logs/error.log;
-#error_log  logs/error.log  notice;
-#error_log  logs/error.log  info;
-error_log stderr error;
-
-#pid        logs/nginx.pid;
-
-
-events {
-    worker_connections  1024;
-}
-
-
-http {
-    include       /usr/local/nginx/conf/mime.types;
-    default_type  application/octet-stream;
-
-    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
-    #                  '$status $body_bytes_sent "$http_referer" '
-    #                  '"$http_user_agent" "$http_x_forwarded_for"';
-
-    #access_log  logs/access.log  main;
-    access_log off;
-
-    sendfile        on;
-    #tcp_nopush     on;
-
-    #keepalive_timeout  0;
-    keepalive_timeout  65;
-
-    #gzip  on;
-
-    upstream fastcgi_backend {
-        server 127.0.0.1:9001;
-        keepalive 32;
-    }
-
-    server {
-        listen       8080;
-        server_name  localhost;
-
-        #charset koi8-r;
-
-        #access_log  logs/host.access.log  main;
-
-        #location / {
-        #    root   html;
-        #    index  index.html index.htm;
-        #}
-
-        #error_page  404              /404.html;
-
-        # redirect server error pages to the static page /50x.html
-        #
-        #error_page   500 502 503 504  /50x.html;
-        #location = /50x.html {
-        #    root   html;
-        #}
-
-        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
-        #
-        #location ~ \.php$ {
-        #    proxy_pass   http://127.0.0.1;
-        #}
-
-        root /home/ubuntu/FrameworkBenchmarks/php-silica/web/;
-        index  index.php;
-
-        location / {
-            try_files $uri @rewriteapp;
-        }
-		
-        location @rewriteapp {
-                rewrite ^(.*)$ /app.php/$1 last;
-        }
-
-        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
-        #
-        location ~ \.php$ {
-            fastcgi_pass   fastcgi_backend;
-            fastcgi_keep_conn on;
-            fastcgi_index  index.php;
-#            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
-            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
-            include        /usr/local/nginx/conf/fastcgi_params;
-        }
-
-        # deny access to .htaccess files, if Apache's document root
-        # concurs with nginx's one
-        #
-        #location ~ /\.ht {
-        #    deny  all;
-        #}
-    }
-
-
-    # another virtual host using mix of IP-, name-, and port-based configuration
-    #
-    #server {
-    #    listen       8000;
-    #    listen       somename:8080;
-    #    server_name  somename  alias  another.alias;
-
-    #    location / {
-    #        root   html;
-    #        index  index.html index.htm;
-    #    }
-    #}
-
-
-    # HTTPS server
-    #
-    #server {
-    #    listen       443;
-    #    server_name  localhost;
-
-    #    ssl                  on;
-    #    ssl_certificate      cert.pem;
-    #    ssl_certificate_key  cert.key;
-
-    #    ssl_session_timeout  5m;
-
-    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
-    #    ssl_ciphers  HIGH:!aNULL:!MD5;
-    #    ssl_prefer_server_ciphers   on;
-
-    #    location / {
-    #        root   html;
-    #        index  index.html index.htm;
-    #    }
-    #}
-
-}

+ 0 - 9
frameworks/PHP/php-silica/deploy/php-silica

@@ -1,9 +0,0 @@
-<VirtualHost *:8080>
-  Alias /php-silex/ "/home/ubuntu/FrameworkBenchmarks/php-silica/web/"
-  <Directory /home/ubuntu/FrameworkBenchmarks/php-silica/web/>
-          Options Indexes FollowSymLinks MultiViews
-          #AllowOverride None
-          Order allow,deny
-          allow from all
-  </Directory>
-</VirtualHost>

+ 0 - 3
frameworks/PHP/php-silica/install.sh

@@ -1,3 +0,0 @@
-#!/bin/bash
-
-fw_depends php composer nginx

+ 0 - 13
frameworks/PHP/php-silica/setup.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-
-sed -i 's|192.168.100.102|'"${DBHOST}"'|g' web/app.php
-sed -i 's|"./FrameworkBenchmarks/php-silica|"'"${TROOT}"'|g' deploy/php-silica
-sed -i 's|Directory .*/FrameworkBenchmarks/php-silica|Directory '"${TROOT}"'|g' deploy/php-silica
-sed -i 's|root .*/FrameworkBenchmarks/php-silica|root '"${TROOT}"'|g' deploy/nginx.conf
-sed -i 's|/usr/local/nginx/|'"${IROOT}"'/nginx/|g' deploy/nginx.conf
-
-export PATH="$COMPOSER_HOME:$PHP_HOME/bin:$PHP_HOME/sbin:$PATH"
-
-composer.phar install
-$PHP_FPM --fpm-config $FWROOT/config/php-fpm.conf -g $TROOT/deploy/php-fpm.pid
-$NGINX_HOME/sbin/nginx -c $TROOT/deploy/nginx.conf

+ 0 - 4
frameworks/PHP/php-silica/source_code

@@ -1,4 +0,0 @@
-./php-silica/web
-./php-silica/web/.htaccess
-./php-silica/web/app.php
-./php-silica/deploy/php-silica

+ 0 - 8
frameworks/PHP/php-silica/web/.htaccess

@@ -1,8 +0,0 @@
-# /web/.htaccess
-<IfModule mod_rewrite.c>
-    Options -MultiViews
-
-    RewriteEngine On
-    RewriteCond %{REQUEST_FILENAME} !-f
-    RewriteRule ^ index.php [L]
-</IfModule>

+ 0 - 51
frameworks/PHP/php-silica/web/app.php

@@ -1,51 +0,0 @@
-<?php
-
-error_reporting(-1);
-
-require_once __DIR__ . '/../vendor/silica/silica/src/Silica/Application.php' ;
-
-$app = new Silica\Application();
-
-$app
-->share('pdo', function($app) {
-    $pdo    = new PDO('mysql::host=192.168.100.102;dbname=hello_world', 'benchmarkdbuser', 'benchmarkdbpass', array(
-				PDO::ATTR_PERSISTENT => true ,
-           ) ) ;
-    return $pdo ;
-})
->get('/json', function() {
-	echo json_encode(array("message" => "Hello World!"));
-}) 
->get('/db', function() use ($app) {
-	
-	$query_count = 1;
-	if (TRUE === isset($_GET['queries'])) {
-	  $query_count = $_GET['queries'];
-	}
-
-	// Create an array with the response string.
-	$arr = array();
-	$id = mt_rand(1, 10000);
-
-	// Define query
-	$statement = $app['pdo']->prepare('SELECT randomNumber FROM World WHERE id = :id');
-	$statement->bindParam(':id', $id, PDO::PARAM_INT);
-
-	// For each query, store the result set values in the response array
-	while (0 < $query_count--) {
-	  $statement->execute();
-  
-	  // Store result in array.
-	  $arr[] = array('id' => $id, 'randomNumber' => $statement->fetchColumn());
-	  $id = mt_rand(1, 10000);
-	}
-
-	// Use the PHP standard JSON encoder.
-	// http://www.php.net/manual/en/function.json-encode.php
-	echo json_encode($arr);
-})
->run() ;
-
-
-
-

+ 4 - 1
frameworks/PHP/php-slim/index.php

@@ -12,7 +12,10 @@ require 'Slim/RedBean/rb.php';
 
 \Slim\Slim::registerAutoloader();
 
-R::setup('mysql:host=localhost;dbname=hello_world','benchmarkdbuser','benchmarkdbpass');
+# Turn off 'beautiful' column names (converting tables names from camelCase to snake_case).
+RedBean_OODBBean::setFlagBeautifulColumnNames(false); 
+
+R::setup('mysql:host=127.0.0.1;dbname=hello_world','benchmarkdbuser','benchmarkdbpass');
 R::freeze(true);
 
 /**

+ 17 - 7
frameworks/Perl/mojolicious/cpanfile.snapshot

@@ -8,6 +8,14 @@ DISTRIBUTIONS
     requirements:
       ExtUtils::MakeMaker 0
       common::sense 0
+  IO-Socket-IP-0.36
+    pathname: P/PE/PEVANS/IO-Socket-IP-0.36.tar.gz
+    provides:
+      IO::Socket::IP 0.36
+    requirements:
+      IO::Socket 0
+      Socket 1.97
+      Test::More 0.88
   JSON-XS-3.01
     pathname: M/ML/MLEHMANN/JSON-XS-3.01.tar.gz
     provides:
@@ -16,10 +24,10 @@ DISTRIBUTIONS
       ExtUtils::MakeMaker 0
       Types::Serialiser 0
       common::sense 0
-  Mango-1.14
-    pathname: S/SR/SRI/Mango-1.14.tar.gz
+  Mango-1.16
+    pathname: O/OD/ODC/Mango-1.16.tar.gz
     provides:
-      Mango 1.14
+      Mango 1.16
       Mango::BSON undef
       Mango::BSON::Binary undef
       Mango::BSON::Code undef
@@ -41,8 +49,9 @@ DISTRIBUTIONS
     requirements:
       ExtUtils::MakeMaker 0
       Mojolicious 5.40
-  Mojolicious-5.65
-    pathname: S/SR/SRI/Mojolicious-5.65.tar.gz
+      perl 5.010001
+  Mojolicious-5.81
+    pathname: S/SR/SRI/Mojolicious-5.81.tar.gz
     provides:
       Mojo undef
       Mojo::Asset undef
@@ -105,7 +114,7 @@ DISTRIBUTIONS
       Mojo::UserAgent::Server undef
       Mojo::UserAgent::Transactor undef
       Mojo::Util undef
-      Mojolicious 5.65
+      Mojolicious 5.81
       Mojolicious::Command undef
       Mojolicious::Command::cgi undef
       Mojolicious::Command::cpanify undef
@@ -115,7 +124,7 @@ DISTRIBUTIONS
       Mojolicious::Command::generate::app undef
       Mojolicious::Command::generate::lite_app undef
       Mojolicious::Command::generate::makefile undef
-      Mojolicious::Command::generate::plugin 0.01
+      Mojolicious::Command::generate::plugin undef
       Mojolicious::Command::get undef
       Mojolicious::Command::inflate undef
       Mojolicious::Command::prefork undef
@@ -156,6 +165,7 @@ DISTRIBUTIONS
       IO::Socket::IP 0.26
       Pod::Simple 3.09
       Time::Local 1.2
+      perl 5.010001
   Types-Serialiser-1.0
     pathname: M/ML/MLEHMANN/Types-Serialiser-1.0.tar.gz
     provides:

+ 1 - 1
frameworks/Python/API-Hour/requirements.txt

@@ -1,4 +1,4 @@
-api_hour==0.6.0
+api_hour==0.6.1
 aiopg==0.5.2
 gunicorn==19.1.1
 psycopg2==2.5.4

+ 31 - 17
toolset/run-ci.py

@@ -415,34 +415,48 @@ class CIRunnner:
 
     # Setup Apache Cassandra
     echo "Populating Apache Cassandra database"
-    until nc -z localhost 9160 ; do echo Waiting for Cassandra; sleep 1; done
-    cat config/cassandra/cleanup-keyspace.cql | sudo cqlsh
-    python config/cassandra/db-data-gen.py > config/cassandra/tfb-data.cql
-    sudo cqlsh -f config/cassandra/create-keyspace.cql
-    sudo cqlsh -f config/cassandra/tfb-data.cql
+    for i in {1..45}; do
+      nc -z localhost 9160 && break || sleep 1;
+      echo "Waiting for Cassandra ($i/45}"
+    done
+    nc -z localhost 9160
+    if [ $? -eq 0 ]; then
+      cat config/cassandra/cleanup-keyspace.cql | sudo cqlsh
+      python config/cassandra/db-data-gen.py > config/cassandra/tfb-data.cql
+      sudo cqlsh -f config/cassandra/create-keyspace.cql
+      sudo cqlsh -f config/cassandra/tfb-data.cql
+    else
+      >&2 echo "Cassandra did not start, skipping"
+    fi
 
     # Setup MongoDB
     echo "Populating MongoDB database"
-    until nc -z localhost 27017 ; do echo Waiting for MongoDB; sleep 1; done
-    mongod --version
-    mongo < config/create.js
-
+    for i in {1..45}; do
+      nc -z localhost 27017 && break || sleep 1;
+      echo "Waiting for MongoDB ($i/45}"
+    done
+    nc -z localhost 27017
+    if [ $? -eq 0 ]; then
+      mongo < create.js
+      mongod --version
+    else
+      >&2 echo "MongoDB did not start, skipping"
+    fi
+    
     # =============Modify Configurations===========================
     # It can be useful to enable debug features for verification 
     # inside Travis-CI
     # =======================================================
 
     sed -i 's|display_errors\] = off|display_errors\] = on|' config/php-fpm.conf
+    
+    exit $?
     '''
 
-    def sh(command):
-      log.info("Running `%s`", command)
-      subprocess.check_call(command, shell=True)  
-
-    for command in script.split('\n'):
-      command = command.lstrip()
-      if command != "" and command[0] != '#':
-        sh(command.lstrip())
+    p = subprocess.Popen(["bash"], stdin=subprocess.PIPE)
+    p.communicate(script)
+    if p.wait() != 0:
+      log.critical("Non-zero exit  from running+wait on subprocess")
 
 if __name__ == "__main__":
   args = sys.argv[1:]

+ 3 - 1
toolset/setup/linux/client.sh

@@ -8,8 +8,10 @@ export DEBIAN_FRONTEND=noninteractive
 ##############################
 # Prerequisites
 ##############################
+sudo apt-get -y update
+
 # WARNING: DONT PUT A SPACE AFTER ANY BACKSLASH OR APT WILL BREAK
-# Dpkg::Options avoid hangs on Travis-CI, don't affect clean systems
+# Dpkg::Options avoid hangs on Travis-CI, doesn't affect clean systems
 sudo apt-get -y install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
     build-essential git libev-dev libpq-dev libreadline6-dev
 

+ 26 - 17
toolset/setup/linux/database.sh

@@ -21,8 +21,6 @@
 # concentrated effort to address these cases, but PR's for specific 
 # problems are welcome
 
-export DB_HOST={database_host}
-
 set -x
 export DEBIAN_FRONTEND=noninteractive
 
@@ -143,10 +141,18 @@ sudo cp -R -p /var/lib/mongodb /ssd/
 sudo cp -R -p /var/log/mongodb /ssd/log/
 sudo service mongod start
 
-until nc -z localhost 27017 ; do echo Waiting for MongoDB; sleep 1; done
-mongo < create.js
-rm create.js
-mongod --version
+for i in {1..45}; do
+  nc -z localhost 27017 && break || sleep 1;
+  echo "Waiting for MongoDB ($i/45}"
+done
+nc -z localhost 27017
+if [ $? -eq 0 ]; then
+  mongo < create.js
+  rm create.js
+  mongod --version
+else
+  >&2 echo "MongoDB did not start, skipping"
+fi
 
 ##############################
 # Apache Cassandra
@@ -159,21 +165,24 @@ tar xzf apache-cassandra-$CASS_V-bin.tar.gz
 
 rm -rf /ssd/cassandra /ssd/log/cassandra
 mkdir -p /ssd/cassandra /ssd/log/cassandra
-
-sed -i "s/^.*seeds:.*/          - seeds: \"$DB_HOST\"/" cassandra/cassandra.yaml
-sed -i "s/^listen_address:.*/listen_address: $DB_HOST/" cassandra/cassandra.yaml
-sed -i "s/^rpc_address:.*/rpc_address: $DB_HOST/" cassandra/cassandra.yaml
-
 mv cassandra/cassandra.yaml apache-cassandra-$CASS_V/conf
 mv cassandra/log4j-server.properties apache-cassandra-$CASS_V/conf
 nohup apache-cassandra-$CASS_V/bin/cassandra -p c.pid > cassandra.log
 
-until nc -z $DB_HOST 9160 ; do echo Waiting for Cassandra; sleep 1; done
-cat cassandra/cleanup-keyspace.cql | apache-cassandra-$CASS_V/bin/cqlsh $DB_HOST
-python cassandra/db-data-gen.py > cassandra/tfb-data.cql
-apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/create-keyspace.cql $DB_HOST
-apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/tfb-data.cql $DB_HOST
-rm -rf apache-cassandra-*-bin.tar.gz cassandra
+for i in {1..45}; do
+  nc -z localhost 9160 && break || sleep 1;
+  echo "Waiting for Cassandra ($i/45}"
+done
+nc -z localhost 9160
+if [ $? -eq 0 ]; then
+  cat cassandra/cleanup-keyspace.cql | apache-cassandra-$CASS_V/bin/cqlsh 127.0.0.1
+  python cassandra/db-data-gen.py > cassandra/tfb-data.cql
+  apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/create-keyspace.cql 127.0.0.1
+  apache-cassandra-$CASS_V/bin/cqlsh -f cassandra/tfb-data.cql 127.0.0.1
+  rm -rf apache-cassandra-*-bin.tar.gz cassandra
+else
+  >&2 echo "Cassandra did not start, skipping"
+fi
 
 ##############################
 # Redis

+ 3 - 2
toolset/setup/linux/installer.py

@@ -26,9 +26,10 @@ class Installer:
       print("\nINSTALL: Installing database software\n")   
       self.__run_command("cd .. && " + self.benchmarker.database_sftp_string(batch_file="../config/database_sftp_batch"), True)
       with open (linux_install_root + "/database.sh", "r") as myfile:
-        remote_script=myfile.read().format(database_host=self.benchmarker.database_host)
         print("\nINSTALL: %s" % self.benchmarker.database_ssh_string)
-        p = subprocess.Popen(self.benchmarker.database_ssh_string.split(" ") + ["bash"], stdin=subprocess.PIPE)
+        p = subprocess.Popen(self.benchmarker.database_ssh_string.split(" ") +
+                             ["bash"], stdin=subprocess.PIPE)
+        remote_script = myfile.read()
         p.communicate(remote_script)
         returncode = p.returncode
         if returncode != 0:

+ 5 - 4
toolset/setup/linux/languages/mono.sh

@@ -8,7 +8,7 @@ RETCODE=$(fw_exists ${IROOT}/mono.installed)
   sudo $IROOT/mono-3.6.0-install/bin/mozroots --import --sync;
   return 0; }
 
-sudo apt-get install -y build-essential \
+sudo apt-get install -qqy build-essential \
              autoconf \
              automake \
              libtool \
@@ -21,10 +21,11 @@ fw_untar mono-3.6.0.tar.bz2
 
 cd mono-3.6.0
 ./autogen.sh --prefix=${IROOT}/mono-3.6.0-install
-make -j4 EXTERNAL_MCS=${IROOT}/mono-3.6.0/mcs/class/lib/monolite/basic.exe
-make install
+echo -n "Installing Mono"
+make -j4 EXTERNAL_MCS=${IROOT}/mono-3.6.0/mcs/class/lib/monolite/basic.exe 2>&1 | tee $IROOT/mono-install.log | awk '{ if (NR%100 == 0) printf "."}'
+make install 2>&1 | tee -a $IROOT/mono-install.log | awk '{ if (NR%100 == 0) printf "."}'
 
 echo "Installing RootCAs from Mozilla..."; 
 sudo ${IROOT}/mono-3.6.0-install/bin/mozroots --import --sync;
 
-touch ${IROOT}/mono.installed
+touch $IROOT/mono.installed

+ 2 - 2
toolset/setup/linux/languages/perl.sh

@@ -5,7 +5,7 @@ RETCODE=$(fw_exists ${IROOT}/perl-5.18.installed)
 
 fw_get https://raw.github.com/tokuhirom/Perl-Build/master/perl-build -O perl-build.pl
 # compile with optimizations, n.b. this does not turn on debugging
-perl perl-build.pl -DDEBUGGING=-g 5.18.2 perl-5.18
+perl perl-build.pl -DDEBUGGING=-g 5.18.2 perl-5.18 2>&1 | tee $IROOT/perl-install.log | awk '{ if (NR%100 == 0) printf "."}'
 
 fw_get http://cpanmin.us -O cpanminus.pl
 perl-5.18/bin/perl cpanminus.pl --notest --no-man-page App::cpanminus
@@ -13,4 +13,4 @@ perl-5.18/bin/perl cpanminus.pl --notest --no-man-page App::cpanminus
 # Install others in the per-framework install script or cpanfile
 perl-5.18/bin/cpanm -f --notest --no-man-page Carton JSON JSON::XS IO::Socket::IP IO::Socket::SSL
 
-touch ${IROOT}/perl-5.18.installed
+touch ${IROOT}/perl-5.18.installed

+ 3 - 2
toolset/setup/linux/languages/python2.sh

@@ -7,8 +7,9 @@ fw_get http://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz
 fw_untar Python-2.7.9.tgz
 cd Python-2.7.9
 ./configure --prefix=${IROOT}/py2 --disable-shared --quiet
-make -j4 --quiet
-make install --quiet
+make -j4 --quiet 2>&1 | tee $IROOT/python-install.log | awk '{ if (NR%100 == 0) printf "."}'
+make install --quiet 2>&1 | tee -a $IROOT/python-install.log | awk '{ if (NR%100 == 0) printf "."}'
+cd ..
 
 ${IROOT}/py2/bin/python -m ensurepip -U
 ${IROOT}/py2/bin/pip install -U setuptools pip

+ 3 - 2
toolset/setup/linux/languages/python3.sh

@@ -7,8 +7,9 @@ fw_get http://www.python.org/ftp/python/3.4.2/Python-3.4.2.tar.xz
 fw_untar Python-3.4.2.tar.xz
 cd Python-3.4.2
 ./configure --prefix=${IROOT}/py3 --disable-shared --quiet
-make -j4 --quiet
-make install --quiet
+make -j4 --quiet 2>&1 | tee $IROOT/python3-install.log | awk '{ if (NR%100 == 0) printf "."}'
+make install --quiet 2>&1 | tee -a $IROOT/python3-install.log | awk '{ if (NR%100 == 0) printf "."}'
+cd ..
 
 ln -s ${IROOT}/py3/bin/python3.4m ${IROOT}/py3/bin/python3.4
 ${IROOT}/py3/bin/python3 -m ensurepip -U

+ 3 - 3
toolset/setup/linux/prerequisites.sh

@@ -20,7 +20,7 @@ sudo apt-get -yq update
 sudo apt-get -yq upgrade -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold"
 
 # WARNING: DONT PUT A SPACE AFTER ANY BACKSLASH OR APT WILL BREAK
-sudo apt-get -yq install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
+sudo apt-get -qqy install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
   cmake build-essential automake    `# Needed for building code` \
   curl wget unzip                   `# Common tools` \
   software-properties-common        `# Needed for add-apt-repository` \
@@ -40,14 +40,14 @@ sudo apt-get -yq install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::
   liborc-0.4-0 libwxbase2.8-0 libwxgtk2.8-0 libgnutls-dev \
   libjson0-dev libmcrypt-dev libicu-dev gettext \
   libpq-dev mlton \
-  libjemalloc-dev                   `# Needed by lwan at least` \
+  libjemalloc-dev libluajit-5.1-dev `# Needed by lwan at least` \
   libhiredis-dev                    `# Redis client - Needed by ngx_mruby at least` \
   cloc dstat                        `# Collect resource usage statistics`
 
 # Install gcc-4.8
 sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
 sudo apt-get -yq update
-sudo apt-get install -yq gcc-4.8 g++-4.8
+sudo apt-get install -qqy gcc-4.8 g++-4.8
 
 # Stop permanently overwriting people's files just for 
 # trying out our software!