Browse Source

Merge branch 'master' into nvm-nodejs

Edward Bramanti 10 years ago
parent
commit
5a0c6ee677
95 changed files with 861 additions and 1170 deletions
  1. 2 2
      .travis.yml
  2. 0 6
      frameworks/Elixir/WeberFramework/.gitignore
  3. 0 2
      frameworks/Elixir/WeberFramework/README.md
  4. 0 23
      frameworks/Elixir/WeberFramework/benchmark_config.json
  5. 0 3
      frameworks/Elixir/WeberFramework/install.sh
  6. 0 0
      frameworks/Elixir/WeberFramework/lang/.gitkeep
  7. 0 18
      frameworks/Elixir/WeberFramework/lib/app.ex
  8. 0 36
      frameworks/Elixir/WeberFramework/lib/config.ex
  9. 0 0
      frameworks/Elixir/WeberFramework/lib/controllers/.keep
  10. 0 13
      frameworks/Elixir/WeberFramework/lib/controllers/main.ex
  11. 0 0
      frameworks/Elixir/WeberFramework/lib/helpers/.keep
  12. 0 0
      frameworks/Elixir/WeberFramework/lib/models/.keep
  13. 0 9
      frameworks/Elixir/WeberFramework/lib/route.ex
  14. 0 0
      frameworks/Elixir/WeberFramework/lib/views/.keep
  15. 0 235
      frameworks/Elixir/WeberFramework/lib/views/Main.html
  16. 0 0
      frameworks/Elixir/WeberFramework/lib/views/layout/.keep
  17. 0 24
      frameworks/Elixir/WeberFramework/mix.exs
  18. 0 0
      frameworks/Elixir/WeberFramework/public/css/.keep
  19. 0 0
      frameworks/Elixir/WeberFramework/public/img/.keep
  20. BIN
      frameworks/Elixir/WeberFramework/public/img/favicon.ico
  21. 0 235
      frameworks/Elixir/WeberFramework/public/index.html
  22. 0 0
      frameworks/Elixir/WeberFramework/public/js/.keep
  23. 0 18
      frameworks/Elixir/WeberFramework/setup_weber.py
  24. 0 7
      frameworks/Elixir/WeberFramework/start.sh
  25. 0 7
      frameworks/Elixir/WeberFramework/test/WeberFramework_test.exs
  26. 0 1
      frameworks/Elixir/WeberFramework/test/test_helper.exs
  27. 0 4
      frameworks/Go/go-mongodb/bash_profile.sh
  28. 0 0
      frameworks/Go/go-mongodb/benchmark_config.json
  29. 4 0
      frameworks/Go/go-mongodb/setup.sh
  30. 7 1
      frameworks/Go/go-mongodb/src/hello/hello.go
  31. 0 95
      frameworks/Java/play2-java/generate_config.py
  32. 45 0
      frameworks/Python/web2py/README.md
  33. 2 0
      frameworks/Python/web2py/app/app/ABOUT
  34. 4 0
      frameworks/Python/web2py/app/app/LICENSE
  35. 1 0
      frameworks/Python/web2py/app/app/__init__.py
  36. 68 0
      frameworks/Python/web2py/app/app/controllers/default.py
  37. 47 0
      frameworks/Python/web2py/app/app/models/db.py
  38. 19 0
      frameworks/Python/web2py/app/app/private/appconfig.ini
  39. 38 0
      frameworks/Python/web2py/app/app/routes.example.py
  40. 1 0
      frameworks/Python/web2py/app/app/views/__init__.py
  41. 15 0
      frameworks/Python/web2py/app/app/views/default/fortune.html
  42. 52 0
      frameworks/Python/web2py/app/app/views/default/index.html
  43. 35 0
      frameworks/Python/web2py/app/app/views/default/user.html
  44. 16 0
      frameworks/Python/web2py/app/app/views/generic.html
  45. 14 0
      frameworks/Python/web2py/app/routes.py
  46. 27 0
      frameworks/Python/web2py/benchmark_config.json
  47. 18 0
      frameworks/Python/web2py/install.sh
  48. 1 0
      frameworks/Python/web2py/requirements.txt
  49. 4 0
      frameworks/Python/web2py/setup.sh
  50. 0 27
      frameworks/Scala/play-activate-mysql/README.md
  51. 0 62
      frameworks/Scala/play-activate-mysql/app/controllers/Application.scala
  52. 0 26
      frameworks/Scala/play-activate-mysql/benchmark_config.json
  53. 0 3
      frameworks/Scala/play-activate-mysql/install.sh
  54. 0 13
      frameworks/Scala/play-activate-mysql/setup.sh
  55. 40 19
      frameworks/Scala/play2-scala/benchmark_config.json
  56. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/.gitignore
  57. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/app/Global.scala
  58. 91 0
      frameworks/Scala/play2-scala/play2-scala-activate/app/controllers/Application.scala
  59. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/app/models/Migrations.scala
  60. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/app/models/Models.scala
  61. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/app/models/PersistenceContext.scala
  62. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/app/views/fortune.scala.html
  63. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/app/views/main.scala.html
  64. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/conf/application.conf
  65. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/conf/play.plugins
  66. 3 2
      frameworks/Scala/play2-scala/play2-scala-activate/conf/routes
  67. 1 1
      frameworks/Scala/play2-scala/play2-scala-activate/project/Build.scala
  68. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/project/build.properties
  69. 0 0
      frameworks/Scala/play2-scala/play2-scala-activate/project/plugins.sbt
  70. 1 1
      frameworks/Scala/play2-scala/play2-scala-anorm/app/controllers/Application.scala
  71. 0 20
      frameworks/Scala/play2-scala/play2-scala-mongodb/README.md
  72. 0 16
      frameworks/Scala/play2-scala/play2-scala-mongodb/project/Build.scala
  73. 0 1
      frameworks/Scala/play2-scala/play2-scala-mongodb/project/build.properties
  74. 0 3
      frameworks/Scala/play2-scala/play2-scala-mongodb/source_code
  75. 0 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/.gitignore
  76. 0 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/app/controllers/Application.scala
  77. 11 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/build.sbt
  78. 0 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/application.conf
  79. 0 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/play.plugins
  80. 1 2
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/routes
  81. 1 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/project/build.properties
  82. 1 1
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/project/plugins.sbt
  83. 3 0
      frameworks/Scala/play2-scala/play2-scala-reactivemongo/source_code
  84. 1 1
      frameworks/Scala/play2-scala/play2-scala-slick/app/controllers/Application.scala
  85. 0 18
      frameworks/Scala/play2-scala/play2-scala/README.md
  86. 4 4
      frameworks/Scala/play2-scala/setup_scala_activate.sh
  87. 16 0
      frameworks/Scala/play2-scala/setup_scala_reactivemongo.sh
  88. 6 0
      frameworks/Ur/urweb/cloc_defs.txt
  89. 11 1
      toolset/benchmark/benchmarker.py
  90. 158 81
      toolset/benchmark/framework_test.py
  91. 2 2
      toolset/benchmark/test_types/json_type.py
  92. 1 69
      toolset/run-ci.py
  93. 34 44
      toolset/setup/linux/installer.py
  94. 55 1
      toolset/setup/linux/setup_util.py
  95. 0 13
      toolset/setup/linux/webservers/weber.sh

+ 2 - 2
.travis.yml

@@ -37,13 +37,13 @@ env:
     - "TESTDIR=Dart/dart-redstone"
     - "TESTDIR=Dart/dart-redstone"
     - "TESTDIR=Dart/dart-start"
     - "TESTDIR=Dart/dart-start"
     - "TESTDIR=Dart/dart-stream"
     - "TESTDIR=Dart/dart-stream"
-    - "TESTDIR=Elixir/WeberFramework"
     - "TESTDIR=Erlang/cowboy"
     - "TESTDIR=Erlang/cowboy"
     - "TESTDIR=Erlang/elli"
     - "TESTDIR=Erlang/elli"
     - "TESTDIR=Go/beego"
     - "TESTDIR=Go/beego"
     - "TESTDIR=Go/falcore"
     - "TESTDIR=Go/falcore"
     - "TESTDIR=Go/gin"
     - "TESTDIR=Go/gin"
     - "TESTDIR=Go/go"
     - "TESTDIR=Go/go"
+    - "TESTDIR=Go/go-mongodb"
     - "TESTDIR=Go/revel"
     - "TESTDIR=Go/revel"
     - "TESTDIR=Go/revel-jet"
     - "TESTDIR=Go/revel-jet"
     - "TESTDIR=Go/revel-qbs"
     - "TESTDIR=Go/revel-qbs"
@@ -125,6 +125,7 @@ env:
     - "TESTDIR=Python/pyramid"
     - "TESTDIR=Python/pyramid"
     - "TESTDIR=Python/tornado"
     - "TESTDIR=Python/tornado"
     - "TESTDIR=Python/uwsgi"
     - "TESTDIR=Python/uwsgi"
+    - "TESTDIR=Python/web2py"
     - "TESTDIR=Python/wheezyweb"
     - "TESTDIR=Python/wheezyweb"
     - "TESTDIR=Python/wsgi"
     - "TESTDIR=Python/wsgi"
     - "TESTDIR=Racket/racket-ws"
     - "TESTDIR=Racket/racket-ws"
@@ -138,7 +139,6 @@ env:
     - "TESTDIR=Scala/finagle"
     - "TESTDIR=Scala/finagle"
     - "TESTDIR=Scala/lift-stateless"
     - "TESTDIR=Scala/lift-stateless"
     - "TESTDIR=Scala/plain"
     - "TESTDIR=Scala/plain"
-    - "TESTDIR=Scala/play-activate-mysql"
     - "TESTDIR=Scala/play2-scala"
     - "TESTDIR=Scala/play2-scala"
     - "TESTDIR=Scala/scalatra"
     - "TESTDIR=Scala/scalatra"
     - "TESTDIR=Scala/scruffy"
     - "TESTDIR=Scala/scruffy"

+ 0 - 6
frameworks/Elixir/WeberFramework/.gitignore

@@ -1,6 +0,0 @@
-/ebin
-/deps
-erl_crash.dump
-/tmp
-_build
-/logs

+ 0 - 2
frameworks/Elixir/WeberFramework/README.md

@@ -1,2 +0,0 @@
-WeberFramework
-=====

+ 0 - 23
frameworks/Elixir/WeberFramework/benchmark_config.json

@@ -1,23 +0,0 @@
-{
-  "framework": "weber",
-  "tests": [{
-    "default": {
-      "setup_file": "setup_weber",
-      "json_url": "/json",
-      "plaintext_url": "/plaintext",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Platform",
-      "database": "Postgres",
-      "framework": "weber",
-      "language": "Elixir",
-      "orm": "Raw",
-      "platform": "Cowboy",
-      "webserver": "Cowboy",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "weber",
-      "notes": "",
-      "versus": ""
-  }}]
-}

+ 0 - 3
frameworks/Elixir/WeberFramework/install.sh

@@ -1,3 +0,0 @@
-#!/bin/bash
-
-fw_depends weber elixir

+ 0 - 0
frameworks/Elixir/WeberFramework/lang/.gitkeep


+ 0 - 18
frameworks/Elixir/WeberFramework/lib/app.ex

@@ -1,18 +0,0 @@
-defmodule WeberFramework do
-
-  require Weber.Templates.ViewsLoader
-  
-  def start(_type, _args) do
-    # Set resources
-    Weber.Templates.ViewsLoader.set_up_resources(File.cwd!)
-    # compile all views
-    Weber.Templates.ViewsLoader.compile_views(File.cwd!)
-    # start weber application
-    Weber.run_weber
-  end
-
-  def stop(_state) do
-    :ok
-  end
-  
-end

+ 0 - 36
frameworks/Elixir/WeberFramework/lib/config.ex

@@ -1,36 +0,0 @@
-defmodule Config do 
-
-  def config do
-    [webserver: 
-      [http_host: "localhost", 
-       http_port: 8080,
-       acceptors: 100,
-       ssl: false,
-       cacertfile_path: "",
-       certfile_path: "",
-       keyfile_path: ""
-      ],
-    ws: 
-      [ws_port: 8080,
-       ws_mod: :Handler
-      ],
-    use_internationalization: false,
-    localization:
-      [default_locale: :en_US,
-       use_locales: [:en_US]
-      ],
-    use_sessions: false,
-    session:
-      [max_age: 1440
-      ],
-    db:
-      [
-        db_host: "",
-        db_port: 5000,
-        db_username: "",
-        db_password: ""
-      ],
-    ]
-  end
-
-end

