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 Nancy;
 
+    
     public class DbModule : NancyModule
     {
         public static string MYSQL_CONNECTION_STRING;
@@ -16,35 +17,22 @@
         {
             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")
         {
             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" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="PlainModule.cs" />
     <Compile Include="DbModule.cs" />
     <Compile Include="JsonModule.cs" />
+    <Compile Include="QueryModule.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </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": [{
     "default": {
       "setup_file": "setup_iis",
+      "plaintext_url":"/plaintext",
       "json_url": "/json",
       "db_url": "/db",
-      "query_url": "/db/",
+      "query_url": "/query/",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",
@@ -23,9 +24,10 @@
     },
     "mono": {
       "setup_file": "setup_nginx",
+      "plaintext_url":"/plaintext",
       "json_url": "/json",
       "db_url": "/db",
-      "query_url": "/db/",
+      "query_url": "/query/",
       "port": 8080,
       "approach": "Realistic",
       "classification": "Micro",
@@ -40,26 +42,7 @@
       "display_name": "nancy",
       "notes": "",
       "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 / {
             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;
         }
     }
-}
+}

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

@@ -19,6 +19,13 @@ for port in $(seq ${port_start} $port_end); do
 done
 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
 ${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),
 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",
       "json_url": "/compojure/json",
       "db_url": "/compojure/db",
-      "query_url": "/compojure/db/",
+      "query_url": "/compojure/queries/",
       "update_url": "/compojure/updates/",
-      "fortune_url": "/compojure/fortune-hiccup",
+      "fortune_url": "/compojure/fortunes",
       "plaintext_url": "/compojure/plaintext",
       "port": 8080,
       "approach": "Realistic",
@@ -26,8 +26,10 @@
     },
     "raw": {
       "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,
       "approach": "Realistic",
       "classification": "Micro",

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

@@ -1,16 +1,18 @@
 (defproject hello "compojure"
-  :description "JSON/Database tests"
+  :description "FrameworkBenchmarks test implementations"
   :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]]
-                 [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"]
-                 [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}
   :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
   (:import com.mchange.v2.c3p0.ComboPooledDataSource)
   (:use compojure.core
+        ring.middleware.content-type
         ring.middleware.json
-        ring.util.response
         korma.db
         korma.core
         hiccup.core
@@ -10,55 +10,41 @@
         hiccup.page)
   (:require [compojure.handler :as handler]
             [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]
-  (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
   {:classname "com.mysql.jdbc.Driver"
    :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"
    :password "benchmarkdbpass"})
 
-
 (defn pool
   [spec]
   (let [cpds (doto (ComboPooledDataSource.)
@@ -72,67 +58,70 @@
                (.setMaxIdleTime (* 3 60 60)))]
     {:datasource cpds}))
 
-
 (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"
   []
   (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
-  "Run the specified number of queries, return the results"
+  "Run query repeatedly, return an array"
   [queries]
   (flatten ; Make it a list of maps
     (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
   (pk :id)
   (table :fortune)
   (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
           (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
   "Fetch the full list of Fortunes from the database, sort them by the fortune
   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
   "Render the given fortunes to simple HTML using Hiccup."
@@ -151,12 +140,11 @@
         [: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"
   [queries]
-  (let [results (run-queries queries)]
+(let [results (run-queries queries)]
     (for [w results]
       (update-in w [:randomNumber (inc (rand-int 9999))]
         (update world
@@ -164,80 +152,107 @@
                 (where {:id [:id w]}))))
     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
   "Test 1: JSON serialization"
-  (response {:message "Hello, World!"}))
-
+  (ring-resp/response {:message "Hello, World!"}))
 
 (def single-query-test
   "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"
   [queries]
   (-> queries
-      (get-query-count)
+      (sanitize-queries-param)
       (run-queries)
-      (response)))
-
+      (ring-resp/response)))
 
 (def single-query-test-raw
   "Test 2: Single database query (raw)"
   (-> 1
       (run-queries-raw)
       (first)
-      (response)))
-
+      (ring-resp/response)))
 
-(defn multiple-query-test-raw
+(defn multiple-queries-test-raw
   "Test 3: Multiple database queries (raw)"
   [queries]
   (-> queries
-      (get-query-count)
+      (sanitize-queries-param)
       (run-queries-raw)
-      (response)))
-
+      (ring-resp/response)))
 
 (def fortune-test
   "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
   "Test 5: Database updates"
   [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
   "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
-  (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"))
 
-
 (def app
   "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
 
-fw_depends java7 resin leiningen
+fw_depends java8 resin leiningen
 
 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/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),
 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)
-* [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",
       "db_url": "/db",
       "query_url": "/queries/",
-      "fortune_url": "/fortunes",
       "update_url": "/updates/",
+      "fortune_url": "/fortunes",
       "plaintext_url": "/plaintext",
       "port": 8080,
       "approach": "Realistic",
@@ -15,6 +15,27 @@
       "database": "MySQL",
       "framework": "http-kit",
       "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",
       "platform": "http-kit",
       "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"]
-                 [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]]
                  ; [ch.qos.logback/logback-classic "1.1.2" :exclusions [org.slf4j/slf4j-api]]
                  ; [org.slf4j/jul-to-slf4j "1.7.7"]
                  ; [org.slf4j/jcl-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
   :aot [hello.handler]
   :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]
             [compojure.route :as route]
             [ring.util.response :as ring-resp]
-            [clojure.data.json :as json]
             [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 {
     :classname "com.mysql.jdbc.Driver"
     :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"
     :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
+  {: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
 (defentity world
   (pk :id)
   (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"
   []
   (let [id (inc (rand-int 9999))] ; Num between 1 and 10,000
     (select world
             (where {:id id }))))
 
-
 (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]
-  (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
   (pk :id)
   (table :fortune)
   (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
           (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
   "Fetch the full list of Fortunes from the database, sort them by the fortune
   message text, and then return the results."
-  []
+  [query-function]
   (sort-by #(:message %)
     (conj
-      (get-all-fortunes)
+      (query-function)
       { :id 0 :message "Additional fortune added at request time." })))
 
-
 (defn fortunes-hiccup
   "Render the given fortunes to simple HTML using Hiccup."
   [fortunes]
@@ -114,14 +142,11 @@
         [: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"
   [queries]
-  (let [results (-> queries
-                    (sanitize-queries-param)
-                    (run-queries))]
+(let [results (run-queries queries)]
     (for [w results]
       (update-in w [:randomNumber (inc (rand-int 9999))]
         (update world
@@ -129,43 +154,80 @@
                 (where {:id [:id w]}))))
     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
   "Test 1: JSON serialization"
   (ring-resp/response {:message "Hello, World!"}))
 
-
 (def single-query-test
   "Test 2: Single database query"
   (ring-resp/response (first (run-queries 1))))
 
-
 (defn multiple-queries-test
   "Test 3: Multiple database queries"
   [queries]
   (-> queries
       (sanitize-queries-param)
       (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
   "Test 4: Fortunes"
   (->
-    (get-fortunes)
+    (get-fortunes get-all-fortunes-korma)
     (fortunes-hiccup)
     (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
   "Test 5: Database updates"
   [queries]
   (-> queries
-      (update-and-persist)
+      (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
   "Test 6: Plaintext"
@@ -173,18 +235,32 @@
     (ring-resp/response "Hello, World!")
     (ring-resp/content-type "text/plain")))
 
-
 ;; Define route handlers
 (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"))
 
+(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]}]
   ;; Format responses as JSON

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

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-fw_depends leiningen java7
+fw_depends leiningen java8
 
 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/src/
-./http-kit/hello/src/log4j.xml
-./http-kit/hello/src/hello
 ./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",
   password: "benchmarkdbpass",
   database: "hello_world",
-  hostname: "192.168.56.101",
+  hostname: "localhost",
   pool_size: 256
 
 # ## SSL Support
@@ -28,7 +28,7 @@ config :hello, Hello.Repo,
 # Where those two env variables point to a file on
 # disk for the key and cert.
 
-config :logger, level: :error
+config :logger, level: :info
 
 # ## Using releases
 #

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

@@ -10,10 +10,16 @@
 
 %% 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) ->
         crypto:start(),
         application:start(emysql),
-        emysql:add_pool(test_pool, 5000,
+        emysql:add_pool(test_pool, 256,
           "benchmarkdbuser", "benchmarkdbpass", "localhost", 3306,
           "hello_world", utf8),
 	emysql:prepare(db_stmt, <<"SELECT * FROM World where id = ?">>),
@@ -24,7 +30,7 @@ start(_Type, _Args) ->
       {"/query", query_handler, []}
 		]}
 	]),
-	{ok, _} = cowboy:start_http(http, 5000, [{port, 8080}], [
+	{ok, _} = cowboy:start_http(http, 256, [{port, 8080}], [
 		{env, [{dispatch, Dispatch}]}
 	]),
 	hello_world_sup:start_link().

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

@@ -2,7 +2,7 @@
 
 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}
 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
 
-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
 api_hour -ac hello:Container &

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

@@ -2,7 +2,7 @@
 
 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
 api_hour -ac hello:Container &

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

@@ -2,6 +2,6 @@
 
 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 &

+ 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
 
-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 &

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

@@ -2,6 +2,6 @@
 
 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 &

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

@@ -24,7 +24,7 @@ DBHOST = os.environ.get('DBHOST', 'localhost')
 # setup
 
 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
 db = SQLAlchemy(app)
 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
 Werkzeug==0.10.4
 flask==0.10.1
-SQLAlchemy==1.0.4
+SQLAlchemy==1.0.11
 Flask-SQLAlchemy==2.0
 mysqlclient==1.3.6
 gunicorn==19.3.0
 meinheld==0.5.7
-uwsgi
+uwsgi==2.0.12
 
 greenlet==0.4.7

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

@@ -2,6 +2,6 @@
 
 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 &

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

@@ -2,6 +2,6 @@
 
 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 &

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

@@ -2,6 +2,6 @@
 
 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 &

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

@@ -2,6 +2,6 @@
 
 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 &

+ 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\"' % (
                  expected_type),
              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
 
 

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

@@ -17,7 +17,13 @@ sudo apt-get update
 
 # Find the most recent snapshot
 #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
 
@@ -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-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
 
-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
 
-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
 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 "."}'

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

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