Browse Source

Merge remote-tracking branch 'origin/master'

Aliaksandr Valialkin 9 years ago
parent
commit
ef16ca729d
37 changed files with 548 additions and 337 deletions
  1. 13 25
      frameworks/CSharp/nancy/NancyModules/DbModule.cs
  2. 2 0
      frameworks/CSharp/nancy/NancyModules/NancyModules.csproj
  3. 15 0
      frameworks/CSharp/nancy/NancyModules/PlainModule.cs
  4. 91 0
      frameworks/CSharp/nancy/NancyModules/QueryModule.cs
  5. 5 22
      frameworks/CSharp/nancy/benchmark_config.json
  6. 2 2
      frameworks/CSharp/nancy/nginx.conf
  7. 7 0
      frameworks/CSharp/nancy/setup_nginx.sh
  8. 4 17
      frameworks/Clojure/compojure/README.md
  9. 6 4
      frameworks/Clojure/compojure/benchmark_config.json
  10. 12 10
      frameworks/Clojure/compojure/hello/project.clj
  11. 132 117
      frameworks/Clojure/compojure/hello/src/hello/handler.clj
  12. 1 1
      frameworks/Clojure/compojure/setup.sh
  13. 1 1
      frameworks/Clojure/compojure/source_code
  14. 3 17
      frameworks/Clojure/http-kit/README.md
  15. 22 1
      frameworks/Clojure/http-kit/benchmark_config.json
  16. 18 14
      frameworks/Clojure/http-kit/hello/project.clj
  17. 137 61
      frameworks/Clojure/http-kit/hello/src/hello/handler.clj
  18. 1 1
      frameworks/Clojure/http-kit/setup.sh
  19. 0 3
      frameworks/Clojure/http-kit/source_code
  20. 2 2
      frameworks/Elixir/phoenix/config/prod.exs
  21. 8 2
      frameworks/Erlang/cowboy/src/hello_world_app.erl
  22. 1 1
      frameworks/Java/wildfly-ee7/setup.sh
  23. 1 1
      frameworks/Python/asyncio/aiohttp.web/setup.sh
  24. 1 1
      frameworks/Python/asyncio/yocto_http/setup.sh
  25. 1 1
      frameworks/Python/bottle/setup_py3.sh
  26. 1 1
      frameworks/Python/cherrypy/setup_py3.sh
  27. 1 1
      frameworks/Python/falcon/setup_py3.sh
  28. 1 1
      frameworks/Python/flask/app.py
  29. 2 2
      frameworks/Python/flask/requirements.txt
  30. 1 1
      frameworks/Python/flask/setup_py3.sh
  31. 1 1
      frameworks/Python/pyramid/setup_py3.sh
  32. 1 1
      frameworks/Python/tornado/setup_py3.sh
  33. 1 1
      frameworks/Python/wheezyweb/setup_py3.sh
  34. 36 13
      toolset/benchmark/test_types/verifications.py
  35. 13 7
      toolset/setup/linux/languages/mono.sh
  36. 3 3
      toolset/setup/linux/languages/python3.sh
  37. 1 1
      toolset/setup/linux/languages/xsp.sh

+ 13 - 25
frameworks/CSharp/nancy/NancyModules/DbModule.cs

@@ -8,6 +8,7 @@
     using MySql.Data.MySqlClient;
     using MySql.Data.MySqlClient;
     using Nancy;
     using Nancy;
 
 
+    
     public class DbModule : NancyModule
     public class DbModule : NancyModule
     {
     {
         public static string MYSQL_CONNECTION_STRING;
         public static string MYSQL_CONNECTION_STRING;
@@ -16,35 +17,22 @@
         {
         {
             MYSQL_CONNECTION_STRING = ConfigurationManager.AppSettings["ConnectionString.MySQL"];
             MYSQL_CONNECTION_STRING = ConfigurationManager.AppSettings["ConnectionString.MySQL"];
         }
         }
-
+        
+        /**
+         * NOTE:
+         * Return a single World objects as JSON, selected randomly from the World
+         * table.  Assume the table has 10,000 rows.
+         */
         public DbModule() : base("/db")
         public DbModule() : base("/db")
         {
         {
             Get["/{queries?1}"] = paramz =>
             Get["/{queries?1}"] = paramz =>
             {
             {
-                var queries = (int)paramz.queries;
-                
-                var random = new Random();
-                using (var db = new MySqlConnection(MYSQL_CONNECTION_STRING))
-                {
-                    db.Open();
-
-                    if (queries == 1)
-                        return GetRandomWorld(db, random);
-                    else
-                    {
-                        var worldCount = queries > 500 ? 500 : queries;
-                        worldCount = worldCount < 1 ? 1 : worldCount;
-
-                        // NOTE: Experiment with running the DB requests in parallel, on both Mono and Windows CLRs.
-                        var worlds = new World[worldCount];
-
-                        for (int i = 0; i < worldCount; ++i)
-                        {
-                            worlds[i] = GetRandomWorld(db, random);
-                        }
-                        return worlds;
-                    }
-                }
+              var random = new Random();
+              using (var db = new MySqlConnection(MYSQL_CONNECTION_STRING))
+              {
+                db.Open();
+                return Response.AsJson(GetRandomWorld(db, random));
+              }
             };
             };
         }
         }
 
 

+ 2 - 0
frameworks/CSharp/nancy/NancyModules/NancyModules.csproj

@@ -52,8 +52,10 @@
     <Reference Include="System.Data" />
     <Reference Include="System.Data" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
+    <Compile Include="PlainModule.cs" />
     <Compile Include="DbModule.cs" />
     <Compile Include="DbModule.cs" />
     <Compile Include="JsonModule.cs" />
     <Compile Include="JsonModule.cs" />
+    <Compile Include="QueryModule.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>

+ 15 - 0
frameworks/CSharp/nancy/NancyModules/PlainModule.cs

@@ -0,0 +1,15 @@
+namespace NancyModules 
+{
+  using Nancy;
+
+  public class PlainModule : NancyModule
+  {
+    public PlainModule() : base("plaintext")
+    {
+      Get["/"] = x =>
+      {
+        return "Hello, World!";
+      };
+    }
+  }
+}

+ 91 - 0
frameworks/CSharp/nancy/NancyModules/QueryModule.cs

@@ -0,0 +1,91 @@
+namespace NancyModules
+{
+    using System;
+    using System.Configuration;
+    using System.Data;
+    using System.Linq;
+    using Dapper;
+    using MySql.Data.MySqlClient;
+    using Nancy;
+
+    public class QueryModule : NancyModule
+    {
+        public static string MYSQL_CONNECTION_STRING;
+        
+        static QueryModule()
+        {
+            MYSQL_CONNECTION_STRING = ConfigurationManager.AppSettings["ConnectionString.MySQL"];
+        }
+        /**
+         * Query:
+         * Return a list of World objects as JSON, selected randomly from the World
+         * table.  Assume the table has 10,000 rows.
+         */
+        public QueryModule() : base("/query")
+        {
+            Get["/{queries?1}"] = paramz =>
+            {
+                var queries = (int)paramz.queries;
+                
+                var random = new Random();
+                using (var db = new MySqlConnection(MYSQL_CONNECTION_STRING))
+                {
+                    db.Open();
+
+                    if (queries == 1)
+                        return Response.AsJson( GetRandomWorld(db, random) );
+                    else
+                    {
+                        var worldCount = queries > 500 ? 500 : queries;
+                        worldCount = worldCount < 1 ? 1 : worldCount;
+
+                        // NOTE: Experiment with running the DB requests in parallel, on both Mono and Windows CLRs.
+                        var worlds = new World[worldCount];
+
+                        for (int i = 0; i < worldCount; ++i)
+                        {
+                            worlds[i] = GetRandomWorld(db, random);
+                        }
+                        return Response.AsJson( worlds );
+                    }
+                }
+            };
+
+            Get["/{name}"] = paramz =>
+            {
+                 var queries = (int)paramz.queries;
+                
+                var random = new Random();
+                using (var db = new MySqlConnection(MYSQL_CONNECTION_STRING))
+                {
+                    db.Open();
+
+                    if (queries == 1)
+                        return Response.AsJson( GetRandomWorld(db, random) );
+                    else
+                    {
+                        var worldCount = queries > 500 ? 500 : queries;
+                        worldCount = worldCount < 1 ? 1 : worldCount;
+
+                        // NOTE: Experiment with running the DB requests in parallel, on both Mono and Windows CLRs.
+                        var worlds = new World[worldCount];
+
+                        for (int i = 0; i < worldCount; ++i)
+                        {
+                            worlds[i] = GetRandomWorld(db, random);
+                        }
+                        return Response.AsJson( worlds );
+                    }
+                }
+
+            };
+        }
+
+        private World GetRandomWorld(IDbConnection db, Random random)
+        {
+            var id = random.Next(1, 10001);
+            return db.Query<World>("SELECT id, randomNumber FROM world WHERE id = @id", new { id = id }).Single();
+        }
+    }
+
+}

+ 5 - 22
frameworks/CSharp/nancy/benchmark_config.json

@@ -3,9 +3,10 @@
   "tests": [{
   "tests": [{
     "default": {
     "default": {
       "setup_file": "setup_iis",
       "setup_file": "setup_iis",
+      "plaintext_url":"/plaintext",
       "json_url": "/json",
       "json_url": "/json",
       "db_url": "/db",
       "db_url": "/db",
-      "query_url": "/db/",
+      "query_url": "/query/",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Micro",
       "classification": "Micro",
@@ -23,9 +24,10 @@
     },
     },
     "mono": {
     "mono": {
       "setup_file": "setup_nginx",
       "setup_file": "setup_nginx",
+      "plaintext_url":"/plaintext",
       "json_url": "/json",
       "json_url": "/json",
       "db_url": "/db",
       "db_url": "/db",
-      "query_url": "/db/",
+      "query_url": "/query/",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Micro",
       "classification": "Micro",
@@ -40,26 +42,7 @@
       "display_name": "nancy",
       "display_name": "nancy",
       "notes": "",
       "notes": "",
       "versus": ""
       "versus": ""
-    },
-    "libevent2": {
-      "setup_file": "setup_libevent",
-      "json_url": "/json",
-      "db_url": "/db",
-      "query_url": "/db/",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Micro",
-      "database": "MySQL",
-      "framework": "nancy",
-      "language": "C#",
-      "orm": "Raw",
-      "platform": "Mono",
-      "webserver": "nginx",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "nancy-libevent",
-      "notes": "",
-      "versus": ""
     }
     }
+
   }]
   }]
 }
 }

