From cb50c0e88c9573ca21d63f49753c540c9f783bbb Mon Sep 17 00:00:00 2001
From: Lloyd Hilaiel <lloyd@hilaiel.com>
Date: Tue, 15 Nov 2011 15:30:44 -0700
Subject: [PATCH] repairing load_gen - issue #504 - update pathing, alter
 fake_verification WSAPI to query the database rather than to use email
 interception (which no longer works)

---
 bin/browserid                      |  2 +-
 bin/load_gen                       | 10 ++++++----
 lib/browserid/fake_verification.js | 27 +++++++++------------------
 lib/db.js                          |  1 +
 lib/db/json.js                     |  9 ++++++++-
 lib/db/mysql.js                    | 11 +++++++++++
 lib/load_gen/include_only.js       |  2 +-
 lib/load_gen/signup.js             |  2 +-
 lib/load_gen/user_db.js            |  2 +-
 lib/wsapi.js                       |  8 +++++++-
 package.json                       |  2 +-
 tests/db-test.js                   |  8 ++++++++
 12 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/bin/browserid b/bin/browserid
index 55aa2a8ba..0e6150977 100755
--- a/bin/browserid
+++ b/bin/browserid
@@ -172,7 +172,7 @@ shutdown.installUpdateHandler(app, function(readyForShutdown) {
 // fake_verification.js.  This is used during testing only and should
 // never be included in a production deployment
 if (process.env['BROWSERID_FAKE_VERIFICATION']) {
-  require('../lib/fake_verification.js').addVerificationWSAPI(app);
+  require('../lib/browserid/fake_verification.js').addVerificationWSAPI(app);
 }
 
 // open the databse
diff --git a/bin/load_gen b/bin/load_gen
index b3cd137a9..26032661e 100755
--- a/bin/load_gen
+++ b/bin/load_gen
@@ -92,6 +92,7 @@ const activitiesPerUserPerSecond = (40.0 / ( 24 * 60 * 60 ));
 
 // activities
 var activity = {
+/*
   "signup": {
     // a %20 montly growth rate means there's a 20% probability of
     // the monthly activity generated by an active user being a
@@ -116,6 +117,7 @@ var activity = {
     // 8 times a day (once every six hours per device)
     probability: (8 / 40.0)
   },
+*/
   "include_only": {
     // most of the time, users are already authenticated to their
     // RPs, so the hit on our servers is simply resource (include.js)
@@ -128,7 +130,7 @@ var activity = {
 // now attach "start functions" to the activity map by including
 // the implementation of each activity
 Object.keys(activity).forEach(function(k) {
-  activity[k].startFunc = require("../lib/performance/" + k).startFunc;
+  activity[k].startFunc = require("../lib/load_gen/" + k).startFunc;
 });
 
 // probs is a 2d array mapping normalized probabilities from 0-1 to
@@ -279,7 +281,7 @@ function poll() {
 }
 
 // always start out by creating a bunch of users
-var NUM_INITIAL_USERS = 100;
+var NUM_INITIAL_USERS = 1;
 
 // if an explicit target was specified, let's output what that means
 // in understandable terms
@@ -287,8 +289,8 @@ if (args.m) outputActiveUserSummary(args.m);
 
 console.log("To start, let's create " + NUM_INITIAL_USERS + " users.  A moment please.");
 
-const userdb = require("./lib/user_db.js");
-var createUser = require("./lib/signup.js").startFunc;
+const userdb = require("../lib/load_gen/user_db.js");
+var createUser = require("../lib/load_gen/signup.js").startFunc;
 var created = 0;
 for (var i = 0; i < NUM_INITIAL_USERS; i++) {
   createUser(configuration, function(rv) {
diff --git a/lib/browserid/fake_verification.js b/lib/browserid/fake_verification.js
index 7212ac81e..8c7194d2b 100644
--- a/lib/browserid/fake_verification.js
+++ b/lib/browserid/fake_verification.js
@@ -41,9 +41,9 @@
  */
 
 const
-email = require('../email.js'),
-configuration = require('../../libs/configuration.js'),
-url = require('url');
+configuration = require('../configuration.js'),
+url = require('url'),
+db = require('../db.js');
 
 // a paranoid check of the configuration.  This module should only
 // be included when in a testing environment
@@ -56,23 +56,14 @@ if (!/^test_/.test(c)) {
   console.log("HEAR YE: Fake verfication enabled, aceess via /wsapi/fake_verification?email=foo@bar.com");
 }
 
-// we store outstanding tokens in memory, folks.  
-var tokens = { };
-
-// set up an interceptor
-email.setInterceptor(function(email, site, secret) {
-  tokens[email] = secret;
-});
-
 exports.addVerificationWSAPI = function(app) {
   app.get('/wsapi/fake_verification', function(req, res) {
     var email = url.parse(req.url, true).query['email'];
-    if (tokens.hasOwnProperty(email)) {
-      res.write(tokens[email]);
-      delete tokens[email];
-    } else {
-      res.writeHead(400, {"Content-Type": "text/plain"});
-    }
-    res.end();
+    console.log(email);
+    db.verificationSecretForEmail(email, function(secret) {
+      if (secret) res.write(secret);
+      else res.writeHead(400, {"Content-Type": "text/plain"});
+      res.end();
+    });
   });
 };
diff --git a/lib/db.js b/lib/db.js
index ce154bd02..fa05e1b64 100644
--- a/lib/db.js
+++ b/lib/db.js
@@ -99,6 +99,7 @@ exports.onReady = function(f) {
   'isStaged',
   'emailsBelongToSameAccount',
   'emailForVerificationSecret',
+  'verificationSecretForEmail',
   'checkAuth',
   'listEmails',
   'lastStaged'
diff --git a/lib/db/json.js b/lib/db/json.js
index d4efbf5e9..9b393950e 100644
--- a/lib/db/json.js
+++ b/lib/db/json.js
@@ -208,12 +208,19 @@ exports.stageEmail = function(existing_email, new_email, cb) {
 
 
 exports.emailForVerificationSecret = function(secret, cb) {
-  sync();
   setTimeout(function() {
+    sync();
     cb(db.staged[secret] ? db.staged[secret].email : undefined);
   }, 0);
 };
 
+exports.verificationSecretForEmail = function(email, cb) {
+  setTimeout(function() {
+    sync();
+    cb(db.stagedEmails[email]);
+  }, 0);
+};
+
 exports.gotVerificationSecret = function(secret, hash, cb) {
   sync();
   if (!db.staged.hasOwnProperty(secret)) return cb("unknown secret");
diff --git a/lib/db/mysql.js b/lib/db/mysql.js
index 78749dac6..08295f7f4 100644
--- a/lib/db/mysql.js
+++ b/lib/db/mysql.js
@@ -257,6 +257,17 @@ exports.emailForVerificationSecret = function(secret, cb) {
     });
 };
 
+exports.verificationSecretForEmail = function(email, cb) {
+  console.log("looking for " + email);
+  client.query(
+    "SELECT secret FROM staged WHERE email = ?", [ email ],
+    function(err, rows) {
+      console.log("got", err, rows);
+      if (err) logUnexpectedError(err);
+      cb((rows && rows.length > 0) ? rows[0].secret : undefined);
+    });
+};
+
 exports.gotVerificationSecret = function(secret, hash, cb) {
   client.query(
     "SELECT * FROM staged WHERE secret = ?", [ secret ],
diff --git a/lib/load_gen/include_only.js b/lib/load_gen/include_only.js
index 5c6e287c2..a0916ccde 100644
--- a/lib/load_gen/include_only.js
+++ b/lib/load_gen/include_only.js
@@ -41,7 +41,7 @@ var
 http = require('http'),
 https = require('https'),
 url = require('url'),
-client = require('../../libs/wsapi_client.js');
+client = require('../../lib/wsapi_client.js');
 
 exports.startFunc = function(cfg, cb) {
   client.get(cfg, '/include.js', {}, undefined, function(r) {
diff --git a/lib/load_gen/signup.js b/lib/load_gen/signup.js
index 557ab151e..12af0e90b 100644
--- a/lib/load_gen/signup.js
+++ b/lib/load_gen/signup.js
@@ -35,7 +35,7 @@
  * ***** END LICENSE BLOCK ***** */
 
 const
-wcli = require("../../libs/wsapi_client.js"),
+wcli = require("../wsapi_client.js"),
 userdb = require("./user_db.js"),
 winston = require('winston');
 
diff --git a/lib/load_gen/user_db.js b/lib/load_gen/user_db.js
index 58867012b..166498355 100644
--- a/lib/load_gen/user_db.js
+++ b/lib/load_gen/user_db.js
@@ -38,7 +38,7 @@
  * purposes of performance testing. 
  */
 
-var secrets = require('../../libs/secrets.js');
+var secrets = require('../secrets.js');
 
 // the grandiose database
 var users = [ ];
diff --git a/lib/wsapi.js b/lib/wsapi.js
index 32d82b6db..e62cf505d 100644
--- a/lib/wsapi.js
+++ b/lib/wsapi.js
@@ -136,7 +136,10 @@ exports.setup = function(options, app) {
       if (!wsapis.hasOwnProperty(operation) ||
           wsapis[operation].method.toLowerCase() !== req.method.toLowerCase())
       {
-        return httputils.badRequest(resp, "no such api");
+        // if the fake verification api is enabled (for load testing),
+        // then let this request fall through
+        if (operation !== 'fake_verification' || !process.env['BROWSERID_FAKE_VERIFICATION']) 
+          return httputils.badRequest(resp, "no such api");
       }
 
       // if this request is to be forwarded, we will not perform request validation,
@@ -278,6 +281,9 @@ exports.setup = function(options, app) {
     if (purl.pathname.substr(0, WSAPI_PREFIX.length) === WSAPI_PREFIX) {
       const operation = purl.pathname.substr(WSAPI_PREFIX.length);
 
+      // the fake_verification wsapi is implemented elsewhere.
+      if (operation == 'fake_verification') return next();
+
       // at this point, we *know* 'operation' is valid API, give checks performed
       // above
 
diff --git a/package.json b/package.json
index b8d11c6d2..0f4817343 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
     , "winston" : "0.5.6"
     , "connect-cookie-session" : "0.0.2"
     , "mysql" : "0.9.4"
-    , "optimist" : "0.2.6"
+    , "optimist" : "0.2.8"
     , "qs" : "0.3.1"
     , "mime" : "1.2.2"
     , "pkginfo" : "0.2.2"
diff --git a/tests/db-test.js b/tests/db-test.js
index c03b22197..892319b46 100755
--- a/tests/db-test.js
+++ b/tests/db-test.js
@@ -116,6 +116,14 @@ suite.addBatch({
       "matches expected email": function(storedEmail) {
         assert.strictEqual('lloyd@nowhe.re', storedEmail);
       }
+    },
+    "fetch secret for email": {
+      topic: function(secret) {
+        db.verificationSecretForEmail('lloyd@nowhe.re', this.callback);
+      },
+      "matches expected secret": function(storedSecret) {
+        assert.strictEqual(storedSecret, secret);
+      }
     }
   }
 });
-- 
GitLab