+ 0 - 0
frameworks/Elixir/WeberFramework/lib/controllers/.keep


+ 0 - 13
frameworks/Elixir/WeberFramework/lib/controllers/main.ex

@@ -1,13 +0,0 @@
-defmodule WeberFramework.Main do
-  
-  use Weber.Controller
-
-  def action_json(_, _) do
-    {:json, [message: "Hello, world!"], [{"Content-type", "application/json"}]}
-  end
-
-  def action_text(_, _) do
-  	{:text, "Hello, world!", [{"Content-type", "text/plain"}]}
-  end
-
-end

+ 0 - 0
frameworks/Elixir/WeberFramework/lib/helpers/.keep


+ 0 - 0
frameworks/Elixir/WeberFramework/lib/models/.keep


+ 0 - 9
frameworks/Elixir/WeberFramework/lib/route.ex

@@ -1,9 +0,0 @@
-defmodule Route do
-
-  import Weber.Route
-  require Weber.Route
-  
-  route on("GET", "/json", :WeberFramework.Main, :action_json)
-     |> on("GET", "/plaintext", :WeberFramework.Main, :action_text)
-
-end

+ 0 - 0
frameworks/Elixir/WeberFramework/lib/views/.keep


+ 0 - 235
frameworks/Elixir/WeberFramework/lib/views/Main.html

@@ -1,235 +0,0 @@
-<!DOCTYPE html>
-<html itemscope itemtype="http://schema.org/WebPage" lang="en">
-
-<head>
-  <meta charset="utf-8">
-  <title>Welcome to Weber!</title>
-  <link href="img/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
-
-  <style>
-    /* Reset */
-    * {
-      margin: 0;
-      padding: 0;
-    }
-
-    /* Default */
-    body {
-      font: normal 13px proxima-nova, sans-serif;
-      color: #666;
-    }
-
-    a {
-      color: #4c0066;
-    }
-
-    code, pre {
-      background: #f9f9f9;
-      border: 1px solid #ddd;
-      border-radius: 3px;
-      display: block;
-      font-family: monospace;
-      margin: 5px 0;
-      padding: 20px 0 20px 30px;
-      white-space: pre;
-    }
-
-    blockquote {
-      background: #f9f9f9;
-      border-left: 10px solid #eee;
-      border-radius: 3px;
-      color: #888;
-      margin: 20px 0 20px 20px;
-      padding: 10px 12px;
-      quotes: "\201C""\201D""\2018""\2019";
-    }
-
-    blockquote:before {
-      color: #ccc;
-      content: open-quote;
-      font-size: 55px;
-      line-height: 1px;
-      margin-right: 15px;
-      vertical-align: -25px;
-    }
-
-    blockquote p {
-      display: inline;
-    }
-
-    p {
-      font-size: 120%;
-      line-height: 25px;
-      margin: 10px 0;
-    }
-
-    /* Classes */
-    .content {
-      margin: 0 auto;
-      padding: 0 10px;
-      width: 960px;
-    }
-
-    /* Structure */
-    header:after, main:after,
-    header:before, main:before {
-      content: " ";
-      display: table;
-    }
-
-    header:after, main:after {
-      clear: both;
-    }
-
-    header {
-      background: #4c0066;
-      height: 150px;
-      margin-bottom: 50px;
-    }
-
-    header .logo {
-      border-radius: 100%;
-      display: block;
-      float: left;
-      padding-top: 25px;
-    }
-
-    header .title {
-      color: #fff;
-      float: left;
-      line-height: 30px;
-      margin: 101px 0 0;
-      text-align: right;
-      width: 660px;
-    }
-
-    header .title h1 {
-      font-size: 100px;
-    }
-
-    main .guide {
-      float: right;
-      width: 610px;
-    }
-
-    main .guide article {
-      margin-bottom: 50px;
-    }
-
-    main .guide h3 {
-      color: #4c0066;
-      font-size: 150%;
-      text-transform: uppercase;
-    }
-
-    main aside {
-      float: left;
-      margin-right: 50px;
-      width: 300px;
-    }
-
-    .sidebar-box {
-      margin: 25px 20px;
-    }
-
-    .sidebar-box h3 {
-      font-size: 110%;
-      margin-bottom: 5px;
-      text-transform: uppercase;
-    }
-
-    .sidebar-box p {
-      font-size: 90%;
-      line-height: 100%;
-      margin: 0;
-    }
-
-    .sidebar-box ol {
-      background: #f9f9f9;
-      border: 1px solid #eee;
-      border-radius: 3px;
-      list-style: none;
-    }
-    
-    .sidebar-box ol a {
-      border-bottom: 1px solid #eee;
-      display: block;
-      padding: 10px 10px;
-      text-decoration: none;
-    }
-    
-    .sidebar-box ol li:last-child a {
-      border-bottom: none;
-    }
-
-    .sidebar-box ol a:hover {
-      background: #f5f5f5;
-    }
-
-    li {
-      margin-left: 20px;
-      font-size: 120%;
-    }
-
-    h4 {
-      font-size: 120%;
-    }
-
-
-  </style>
-</head>
-
-<body>
-  <header role="banner">
-    <div class="content">
-      <a class="logo" href="http://0xAX.github.io/weber" target="_blank">
-        <svg height="300" width="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-          <g>
-            <circle cx="150" cy="150" fill="#4c0066" r="147" stroke="#ffffff" stroke-width="6" />
-            <path d="M191.75,213.42l34.57-126.24c2.39-8.71-4.36-15.78-15.08-15.78c-10.721,0-21.02,7.06-23.01,15.78l-28.82,126.24c-1.99,8.71,3.47,15.78,12.21,15.78C180.35,229.2,189.359,222.141,191.75,213.42z" fill="#ffffff" />
-            <path d="M148.77,213.42l26.74-126.24c1.85-8.71-5.289-15.78-15.939-15.78c-10.66,0-20.47,7.06-21.92,15.78l-21.03,126.24c-1.45,8.71,4.41,15.78,13.09,15.78S146.92,222.141,148.77,213.42z" fill="#ffffff" />
-            <path d="M106.05,213.45l4.78-31.511c1.33-8.689-5.28-15.739-14.76-15.739c-9.47,0-17.9,7.05-18.82,15.739l-3.36,31.511c-0.92,8.7,5.36,15.75,14.05,15.75C96.62,229.2,104.73,222.15,106.05,213.45z" fill="#ffffff" />
-          </g>
-        </svg>
-      </a>
-
-      <div class="title">
-        <h1 style="margin-top: -20px;">Weber</h1>
-      </div>
-    </div>
-  </header>
-
-  <main class="content" role="main">
-    <div class="guide">
-      <article id="getting-started">
-        <h3>Getting started</h3>
-        <p>Welcome to the default <a href="https://github.com/0xAX/weber">Weber's</a> page. Weber is a MVC Rails like web framework which was built with <a href="http://elixir-lang.org/">Elixir</a> programming language. Build web applications quickly and efficiently as possible. Let's build Web with Elixir.</p>
-        <h4>Weber features:</h4>
-        <br/>
-        <ul>
-          <li>MVC web framework;</li>
-          <li>New project generation;</li>
-          <li>Json generation with exjson;</li>
-          <li>Websocket support;</li>
-          <li>HTML helpers;</li>
-          <li>Site internationalization</li>
-          <li>Sessions support;</li>
-          <li>and many more</li>
-        </ul>
-      </article>
-    </div>
-    
-    <aside role="contentinfo">
-      <div class="sidebar-box">
-        <h3>Links</h3>
-        <ol>
-          <li><a href="https://github.com/0xAX/weber">Weber source code</a></li>
-          <li><a href="http://0xax.github.io/weber/index.html">Weber site</a></li>
-          <li><a href="http://elixir-lang.org/">Elixir</a></li>
-        </ol>
-      </div>
-    </aside>
-  </main>
-</body>
-
-</html>

+ 0 - 0
frameworks/Elixir/WeberFramework/lib/views/layout/.keep


+ 0 - 24
frameworks/Elixir/WeberFramework/mix.exs

@@ -1,24 +0,0 @@
-defmodule WeberFramework.Mixfile do
-  use Mix.Project
-
-  def project do
-    [ 
-      app: :WeberFramework,
-      version: "0.0.1",
-      deps: deps
-    ]
-  end
-
-  def application do
-    [
-      applications: [],
-      mod: {WeberFramework, []}
-    ]
-  end
-
-  defp deps do
-    [ 
-      { :weber, github: "0xAX/weber" } 
-    ]
-  end
-end

+ 0 - 0
frameworks/Elixir/WeberFramework/public/css/.keep


+ 0 - 0
frameworks/Elixir/WeberFramework/public/img/.keep


BIN
frameworks/Elixir/WeberFramework/public/img/favicon.ico


+ 0 - 235
frameworks/Elixir/WeberFramework/public/index.html

@@ -1,235 +0,0 @@
-<!DOCTYPE html>
-<html itemscope itemtype="http://schema.org/WebPage" lang="en">
-
-<head>
-  <meta charset="utf-8">
-  <title>Welcome to Weber!</title>
-  <link href="img/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
-
-  <style>
-    /* Reset */
-    * {
-      margin: 0;
-      padding: 0;
-    }
-
-    /* Default */
-    body {
-      font: normal 13px proxima-nova, sans-serif;
-      color: #666;
-    }
-
-    a {
-      color: #4c0066;
-    }
-
-    code, pre {
-      background: #f9f9f9;
-      border: 1px solid #ddd;
-      border-radius: 3px;
-      display: block;
-      font-family: monospace;
-      margin: 5px 0;
-      padding: 20px 0 20px 30px;
-      white-space: pre;
-    }
-
-    blockquote {
-      background: #f9f9f9;
-      border-left: 10px solid #eee;
-      border-radius: 3px;
-      color: #888;
-      margin: 20px 0 20px 20px;
-      padding: 10px 12px;
-      quotes: "\201C""\201D""\2018""\2019";
-    }
-
-    blockquote:before {
-      color: #ccc;
-      content: open-quote;
-      font-size: 55px;
-      line-height: 1px;
-      margin-right: 15px;
-      vertical-align: -25px;
-    }
-
-    blockquote p {
-      display: inline;
-    }
-
-    p {
-      font-size: 120%;
-      line-height: 25px;
-      margin: 10px 0;
-    }
-
-    /* Classes */
-    .content {
-      margin: 0 auto;
-      padding: 0 10px;
-      width: 960px;
-    }
-
-    /* Structure */
-    header:after, main:after,
-    header:before, main:before {
-      content: " ";
-      display: table;
-    }
-
-    header:after, main:after {
-      clear: both;
-    }
-
-    header {
-      background: #4c0066;
-      height: 150px;
-      margin-bottom: 50px;
-    }
-
-    header .logo {
-      border-radius: 100%;
-      display: block;
-      float: left;
-      padding-top: 25px;
-    }
-
-    header .title {
-      color: #fff;
-      float: left;
-      line-height: 30px;
-      margin: 101px 0 0;
-      text-align: right;
-      width: 660px;
-    }
-
-    header .title h1 {
-      font-size: 100px;
-    }
-
-    main .guide {
-      float: right;
-      width: 610px;
-    }
-
-    main .guide article {
-      margin-bottom: 50px;
-    }
-
-    main .guide h3 {
-      color: #4c0066;
-      font-size: 150%;
-      text-transform: uppercase;
-    }
-
-    main aside {
-      float: left;
-      margin-right: 50px;
-      width: 300px;
-    }
-
-    .sidebar-box {
-      margin: 25px 20px;
-    }
-
-    .sidebar-box h3 {
-      font-size: 110%;
-      margin-bottom: 5px;
-      text-transform: uppercase;
-    }
-
-    .sidebar-box p {
-      font-size: 90%;
-      line-height: 100%;
-      margin: 0;
-    }
-
-    .sidebar-box ol {
-      background: #f9f9f9;
-      border: 1px solid #eee;
-      border-radius: 3px;
-      list-style: none;
-    }
-    
-    .sidebar-box ol a {
-      border-bottom: 1px solid #eee;
-      display: block;
-      padding: 10px 10px;
-      text-decoration: none;
-    }
-    
-    .sidebar-box ol li:last-child a {
-      border-bottom: none;
-    }
-
-    .sidebar-box ol a:hover {
-      background: #f5f5f5;
-    }
-
-    li {
-      margin-left: 20px;
-      font-size: 120%;
-    }
-
-    h4 {
-      font-size: 120%;
-    }
-
-
-  </style>
-</head>
-
-<body>
-  <header role="banner">
-    <div class="content">
-      <a class="logo" href="http://0xAX.github.io/weber" target="_blank">
-        <svg height="300" width="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-          <g>
-            <circle cx="150" cy="150" fill="#4c0066" r="147" stroke="#ffffff" stroke-width="6" />
-            <path d="M191.75,213.42l34.57-126.24c2.39-8.71-4.36-15.78-15.08-15.78c-10.721,0-21.02,7.06-23.01,15.78l-28.82,126.24c-1.99,8.71,3.47,15.78,12.21,15.78C180.35,229.2,189.359,222.141,191.75,213.42z" fill="#ffffff" />
-            <path d="M148.77,213.42l26.74-126.24c1.85-8.71-5.289-15.78-15.939-15.78c-10.66,0-20.47,7.06-21.92,15.78l-21.03,126.24c-1.45,8.71,4.41,15.78,13.09,15.78S146.92,222.141,148.77,213.42z" fill="#ffffff" />
-            <path d="M106.05,213.45l4.78-31.511c1.33-8.689-5.28-15.739-14.76-15.739c-9.47,0-17.9,7.05-18.82,15.739l-3.36,31.511c-0.92,8.7,5.36,15.75,14.05,15.75C96.62,229.2,104.73,222.15,106.05,213.45z" fill="#ffffff" />
-          </g>
-        </svg>
-      </a>
-
-      <div class="title">
-        <h1 style="margin-top: -20px;">Weber</h1>
-      </div>
-    </div>
-  </header>
-
-  <main class="content" role="main">
-    <div class="guide">
-      <article id="getting-started">
-        <h3>Getting started</h3>
-        <p>Welcome to the default <a href="https://github.com/0xAX/weber">Weber's</a> page. Weber is a MVC Rails like web framework which was built with <a href="http://elixir-lang.org/">Elixir</a> programming language. Build web applications quickly and efficiently as possible. Let's build Web with Elixir.</p>
-        <h4>Weber features:</h4>
-        <br/>
-        <ul>
-          <li>MVC web framework;</li>
-          <li>New project generation;</li>
-          <li>Json generation with exjson;</li>
-          <li>Websocket support;</li>
-          <li>HTML helpers;</li>
-          <li>Site internationalization</li>
-          <li>Sessions support;</li>
-          <li>and many more</li>
-        </ul>
-      </article>
-    </div>
-    
-    <aside role="contentinfo">
-      <div class="sidebar-box">
-        <h3>Links</h3>
-        <ol>
-          <li><a href="https://github.com/0xAX/weber">Weber source code</a></li>
-          <li><a href="http://0xax.github.io/weber/index.html">Weber site</a></li>
-          <li><a href="http://elixir-lang.org/">Elixir</a></li>
-        </ol>
-      </div>
-    </aside>
-  </main>
-</body>
-
-</html>