+ 2 - 2
frameworks/CSharp/nancy/nginx.conf

@@ -19,8 +19,8 @@ http {
 
 
         location / {
         location / {
             fastcgi_pass mono;
             fastcgi_pass mono;
-            include /usr/local/nginx/conf/fastcgi_params;
+            include nginx.osenv.conf; # read os env from this file
             fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
             fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
         }
         }
     }
     }
-}
+}

+ 7 - 0
frameworks/CSharp/nancy/setup_nginx.sh

@@ -19,6 +19,13 @@ for port in $(seq ${port_start} $port_end); do
 done
 done
 conf+="}"
 conf+="}"
 
 
+# Store path of fastcgi_params dynamically in a file called "nginx.osenv.conf". 
+# The reason why I do this is Ngix "include" cannot recognize variables. (Well known issue of Nginx)
+# To use OS Environment at ngix.conf 3rd party library or perl module is needed
+# Current approach is one trick to solve the problem without utilize those 3rd party libraries.
+echo "include $IROOT/nginx/conf/fastcgi_params;" > $TROOT/nginx.osenv.conf
+
+
 echo -e $conf > $TROOT/nginx.upstream.conf
 echo -e $conf > $TROOT/nginx.upstream.conf
 ${NGINX_HOME}/sbin/nginx -c $TROOT/nginx.conf -g "worker_processes '"${MAX_THREADS}"';"
 ${NGINX_HOME}/sbin/nginx -c $TROOT/nginx.conf -g "worker_processes '"${MAX_THREADS}"';"
 
 

+ 4 - 17
frameworks/Clojure/compojure/README.md

@@ -14,20 +14,7 @@ This is the Compojure portion of a [benchmarking test suite](../) comparing a va
 The dependencies are documented in [project.clj](hello/project.clj),
 The dependencies are documented in [project.clj](hello/project.clj),
 but the main ones are:
 but the main ones are:
 
 
-* [Clojure 1.5.1](http://clojure.org/)
-* [Compojure 1.1.5](https://github.com/weavejester/compojure)
-* [Ring-JSON 0.2.0](https://github.com/ring-clojure/ring-json), which in turn uses [Cheshire](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
-* [Korma 0.3.0-RC5](http://sqlkorma.com/)
-
-## Test URLs
-### JSON Encoding Test
-
-http://localhost/hello-compojure-standalone/json
-
-### Data-Store/Database Mapping Test
-
-http://localhost/hello-compojure-standalone/db
-
-### Variable Query Test
-
-http://localhost/hello-compojure-standalone/db/2
+* [Clojure 1.7.0](http://clojure.org/)
+* [Compojure 1.4.0](https://github.com/weavejester/compojure)
+* [Ring-JSON 0.4.0](https://github.com/ring-clojure/ring-json), which in turn uses [Cheshire](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
+* [Korma 0.4.2](http://sqlkorma.com/)

+ 6 - 4
frameworks/Clojure/compojure/benchmark_config.json

@@ -5,9 +5,9 @@
       "setup_file": "setup",
       "setup_file": "setup",
       "json_url": "/compojure/json",
       "json_url": "/compojure/json",
       "db_url": "/compojure/db",
       "db_url": "/compojure/db",
-      "query_url": "/compojure/db/",
+      "query_url": "/compojure/queries/",
       "update_url": "/compojure/updates/",
       "update_url": "/compojure/updates/",
-      "fortune_url": "/compojure/fortune-hiccup",
+      "fortune_url": "/compojure/fortunes",
       "plaintext_url": "/compojure/plaintext",
       "plaintext_url": "/compojure/plaintext",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
@@ -26,8 +26,10 @@
     },
     },
     "raw": {
     "raw": {
       "setup_file": "setup",
       "setup_file": "setup",
-      "db_url": "/compojure/dbraw",
-      "query_url": "/compojure/dbraw/",
+      "db_url": "/compojure/raw/db",
+      "query_url": "/compojure/raw/queries/",
+      "update_url": "/compojure/raw/updates/",
+      "fortune_url": "/compojure/raw/fortunes",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Micro",
       "classification": "Micro",

+ 12 - 10
frameworks/Clojure/compojure/hello/project.clj

@@ -1,16 +1,18 @@
 (defproject hello "compojure"
 (defproject hello "compojure"
-  :description "JSON/Database tests"
+  :description "FrameworkBenchmarks test implementations"
   :url "http://localhost:3000/"
   :url "http://localhost:3000/"
-  :dependencies [[org.clojure/clojure "1.5.1"]
-                 [compojure "1.1.6"]
-                 [ring/ring-json "0.2.0"]
-                 [korma "0.3.0-RC6"]
+  :min-lein-version "2.0.0"
+  :dependencies [[org.clojure/clojure "1.7.0"]
+                 [compojure "1.4.0"]
+                 [ring/ring-json "0.4.0"]
+                 [korma "0.4.2"]
                  [log4j "1.2.15" :exclusions [javax.mail/mail javax.jms/jms com.sun.jdmk/jmxtools com.sun.jmx/jmxri]]
                  [log4j "1.2.15" :exclusions [javax.mail/mail javax.jms/jms com.sun.jdmk/jmxtools com.sun.jmx/jmxri]]
-                 [mysql/mysql-connector-java "5.1.6"]
-                 [org.clojure/java.jdbc "0.3.0-alpha1"]
+                 [mysql/mysql-connector-java "5.1.38"]
+                 [org.clojure/java.jdbc "0.3.7"]
                  [c3p0/c3p0 "0.9.1.2"]
                  [c3p0/c3p0 "0.9.1.2"]
-                 [hiccup "1.0.4"]]
-  :plugins [[lein-ring "0.8.10"]]
+                 [hiccup "1.0.5"]]
+  :plugins [[lein-ring "0.9.7"]]
   :ring {:handler hello.handler/app}
   :ring {:handler hello.handler/app}
   :profiles
   :profiles
-  {:dev {:dependencies [[ring-mock "0.1.5"]]}})
+  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
+                        [ring/ring-mock "0.3.0"]]}})

+ 132 - 117
frameworks/Clojure/compojure/hello/src/hello/handler.clj

@@ -1,8 +1,8 @@
 (ns hello.handler
 (ns hello.handler
   (:import com.mchange.v2.c3p0.ComboPooledDataSource)
   (:import com.mchange.v2.c3p0.ComboPooledDataSource)
   (:use compojure.core
   (:use compojure.core
+        ring.middleware.content-type
         ring.middleware.json
         ring.middleware.json
-        ring.util.response
         korma.db
         korma.db
         korma.core
         korma.core
         hiccup.core
         hiccup.core
@@ -10,55 +10,41 @@
         hiccup.page)
         hiccup.page)
   (:require [compojure.handler :as handler]
   (:require [compojure.handler :as handler]
             [compojure.route :as route]
             [compojure.route :as route]
-            [clojure.java.jdbc :as jdbc]
-            [clojure.java.jdbc.sql :as sql]))
+            [ring.util.response :as ring-resp]
+            [clojure.java.jdbc :as jdbc]))
 
 
-
-; Database connection
-(defdb db (mysql {:subname "//localhost:3306/hello_world?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"
-                  :user "benchmarkdbuser"
-                  :password "benchmarkdbpass"
-                  ;;OPTIONAL KEYS
-                  :delimiters "" ;; remove delimiters
-                  :maximum-pool-size 256
-                  }))
-
-
-; Set up entity World and the database representation
-(defentity world
-  (pk :id)
-  (table :world)
-  (entity-fields :id :randomNumber)
-  (database db))
-
-
-(defn get-world
-  "Query a random World record from the database"
-  []
-  (let [id (inc (rand-int 9999))] ; Num between 1 and 10,000
-    (select world
-            (fields :id :randomNumber)
-            (where {:id id }))))
-
-
-(defn run-queries
-  "Run the specified number of queries, return the results"
+(defn sanitize-queries-param
+  "Sanitizes the `queries` parameter. Clamps the value between 1 and 500.
+  Invalid (string) values become 1."
   [queries]
   [queries]
-  (flatten ; Make it a list of maps
-    (take queries ; Number of queries to run
-          (repeatedly get-world))))
-
+  (let [n (try (Integer/parseInt queries)
+               (catch Exception e 1))] ; default to 1 on parse failure
+    (cond
+      (< n 1) 1
+      (> n 500) 500
+      :else n)))
 
 
-; Database connection for java.jdbc "raw"
-; https://github.com/clojure/java.jdbc/blob/master/doc/clojure/java/jdbc/ConnectionPooling.md
+;; MySQL database connection
+(defdb db-mysql
+  (mysql {
+          :classname "com.mysql.jdbc.Driver"
+          :subprotocol "mysql"
+          :subname "//127.0.0.1:3306/hello_world?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"
+          :user "benchmarkdbuser"
+          :password "benchmarkdbpass"
+          ;;OPTIONAL KEYS
+          :delimiters "" ;; remove delimiters
+          :maximum-pool-size 256}))
+
+;; MySQL database connection for java.jdbc "raw"
+;; https://github.com/clojure/java.jdbc/blob/master/doc/clojure/java/jdbc/ConnectionPooling.md
 (def db-spec-mysql-raw
 (def db-spec-mysql-raw
   {:classname "com.mysql.jdbc.Driver"
   {:classname "com.mysql.jdbc.Driver"
    :subprotocol "mysql"
    :subprotocol "mysql"
-   :subname "//localhost:3306/hello_world?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"
+   :subname "//127.0.0.1:3306/hello_world?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"
    :user "benchmarkdbuser"
    :user "benchmarkdbuser"
    :password "benchmarkdbpass"})
    :password "benchmarkdbpass"})
 
 
-
 (defn pool
 (defn pool
   [spec]
   [spec]
   (let [cpds (doto (ComboPooledDataSource.)
   (let [cpds (doto (ComboPooledDataSource.)
@@ -72,67 +58,70 @@
                (.setMaxIdleTime (* 3 60 60)))]
                (.setMaxIdleTime (* 3 60 60)))]
     {:datasource cpds}))
     {:datasource cpds}))
 
 
-
 (def pooled-db (delay (pool db-spec-mysql-raw)))
 (def pooled-db (delay (pool db-spec-mysql-raw)))
 
 
+(defn db-mysql-raw [] @pooled-db)
 
 
-(defn db-raw [] @pooled-db)
+;; Set up entity World and the database representation
+(defentity world
+  (pk :id)
+  (table :world)
+  (entity-fields :id :randomNumber) ; Default fields for select
+  (database db-mysql))
 
 
+(defn get-random-world-korma
+  "Query a random World record from the database"
+  []
+  (let [id (inc (rand-int 9999))] ; Num between 1 and 10,000
+    (select world
+            (where {:id id }))))
 
 
-(defn get-world-raw
+(defn run-queries
+  "Run query repeatedly, return an array"
+  [queries]
+  (flatten ; Make it a list of maps
+    (take queries ; Number of queries to run
+          (repeatedly get-random-world-korma))))
+
+(defn get-random-world-raw
   "Query a random World record from the database"
   "Query a random World record from the database"
   []
   []
   (let [id (inc (rand-int 9999))]
   (let [id (inc (rand-int 9999))]
-    (jdbc/with-connection (db-raw)
-      ; Set a naming strategy to preserve column name case
-      (jdbc/with-naming-strategy {:keyword identity}
-        (jdbc/with-query-results rs [(str "select * from world where id = ?") id]
-          (doall rs))))))
-
+    (jdbc/query (db-mysql-raw) [(str "select * from world where id = ?") id])))
 
 
 (defn run-queries-raw
 (defn run-queries-raw
-  "Run the specified number of queries, return the results"
+  "Run query repeatedly, return an array"
   [queries]
   [queries]
   (flatten ; Make it a list of maps
   (flatten ; Make it a list of maps
     (take queries
     (take queries
-          (repeatedly get-world-raw))))
+          (repeatedly get-random-world-raw))))
 
 
-
-(defn get-query-count
-  "Parse provided string value of query count, clamping values to between 1 and 500."
-  [queries]
-  (let [n (try (Integer/parseInt queries)
-               (catch Exception e 1))] ; default to 1 on parse failure
-    (cond
-      (< n 1) 1
-      (> n 500) 500
-      :else n)))
-
-
-; Set up entity World and the database representation
+;; Set up entity Fortune and the database representation
 (defentity fortune
 (defentity fortune
   (pk :id)
   (pk :id)
   (table :fortune)
   (table :fortune)
   (entity-fields :id :message)
   (entity-fields :id :message)
-  (database db))
+  (database db-mysql))
 
 
-
-(defn get-all-fortunes
-  "Query all Fortune records from the database."
+(defn get-all-fortunes-korma
+  "Query all Fortune records from the database using Korma."
   []
   []
   (select fortune
   (select fortune
           (fields :id :message)))
           (fields :id :message)))
 
 
+(defn get-all-fortunes-raw
+  "Query all Fortune records from the database using JDBC."
+  []
+  (jdbc/query (db-mysql-raw) [(str "select * from fortune")]))
 
 
 (defn get-fortunes
 (defn get-fortunes
   "Fetch the full list of Fortunes from the database, sort them by the fortune
   "Fetch the full list of Fortunes from the database, sort them by the fortune
   message text, and then return the results."
   message text, and then return the results."
-  []
-  (let [fortunes (conj (get-all-fortunes)
-                       {:id 0
-                        :message "Additional fortune added at request time."})]
-    (sort-by #(:message %) fortunes)))
-
+  [query-function]
+  (sort-by #(:message %)
+    (conj
+      (query-function)
+      { :id 0 :message "Additional fortune added at request time." })))
 
 
 (defn fortunes-hiccup
 (defn fortunes-hiccup
   "Render the given fortunes to simple HTML using Hiccup."
   "Render the given fortunes to simple HTML using Hiccup."
@@ -151,12 +140,11 @@
         [:td (escape-html (:message x))]])
         [:td (escape-html (:message x))]])
      ]]))
      ]]))
 
 