+ 0 - 0
frameworks/Elixir/WeberFramework/public/js/.keep


+ 0 - 18
frameworks/Elixir/WeberFramework/setup_weber.py

@@ -1,18 +0,0 @@
-import sys
-import subprocess
-
-def start(args, logfile, errfile):
-    try:
-        subprocess.check_call("mix deps.get", cwd="WeberFramework", shell=True, stderr=errfile, stdout=logfile)
-        subprocess.check_call("mix compile --all --force", cwd="WeberFramework", shell=True, stderr=errfile, stdout=logfile)
-        subprocess.check_call("./start.sh", cwd="WeberFramework", shell=True, stderr=errfile, stdout=logfile)
-        return 0
-    except subprocess.CalledProcessError:
-        return 1
- 
-def stop(logfile, errfile):
-    try:
-        subprocess.check_call("killall beam", shell=True, cwd="/usr/bin")
-        return 0
-    except subprocess.CalledProcessError:
-        return 1

+ 0 - 7
frameworks/Elixir/WeberFramework/start.sh

@@ -1,7 +0,0 @@
-#!/usr/bin/env sh
-
-if [ ! -f deps ]; then
-  mix deps.get && mix compile
-fi
-
-exec elixir --detached -S mix run --no-halt

+ 0 - 7
frameworks/Elixir/WeberFramework/test/WeberFramework_test.exs

@@ -1,7 +0,0 @@
-defmodule WeberFrameworkTest do
-  use ExUnit.Case
-
-  test "the truth" do
-    assert(true)
-  end
-end

+ 0 - 1
frameworks/Elixir/WeberFramework/test/test_helper.exs

@@ -1 +0,0 @@
-ExUnit.start

+ 0 - 4
frameworks/Go/go-mongodb/bash_profile.sh

@@ -1,4 +0,0 @@
-# Set the root of our go installation
-export GOROOT=${IROOT}/go
-
-export GOPATH=${TROOT}

+ 0 - 0
frameworks/Go/go-mongodb/benchmark_config → frameworks/Go/go-mongodb/benchmark_config.json


+ 4 - 0
frameworks/Go/go-mongodb/setup.sh

@@ -1,5 +1,9 @@
 #!/bin/bash
 #!/bin/bash
 
 
+# Set the root of our go installation
+export GOROOT=${IROOT}/go
+export GOPATH=${TROOT}
+
 # Where to find the go executable
 # Where to find the go executable
 export PATH="$GOROOT/bin:$PATH"
 export PATH="$GOROOT/bin:$PATH"
 
 

+ 7 - 1
frameworks/Go/go-mongodb/src/hello/hello.go

@@ -84,7 +84,8 @@ func getRandomNumber() uint16 {
 
 
 // Test 1: JSON serialization
 // Test 1: JSON serialization
 func jsonHandler(w http.ResponseWriter, r *http.Request) {
 func jsonHandler(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "application/javascript")
+	w.Header().Set("Content-Type", "application/json")
+	w.Header().Set("Server", "go-mongodb")
 	json.NewEncoder(w).Encode(&Message{helloWorldString})
 	json.NewEncoder(w).Encode(&Message{helloWorldString})
 }
 }
 
 
@@ -97,6 +98,7 @@ func dbHandler(w http.ResponseWriter, r *http.Request) {
 			return
 			return
 		} else {
 		} else {
 			w.Header().Set("Content-Type", "application/json")
 			w.Header().Set("Content-Type", "application/json")
+			w.Header().Set("Server", "go-mongodb")
 			json.NewEncoder(w).Encode(&world)
 			json.NewEncoder(w).Encode(&world)
 			return
 			return
 		}
 		}