-
-(defn update-and-persist
-  "Changes the :randomNumber of a number of world entities.
+(defn update-and-persist-korma
+  "Using Korma: Changes the :randomNumber of a number of world entities.
   Persists the changes to sql then returns the updated entities"
   Persists the changes to sql then returns the updated entities"
   [queries]
   [queries]
-  (let [results (run-queries queries)]
+(let [results (run-queries queries)]
     (for [w results]
     (for [w results]
       (update-in w [:randomNumber (inc (rand-int 9999))]
       (update-in w [:randomNumber (inc (rand-int 9999))]
         (update world
         (update world
@@ -164,80 +152,107 @@
                 (where {:id [:id w]}))))
                 (where {:id [:id w]}))))
     results))
     results))
 
 
+(defn update-and-persist-raw
+  "Using JDBC: Changes the :randomNumber of a number of world entities.
+  Persists the changes to sql then returns the updated entities"
+  [queries]
+(let [results (run-queries queries)]
+    (for [w results]
+      (update-in w [:randomNumber (inc (rand-int 9999))]
+        (jdbc/update! (db-mysql-raw) :world {:randomNumber (:randomNumber w)} ["id = ?" (:id w)])))
+    results))
 
 
 (def json-serialization
 (def json-serialization
   "Test 1: JSON serialization"
   "Test 1: JSON serialization"
-  (response {:message "Hello, World!"}))
-
+  (ring-resp/response {:message "Hello, World!"}))
 
 
 (def single-query-test
 (def single-query-test
   "Test 2: Single database query"
   "Test 2: Single database query"
-  (-> 1
-      (run-queries)
-      (first)
-      (response)))
-
+  (ring-resp/response (first (run-queries 1))))
 
 
-(defn multiple-query-test
+(defn multiple-queries-test
   "Test 3: Multiple database queries"
   "Test 3: Multiple database queries"
   [queries]
   [queries]
   (-> queries
   (-> queries
-      (get-query-count)
+      (sanitize-queries-param)
       (run-queries)
       (run-queries)
-      (response)))
-
+      (ring-resp/response)))
 
 
 (def single-query-test-raw
 (def single-query-test-raw
   "Test 2: Single database query (raw)"
   "Test 2: Single database query (raw)"
   (-> 1
   (-> 1
       (run-queries-raw)
       (run-queries-raw)
       (first)
       (first)
-      (response)))
-
+      (ring-resp/response)))
 
 
-(defn multiple-query-test-raw
+(defn multiple-queries-test-raw
   "Test 3: Multiple database queries (raw)"
   "Test 3: Multiple database queries (raw)"
   [queries]
   [queries]
   (-> queries
   (-> queries
-      (get-query-count)
+      (sanitize-queries-param)
       (run-queries-raw)
       (run-queries-raw)
-      (response)))
-
+      (ring-resp/response)))
 
 
 (def fortune-test
 (def fortune-test
   "Test 4: Fortunes"
   "Test 4: Fortunes"
-  (response (fortunes-hiccup (get-fortunes))))
-
+  (->
+    (get-fortunes get-all-fortunes-korma)
+    (fortunes-hiccup)
+    (ring-resp/response)
+    (ring-resp/content-type "text/html")
+    (ring-resp/charset "utf-8")))
+
+(def fortune-test-raw
+  "Test 4: Fortunes Raw"
+  (->
+    (get-fortunes get-all-fortunes-raw)
+    (fortunes-hiccup)
+    (ring-resp/response)
+    (ring-resp/content-type "text/html")
+    (ring-resp/charset "utf-8")))
 
 
 (defn db-updates
 (defn db-updates
   "Test 5: Database updates"
   "Test 5: Database updates"
   [queries]
   [queries]
   (-> queries
   (-> queries
-      (get-query-count)
-      (update-and-persist)
-      (response)))
+      (sanitize-queries-param)
+      (update-and-persist-korma)
+      (ring-resp/response)))
+
+(defn db-updates-raw
+  "Test 5: Database updates Raw"
+  [queries]
+  (-> queries
+      (sanitize-queries-param)
+      (update-and-persist-raw)
+      (ring-resp/response)))
 
 
 (def plaintext
 (def plaintext
   "Test 6: Plaintext"
   "Test 6: Plaintext"
-  {:status 200
-   :headers {"Content-Type" "text/plain; charset=utf-8"}
-   :body "Hello, World!"})
-
+  (->
+    (ring-resp/response "Hello, World!")
+    (ring-resp/content-type "text/plain")))
 
 
+;; Define route handlers
 (defroutes app-routes
 (defroutes app-routes
-  (GET "/"                 [] "Hello, World!")
-  (GET "/json"             [] json-serialization)
-  (GET "/db"               [] single-query-test)
-  (GET "/db/:queries"      [queries] (multiple-query-test queries))
-  (GET "/dbraw"            [] single-query-test-raw)
-  (GET "/dbraw/:queries"   [queries] (multiple-query-test-raw queries))
-  (GET "/fortunes"         [] (response (get-fortunes))) ; Raw json of fortunes
-  (GET "/fortune-hiccup"   [] fortune-test)
-  (GET "/updates/:queries" [queries] (db-updates queries))
-  (GET "/plaintext"        [] plaintext)
+  (GET "/"                     [] "Hello, World!")
+  (GET "/plaintext"            [] plaintext)
+  (GET "/json"                 [] json-serialization)
+  (GET "/db"                   [] single-query-test)
+  (GET "/queries/:queries"     [queries] (multiple-queries-test queries))
+  (GET "/queries/"             [] (multiple-queries-test queries)) ; When param is omitted
+  (GET "/fortunes"             [] fortune-test)
+  (GET "/updates/:queries"     [queries] (db-updates queries))
+  (GET "/updates/"             [] (db-updates queries)) ; When param is omitted
+  (GET "/raw/db"               [] single-query-test-raw)
+  (GET "/raw/queries/:queries" [queries] (multiple-queries-test-raw queries))
+  (GET "/raw/queries/"         [] (multiple-queries-test-raw queries)) ; When param is omitted
+  (GET "/raw/fortunes"         [] fortune-test-raw)
+  (GET "/raw/updates/:queries" [queries] (db-updates-raw queries))
+  (GET "/raw/updates/"         [] (db-updates-raw queries)) ; When param is omitted
   (route/not-found "Not Found"))
   (route/not-found "Not Found"))
 
 
-
 (def app
 (def app
   "Format responses as JSON"
   "Format responses as JSON"
-  (wrap-json-response app-routes))
+  (-> app-routes
+      (wrap-json-response)))

+ 1 - 1
frameworks/Clojure/compojure/setup.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 #!/bin/bash
 
 
-fw_depends java7 resin leiningen
+fw_depends java8 resin leiningen
 
 
 sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/handler.clj
 sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/handler.clj
 
 

+ 1 - 1
frameworks/Clojure/compojure/source_code

@@ -1,2 +1,2 @@
-./compojure/hello/src/hello/handler.clj
 ./compojure/hello/project.clj
 ./compojure/hello/project.clj
+./compojure/hello/src/hello/handler.clj

+ 3 - 17
frameworks/Clojure/http-kit/README.md

@@ -14,21 +14,7 @@ This is the Compojure (using http-kit) portion of a [benchmarking test suite](..
 The dependencies are documented in [project.clj](hello/project.clj),
 The dependencies are documented in [project.clj](hello/project.clj),
 but the main ones are:
 but the main ones are:
 
 
-* [Clojure 1.5.1](http://clojure.org/)
-* [Compojure 1.1.5](https://github.com/weavejester/compojure)
-* [Ring-JSON 0.2.0](https://github.com/ring-clojure/ring-json), which in turn uses [Cheshire](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
+* [Clojure 1.7.0](http://clojure.org/)
 * [http-kit](http://http-kit.org)
 * [http-kit](http://http-kit.org)
-* [dbcp.clj](https://github.com/http-kit/dbcp.clj)
-
-## Test URLs
-### JSON Encoding Test
-
-http://localhost/http-kit/json
-
-### Data-Store/Database Mapping Test
-
-http://localhost/http-kit/db
-
-### Variable Query Test
-
-http://localhost/http-kit/db/2
+* [Ring-JSON 0.4.0](https://github.com/ring-clojure/ring-json), which in turn uses [Cheshire](https://github.com/dakrone/cheshire), which in turn uses [Jackson](http://jackson.codehaus.org/)
+* [Korma 0.4.2](http://sqlkorma.com/)

+ 22 - 1
frameworks/Clojure/http-kit/benchmark_config.json

@@ -6,8 +6,8 @@
       "json_url": "/json",
       "json_url": "/json",
       "db_url": "/db",
       "db_url": "/db",
       "query_url": "/queries/",
       "query_url": "/queries/",
-      "fortune_url": "/fortunes",
       "update_url": "/updates/",
       "update_url": "/updates/",
+      "fortune_url": "/fortunes",
       "plaintext_url": "/plaintext",
       "plaintext_url": "/plaintext",
       "port": 8080,
       "port": 8080,
       "approach": "Realistic",
       "approach": "Realistic",
@@ -15,6 +15,27 @@
       "database": "MySQL",
       "database": "MySQL",
       "framework": "http-kit",
       "framework": "http-kit",
       "language": "Clojure",
       "language": "Clojure",
+      "orm": "Micro",
+      "platform": "http-kit",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "http-kit",
+      "notes": "",
+      "versus": ""
+    },
+    "raw": {
+      "setup_file": "setup",
+      "db_url": "/raw/db",
+      "query_url": "/raw/queries/",
+      "update_url": "/raw/updates/",
+      "fortune_url": "/raw/fortunes",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "MySQL",
+      "framework": "http-kit",
+      "language": "Clojure",
       "orm": "Raw",
       "orm": "Raw",
       "platform": "http-kit",
       "platform": "http-kit",
       "webserver": "None",
       "webserver": "None",

+ 18 - 14
frameworks/Clojure/http-kit/hello/project.clj

@@ -1,23 +1,27 @@
-(defproject hello "compojure"
-  :description "JSON/Database tests"
-  :url "http://example.com/FIXME"
-  :dependencies [[org.clojure/clojure "1.5.1"]
-                 [compojure "1.1.5"]
-                 [ring/ring-json "0.2.0"]
+(defproject hello "http-kit"
+  :description "FrameworkBenchmarks test implementations"
+  :url "http://localhost:8080/"
+  :dependencies [[org.clojure/clojure "1.7.0"]
+                 [compojure "1.4.0"]
+                 [ring/ring-json "0.4.0"]
                  [org.clojure/tools.cli "0.2.1"]
                  [org.clojure/tools.cli "0.2.1"]
-                 [http-kit/dbcp "0.1.0"]
-                 [http-kit "2.1.18"]
+                 [http-kit "2.1.19"]
+                 [korma "0.4.2"]
                  [log4j "1.2.15" :exclusions [javax.mail/mail javax.jms/jms com.sun.jdmk/jmxtools com.sun.jmx/jmxri]]
                  [log4j "1.2.15" :exclusions [javax.mail/mail javax.jms/jms com.sun.jdmk/jmxtools com.sun.jmx/jmxri]]
                  ; [ch.qos.logback/logback-classic "1.1.2" :exclusions [org.slf4j/slf4j-api]]
                  ; [ch.qos.logback/logback-classic "1.1.2" :exclusions [org.slf4j/slf4j-api]]
                  ; [org.slf4j/jul-to-slf4j "1.7.7"]
                  ; [org.slf4j/jul-to-slf4j "1.7.7"]
                  ; [org.slf4j/jcl-over-slf4j "1.7.7"]
                  ; [org.slf4j/jcl-over-slf4j "1.7.7"]
                  ; [org.slf4j/log4j-over-slf4j "1.7.7"]
                  ; [org.slf4j/log4j-over-slf4j "1.7.7"]
-                 [org.clojure/data.json "0.2.5"]
-                 [org.clojure/java.jdbc "0.3.6"]
-                 [korma "0.4.0"]
-                 [mysql/mysql-connector-java "5.1.6"]
-                 [hiccup "1.0.4"]]
+                 [ring/ring-jetty-adapter "1.4.0"]
+                 [mysql/mysql-connector-java "5.1.38"]
+                 [org.clojure/java.jdbc "0.3.7"]
+                 [c3p0/c3p0 "0.9.1.2"]
+                 [hiccup "1.0.5"]]
+  :plugins [[lein-ring "0.9.7"]]
+  :ring {:handler hello.handler/app}
   :main hello.handler
   :main hello.handler
   :aot [hello.handler]
   :aot [hello.handler]
   :uberjar-name "http-kit-standalone.jar"
   :uberjar-name "http-kit-standalone.jar"
-  :profiles {:dev {:dependencies [[ring-mock "0.1.5"]]}})
+  :profiles
+  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
+                        [ring/ring-mock "0.3.0"]]}})

+ 137 - 61
frameworks/Clojure/http-kit/hello/src/hello/handler.clj

@@ -13,90 +13,118 @@
   (:require [compojure.handler :as handler]
   (:require [compojure.handler :as handler]
             [compojure.route :as route]
             [compojure.route :as route]
             [ring.util.response :as ring-resp]
             [ring.util.response :as ring-resp]
-            [clojure.data.json :as json]
             [clojure.java.jdbc :as jdbc]))
             [clojure.java.jdbc :as jdbc]))
 
 
+(defn sanitize-queries-param
+  "Sanitizes the `queries` parameter. Clamps the value between 1 and 500.
+  Invalid (string) values become 1."
+  [queries]
+  (let [n (try (Integer/parseInt queries)
+               (catch Exception e 1))] ; default to 1 on parse failure
+    (cond
+      (< n 1) 1
+      (> n 500) 500
+      :else n)))
 
 
-(defn parse-port [s] 
-  "Convert stringy port number int. Defaults to 8080."
-  (cond
-    (string? s) (Integer/parseInt s)
-    (instance? Integer s) s
-    (instance? Long s) (.intValue ^Long s)
-    :else 8080))
-
-
-;; MySQL connection
-(defdb mysql-db
+;; MySQL database connection
+(defdb db-mysql
   (mysql {
   (mysql {
     :classname "com.mysql.jdbc.Driver"
     :classname "com.mysql.jdbc.Driver"
     :subprotocol "mysql"
     :subprotocol "mysql"
-    :subname "//127.0.0.1:3306/hello_world"
+    :subname "//127.0.0.1:3306/hello_world?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"
     :user "benchmarkdbuser"
     :user "benchmarkdbuser"
     :password "benchmarkdbpass"
     :password "benchmarkdbpass"
     ;;OPTIONAL KEYS
     ;;OPTIONAL KEYS
     :delimiters "" ;; remove delimiters
     :delimiters "" ;; remove delimiters
     :maximum-pool-size 256}))
     :maximum-pool-size 256}))
 
 
+;; MySQL database connection for java.jdbc "raw"
+;; https://github.com/clojure/java.jdbc/blob/master/doc/clojure/java/jdbc/ConnectionPooling.md
+(def db-spec-mysql-raw
+  {:classname "com.mysql.jdbc.Driver"
+   :subprotocol "mysql"
+   :subname "//127.0.0.1:3306/hello_world?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"
+   :user "benchmarkdbuser"
+   :password "benchmarkdbpass"})
+
+(defn pool
+  [spec]
+  (let [cpds (doto (ComboPooledDataSource.)
+               (.setDriverClass (:classname spec))
+               (.setJdbcUrl (str "jdbc:" (:subprotocol spec) ":" (:subname spec)))
+               (.setUser (:user spec))
+               (.setPassword (:password spec))
+               ;; expire excess connections after 30 minutes of inactivity:
+               (.setMaxIdleTimeExcessConnections (* 30 60))
+               ;; expire connections after 3 hours of inactivity:
+               (.setMaxIdleTime (* 3 60 60)))]
+    {:datasource cpds}))
+
+(def pooled-db (delay (pool db-spec-mysql-raw)))
+
+(defn db-mysql-raw [] @pooled-db)
 
 
 ;; Set up entity World and the database representation
 ;; Set up entity World and the database representation
 (defentity world
 (defentity world
   (pk :id)
   (pk :id)
   (table :world)
   (table :world)
-  (entity-fields :id :randomNumber) ;; Default fields for select
-  (database mysql-db))
-
+  (entity-fields :id :randomNumber) ; Default fields for select
+  (database db-mysql))
 
 
-(defn sanitize-queries-param
-  "Sanitizes the `queries` parameter. Caps the value between 1 and 500.
-  Invalid (stringy) values become 1"
-  [queries]
-  (let [n (try (Integer/parseInt queries)
-               (catch Exception e 1))] ; default to 1 on parse failure
-    (cond
-      (< n 1) 1
-      (> n 500) 500
-      :else n)))
-
-
-(defn random-world
+(defn get-random-world-korma
   "Query a random World record from the database"
   "Query a random World record from the database"
   []
   []
   (let [id (inc (rand-int 9999))] ; Num between 1 and 10,000
   (let [id (inc (rand-int 9999))] ; Num between 1 and 10,000
     (select world
     (select world
             (where {:id id }))))
             (where {:id id }))))
 
 
-
 (defn run-queries
 (defn run-queries
-  "Run query repeatedly -- Always returns an array"
+  "Run query repeatedly, return an array"
+  [queries]
+  (flatten ; Make it a list of maps
+    (take queries ; Number of queries to run
+          (repeatedly get-random-world-korma))))
+
+(defn get-random-world-raw
+  "Query a random World record from the database"
+  []
+  (let [id (inc (rand-int 9999))]
+    (jdbc/query (db-mysql-raw) [(str "select * from world where id = ?") id])))
+
+(defn run-queries-raw
+  "Run query repeatedly, return an array"
   [queries]
   [queries]
-  (flatten (take queries (repeatedly random-world))))
+  (flatten ; Make it a list of maps
+    (take queries
+          (repeatedly get-random-world-raw))))
 
 
-; Set up entity Fortune and the database representation
+;; Set up entity Fortune and the database representation
 (defentity fortune
 (defentity fortune
   (pk :id)
   (pk :id)
   (table :fortune)
   (table :fortune)
   (entity-fields :id :message)
   (entity-fields :id :message)
-  (database mysql-db))
-
+  (database db-mysql))
 
 
-(defn get-all-fortunes
-  "Query all Fortune records from the database."
+(defn get-all-fortunes-korma
+  "Query all Fortune records from the database using Korma."
   []
   []
   (select fortune
   (select fortune
           (fields :id :message)))
           (fields :id :message)))
 
 
+(defn get-all-fortunes-raw
+  "Query all Fortune records from the database using JDBC."
+  []
+  (jdbc/query (db-mysql-raw) [(str "select * from fortune")]))
 
 
 (defn get-fortunes
 (defn get-fortunes
   "Fetch the full list of Fortunes from the database, sort them by the fortune
   "Fetch the full list of Fortunes from the database, sort them by the fortune
   message text, and then return the results."
   message text, and then return the results."
-  []
+  [query-function]
   (sort-by #(:message %)
   (sort-by #(:message %)
     (conj
     (conj
-      (get-all-fortunes)
+      (query-function)
       { :id 0 :message "Additional fortune added at request time." })))
       { :id 0 :message "Additional fortune added at request time." })))
 
 
-
 (defn fortunes-hiccup
 (defn fortunes-hiccup
   "Render the given fortunes to simple HTML using Hiccup."
   "Render the given fortunes to simple HTML using Hiccup."
   [fortunes]
   [fortunes]
@@ -114,14 +142,11 @@
         [:td (escape-html (:message x))]])
         [:td (escape-html (:message x))]])
      ]]))
      ]]))
 
 