@@ -116,6 +118,7 @@ func queriesHandler(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 
 
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Content-Type", "application/json")
+	w.Header().Set("Server", "go-mongodb")
 	encoder := json.NewEncoder(w)
 	encoder := json.NewEncoder(w)
 
 
 	if n <= 1 {
 	if n <= 1 {
@@ -141,6 +144,7 @@ func queriesHandler(w http.ResponseWriter, r *http.Request) {
 
 
 func fortuneHandler(w http.ResponseWriter, r *http.Request) {
 func fortuneHandler(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "text/html")
 	w.Header().Set("Content-Type", "text/html")
+	w.Header().Set("Server", "go-mongodb")
 	f := make(Fortunes, 16)
 	f := make(Fortunes, 16)
 	if err := fortunes.Find(nil).All(&f); err == nil {
 	if err := fortunes.Find(nil).All(&f); err == nil {
 		f = append(f, Fortune{
 		f = append(f, Fortune{
@@ -161,6 +165,7 @@ func updateHandler(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 
 
 	w.Header().Set("Content-Type", "application/json")
 	w.Header().Set("Content-Type", "application/json")
+	w.Header().Set("Server", "go-mongodb")
 	encoder := json.NewEncoder(w)
 	encoder := json.NewEncoder(w)
 
 
 	if n <= 1 {
 	if n <= 1 {
@@ -195,5 +200,6 @@ func updateHandler(w http.ResponseWriter, r *http.Request) {
 
 
 func plaintextHandler(w http.ResponseWriter, r *http.Request) {
 func plaintextHandler(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "text/plain")
 	w.Header().Set("Content-Type", "text/plain")
+	w.Header().Set("Server", "go-mongodb")
 	w.Write([]byte(helloWorldString))
 	w.Write([]byte(helloWorldString))
 }
 }

+ 0 - 95
frameworks/Java/play2-java/generate_config.py

@@ -1,95 +0,0 @@
-#!/usr/bin/env python
-
-import collections, json, os, textwrap
-
-# This script generates the benchmark_config.json and setup_*.py files.
-# To add new tests, modify the `configurations` and `test_urls` tables.
-
-# Each line corresponds to a test application.
-# Format is: (language, orm, (opsys, ...), (test, ...))
-# See the dir_name logic below to see the directory name for each test application.
-configurations = [
-  ('Java',  None,    			['Linux'],            ['json', 'plaintext']),
-  ('Java',  'Ebean BoneCP', 	['Linux'],            ['db', 'query', 'fortune', 'update']),
-  ('Java',  'Ebean HikariCP', 	['Linux'],            ['db', 'query', 'fortune', 'update']),
-  ('Java',  'JPA BoneCP',		['Linux'],            ['db', 'query', 'fortune', 'update']),
-  ('Java',  'JPA HikariCP',		['Linux'],            ['db', 'query', 'fortune', 'update']),
-  ('Scala', None,    			['Linux'],            ['json']),
-  ('Scala', 'Anorm', 			['Linux', 'Windows'], ['db', 'query', 'fortune', 'update']),
-  ('Scala', 'Slick', 			['Linux'],            ['db', 'query', 'fortune', 'update']),
-]
-
-# All play2 test applications must use the same URLs.
-test_urls = {
-  'json': '/json',
-  'db': '/db',
-  'query': '/queries?queries=',
-  'fortune': '/fortunes',
-  'update': '/update?queries=',
-  'plaintext': '/plaintext',
-}
-
-langs = {
-  'Java': ['Java', 'play2-java'],
-  'Scala': ['Scala', 'play2-scala']
-}
-def pathForLang(lang):
-  return os.path.join(frameworksPath(), *langs[lang])
-def frameworksPath():
-  'Get the absolute path of ROOT/frameworks'
-  return os.path.abspath(os.path.join(__file__, '..', '..', '..'))
-
-lang_test_configs = {}
-for lang, _ in langs.iteritems():
-  lang_test_configs[lang] = collections.OrderedDict()
-
-for lang, orm, opsyses, tests in configurations:
-  dir_name = 'play2-' + lang.lower() + (('-'+orm.replace(' ', '-').lower()) if orm else '')
-  setup_name = 'setup_' + lang.lower() + (('_'+orm.replace(' ', '_').lower()) if orm else '')
-
-  setup_path = os.path.join(pathForLang(lang), setup_name+'.py')
-  print 'Generating', setup_path
-  with open(setup_path, 'w') as f:
-    f.write(textwrap.dedent("""
-      # This file was generated by frameworks/Java/play2-java/generate_config.py.
-      # Do not edit this file directly, use the script to regenerate.
-      from .setup_common import make_setup_for_dir
-
-      make_setup_for_dir(globals(), '"""+dir_name+"""')
-    """))
-
-  for opsys in opsyses:
-    if len(opsyses) == 1:
-      test_name = lang.lower() + (('-'+orm.replace(' ', '-').lower()) if orm else '')
-    else:
-      test_name = lang.lower() + (('-'+orm.replace(' ', '-').lower()) if orm else '') + '-'+opsys.lower()
-    test_config_json = collections.OrderedDict([
-      ('display_name', 'play2-'+test_name),
-      ('setup_file', setup_name),
-      ('framework', 'play2'),
-      ('language', lang),
-      ('orm', 'Full' if orm else 'Raw'),
-      ('os', opsys),
-      ('database', 'MySQL' if orm else 'None'),
-      ('approach', 'Realistic'),
-      ('classification', 'Fullstack'),
-      ('platform', 'Netty'),
-      ('webserver', 'None'),
-      ('database_os', 'Linux'),
-      ('notes', ''),
-      ('versus', 'netty'),
-      ('port', '9000'),
-    ])
-    for test in tests:
-      test_config_json[test+'_url'] = test_urls[test]
-      lang_test_configs[lang][test_name] = test_config_json
-
-for lang, _ in langs.iteritems():
-  benchmark_config_path = os.path.join(pathForLang(lang), 'benchmark_config.json')
-  print 'Generating', benchmark_config_path
-  with open(benchmark_config_path, 'w') as f:
-    json_str = json.dumps({
-      'framework': 'play2',
-      'tests': [lang_test_configs[lang]]
-    }, indent=2)
-    f.write(json_str)

+ 45 - 0
frameworks/Python/web2py/README.md

@@ -0,0 +1,45 @@
+# web2py Benchmark Test 
+
+Main controller found [here](web2py/applications/app/controllers/default.py)
+
+Database model found [here](web2py/applications/app/models/db.py)
+
+Fortunes template found [here](web2py/applications/app/views/default/fortune.html)
+
+## Description
+
+web2py framework (http://www.web2py.com/)
+
+### Database
+
+MySQL
+
+### Server
+
+* Rocket (default web2py server)
+
+## Test URLs
+### JSON Encoding
+
+http://localhost:8080/json
+
+### Plaintext
+
+http://localhost:8080/plaintext
+
+### DB
+
+http://localhost:8080/db
+
+### Query
+
+http://localhost:8080/queries?queries=2
+
+### Update
+
+http://localhost:8080/updates?queries=2
+
+### Fortune
+
+http://localhost:8080/fortune
+

+ 2 - 0
frameworks/Python/web2py/app/app/ABOUT

@@ -0,0 +1,2 @@
+Write something about this app.
+Developed with web2py.

+ 4 - 0
frameworks/Python/web2py/app/app/LICENSE

@@ -0,0 +1,4 @@
+The web2py welcome app is licensed under public domain 
+(except for the css and js files that it includes, which have their own third party licenses).
+
+You can modify this license when you add your own code.

+ 1 - 0
frameworks/Python/web2py/app/app/__init__.py

@@ -0,0 +1 @@
+

+ 68 - 0
frameworks/Python/web2py/app/app/controllers/default.py

@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+from random import randint
+from functools import partial
+import json as jsonOut
+
+def getQueryNum(queryString):
+    try:
+        num_queries = int(queryString)
+        if num_queries < 1:
+            return 1
+        if num_queries > 500:
+            return 500
+        return num_queries
+    except ValueError:
+         return 1
+
+def serializeWorld(world):
+    return {
+        "id" : world.id,
+        "randomNumber" : world.randomNumber
+    }
+
+def serializeFortune(fortune):
+    return {
+        "id" : fortune.id,
+        "message": fortune.message
+    }
+
+def plaintext():
+    response.headers["Content-Type"]="text/plain; charset=UTF-8"
+    return "Hello, World!"
+
+def json():
+    response.headers["Content-Type"]="application/json; charset=UTF-8"
+    return jsonOut.dumps({"message":"Hello, World!"})
+
+def db():
+    response.headers["Content-Type"]="application/json; charset=UTF-8"
+    wid = randint(1, 10000)
+    world = DATABASE.world[wid]
+    return jsonOut.dumps(serializeWorld(world))
+
+def queries():
+    response.headers["Content-Type"]="application/json; charset=UTF-8"
+    num_queries = getQueryNum(request.vars["queries"])
+    rp = partial(randint, 1, 10000)
+    worlds = [serializeWorld(DATABASE.world[rp()]) for _ in xrange(num_queries)]
+    return jsonOut.dumps(worlds)
+
+def updates():
+    response.headers["Content-Type"]="application/json; charset=UTF-8"
+    num_queries = getQueryNum(request.vars["queries"])
+    worlds = []
+    rp = partial(randint, 1, 10000)
+    ids = [rp() for _ in xrange(num_queries)]
+    ids.sort() # To avoid deadlock
+    for id in ids:
+        world = DATABASE(DATABASE.world.id==id).select()[0]
+        world.randomNumber = rp()
+        worlds.append(serializeWorld(world))
+    return jsonOut.dumps(worlds)
+
+def fortune():
+    fortunes = DATABASE(DATABASE.fortune).select()
+    fortune_list = fortunes.as_list();
+    fortune_list.append({"id":0, "message":"Additional fortune added at request time."})
+    fortune_list = sorted(fortune_list, key=lambda k: k["message"])
+    return dict(fortunes=fortune_list)

+ 47 - 0
frameworks/Python/web2py/app/app/models/db.py

@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+#########################################################################
+## This scaffolding model makes your app work on Google App Engine too
+## File is released under public domain and you can use without limitations
+#########################################################################
+
+## if SSL/HTTPS is properly configured and you want all HTTP requests to
+## be redirected to HTTPS, uncomment the line below:
+# request.requires_https()
+
+## app configuration made easy. Look inside private/appconfig.ini
+from gluon.contrib.appconfig import AppConfig
+## once in production, remove reload=True to gain full speed
+myconf = AppConfig(reload=True)
+
+DATABASE = None
+DATABASE_URI = "mysql://benchmarkdbuser:benchmarkdbpass@localhost:3306/hello_world"
+
+if not request.env.web2py_runtime_gae:
+    ## if NOT running on Google App Engine use SQLite or other DB
+    db = DAL(DATABASE_URI, fake_migrate_all=True)
+    DATABASE = db
+else:
+    ## connect to Google BigTable (optional 'google:datastore://namespace')
+    db = DAL(DATABASE_URI, fake_migrate_all=True)
+    DATABASE = db
+    ## store sessions and tickets there
+    session.connect(request, response, db=db)
+    ## or store session in Memcache, Redis, etc.
+    ## from gluon.contrib.memdb import MEMDB
+    ## from google.appengine.api.memcache import Client
+    ## session.connect(request, response, db = MEMDB(Client()))
+
+## by default give a view/generic.extension to all actions from localhost
+## none otherwise. a pattern can be 'controller/function.extension'
+response.generic_patterns = ['*'] if request.is_local else []
+
+db.define_table("world",
+    Field("id"),
+    Field("randomNumber")
+)
+
+db.define_table("fortune",
+    Field("id"),
+    Field("message")
+)

+ 19 - 0
frameworks/Python/web2py/app/app/private/appconfig.ini

@@ -0,0 +1,19 @@
+; App configuration
+
+; db configuration
+[db]
+uri       = sqlite://storage.sqlite
+migrate   = 1
+pool_size = 1
+
+; smtp address and credentials
+[smtp]
+server = smtp.gmail.com:587
+sender = [email protected]
+login  = username:password
+
+
+; form styling
+[forms]
+formstyle = bootstrap3_inline
+separator = 

+ 38 - 0
frameworks/Python/web2py/app/app/routes.example.py

@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+#  This is an app-specific example router
+#
+#  This simple router is used for setting languages from app/languages directory
+#  as a part of the application path:  app/<lang>/controller/function
+#  Language from default.py or 'en' (if the file is not found) is used as
+#  a default_language
+#
+# See <web2py-root-dir>/router.example.py for parameter's detail
+#-------------------------------------------------------------------------------------
+# To enable this route file you must do the steps:
+#
+# 1. rename <web2py-root-dir>/router.example.py to routes.py
+# 2. rename this APP/routes.example.py to APP/routes.py
+#    (where APP - is your application directory)
+# 3. restart web2py (or reload routes in web2py admin interfase)
+#
+# YOU CAN COPY THIS FILE TO ANY APPLICATION'S ROOT DIRECTORY WITHOUT CHANGES!
+
+from fileutils import abspath
+from languages import read_possible_languages
+
+possible_languages = read_possible_languages(abspath('applications', app))
+#NOTE! app - is an application based router's parameter with name of an
+#            application. E.g.'welcome'
+
+routers = {
+    app: dict(
+        default_language = possible_languages['default'][0],
+        languages = [lang for lang in possible_languages
+                           if lang != 'default']
+    )
+}
+
+#NOTE! To change language in your application using these rules add this line
+#in one of your models files:
+#   if request.uri_language: T.force(request.uri_language)

+ 1 - 0
frameworks/Python/web2py/app/app/views/__init__.py

@@ -0,0 +1 @@
+

+ 15 - 0
frameworks/Python/web2py/app/app/views/default/fortune.html

@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Fortunes</title>
+  </head>
+  <body>
+    <table><tr><th>id</th><th>message</th></tr>
+    {{for fortune in fortunes:}}
+      <tr><td>{{=fortune["id"]}}</td><td>{{=fortune["message"]}}</td></tr>
+      {{pass}}
+      </table>
+  </body>
+</html>
+
+

+ 52 - 0
frameworks/Python/web2py/app/app/views/default/index.html

@@ -0,0 +1,52 @@
+{{left_sidebar_enabled,right_sidebar_enabled=False,('message' in globals())}}
+{{extend 'layout.html'}}
+
+{{block header}}
+    <header class="container-fluid background">
+      <div class="jumbotron text-center">
+        {{if response.title:}}
+        <h1>{{=response.title}}
+          <small>{{=response.subtitle or ''}}</small></h1>
+        {{pass}}
+      </div>
+    </header>
+{{end}}
+
+{{if 'message' in globals():}}
+<h2>{{=message}}</h2>
+<p class="lead">{{=T('How did you get here?')}}</p>
+<ol>
+  <li>{{=T('You are successfully running web2py')}}</li>
+  <li>{{=XML(T('You visited the url %s', A(request.env.path_info,_href=request.env.path_info)))}}</li>
+  <li>{{=XML(T('Which called the function %s located in the file %s',
+    (A(request.function+'()',_href='#'),
+    A('web2py/applications/%(application)s/controllers/%(controller)s.py' % request,
+    _href=URL('admin','default','peek', args=(request.application,'controllers',request.controller+'.py'))))))}}</li>
+  <li>{{=XML(T('The output of the file is a dictionary that was rendered by the view %s',
+    A('web2py/applications/%(application)s/views/%(controller)s/index.html' % request,
+    _href=URL('admin','default','peek',args=(request.application,'views',request.controller,'index.html')))))}}</li>
+  <li>{{=T('You can modify this application and adapt it to your needs')}}</li>
+</ol>
+{{elif 'content' in globals():}}
+{{=content}}
+{{else:}}
+{{=BEAUTIFY(response._vars)}}
+{{pass}}
+
+{{block right_sidebar}}
+<div class="panel panel-info">
+  <div class="panel-heading"><h3 class="panel-title"><a class="btn-block"
+      href="{{=URL('admin','default','index')}}">
+      <i class="glyphicon glyphicon-cog"></i>
+      {{=T("admin")}}
+    </a></h3></div>
+  <div class="panel-body">
+    {{=T("Don't know what to do?")}}
+  </div>
+  <ul class="list-group">
+    <li class="list-group-item">{{=A(T("Online examples"), _href=URL('examples','default','index'))}}</li>
+    <li class="list-group-item"><a href="http://web2py.com">web2py.com</a></li>
+    <li class="list-group-item"><a href="http://web2py.com/book">{{=T('Documentation')}}</a></li>
+  </ul>
+</div>
+{{end}}

+ 35 - 0
frameworks/Python/web2py/app/app/views/default/user.html

@@ -0,0 +1,35 @@
+{{extend 'layout.html'}}
+
+<h2>
+{{=T('Sign Up') if request.args(0) == 'register' else T('Log In') if request.args(0) == 'login' else T(request.args(0).replace('_',' ').title())}}
+</h2>
+
+<div class="container">
+    <div class="row">
+        <div id="web2py_user_form" class="col-lg-6">
+        {{
+        if request.args(0)=='login':
+            if not 'register' in auth.settings.actions_disabled:
+                form.add_button(T('Sign Up'),URL(args='register', vars={'_next': request.vars._next} if request.vars._next else None),_class='btn btn-default')
+            pass
+            if not 'request_reset_password' in auth.settings.actions_disabled:
+                form.add_button(T('Lost Password'),URL(args='request_reset_password'),_class='btn btn-default')
+            pass
+        pass
+        =form
+        }}
+        </div>
+    </div>
+</div>
+
+
+{{block page_js}}
+<script>
+    jQuery("#web2py_user_form input:visible:enabled:first").focus();
+{{if request.args(0)=='register':}}
+    web2py_validate_entropy(jQuery('#auth_user_password'),100);
+{{elif request.args(0)=='change_password':}}
+    web2py_validate_entropy(jQuery('#no_table_new_password'),100);
+{{pass}}
+</script>
+{{end page_js}}

+ 16 - 0
frameworks/Python/web2py/app/app/views/generic.html

@@ -0,0 +1,16 @@
+{{extend 'layout.html'}}
+{{"""
+
+You should not modify this file. 
+It is used as default when a view is not provided for your controllers
+
+"""}}
+<h2>{{=' '.join(x.capitalize() for x in request.function.split('_'))}}</h2>
+{{if len(response._vars)==1:}}
+{{=BEAUTIFY(response._vars.values()[0])}}
+{{elif len(response._vars)>1:}}
+{{=BEAUTIFY(response._vars)}}
+{{pass}}
+{{if request.is_local:}}
+{{=response.toolbar()}}
+{{pass}}

+ 14 - 0
frameworks/Python/web2py/app/routes.py

@@ -0,0 +1,14 @@
+routers = dict(
+    BASE = dict(
+        default_application='app',
+    )
+)
+
+routes_in = (
+	("/json", "/app/default/json"),
+	("/plaintext", "/app/default/plaintext"),
+        ("/db", "/app/default/db"),
+	("/queries", "/app/default/queries"),
+	("/updates", "/app/default/updates"),
+	("/fortune", "/app/default/fortune")
+)

+ 27 - 0
frameworks/Python/web2py/benchmark_config.json

@@ -0,0 +1,27 @@
+{
+  "framework": "web2py",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "plaintext_url": "/plaintext",
+      "json_url": "/json",
+      "db_url": "/db",
+      "query_url": "/queries?queries=",
+      "fortune_url": "/fortune",
+      "update_url": "/updates?queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "MySQL",
+      "framework": "web2py",
+      "language": "Python",
+      "orm": "Full",
+      "platform": "web2Py",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "web2py",
+      "notes": "CPython 2.7"
+    } 
+  }]
+}

+ 18 - 0
frameworks/Python/web2py/install.sh

@@ -0,0 +1,18 @@
+#!/bin/bash
+
+mkdir -p $IROOT/.pip_cache
+
+export PIP_DOWNLOAD_CACHE=$IROOT/.pip_cache
+
+fw_depends python2
+
+export PY2_ROOT=$IROOT/py2
+export PY2_PIP=$PY2_ROOT/bin/pip
+
+$PY2_PIP install --install-option="--prefix=${PY2_ROOT}" -r $TROOT/requirements.txt
+
+cd $TROOT
+rm -fr web2py
+git clone --recursive --branch R-2.10.3 https://github.com/web2py/web2py.git 
+cp -r app/app/ web2py/applications/
+cp app/routes.py web2py/

+ 1 - 0
frameworks/Python/web2py/requirements.txt

@@ -0,0 +1 @@
+mysqlclient==1.3.6

+ 4 - 0
frameworks/Python/web2py/setup.sh

@@ -0,0 +1,4 @@
+export PY2_ROOT=$IROOT/py2
+export PY2=$PY2_ROOT/bin/python
+
+$PY2 web2py/web2py.py -a '' -i 127.0.0.1 -p 8080  &

+ 0 - 27
frameworks/Scala/play-activate-mysql/README.md

@@ -1,27 +0,0 @@
-#Play Benchmarking Test
-
-This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
-
-### JSON Encoding Test
-
-* [JSON test source](app/controllers/Application.scala)
-
-### Data-Store/Database Mapping Test
-
-* [Database test controller](app/controllers/Application.scala)
-* [Database test model](app/models/World.scala)
-
-## Infrastructure Software Versions
-The tests were run with:
-
-* [Java OpenJDK 1.7.0_09](http://openjdk.java.net/)
-* [Play 2.1.0](http://http://www.playframework.com/)
-
-## Test URLs
-### JSON Encoding Test
-
-http://localhost/json
-
-### Data-Store/Database Mapping Test
-
-http://localhost/db?queries=5

+ 0 - 62
frameworks/Scala/play-activate-mysql/app/controllers/Application.scala

@@ -1,62 +0,0 @@
-package controllers
-
-import play.api.Play.current
-import play.api.mvc._
-import play.api.libs.json.Json
-import java.util.concurrent._
-import scala.concurrent._
-import scala.concurrent.Future
-import play.api.libs.concurrent.Execution.Implicits._
-import play.core.NamedThreadFactory
-import models.ActivateWorld
-import models.Models._
-import models.ActivateFortune
-import models.persistenceContext._
-
-object Application extends Controller {
-
-    private val TestDatabaseRows = 10000
-
-    def db(queries: Int) =
-        Action {
-            transactional {
-                val random = ThreadLocalRandom.current()
-
-                val worlds =
-                    for (_ <- 1 to queries) yield {
-                        ActivateWorld.fingByLegacyId(random.nextInt(TestDatabaseRows) + 1)
-                    }
-
-                Ok(Json.toJson(worlds))
-            }
-        }
-
-    def fortunes() =
-        Action {
-            val transaction = new Transaction
-            try
-                transactional(transaction) {
-                    val fortunes =
-                        ActivateFortune.all ++ List(new ActivateFortune(0, "Additional fortune added at request time."))
-                    Ok(views.html.fortune(fortunes))
-                }
-            finally
-                transaction.rollback
-        }
-
-    def update(queries: Int) =
-        Action {
-
-            val random = ThreadLocalRandom.current()
-
-            transactional {
-                val worlds =
-                    for (_ <- 1 to queries) yield {
-                        val world = ActivateWorld.fingByLegacyId(random.nextInt(TestDatabaseRows) + 1)
-                        world.randomNumber = random.nextInt(TestDatabaseRows) + 1
-                        world
-                    }
-                Ok(Json.toJson(worlds)).withHeaders("Server" -> "Netty")
-            }
-        }
-}

+ 0 - 26
frameworks/Scala/play-activate-mysql/benchmark_config.json

@@ -1,26 +0,0 @@
-{
-  "framework": "play-activate-mysql",
-  "tests": [{
-    "default": {
-      "setup_file": "setup",
-      "db_url": "/db",
-      "query_url": "/db?queries=",
-      "fortune_url": "/fortunes",
-      "update_url": "/update?queries=",
-      "port": 9000,
-      "approach": "Realistic",
-      "classification": "Fullstack",
-      "database": "MySQL",
-      "framework": "play2",
-      "language": "Scala",
-      "orm": "Full",
-      "platform": "Netty",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "play-scala-activate",
-      "notes": "",
-      "versus": "netty"
-    }
-  }]
-}

+ 0 - 3
frameworks/Scala/play-activate-mysql/install.sh

@@ -1,3 +0,0 @@
-#!/bin/bash
-
-fw_depends java maven play2 sbt

+ 0 - 13
frameworks/Scala/play-activate-mysql/setup.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-export PLAY2_HOME=${IROOT}/play-2.2.0
-
-sed -i 's|jdbc:mysql://.*:3306|jdbc:mysql://'"${DBHOST}"':3306|g' conf/application.conf
-
-${PLAY2_HOME}/play clean dist
-
-cd target/universal
-unzip play-activate-mysql-1.0-SNAPSHOT.zip
-cd play-activate-mysql-1.0-SNAPSHOT/bin
-chmod +x play-activate-mysql
-
-./play-activate-mysql &

+ 40 - 19
frameworks/Scala/play2-scala/benchmark_config.json

@@ -20,6 +20,27 @@
         "port": "9000", 
         "port": "9000", 
         "json_url": "/json"
         "json_url": "/json"
       }, 
       }, 
+      "activate": {
+        "display_name": "play2-scala-activate", 
+        "setup_file": "setup_scala_activate", 
+        "framework": "play2", 
+        "language": "Scala", 
+        "orm": "Full", 
+        "os": "Linux", 
+        "database": "MySQL", 
+        "approach": "Realistic", 
+        "classification": "Fullstack", 
+        "platform": "Netty", 
+        "webserver": "None", 
+        "database_os": "Linux", 
+        "notes": "", 
+        "versus": "netty", 
+        "port": "9000", 
+        "db_url": "/db", 
+        "query_url": "/queries?queries=", 
+        "fortune_url": "/fortunes", 
+        "update_url": "/update?queries="
+      }, 
       "anorm-linux": {
       "anorm-linux": {
         "display_name": "play2-scala-anorm-linux", 
         "display_name": "play2-scala-anorm-linux", 
         "setup_file": "setup_scala_anorm", 
         "setup_file": "setup_scala_anorm", 
@@ -62,6 +83,25 @@
         "fortune_url": "/fortunes", 
         "fortune_url": "/fortunes", 
         "update_url": "/update?queries="
         "update_url": "/update?queries="
       }, 
       }, 
+      "reactivemongo": {
+        "display_name": "play2-scala-reactivemongo", 
+        "setup_file": "setup_scala_reactivemongo", 
+        "framework": "play2", 
+        "language": "Scala", 
+        "orm": "Full", 
+        "os": "Linux", 
+        "database": "MongoDB", 
+        "approach": "Realistic", 
+        "classification": "Fullstack", 
+        "platform": "Netty", 
+        "webserver": "None", 
+        "database_os": "Linux", 
+        "notes": "", 
+        "versus": "netty", 
+        "port": "9000", 
+        "db_url": "/db", 
+        "query_url": "/queries?queries="
+      }, 
       "slick": {
       "slick": {
         "display_name": "play2-scala-slick", 
         "display_name": "play2-scala-slick", 
         "setup_file": "setup_scala_slick", 
         "setup_file": "setup_scala_slick", 
@@ -82,25 +122,6 @@
         "query_url": "/queries?queries=", 
         "query_url": "/queries?queries=", 
         "fortune_url": "/fortunes", 
         "fortune_url": "/fortunes", 
         "update_url": "/update?queries="
         "update_url": "/update?queries="
-      },
-      "scala-mongodb": {
-        "setup_file": "setup_scala_mongodb",
-        "db_url": "/db",
-        "query_url": "/queries?queries=",
-        "port": 9000,
-        "approach": "Realistic",
-        "classification": "Fullstack",
-        "database": "MongoDB",
-        "framework": "play2",
-        "language": "Scala",
-        "orm": "Raw",
-        "platform": "Netty",
-        "webserver": "None",
-        "os": "Linux",
-        "database_os": "Linux",
-        "display_name": "play2-scala-mongodb",
-        "notes": "Uses Reactive Mongo",
-        "versus": "netty"
       }
       }
     }
     }
   ]
   ]

+ 0 - 0
frameworks/Scala/play-activate-mysql/.gitignore → frameworks/Scala/play2-scala/play2-scala-activate/.gitignore


+ 0 - 0
frameworks/Scala/play-activate-mysql/app/Global.scala → frameworks/Scala/play2-scala/play2-scala-activate/app/Global.scala


+ 91 - 0
frameworks/Scala/play2-scala/play2-scala-activate/app/controllers/Application.scala

@@ -0,0 +1,91 @@
+package controllers
+
+import play.api.Play.current
+import play.api.mvc._
+import play.api.libs.json.Json
+import java.util.concurrent._
+import scala.concurrent._
+import scala.concurrent.Future
+import play.api.libs.concurrent.Execution.Implicits._
+import play.core.NamedThreadFactory
+import models.ActivateWorld
+import models.Models._
+import models.ActivateFortune
+import models.persistenceContext._
+
+object Application extends Controller {
+
+  def getRandomWorlds(n: Int): Seq[ActivateWorld] = {
+      val random = ThreadLocalRandom.current()
+      for (_ <- 1 to n) yield {
+          val randomId = random.nextInt(TestDatabaseRows) + 1
+          ActivateWorld.fingByLegacyId(randomId)
+      }
+  }
+
+  def getFortunes(): Seq[ActivateFortune] = {
+      ActivateFortune.all
+  }
+
+  def updateWorlds(n: Int): Seq[ActivateWorld] = {
+      val random = ThreadLocalRandom.current()
+      for (_ <- 1 to n) yield {
+            val randomId = random.nextInt(TestDatabaseRows) + 1
+            val world = ActivateWorld.fingByLegacyId(randomId)
+            world.randomNumber = random.nextInt(10000) + 1
+            world
+      }
+  }
+
+  // Common(ish) code between Scala database code
+
+  protected val TestDatabaseRows = 10000
+
+  def db = Action {
+      transactional {
+          val worlds = getRandomWorlds(1)
+          Ok(Json.toJson(worlds.head))
+      }
+  }
+
+  def queries(countString: String) = Action {
+      val n = parseCount(countString)
+      transactional {
+          val worlds = getRandomWorlds(n)
+          Ok(Json.toJson(worlds))
+      }
+  }
+
+  def fortunes() = Action {
+      val transaction = new Transaction
+      try
+          transactional(transaction) {
+              val dbFortunes = getFortunes()
+              val appendedFortunes =  new ActivateFortune(0, "Additional fortune added at request time.") :: (dbFortunes.to[List])
+              Ok(views.html.fortune(appendedFortunes))
+          }
+      finally
+          transaction.rollback
+  }
+
+  def update(queries: String) = Action {
+      transactional {
+          val n = parseCount(queries)
+          val worlds = updateWorlds(n)
+          Ok(Json.toJson(worlds))
+      }
+  }
+
+  private def parseCount(s: String): Int = {
+      try {
+          val parsed = java.lang.Integer.parseInt(s, 10)
+          parsed match {
+              case i if i < 1 => 1
+              case i if i > 500 => 500
+              case i => i
+          }
+      } catch {
+          case _: NumberFormatException => 1
+      }
+  }
+}

+ 0 - 0
frameworks/Scala/play-activate-mysql/app/models/Migrations.scala → frameworks/Scala/play2-scala/play2-scala-activate/app/models/Migrations.scala


+ 0 - 0
frameworks/Scala/play-activate-mysql/app/models/Models.scala → frameworks/Scala/play2-scala/play2-scala-activate/app/models/Models.scala


+ 0 - 0
frameworks/Scala/play-activate-mysql/app/models/PersistenceContext.scala → frameworks/Scala/play2-scala/play2-scala-activate/app/models/PersistenceContext.scala


+ 0 - 0
frameworks/Scala/play-activate-mysql/app/views/fortune.scala.html → frameworks/Scala/play2-scala/play2-scala-activate/app/views/fortune.scala.html


+ 0 - 0
frameworks/Scala/play-activate-mysql/app/views/main.scala.html → frameworks/Scala/play2-scala/play2-scala-activate/app/views/main.scala.html


+ 0 - 0
frameworks/Scala/play-activate-mysql/conf/application.conf → frameworks/Scala/play2-scala/play2-scala-activate/conf/application.conf


+ 0 - 0
frameworks/Scala/play-activate-mysql/conf/play.plugins → frameworks/Scala/play2-scala/play2-scala-activate/conf/play.plugins


+ 3 - 2
frameworks/Scala/play-activate-mysql/conf/routes → frameworks/Scala/play2-scala/play2-scala-activate/conf/routes

@@ -3,9 +3,10 @@
 # ~~~~
 # ~~~~
 
 
 # Home page
 # Home page
-GET     /db                             controllers.Application.db(queries: Int ?= 1)
+GET     /db                             controllers.Application.db
+GET     /queries                        controllers.Application.queries(queries ?= "1")
 GET     /fortunes                       controllers.Application.fortunes
 GET     /fortunes                       controllers.Application.fortunes
-GET     /update                         controllers.Application.update(queries: Int ?= 1)
+GET     /update                         controllers.Application.update(queries ?= "1")
 
 
 # Map static resources from the /public folder to the /assets URL path
 # Map static resources from the /public folder to the /assets URL path
 GET     /assets/*file                   controllers.Assets.at(path="/public", file)
 GET     /assets/*file                   controllers.Assets.at(path="/public", file)

+ 1 - 1
frameworks/Scala/play-activate-mysql/project/Build.scala → frameworks/Scala/play2-scala/play2-scala-activate/project/Build.scala

@@ -4,7 +4,7 @@ import play.Project._
 
 
 object ApplicationBuild extends Build {
 object ApplicationBuild extends Build {
 
 
-  val appName         = "play-activate-mysql"
+  val appName         = "play2-scala-activate"
   val appVersion      = "1.0-SNAPSHOT"
   val appVersion      = "1.0-SNAPSHOT"
 
 
   val activateVersion = "1.4.4"
   val activateVersion = "1.4.4"

+ 0 - 0
frameworks/Scala/play-activate-mysql/project/build.properties → frameworks/Scala/play2-scala/play2-scala-activate/project/build.properties


+ 0 - 0
frameworks/Scala/play-activate-mysql/project/plugins.sbt → frameworks/Scala/play2-scala/play2-scala-activate/project/plugins.sbt


+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-anorm/app/controllers/Application.scala

@@ -42,7 +42,7 @@ object Application extends Controller {
     }
     }
   }
   }
 
 
-  // Common code between Anorm and Slick
+  // Common code between Scala database code
 
 
   protected val TestDatabaseRows = 10000
   protected val TestDatabaseRows = 10000
 
 

+ 0 - 20
frameworks/Scala/play2-scala/play2-scala-mongodb/README.md

@@ -1,20 +0,0 @@
-#Play Benchmarking Test
-
-This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
-
-### Data-Store/Database Mapping Test
-
-* [Database test controller](app/controllers/Application.scala)
-
-## Infrastructure Software Versions
-The tests were run with:
-
-* [Java OpenJDK 1.7.0_09](http://openjdk.java.net/)
-* [Play 2.2.0](http://http://www.playframework.com/)
-* [Reactivemongo 0.10.5.0.akka22](https://github.com/zenexity/Play-ReactiveMongo)
-
-## Test URLs
-### Single Database Query test
-http://localhost:9000/db
-### Multiple Database Query test
-http://localhost:9000/queries?queries=5

+ 0 - 16
frameworks/Scala/play2-scala/play2-scala-mongodb/project/Build.scala

@@ -1,16 +0,0 @@
-import sbt._
-import Keys._
-
-object ApplicationBuild extends Build {
-
-  val appName         = "play2-scala-mongodb"
-  val appVersion      = "1.0-SNAPSHOT"
-
-  val appDependencies = Seq(
-    "org.reactivemongo" %% "play2-reactivemongo" % "0.10.5.0.akka22" exclude("org.scala-stm", "scala-stm_2.10.0")
-  )
-
-  val main = play.Project(appName, appVersion, appDependencies).settings(
-  )
-
-}

+ 0 - 1
frameworks/Scala/play2-scala/play2-scala-mongodb/project/build.properties

@@ -1 +0,0 @@
-sbt.version=0.13.0

+ 0 - 3
frameworks/Scala/play2-scala/play2-scala-mongodb/source_code

@@ -1,3 +0,0 @@
-./play-scala-mongodb/app/
-./play-scala-mongodb/app/controllers
-./play-scala-mongodb/app/controllers/Application.scala

+ 0 - 0
frameworks/Scala/play2-scala/play2-scala-mongodb/.gitignore → frameworks/Scala/play2-scala/play2-scala-reactivemongo/.gitignore


+ 0 - 0
frameworks/Scala/play2-scala/play2-scala-mongodb/app/controllers/Application.scala → frameworks/Scala/play2-scala/play2-scala-reactivemongo/app/controllers/Application.scala


+ 11 - 0
frameworks/Scala/play2-scala/play2-scala-reactivemongo/build.sbt

@@ -0,0 +1,11 @@
+name := "play2-scala-reactivemongo"
+
+version := "1.0-SNAPSHOT"
+
+scalaVersion := "2.11.4"
+
+lazy val root = (project in file(".")).enablePlugins(PlayScala)
+
+libraryDependencies ++= Seq(
+  "org.reactivemongo" %% "play2-reactivemongo" % "0.10.5.0.akka23"
+)

+ 0 - 0
frameworks/Scala/play2-scala/play2-scala-mongodb/conf/application.conf → frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/application.conf


+ 0 - 0
frameworks/Scala/play2-scala/play2-scala-mongodb/conf/play.plugins → frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/play.plugins


+ 1 - 2
frameworks/Scala/play2-scala/play2-scala-mongodb/conf/routes → frameworks/Scala/play2-scala/play2-scala-reactivemongo/conf/routes

@@ -2,8 +2,7 @@
 # This file defines all application routes (Higher priority routes first)
 # This file defines all application routes (Higher priority routes first)
 # ~~~~
 # ~~~~
 
 
-# Home page
-GET     /db                             controllers.Application.singledb()
+GET     /db                             controllers.Application.singledb
 GET     /queries                        controllers.Application.dbqueries(queries: String ?= "1")
 GET     /queries                        controllers.Application.dbqueries(queries: String ?= "1")
 
 
 # Map static resources from the /public folder to the /assets URL path
 # Map static resources from the /public folder to the /assets URL path

+ 1 - 0
frameworks/Scala/play2-scala/play2-scala-reactivemongo/project/build.properties

@@ -0,0 +1 @@
+sbt.version=0.13.5

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-mongodb/project/plugins.sbt → frameworks/Scala/play2-scala/play2-scala-reactivemongo/project/plugins.sbt

@@ -5,4 +5,4 @@ logLevel := Level.Warn
 resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
 resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
 
 
 // Use the Play sbt plugin for Play projects
 // Use the Play sbt plugin for Play projects
-addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.6")

+ 3 - 0
frameworks/Scala/play2-scala/play2-scala-reactivemongo/source_code

@@ -0,0 +1,3 @@
+./play2-scala-reactivemongo/app/
+./play2-scala-reactivemongo/app/controllers
+./play2-scala-reactivemongo/app/controllers/Application.scala

+ 1 - 1
frameworks/Scala/play2-scala/play2-scala-slick/app/controllers/Application.scala

@@ -44,7 +44,7 @@ object Application extends Controller {
     }
     }
   }
   }
 
 
-  // Common code between Anorm and Slick
+  // Common code between Scala database code
 
 
   protected val TestDatabaseRows = 10000
   protected val TestDatabaseRows = 10000
 
 

+ 0 - 18
frameworks/Scala/play2-scala/play2-scala/README.md

@@ -1,18 +0,0 @@
-#Play Benchmarking Test
-
-This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
-
-### JSON Encoding Test
-
-* [JSON test source](app/controllers/Application.scala)
-
-## Infrastructure Software Versions
-The tests were run with:
-
-* [Java OpenJDK 1.7.0_09](http://openjdk.java.net/)
-* [Play 2](http://http://www.playframework.com/)
-
-## Test URLs
-### JSON Encoding Test
-
-http://localhost/json

+ 4 - 4
frameworks/Scala/play2-scala/setup_scala_mongodb.sh → frameworks/Scala/play2-scala/setup_scala_activate.sh

@@ -1,16 +1,16 @@
 #!/bin/bash
 #!/bin/bash
 
 
-cd play2-scala-mongodb
+cd play2-scala-activate
 sed -i 's|jdbc:mysql://.*:3306|jdbc:mysql://'"${DBHOST}"':3306|g' conf/application.conf
 sed -i 's|jdbc:mysql://.*:3306|jdbc:mysql://'"${DBHOST}"':3306|g' conf/application.conf
 
 
 # If application has an already existing process id, clear it.
 # If application has an already existing process id, clear it.
-if [ -f ${TROOT}/play2-scala-mongodb/target/universal/stage/RUNNING_PID ]
+if [ -f ${TROOT}/play2-scala-activate/target/universal/stage/RUNNING_PID ]
 then
 then
-  rm -f -r ${TROOT}/play2-scala-mongodb/target/universal/stage/RUNNING_PID
+  rm -f -r ${TROOT}/play2-scala-activate/target/universal/stage/RUNNING_PID
 fi
 fi
 
 
 # Stage application.
 # Stage application.
 ${IROOT}/sbt/bin/sbt stage
 ${IROOT}/sbt/bin/sbt stage
 
 
 # Execute Start script in background.
 # Execute Start script in background.
-${TROOT}/play2-scala-mongodb/target/universal/stage/bin/play2-scala-mongodb &
+${TROOT}/play2-scala-activate/target/universal/stage/bin/play2-scala-activate &

+ 16 - 0
frameworks/Scala/play2-scala/setup_scala_reactivemongo.sh

@@ -0,0 +1,16 @@
+#!/bin/bash
+
+cd play2-scala-reactivemongo
+sed -i 's|jdbc:mysql://.*:3306|jdbc:mysql://'"${DBHOST}"':3306|g' conf/application.conf
+
+# If application has an already existing process id, clear it.
+if [ -f ${TROOT}/play2-scala-reactivemongo/target/universal/stage/RUNNING_PID ]
+then
+  rm -f -r ${TROOT}/play2-scala-reactivemongo/target/universal/stage/RUNNING_PID
+fi
+
+# Stage application.
+${IROOT}/sbt/bin/sbt stage
+
+# Execute Start script in background.
+${TROOT}/play2-scala-reactivemongo/target/universal/stage/bin/play2-scala-reactivemongo &

+ 6 - 0
frameworks/Ur/urweb/cloc_defs.txt

@@ -0,0 +1,6 @@
+Ur/Web
+    filter call_regexp_common Pascal
+    extension ur
+    extension urs
+    end_of_line_continuation \\$
+    3rd_gen_scale 3.00

+ 11 - 1
toolset/benchmark/benchmarker.py

@@ -383,8 +383,10 @@ class Benchmarker:
       sudo sysctl -w kernel.shmmax=2147483648
       sudo sysctl -w kernel.shmmax=2147483648
       sudo sysctl -w kernel.shmall=2097152
       sudo sysctl -w kernel.shmall=2097152
       sudo sysctl -w kernel.sem="250 32000 256 512"
       sudo sysctl -w kernel.sem="250 32000 256 512"
-      echo "Printing kernel configuration:" && sudo sysctl -a
     """)
     """)
+    # TODO - print kernel configuration to file
+    # echo "Printing kernel configuration:" && sudo sysctl -a
+
         # Explanations:
         # Explanations:
         # net.ipv4.tcp_max_syn_backlog, net.core.somaxconn, kernel.sched_autogroup_enabled: http://tweaked.io/guide/kernel/
         # net.ipv4.tcp_max_syn_backlog, net.core.somaxconn, kernel.sched_autogroup_enabled: http://tweaked.io/guide/kernel/
         # ulimit -n: http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/
         # ulimit -n: http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/
@@ -692,6 +694,9 @@ class Benchmarker:
   # End __stop_test
   # End __stop_test
   ############################################################
   ############################################################
 
 
+  def is_port_bound(self, port):
+    return self.__is_port_bound(port)
+
   ############################################################
   ############################################################
   # __is_port_bound
   # __is_port_bound
   # Check if the requested port is available. If it
   # Check if the requested port is available. If it
@@ -773,6 +778,11 @@ class Benchmarker:
       
       
       try:
       try:
         command = "cloc --list-file=%s/source_code --yaml" % testlist[0].directory
         command = "cloc --list-file=%s/source_code --yaml" % testlist[0].directory
+
+        if os.path.exists(os.path.join(testlist[0].directory, "cloc_defs.txt")):
+          command += " --read-lang-def %s" % os.path.join(testlist[0].directory, "cloc_defs.txt")
+          logging.info("Using custom cloc definitions for %s", framework)
+
         # Find the last instance of the word 'code' in the yaml output. This should
         # Find the last instance of the word 'code' in the yaml output. This should
         # be the line count for the sum of all listed files or just the line count
         # be the line count for the sum of all listed files or just the line count
         # for the last file in the case where there's only one file listed.
         # for the last file in the case where there's only one file listed.

+ 158 - 81
toolset/benchmark/framework_test.py

@@ -21,6 +21,9 @@ from threading import Event
 
 
 from utils import header
 from utils import header
 
 
+from datetime import datetime
+from datetime import timedelta
+
 class FrameworkTest:
 class FrameworkTest:
   headers_template = "-H 'Host: localhost' -H '{accept}' -H 'Connection: keep-alive'"
   headers_template = "-H 'Host: localhost' -H '{accept}' -H 'Connection: keep-alive'"
  
  
@@ -161,94 +164,168 @@ class FrameworkTest:
   # Start the test using it's setup file
   # Start the test using it's setup file
   ############################################################
   ############################################################
   def start(self, out, err):
   def start(self, out, err):
-    # Load profile for this installation
-    profile="$FWROOT/config/benchmark_profile"
-
-    # Setup variables for TROOT and IROOT
-    setup_util.replace_environ(config=profile, 
-              command='export TROOT=%s && export IROOT=%s && export DBHOST=%s && export MAX_THREADS=%s && export OUT=%s && export ERR=%s' %
-              (self.directory, self.install_root, self.database_host, self.benchmarker.threads, os.path.join(self.fwroot, out.name), os.path.join(self.fwroot, err.name)))
-
-    # Because start can take so long, we print a dot to let the user know 
-    # we are working
-    class ProgressPrinterThread(Thread):
-      def __init__(self, event):
-          Thread.__init__(self)
-          self.stopped = event
-
-      def run(self):
-        while not self.stopped.wait(20):
-          sys.stderr.write("Waiting for start to return...\n")
-    stopFlag = Event()
-    thread = ProgressPrinterThread(stopFlag)
-    thread.start()
-
-    # Run the module start (inside parent of TROOT)
-    #     - we use the parent as a historical accident - a lot of tests
-    #       use subprocess's cwd argument already
+
+    # Setup environment variables
+    setup_util.replace_environ(config='$FWROOT/config/benchmark_profile', 
+              command='''\
+              export TROOT=%s       && \
+              export IROOT=%s       && \
+              export DBHOST=%s      && \
+              export MAX_THREADS=%s    \
+              ''' % (
+                self.directory, 
+                self.install_root, 
+                self.database_host, 
+                self.benchmarker.threads))
+
+    # Run the module start inside parent of TROOT
+    #  - we use the parent as a historical accident, a number of tests
+    # refer to their TROOT maually still
     previousDir = os.getcwd()
     previousDir = os.getcwd()
     os.chdir(os.path.dirname(self.troot))
     os.chdir(os.path.dirname(self.troot))
     logging.info("Running setup module start (cwd=%s)", self.directory)
     logging.info("Running setup module start (cwd=%s)", self.directory)
       
       
-    # Write the stderr to our temp.txt file to be read and fed back
-    # to the user via logging later.
-    with open('temp', 'w') as errout:
-      # Run the start script for the test as the "testrunner" user.
-      # This requires superuser privs, so `sudo` is necessary.
-      #   -u [username] The username
-      #   -E Preserves the current environment variables
-      #   -H Forces the home var (~) to be reset to the user specified
-      #   -e Force bash to exit on first error
-      # Note: check_call is a blocking call, so any startup scripts
-      # run by the framework that need to continue (read: server has
-      # started and needs to remain that way), then they should be
-      # executed in the background.
-      command = 'sudo -u %s -E -H bash -e %s.sh' % (self.benchmarker.runner_user, self.setup_file)
-      
-      debug_command = '''\
-        export FWROOT=%s && \\
-        export TROOT=%s && \\
-        export IROOT=%s && \\
-        export DBHOST=%s && \\
-        export MAX_THREADS=%s && \\
-        export OUT=%s && \\
-        export ERR=%s && \\
-        cd %s && \\
-        %s''' % (self.fwroot, 
-          self.directory, 
-          self.install_root, 
-          self.database_host, 
-          self.benchmarker.threads, 
-          os.path.join(self.fwroot, out.name), 
-          os.path.join(self.fwroot, err.name),
-          self.directory,
-          command)
-      logging.info("To run framework manually, copy/paste this:\n%s", debug_command)
+    # Run the start script for the test as the "testrunner" user
+    # 
+    # `sudo` - Switching user requires superuser privs
+    #   -u [username] The username
+    #   -E Preserves the current environment variables
+    #   -H Forces the home var (~) to be reset to the user specified
+    # `stdbuf` - Disable buffering, send output to python ASAP
+    #   -o0 zero-sized buffer for stdout
+    #   -e0 zero-sized buffer for stderr
+    # `bash` - Run the setup.sh script using bash
+    #   -e Force bash to exit on first error
+    #   -x Turn on bash tracing e.g. print commands before running
+    #
+    # Most servers do not output to stdout/stderr while serving 
+    # requests so there is no performance hit from disabling 
+    # output buffering. This disabling is necessary to 
+    # a) allow TFB to show output in real time and b) avoid loosing 
+    # output in the buffer when the testrunner processes are forcibly 
+    # killed
+    # 
+    # See http://www.pixelbeat.org/programming/stdio_buffering/
+    # See https://blogs.gnome.org/markmc/2013/06/04/async-io-and-python/
+    # See http://eyalarubas.com/python-subproc-nonblock.html
+    command = 'sudo -u %s -E -H stdbuf -o0 -e0 bash -ex %s.sh' % (self.benchmarker.runner_user, self.setup_file)
+    
+    debug_command = '''\
+      export FWROOT=%s && \\
+      export TROOT=%s && \\
+      export IROOT=%s && \\
+      export DBHOST=%s && \\
+      export MAX_THREADS=%s && \\
+      cd %s && \\
+      %s''' % (self.fwroot, 
+        self.directory, 
+        self.install_root, 
+        self.database_host, 
+        self.benchmarker.threads, 
+        self.directory,
+        command)
+    logging.info("To run %s manually, copy/paste this:\n%s", self.name, debug_command)
+
+
+    def tee_output(prefix, line):
+      # Needs to be one atomic write
+      # Explicitly use UTF-8 as it's the most common framework output 
+      # TODO improve encoding handling 
+      line = prefix.encode('utf-8') + line
+
+      # Log to current terminal
+      sys.stdout.write(line)
+      sys.stdout.flush()
+      # logging.error("".join([prefix, line]))
+
+      out.write(line)
+      out.flush()
 
 
-      try:
-        subprocess.check_call(command, cwd=self.directory, 
-          shell=True, stderr=errout, stdout=out)
-        retcode = 0
-      except Exception:
-        logging.exception("Failure running setup.sh")
-        retcode = 1
-    with open('temp', 'r') as errout:
-      # Read out temp error output in its entirety
-      body = errout.read()
-      if len(body) > 0:
-        # Log it to the user.
-        logging.error(body)
-        # Log it to our err.txt file
-        err.write(body)
-    # We are done with our temp file - delete it
-    os.remove('temp')
+    # Start the setup.sh command
+    p = subprocess.Popen(command, cwd=self.directory, 
+          shell=True, stdout=subprocess.PIPE, 
+          stderr=subprocess.STDOUT)
+    nbsr = setup_util.NonBlockingStreamReader(p.stdout, 
+      "%s: %s.sh and framework processes have terminated" % (self.name, self.setup_file))
+
+    # Setup a timeout
+    timeout = datetime.now() + timedelta(minutes = 20)
+    time_remaining = timeout - datetime.now()
+
+    # Flush output until setup.sh work is finished. This is 
+    # either a) when setup.sh exits b) when the port is bound
+    # c) when we run out of time. Note that 'finished' doesn't 
+    # guarantee setup.sh process is dead - the OS may choose to make 
+    # setup.sh a zombie process if it still has living children
+    #
+    # Note: child processes forked (using &) will remain alive 
+    # after setup.sh has exited. The will have inherited the 
+    # stdout/stderr descriptors and will be directing their 
+    # output to the pipes. 
+    #
+    prefix = "Setup %s: " % self.name
+    while not (p.poll() 
+      or self.benchmarker.is_port_bound(self.port)
+      or time_remaining.total_seconds() < 0):
+      
+      # The conditions above are slow to check, so 
+      # we will delay output substantially if we only
+      # print one line per condition check. 
+      # Adding a tight loop here mitigates the effect, 
+      # ensuring that most of the output directly from 
+      # setup.sh is sent to tee_output before the outer
+      # loop exits and prints things like "setup.sh exited"
+      # 
+      for i in xrange(10):
+        try:
+          line = nbsr.readline(0.05)
+          if line:
+            tee_output(prefix, line)
+        except setup_util.EndOfStream:
+          tee_output(prefix, "Setup has terminated\n")
+          break
+      time_remaining = timeout - datetime.now()
+
+    # Did we time out?
+    if time_remaining.total_seconds() < 0: 
+      tee_output(prefix, "%s.sh timed out!! Aborting...\n" % self.setup_file)
+      p.kill()
+      return 1
+
+    # What's our return code? 
+    # If setup.sh has terminated, use that code
+    # Otherwise, detect if the port was bound
+    retcode = (p.poll() or 0 if self.benchmarker.is_port_bound(self.port) else 1)
+    if p.poll():
+      tee_output(prefix, "%s.sh process exited with %s\n" % (self.setup_file, p.poll()))
+    elif self.benchmarker.is_port_bound(self.port):
+      tee_output(prefix, "%s.sh exited due to bound port\n" % self.setup_file)
+
+    # Before we return control to the benchmarker, spin up a 
+    # thread to keep an eye on the pipes in case the running 
+    # framework uses stdout/stderr. Once all processes accessing
+    # the subprocess.PIPEs are dead, this thread will terminate. 
+    # Use a different prefix to indicate this is the framework 
+    # speaking
+    prefix = "Server %s: " % self.name
+    def watch_child_pipes(nbsr, prefix):
+      while True:
+        try:
+          line = nbsr.readline(60)
+          if line:
+            tee_output(prefix, line)
+        except setup_util.EndOfStream:
+          tee_output(prefix, "Framework processes have terminated\n")
+          return
+
+    watch_thread = Thread(target = watch_child_pipes,
+      args = (nbsr, prefix))
+    watch_thread.daemon = True
+    watch_thread.start()
+
+    logging.info("Executed %s.sh, returning %s", self.setup_file, retcode)
     os.chdir(previousDir)
     os.chdir(previousDir)
 
 
-    # Stop the progress printer
-    stopFlag.set()
-
-    logging.info("Executed %s.sh", self.setup_file)
-
     return retcode
     return retcode
   ############################################################
   ############################################################
   # End start
   # End start

+ 2 - 2
toolset/benchmark/test_types/json_type.py

@@ -45,8 +45,8 @@ class JsonTestType(FrameworkTestType):
       return [('fail',"Expected message of 'hello, world!', got '%s'"%response['message'], url)]
       return [('fail',"Expected message of 'hello, world!', got '%s'"%response['message'], url)]
 
 
     # Ensure required response headers are present
     # Ensure required response headers are present
-    if any(v.lower() not in full_response for v in ('Server','Date','Content-Type: application/json')) \
-       or all(v.lower() not in full_response for v in ('Content-Length','Transfer-Encoding')):
+    if any(v.lower() not in full_response.lower() for v in ('Server','Date','Content-Type: application/json')) \
+       or all(v.lower() not in full_response.lower() for v in ('Content-Length','Transfer-Encoding')):
       return [('warn','Required response header missing.',url)]
       return [('warn','Required response header missing.',url)]
 
 
     return [('pass','',url)]
     return [('pass','',url)]

+ 1 - 69
toolset/run-ci.py

@@ -526,75 +526,7 @@ if __name__ == "__main__":
     log.critical("Unknown error")
     log.critical("Unknown error")
     print traceback.format_exc()
     print traceback.format_exc()
     retcode = 1
     retcode = 1
-  finally:  # Ensure that logs are printed
-    
-    # Only print logs if we ran a verify
-    if mode != 'verify':
-      sys.exit(retcode)
-
-    # Only print logs if we actually did something
-    if os.path.isfile('.run-ci.should_not_run'):
-      sys.exit(retcode)
-
-    log.error("Running inside Travis-CI, so I will print err and out to console...")
-    
-    for name in runner.names:
-      log.error("Test %s", name)
-      try:
-        log.error("Here is ERR:")
-        with open("results/ec2/latest/logs/%s/err.txt" % name, 'r') as err:
-          for line in err:
-            log.info(line.rstrip('\n'))
-      except IOError:
-        log.error("No ERR file found")
-
-      try:
-        log.error("Here is OUT:")
-        with open("results/ec2/latest/logs/%s/out.txt" % name, 'r') as out:
-          for line in out:
-            log.info(line.rstrip('\n'))
-      except IOError:
-        log.error("No OUT file found")
-
-    log.error("Running inside Travis-CI, so I will print a copy of the verification summary")
-
-    results = None
-    try:
-      with open('results/ec2/latest/results.json', 'r') as f:
-        results = json.load(f)
-    except IOError:
-      log.critical("No results.json found, unable to print verification summary") 
-      sys.exit(retcode)
-
-    target_dir = setup_util.get_fwroot() + '/frameworks/' + testdir
-    dirtests = [t for t in gather_tests() if t.directory == target_dir]
-
-    # Normally you don't have to use Fore.* before each line, but 
-    # Travis-CI seems to reset color codes on newline (see travis-ci/travis-ci#2692)
-    # or stream flush, so we have to ensure that the color code is printed repeatedly
-    prefix = Fore.CYAN
-    for line in header("Verification Summary", top='=', bottom='').split('\n'):
-      print prefix + line
-
-    for test in dirtests:
-      print prefix + "| Test: %s" % test.name
-      if test.name not in runner.names:
-        print prefix + "|      " + Fore.YELLOW + "Unable to verify in Travis-CI"
-      elif test.name in results['verify'].keys():
-        for test_type, result in results['verify'][test.name].iteritems():
-          if result.upper() == "PASS":
-            color = Fore.GREEN
-          elif result.upper() == "WARN":
-            color = Fore.YELLOW
-          else:
-            color = Fore.RED
-          print prefix + "|       " + test_type.ljust(11) + ' : ' + color + result.upper()
-      else:
-        print prefix + "|      " + Fore.RED + "NO RESULTS (Did framework launch?)"
-    print prefix + header('', top='', bottom='=') + Style.RESET_ALL
-
-
+  finally:
     sys.exit(retcode)
     sys.exit(retcode)
 
 
-
 # vim: set sw=2 ts=2 expandtab
 # vim: set sw=2 ts=2 expandtab

+ 34 - 44
toolset/setup/linux/installer.py

@@ -107,22 +107,38 @@ class Installer:
       previousDir = os.getcwd()
       previousDir = os.getcwd()
       os.chdir(test_dir)
       os.chdir(test_dir)
 
 
-      # Load benchmark_profile file
-      profile="$FWROOT/config/benchmark_profile"
-      setup_util.replace_environ(config=profile, 
+      # Load environment
+      setup_util.replace_environ(config='$FWROOT/config/benchmark_profile', 
         command='export TROOT=%s && export IROOT=%s' %
         command='export TROOT=%s && export IROOT=%s' %
         (test_dir, test_install_dir))
         (test_dir, test_install_dir))
 
 
-      # Run test installation script
-      #   FWROOT - Path of the FwBm root
-      #   IROOT  - Path of this test's install directory
+      # Run the install.sh script for the test as the "testrunner" user
+      # 
+      # `sudo` - Switching user requires superuser privs
+      #   -u [username] The username
+      #   -E Preserves the current environment variables
+      #   -H Forces the home var (~) to be reset to the user specified
       #   TROOT  - Path to this test's directory 
       #   TROOT  - Path to this test's directory 
-      # Note: Cannot use ''' for newlines here or the script
-      # passed to `bash -c` will fail.
-      self.__run_command('sudo -u %s -E -H bash -c "export TROOT=%s && export IROOT=%s && source %s && source %s"' % 
-        (self.benchmarker.runner_user, test_dir, test_install_dir, 
-          bash_functions_path, test_install_file),
-          cwd=test_install_dir)
+      #   IROOT  - Path of this test's install directory
+      # TODO export bash functions and call install.sh directly
+      command = 'sudo -u %s -E -H bash -c "source %s && source %s"' % (
+        self.benchmarker.runner_user, 
+        bash_functions_path, 
+        test_install_file)
+
+      debug_command = '''\
+        export FWROOT=%s && \\
+        export TROOT=%s && \\
+        export IROOT=%s && \\
+        cd $IROOT && \\
+        %s''' % (self.fwroot, 
+          test_dir, 
+          test_install_dir,
+          command)
+      logging.info("To run installation manually, copy/paste this:\n%s", debug_command)
+
+      # Run test installation script
+      self.__run_command(command, cwd=test_install_dir)
 
 
       # Move back to previous directory
       # Move back to previous directory
       os.chdir(previousDir)
       os.chdir(previousDir)
@@ -148,47 +164,21 @@ class Installer:
   ############################################################
   ############################################################
   # __run_command
   # __run_command
   ############################################################
   ############################################################
-  def __run_command(self, command, send_yes=False, cwd=None, retry=False):
+  def __run_command(self, command, send_yes=False, cwd=None):
     if cwd is None: 
     if cwd is None: 
         cwd = self.install_dir
         cwd = self.install_dir
 
 
-    if retry:
-      max_attempts = 5
-    else:
-      max_attempts = 1
-    attempt = 1
-    delay = 0
     if send_yes:
     if send_yes:
       command = "yes yes | " + command
       command = "yes yes | " + command
         
         
     rel_cwd = setup_util.path_relative_to_root(cwd)
     rel_cwd = setup_util.path_relative_to_root(cwd)
     print("INSTALL: %s (cwd=$FWROOT/%s)" % (command, rel_cwd))
     print("INSTALL: %s (cwd=$FWROOT/%s)" % (command, rel_cwd))
 
 
-    while attempt <= max_attempts:
-      error_message = ""
-      try:
-
-        # Execute command.
-        subprocess.check_call(command, shell=True, cwd=cwd, executable='/bin/bash')
-        break  # Exit loop if successful.
-      except:
-        exceptionType, exceptionValue, exceptionTraceBack = sys.exc_info()
-        error_message = "".join(traceback.format_exception_only(exceptionType, exceptionValue))
-
-      # Exit if there are no more attempts left.
-      attempt += 1
-      if attempt > max_attempts:
-        break
-
-      # Delay before next attempt.
-      if delay == 0:
-        delay = 5
-      else:
-        delay = delay * 2
-      print("Attempt %s/%s starting in %s seconds." % (attempt, max_attempts, delay))
-      time.sleep(delay)
-
-    if error_message:
+    try:
+      subprocess.check_call(command, shell=True, cwd=cwd, executable='/bin/bash')
+    except:
+      exceptionType, exceptionValue, exceptionTraceBack = sys.exc_info()
+      error_message = "".join(traceback.format_exception_only(exceptionType, exceptionValue))
       self.__install_error(error_message)
       self.__install_error(error_message)
   ############################################################
   ############################################################
   # End __run_command
   # End __run_command

+ 55 - 1
toolset/setup/linux/setup_util.py

@@ -1,8 +1,62 @@
 import re
 import re
 import os
 import os
+import sys
 import subprocess
 import subprocess
 import platform
 import platform
 
 
+from threading import Thread
+from Queue import Queue, Empty
+
+class NonBlockingStreamReader:
+  '''
+  Enables calling readline in a non-blocking manner with a blocking stream, 
+  such as the ones returned from subprocess.Popen
+
+  Originally written by Eyal Arubas, who granted permission to use this inside TFB
+  See http://eyalarubas.com/python-subproc-nonblock.html
+  '''
+  def __init__(self, stream, eof_message = None):
+    '''
+    stream: the stream to read from.
+            Usually a process' stdout or stderr.
+    eof_message: A message to print to stdout as soon
+      as the stream's end is reached. Useful if you
+      want to track the exact moment a stream terminates
+    '''
+
+    self._s = stream
+    self._q = Queue()
+    self._eof_message = eof_message
+    self._poisonpill = 'MAGIC_POISONPILL_STRING'
+
+    def _populateQueue(stream, queue):
+      while True:
+        line = stream.readline()
+        if line: # 'data\n' or '\n'
+          queue.put(line)
+        else:    # '' e.g. EOF
+          if self._eof_message:
+            sys.stdout.write(self._eof_message + '\n')
+          queue.put(self._poisonpill)
+          return
+
+    self._t = Thread(target = _populateQueue,
+            args = (self._s, self._q))
+    self._t.daemon = True
+    self._t.start()
+
+  def readline(self, timeout = None):
+    try:
+      line = self._q.get(block = timeout is not None,
+        timeout = timeout)
+      if line == self._poisonpill: 
+        raise EndOfStream
+      return line
+    except Empty:
+      return None
+
+class EndOfStream(Exception): pass
+
 # Replaces all text found using the regular expression to_replace with the supplied replacement.
 # Replaces all text found using the regular expression to_replace with the supplied replacement.
 def replace_text(file, to_replace, replacement):
 def replace_text(file, to_replace, replacement):
     with open(file, "r") as conf:
     with open(file, "r") as conf:
@@ -29,7 +83,7 @@ def replace_environ(config=None, root=None, print_result=False, command='true'):
     
     
         # Clean up our current environment, preserving some important items
         # Clean up our current environment, preserving some important items
         mini_environ = {}
         mini_environ = {}
-        for envname in ['HOME', 'PATH', 'USER', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'FWROOT', 'TRAVIS']:
+        for envname in ['HOME', 'PATH', 'LANG', 'USER', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'FWROOT', 'TRAVIS']:
           if envname in os.environ:
           if envname in os.environ:
             mini_environ[envname] = os.environ[envname]
             mini_environ[envname] = os.environ[envname]
         for key in os.environ:
         for key in os.environ:

+ 0 - 13
toolset/setup/linux/webservers/weber.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-
-#echo "WARN: Weber is not working"
-#return 1
-fw_exists weber
-[ $? -ne 0 ] || { return 0; }
-
-git clone https://github.com/elixir-web/weber.git
-
-# To get the two make commands working, we need to hard code the path for elixir's "mix"
-cd weber
-make
-bash -i -c 'sudo make test'