-
-(defn update-and-persist
-  "Changes the :randomNumber of a number of world entities.
+(defn update-and-persist-korma
+  "Using Korma: Changes the :randomNumber of a number of world entities.
   Persists the changes to sql then returns the updated entities"
   Persists the changes to sql then returns the updated entities"
   [queries]
   [queries]
-  (let [results (-> queries
-                    (sanitize-queries-param)
-                    (run-queries))]
+(let [results (run-queries queries)]
     (for [w results]
     (for [w results]
       (update-in w [:randomNumber (inc (rand-int 9999))]
       (update-in w [:randomNumber (inc (rand-int 9999))]
         (update world
         (update world
@@ -129,43 +154,80 @@
                 (where {:id [:id w]}))))
                 (where {:id [:id w]}))))
     results))
     results))
 
 
+(defn update-and-persist-raw
+  "Using JDBC: Changes the :randomNumber of a number of world entities.
+  Persists the changes to sql then returns the updated entities"
+  [queries]
+(let [results (run-queries queries)]
+    (for [w results]
+      (update-in w [:randomNumber (inc (rand-int 9999))]
+        (jdbc/update! (db-mysql-raw) :world {:randomNumber (:randomNumber w)} ["id = ?" (:id w)])))
+    results))
 
 
 (def json-serialization
 (def json-serialization
   "Test 1: JSON serialization"
   "Test 1: JSON serialization"
   (ring-resp/response {:message "Hello, World!"}))
   (ring-resp/response {:message "Hello, World!"}))
 
 
-
 (def single-query-test
 (def single-query-test
   "Test 2: Single database query"
   "Test 2: Single database query"
   (ring-resp/response (first (run-queries 1))))
   (ring-resp/response (first (run-queries 1))))
 
 
-
 (defn multiple-queries-test
 (defn multiple-queries-test
   "Test 3: Multiple database queries"
   "Test 3: Multiple database queries"
   [queries]
   [queries]
   (-> queries
   (-> queries
       (sanitize-queries-param)
       (sanitize-queries-param)
       (run-queries)
       (run-queries)
-      (ring-resp/response)
-      (ring-resp/content-type "application/json")))
+      (ring-resp/response)))
+
+(def single-query-test-raw
+  "Test 2: Single database query (raw)"
+  (-> 1
+      (run-queries-raw)
+      (first)
+      (ring-resp/response)))
 
 
+(defn multiple-queries-test-raw
+  "Test 3: Multiple database queries (raw)"
+  [queries]
+  (-> queries
+      (sanitize-queries-param)
+      (run-queries-raw)
+      (ring-resp/response)))
 
 
 (def fortune-test
 (def fortune-test
   "Test 4: Fortunes"
   "Test 4: Fortunes"
   (->
   (->
-    (get-fortunes)
+    (get-fortunes get-all-fortunes-korma)
     (fortunes-hiccup)
     (fortunes-hiccup)
     (ring-resp/response)
     (ring-resp/response)
-    (ring-resp/content-type "text/html")))
+    (ring-resp/content-type "text/html")
+    (ring-resp/charset "utf-8")))
 
 
+(def fortune-test-raw
+  "Test 4: Fortunes Raw"
+  (->
+    (get-fortunes get-all-fortunes-raw)
+    (fortunes-hiccup)
+    (ring-resp/response)
+    (ring-resp/content-type "text/html")
+    (ring-resp/charset "utf-8")))
 
 
 (defn db-updates
 (defn db-updates
   "Test 5: Database updates"
   "Test 5: Database updates"
   [queries]
   [queries]
   (-> queries
   (-> queries
-      (update-and-persist)
+      (sanitize-queries-param)
+      (update-and-persist-korma)
       (ring-resp/response)))
       (ring-resp/response)))
 
 
+(defn db-updates-raw
+  "Test 5: Database updates Raw"
+  [queries]
+  (-> queries
+      (sanitize-queries-param)
+      (update-and-persist-raw)
+      (ring-resp/response)))
 
 
 (def plaintext
 (def plaintext
   "Test 6: Plaintext"
   "Test 6: Plaintext"
@@ -173,18 +235,32 @@
     (ring-resp/response "Hello, World!")
     (ring-resp/response "Hello, World!")
     (ring-resp/content-type "text/plain")))
     (ring-resp/content-type "text/plain")))
 
 
-
 ;; Define route handlers
 ;; Define route handlers
 (defroutes app-routes
 (defroutes app-routes
-  (GET "/"                 [] "Hello, World!")
-  (GET "/json"             [] json-serialization)
-  (GET "/db"               [] single-query-test)
-  (GET "/queries/:queries" [queries] (multiple-queries-test queries))
-  (GET "/fortunes"         [] fortune-test)
-  (GET "/updates/:queries" [queries] (db-updates queries))
-  (GET "/plaintext"        [] plaintext)
+  (GET "/"                     [] "Hello, World!")
+  (GET "/plaintext"            [] plaintext)
+  (GET "/json"                 [] json-serialization)
+  (GET "/db"                   [] single-query-test)
+  (GET "/queries/:queries"     [queries] (multiple-queries-test queries))
+  (GET "/queries/"             [] (multiple-queries-test queries)) ; When param is omitted
+  (GET "/fortunes"             [] fortune-test)
+  (GET "/updates/:queries"     [queries] (db-updates queries))
+  (GET "/updates/"             [] (db-updates queries)) ; When param is omitted
+  (GET "/raw/db"               [] single-query-test-raw)
+  (GET "/raw/queries/:queries" [queries] (multiple-queries-test-raw queries))
+  (GET "/raw/queries/"         [] (multiple-queries-test-raw queries)) ; When param is omitted
+  (GET "/raw/fortunes"         [] fortune-test-raw)
+  (GET "/raw/updates/:queries" [queries] (db-updates-raw queries))
+  (GET "/raw/updates/"         [] (db-updates-raw queries)) ; When param is omitted
   (route/not-found "Not Found"))
   (route/not-found "Not Found"))
 
 
+(defn parse-port [s] 
+  "Convert stringy port number int. Defaults to 8080."
+  (cond
+    (string? s) (Integer/parseInt s)
+    (instance? Integer s) s
+    (instance? Long s) (.intValue ^Long s)
+    :else 8080))
 
 
 (defn start-server [{:keys [port]}]
 (defn start-server [{:keys [port]}]
   ;; Format responses as JSON
   ;; Format responses as JSON

+ 1 - 1
frameworks/Clojure/http-kit/setup.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 #!/bin/bash
 
 
-fw_depends leiningen java7
+fw_depends leiningen java8
 
 
 sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/handler.clj
 sed -i 's|:subname "//.*:3306|:subname "//'"${DBHOST}"':3306|g' hello/src/hello/handler.clj
 
 

+ 0 - 3
frameworks/Clojure/http-kit/source_code

@@ -1,5 +1,2 @@
 ./http-kit/hello/project.clj
 ./http-kit/hello/project.clj
-./http-kit/hello/src/
-./http-kit/hello/src/log4j.xml
-./http-kit/hello/src/hello
 ./http-kit/hello/src/hello/handler.clj
 ./http-kit/hello/src/hello/handler.clj

+ 2 - 2
frameworks/Elixir/phoenix/config/prod.exs

@@ -11,7 +11,7 @@ config :hello, Hello.Repo,
   username: "benchmarkdbuser",
   username: "benchmarkdbuser",
   password: "benchmarkdbpass",
   password: "benchmarkdbpass",
   database: "hello_world",
   database: "hello_world",
-  hostname: "192.168.56.101",
+  hostname: "localhost",
   pool_size: 256
   pool_size: 256
 
 
 # ## SSL Support
 # ## SSL Support
@@ -28,7 +28,7 @@ config :hello, Hello.Repo,
 # Where those two env variables point to a file on
 # Where those two env variables point to a file on
 # disk for the key and cert.
 # disk for the key and cert.
 
 
-config :logger, level: :error
+config :logger, level: :info
 
 
 # ## Using releases
 # ## Using releases
 #
 #

+ 8 - 2
frameworks/Erlang/cowboy/src/hello_world_app.erl

@@ -10,10 +10,16 @@
 
 
 %% API.
 %% API.
 
 
+%% NOTE: 
+%%   If size of db testpool is too big (e.g: 5000), 
+%%   it will fail travis ci test. So I shrink this to 256.
+%%   [email protected]
+
+
 start(_Type, _Args) ->
 start(_Type, _Args) ->
         crypto:start(),
         crypto:start(),
         application:start(emysql),
         application:start(emysql),
-        emysql:add_pool(test_pool, 5000,
+        emysql:add_pool(test_pool, 256,
           "benchmarkdbuser", "benchmarkdbpass", "localhost", 3306,
           "benchmarkdbuser", "benchmarkdbpass", "localhost", 3306,
           "hello_world", utf8),
           "hello_world", utf8),
 	emysql:prepare(db_stmt, <<"SELECT * FROM World where id = ?">>),
 	emysql:prepare(db_stmt, <<"SELECT * FROM World where id = ?">>),
@@ -24,7 +30,7 @@ start(_Type, _Args) ->
       {"/query", query_handler, []}
       {"/query", query_handler, []}
 		]}
 		]}
 	]),
 	]),
-	{ok, _} = cowboy:start_http(http, 5000, [{port, 8080}], [
+	{ok, _} = cowboy:start_http(http, 256, [{port, 8080}], [
 		{env, [{dispatch, Dispatch}]}
 		{env, [{dispatch, Dispatch}]}
 	]),
 	]),
 	hello_world_sup:start_link().
 	hello_world_sup:start_link().

+ 1 - 1
frameworks/Java/wildfly-ee7/setup.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends java7 maven
 fw_depends java7 maven
 
 
-export JAVA_OPTS="-Xms2g -Xmx2g -XX:MaxPermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=25 -verbosegc -Xloggc:/tmp/wildfly_gc.log"
+export JAVA_OPTS="-Djava.net.preferIPv4Stack=true -Xms2g -Xmx2g -XX:MaxPermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=25 -verbosegc -Xloggc:/tmp/wildfly_gc.log"
 
 
 mvn clean initialize package -Pbenchmark -Ddatabase.host=${DBHOST}
 mvn clean initialize package -Pbenchmark -Ddatabase.host=${DBHOST}
 target/wildfly-9.0.1.Final/bin/standalone.sh -b 0.0.0.0 &
 target/wildfly-9.0.1.Final/bin/standalone.sh -b 0.0.0.0 &

+ 1 - 1
frameworks/Python/asyncio/aiohttp.web/setup.sh

@@ -4,7 +4,7 @@ fw_depends python3
 
 
 sed -i 's|host: 127.0.0.1|host: '${DBHOST}'|g' aiohttp.web/etc/hello/main/main.yaml
 sed -i 's|host: 127.0.0.1|host: '${DBHOST}'|g' aiohttp.web/etc/hello/main/main.yaml
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 cd $TROOT/aiohttp.web
 cd $TROOT/aiohttp.web
 api_hour -ac hello:Container &
 api_hour -ac hello:Container &

+ 1 - 1
frameworks/Python/asyncio/yocto_http/setup.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends python3
 fw_depends python3
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 cd $TROOT/yocto_http
 cd $TROOT/yocto_http
 api_hour -ac hello:Container &
 api_hour -ac hello:Container &

+ 1 - 1
frameworks/Python/bottle/setup_py3.sh

@@ -2,6 +2,6 @@
 
 
 fw_depends python3
 fw_depends python3
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 gunicorn app:app -c gunicorn_conf.py &
 gunicorn app:app -c gunicorn_conf.py &

+ 1 - 1
frameworks/Python/cherrypy/setup_py3.sh

@@ -4,6 +4,6 @@ fw_depends python3
 
 
 sed -i 's|127.0.0.1|'${DBHOST}'|g' app.py
 sed -i 's|127.0.0.1|'${DBHOST}'|g' app.py
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 python3 app.py &
 python3 app.py &

+ 1 - 1
frameworks/Python/falcon/setup_py3.sh

@@ -2,6 +2,6 @@
 
 
 fw_depends python3
 fw_depends python3
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 gunicorn app:app -c gunicorn_conf.py &
 gunicorn app:app -c gunicorn_conf.py &

+ 1 - 1
frameworks/Python/flask/app.py

@@ -24,7 +24,7 @@ DBHOST = os.environ.get('DBHOST', 'localhost')
 # setup
 # setup
 
 
 app = Flask(__name__)
 app = Flask(__name__)
-app.config['SQLALCHEMY_DATABASE_URI'] = DBDRIVER + '//benchmarkdbuser:benchmarkdbpass@%s:3306/hello_world?charset=utf8' % DBHOST
+app.config['SQLALCHEMY_DATABASE_URI'] = DBDRIVER + '://benchmarkdbuser:benchmarkdbpass@%s:3306/hello_world?charset=utf8' % DBHOST
 app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
 app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
 db = SQLAlchemy(app)
 db = SQLAlchemy(app)
 dbraw_engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'], connect_args={'autocommit': True}, pool_reset_on_return=None)
 dbraw_engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'], connect_args={'autocommit': True}, pool_reset_on_return=None)

+ 2 - 2
frameworks/Python/flask/requirements.txt

@@ -1,11 +1,11 @@
 Jinja2==2.7.3
 Jinja2==2.7.3
 Werkzeug==0.10.4
 Werkzeug==0.10.4
 flask==0.10.1
 flask==0.10.1
-SQLAlchemy==1.0.4
+SQLAlchemy==1.0.11
 Flask-SQLAlchemy==2.0
 Flask-SQLAlchemy==2.0
 mysqlclient==1.3.6
 mysqlclient==1.3.6
 gunicorn==19.3.0
 gunicorn==19.3.0
 meinheld==0.5.7
 meinheld==0.5.7
-uwsgi
+uwsgi==2.0.12
 
 
 greenlet==0.4.7
 greenlet==0.4.7

+ 1 - 1
frameworks/Python/flask/setup_py3.sh

@@ -2,6 +2,6 @@
 
 
 fw_depends python3
 fw_depends python3
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 gunicorn app:app -c gunicorn_conf.py &
 gunicorn app:app -c gunicorn_conf.py &

+ 1 - 1
frameworks/Python/pyramid/setup_py3.sh

@@ -2,6 +2,6 @@
 
 
 fw_depends python3
 fw_depends python3
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 gunicorn wsgi:app -c gunicorn_conf.py &
 gunicorn wsgi:app -c gunicorn_conf.py &

+ 1 - 1
frameworks/Python/tornado/setup_py3.sh

@@ -2,6 +2,6 @@
 
 
 fw_depends python3
 fw_depends python3
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 python3 server.py --port=8080 --mongo=$DBHOST --logging=error &
 python3 server.py --port=8080 --mongo=$DBHOST --logging=error &

+ 1 - 1
frameworks/Python/wheezyweb/setup_py3.sh

@@ -2,6 +2,6 @@
 
 
 fw_depends python3
 fw_depends python3
 
 
-pip install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
+pip3 install --install-option="--prefix=${PY3_ROOT}" -r $TROOT/requirements.txt
 
 
 gunicorn app:app -c gunicorn_conf.py &
 gunicorn app:app -c gunicorn_conf.py &

+ 36 - 13
toolset/benchmark/test_types/verifications.py

@@ -66,19 +66,42 @@ def verify_headers(headers, url, should_be='json'):
              'No content encoding found, expected \"%s\"' % (
              'No content encoding found, expected \"%s\"' % (
                  expected_type),
                  expected_type),
              url))
              url))
-    elif content_type.lower() == includes_charset:
-        problems.append(
-            ('warn',
-             ("Content encoding found \"%s\" where \"%s\" is acceptable.\n"
-              "Additional response bytes may negatively affect benchmark performance."
-              % (includes_charset, expected_type)),
-             url))
-    elif content_type != expected_type:
-        problems.append(
-            ('warn',
-             'Unexpected content encoding, found \"%s\", expected \"%s\"' % (
-                 content_type, expected_type),
-             url))
+    else:
+    	content_type = content_type.lower()
+        # "text/html" requires charset to be set. The others do not
+        if expected_type == types['html']:
+            if content_type == expected_type:
+                problems.append(
+                    ('warn',
+                     ('The \"%s\" content type requires \"charset=utf-8\" to be specified.'
+                      % content_type),
+                     url))
+            elif content_type != includes_charset:
+                problems.append(
+                    ('warn',
+                     'Unexpected content encoding, found \"%s\", expected \"%s\".' % (
+                         content_type, expected_type),
+                     url))
+        elif expected_type == types['json']:
+            if content_type == includes_charset:
+                problems.append(
+                    ('warn',
+                     ("Content encoding found \"%s\" where \"%s\" is acceptable.\n"
+                      "Additional response bytes may negatively affect benchmark performance."
+                      % (content_type, expected_type)),
+                     url))
+            elif content_type != expected_type:
+                problems.append(
+                    ('warn',
+                     'Unexpected content encoding, found \"%s\", expected \"%s\"' % (
+                         content_type, expected_type),
+                     url))
+        elif content_type != expected_type and content_type != includes_charset:
+            problems.append(
+                ('warn',
+                 'Unexpected content encoding, found \"%s\", expected \"%s\"' % (
+                     content_type, expected_type),
+                 url))
     return problems
     return problems
 
 
 
 

+ 13 - 7
toolset/setup/linux/languages/mono.sh

@@ -17,7 +17,13 @@ sudo apt-get update
 
 
 # Find the most recent snapshot
 # Find the most recent snapshot
 #SNAPSHOT=$(apt-cache search 'mono-snapshot-.*-assemblies' | cut -d'-' -f3 | tail -1)
 #SNAPSHOT=$(apt-cache search 'mono-snapshot-.*-assemblies' | cut -d'-' -f3 | tail -1)
-SNAPSHOT="20150202010831"
+
+# REMARK:
+# Rollback this after I execute above command manually due to "msmith-techempower"'s request.
+# According to him "apt-get to install mono is not stable", so keep this way. 
+# If you see mono fail, please doubt this SNAPSHOT and execute above command manually, then
+# copy and paste the value to SNAPSHOT variable just like below.
+SNAPSHOT="2016.01.04+14.28.05"
 
 
 # save environment
 # save environment
 
 
@@ -40,13 +46,13 @@ rm -rf $MONO_HOME && mkdir -p $MONO_HOME
 fw_apt_to_iroot mono-snapshot-$SNAPSHOT
 fw_apt_to_iroot mono-snapshot-$SNAPSHOT
 fw_apt_to_iroot mono-snapshot-$SNAPSHOT-assemblies mono-snapshot-$SNAPSHOT
 fw_apt_to_iroot mono-snapshot-$SNAPSHOT-assemblies mono-snapshot-$SNAPSHOT
 
 
-# Simplify paths
-mv $MONO_HOME/opt/mono-*/* $MONO_HOME
-file $MONO_HOME/bin/* | grep "POSIX shell script" | awk -F: '{print $1}' | xargs sed -i "s|/opt/mono-$SNAPSHOT|$MONO_HOME|g"
-sed -i "s|/opt/mono-$SNAPSHOT|$MONO_HOME|g" $MONO_HOME/lib/pkgconfig/*.pc $MONO_HOME/etc/mono/config
 
 
+# Simplify paths
+sudo mv $MONO_HOME/opt/mono-*/* $MONO_HOME
+file $MONO_HOME/bin/* | grep "POSIX shell script" | awk -F: '{print $1}' | xargs sudo sed -i "s|/opt/mono-$SNAPSHOT|$MONO_HOME|g"
+sudo sed -i "s|/opt/mono-$SNAPSHOT|$MONO_HOME|g" $MONO_HOME/lib/pkgconfig/*.pc $MONO_HOME/etc/mono/config
 echo "mozroots --import --sync" >> $IROOT/mono.installing
 echo "mozroots --import --sync" >> $IROOT/mono.installing
 
 
-mv $IROOT/mono.installing $IROOT/mono.installed
+sudo mv $IROOT/mono.installing $IROOT/mono.installed
 
 
-source $IROOT/mono.installed
+source $IROOT/mono.installed

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

@@ -7,9 +7,9 @@ RETCODE=$(fw_exists ${IROOT}/py3.installed)
   
   
 PY3_ROOT=$IROOT/py3
 PY3_ROOT=$IROOT/py3
 
 
-fw_get -O 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
+fw_get -O http://www.python.org/ftp/python/3.5.1/Python-3.5.1.tar.xz
+fw_untar Python-3.5.1.tar.xz
+cd Python-3.5.1
 ./configure --prefix=$PY3_ROOT --disable-shared --with-computed-gotos --quiet
 ./configure --prefix=$PY3_ROOT --disable-shared --with-computed-gotos --quiet
 make -j4 --quiet 2>&1 | tee $IROOT/python3-install.log | awk '{ if (NR%100 == 0) printf "."}'
 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 "."}'
 make install --quiet 2>&1 | tee -a $IROOT/python3-install.log | awk '{ if (NR%100 == 0) printf "."}'

+ 1 - 1
toolset/setup/linux/languages/xsp.sh

@@ -15,7 +15,7 @@ git checkout e272a2c006211b6b03be2ef5bbb9e3f8fefd0768
 # build
 # build
 ./autogen.sh --prefix=$MONO_HOME --disable-docs
 ./autogen.sh --prefix=$MONO_HOME --disable-docs
 make
 make
-make install
+sudo make install
 
 
 # cleanup
 # cleanup
 cd ..
 cd ..