Merge "core.js: Documenting the crash event on runtime with @event Also loading fonts from https"
diff --git a/Makefile b/Makefile
index 4640f7c..744a171 100644
--- a/Makefile
+++ b/Makefile
@@ -90,6 +90,8 @@
 # string with no spaces.
 COMMON_SERVICES := "test_serviced"
 
+LOADTEST_SERVICE := "stressd"
+
 all: gen-vdl lint build docs
 
 build: dist docs extension/vanadium.zip
@@ -214,10 +216,29 @@
 	$(MAKE) -C extension build-test
 	prova test/integration/test-*.js --log=./tmp/chrome.log $(PROVA_OPTS) $(BROWSER_OPTS) $(BROWSER_OUTPUT_LOCAL) $(SAVE_CHROME_LOGS)
 
+test-load-node: test-precheck go/bin
+	node test/integration/runner.js --services=$(LOADTEST_SERVICE)  -- \
+	prova test/load/test-*.js $(PROVA_OPTS) $(NODE_OUTPUT_LOCAL)
+
+
+test-load-browser: test-precheck go/bin
+	node test/integration/runner.js --services=$(LOADTEST_SERVICE)  -- \
+	make test-load-browser-runner
+
+test-load-browser-runner: BROWSER_OPTS := --options="--load-extension=$(PWD)/extension/build-test/,--ignore-certificate-errors,--enable-logging=stderr" $(BROWSER_OPTS)
+test-load-browser-runner:
+	@$(RM) -fr extension/build-test
+	$(MAKE) -C extension build-test
+	prova test/load/test-*.js --log=./tmp/chrome.log $(PROVA_OPTS) $(BROWSER_OPTS) $(BROWSER_OUTPUT_LOCAL) $(SAVE_CHROME_LOGS)
+
+
+
+
 go/bin: $(GO_FILES)
 	@$(VGO) build -o $(GOBIN)/servicerunner -a -tags wspr v.io/x/ref/cmd/servicerunner
 	@$(VGO) build -o $(GOBIN)/principal v.io/x/ref/cmd/principal
 	@$(VGO) build -o $(GOBIN)/test_serviced v.io/x/js.core/test_service/test_serviced
+	@$(VGO) build -o $(GOBIN)/stressd v.io/x/ref/profiles/internal/rpc/stress/stressd
 
 lint: node_modules
 ifdef NOLINT
diff --git a/extension/manifest.json b/extension/manifest.json
index 1eedece..24961b9 100644
--- a/extension/manifest.json
+++ b/extension/manifest.json
@@ -1,6 +1,6 @@
 {
   "name": "Vanadium Extension",
-  "version": "0.1.3",
+  "version": "0.1.4",
   "description": "Access and create Vanadium services from JavaScript.",
   "manifest_version": 2,
   "icons": {
diff --git a/src/proxy/index.js b/src/proxy/index.js
index 1f6d18c..6e0b705 100644
--- a/src/proxy/index.js
+++ b/src/proxy/index.js
@@ -18,6 +18,9 @@
 var byteUtil = require('../vdl/byte-util');
 var vom = require('../vom');
 var unwrap = require('../vdl/type-util').unwrap;
+var Encoder = require('../vom/encoder');
+var Decoder = require('../vom/decoder');
+
 
 // Cache the service signatures for one hour.
 var SIGNATURE_CACHE_TTL = 3600 * 1000;
@@ -41,6 +44,8 @@
   });
   this.senderPromise = senderPromise;
   this.incomingRequestHandlers = {};
+  this.clientEncoder = new Encoder();
+  this.clientDecoder = new Decoder();
   EE.call(this);
 }
 inherits(Proxy, EE);
diff --git a/src/proxy/nacl.js b/src/proxy/nacl.js
index 5d845db..4d9d483 100644
--- a/src/proxy/nacl.js
+++ b/src/proxy/nacl.js
@@ -34,7 +34,7 @@
     try {
       body = vom.decode(byteUtil.hex2Bytes(msg.body));
     } catch (e) {
-      vlog.logger.warn('Failed to parse ' + msg.body);
+      vlog.logger.warn('Failed to parse ' + msg.body + 'err: ' + e);
       return;
     }
 
diff --git a/src/proxy/websocket.js b/src/proxy/websocket.js
index b2d33f9..ef23e59 100644
--- a/src/proxy/websocket.js
+++ b/src/proxy/websocket.js
@@ -88,7 +88,7 @@
     try {
       message = vom.decode(byteUtil.hex2Bytes(frame.data));
     } catch (e) {
-      vlog.logger.warn('Failed to parse ' + frame.data);
+      vlog.logger.warn('Failed to parse ' + frame.data + ' err: ' + e);
       return;
     }
 
diff --git a/src/rpc/client.js b/src/rpc/client.js
index ba291a9..4c5e292 100644
--- a/src/rpc/client.js
+++ b/src/rpc/client.js
@@ -13,14 +13,12 @@
  */
 
 var actions = require('../verror/actions');
-var ByteArrayMessageWriter = require('../vom/byte-array-message-writer');
 var byteUtil = require('../vdl/byte-util');
 var Controller =
   require('../gen-vdl/v.io/x/ref/services/wspr/internal/app').Controller;
 var context = require('../context');
 var Deferred = require('../lib/deferred');
 var emitStreamError = require('../lib/emit-stream-error');
-var Encoder = require('../vom/encoder');
 var Incoming = require('../proxy/message-type').Incoming;
 var makeError = require('../verror/make-errors');
 var Outgoing = require('../proxy/message-type').Outgoing;
@@ -44,7 +42,10 @@
 var Blessings = require('../security/blessings');
 var JsBlessings =
   require('../gen-vdl/v.io/x/ref/services/wspr/internal/principal').JsBlessings;
-
+var ByteStreamMessageReader = require('../vom/byte-stream-message-reader');
+var ByteStreamMessageWriter = require('../vom/byte-stream-message-writer');
+var Encoder = require('../vom/encoder');
+var Decoder = require('../vom/decoder');
 
 var OutstandingRPC = function(ctx, options, cb) {
   this._ctx = ctx;
@@ -61,6 +62,8 @@
   this._outStreamingType = options.outStreamingType;
   this._callOptions = options.callOptions;
   this._cb = cb;
+  this._encoder = options.encoder;
+  this._decoder = options.decoder;
   this._def = null;
 };
 
@@ -211,7 +214,14 @@
 OutstandingRPC.prototype.handleCompletion = function(data) {
   var response;
   try {
-    response = vom.decode(byteUtil.hex2Bytes(data));
+    var bytes = byteUtil.hex2Bytes(data);
+    if (!this._decoder._messageReader) {
+      this._decoder._messageReader = new ByteStreamMessageReader(bytes);
+    } else {
+      this._decoder._messageReader.clear();
+      this._decoder._messageReader.addBytes(bytes);
+    }
+    response = this._decoder.decode();
   } catch (e) {
     this.handleError(
       new verror.InternalError(this._ctx, 'Failed to decode result: ', e));
@@ -296,9 +306,10 @@
   };
 
   var header = new RpcRequest(jsonMessage);
-
-  var writer = new ByteArrayMessageWriter();
-  var encoder = new Encoder(writer);
+  var encoder = this._encoder;
+  if (!encoder._messageWriter) {
+    encoder._messageWriter = new ByteStreamMessageWriter();
+  }
   encoder.encode(header);
   for (var i = 0; i < this._args.length; i++) {
     var o = this._args[i];
@@ -307,7 +318,7 @@
     }
     encoder.encode(o);
   }
-  return byteUtil.bytes2Hex(writer.getBytes());
+  return byteUtil.bytes2Hex(encoder._messageWriter.consumeBytes());
 };
 
 /**
@@ -327,6 +338,18 @@
   }
 
   this._proxyConnection = proxyConnection;
+  if (proxyConnection && proxyConnection.clientEncoder) {
+    this._encoder = proxyConnection.clientEncoder;
+  } else {
+    this._encoder = new Encoder();
+  }
+
+  if (proxyConnection && proxyConnection.clientDecoder) {
+    this._decoder = proxyConnection.clientDecoder;
+  } else {
+    this._decoder = new Decoder();
+  }
+
   this._controller = this.bindWithSignature(
     '__controller', [Controller.prototype._serviceDescription]);
 }
@@ -539,7 +562,9 @@
         isStreaming: isStreaming,
         inStreamingType: inStreaming ? methodSig.inStream.type : null,
         outStreamingType: outStreaming ? methodSig.outStream.type : null,
-        callOptions: callOptions
+        callOptions: callOptions,
+        encoder: client._encoder,
+        decoder: client._decoder,
       }, callback);
 
       return rpc.start();
diff --git a/src/security/caveats.js b/src/security/caveats.js
index df780e0..cfd1822 100644
--- a/src/security/caveats.js
+++ b/src/security/caveats.js
@@ -30,6 +30,13 @@
   });
 }
 
+/**
+ * createConstCaveat returns a [Caveat]{@link module:vanadium.security.Caveat}
+ * that validates iff value is true.
+ * @param {boolean} value
+ * @returns module:vanadium.security.Caveat
+ * @memberof module:vanadium.security
+ */
 function createConstCaveat(value) {
   return createCaveat(vdlSecurity.ConstCaveat, value);
 }
diff --git a/src/security/index.js b/src/security/index.js
index f8645f6..5e2dff6 100644
--- a/src/security/index.js
+++ b/src/security/index.js
@@ -42,6 +42,7 @@
   access: require('./access'),
   createExpiryCaveat: require('./caveats').createExpiryCaveat,
   createMethodCaveat: require('./caveats').createMethodCaveat,
+  createConstCaveat: require('./caveats').createConstCaveat,
   unconstrainedUse: require('./caveats').unconstrainedUse,
   createCaveat: require('./caveats').createCaveat,
   unionOfBlessings: require('./blessings-util').unionOfBlessings
diff --git a/src/vdl/kind.js b/src/vdl/kind.js
index 30d01ff..2277f2b 100644
--- a/src/vdl/kind.js
+++ b/src/vdl/kind.js
@@ -16,97 +16,120 @@
 var kind = {
   // Nullable kinds
   /**
+   * @type {string}
    * @const
    */
   ANY: 'any',
   /**
+   * @type {string}
    * @const
    */
   OPTIONAL: 'optional',
   // Scalar kinds
   /**
+   * @type {string}
    * @const
    */
   BOOL: 'bool',
   /**
+   * @type {string}
    * @const
    */
   BYTE: 'byte',
   /**
+   * @type {string}
    * @const
    */
   UINT16: 'uint16',
   /**
+   * @type {string}
    * @const
    */
   UINT32: 'uint32',
   /**
+   * @type {string}
    * @const
    */
   UINT64: 'uint64',
   /**
+   * @type {string}
    * @const
    */
   INT16: 'int16',
   /**
+   * @type {string}
    * @const
    */
   INT32: 'int32',
   /**
+   * @type {string}
    * @const
    */
   INT64: 'int64',
   /**
+   * @type {string}
    * @const
    */
   FLOAT32: 'float32',
   /**
+   * @type {string}
    * @const
    */
   FLOAT64: 'float64',
   /**
+   * @type {string}
    * @const
    */
   COMPLEX64: 'complex64',
   /**
+   * @type {string}
    * @const
    */
   COMPLEX128: 'complex128',
   /**
+   * @type {string}
    * @const
    */
   STRING: 'string',
   /**
+   * @type {string}
    * @const
    */
   ENUM: 'enum',
   /**
+   * @type {string}
    * @const
    */
   TYPEOBJECT: 'typeobject',
   // Composite kinds
   /**
+   * @type {string}
    * @const
    */
   ARRAY: 'array',
   /**
+   * @type {string}
    * @const
    */
   LIST: 'list',
   /**
+   * @type {string}
    * @const
    */
   SET: 'set',
   /**
+   * @type {string}
    * @const
    */
   MAP: 'map',
   /**
+   * @type {string}
    * @const
    */
   STRUCT: 'struct',
   /**
    * Union is like struct, but with only 1 field filled in.
+   * @type {string}
    * @const
    */
   UNION: 'union',
diff --git a/src/vdl/types.js b/src/vdl/types.js
index 23f216e..25eb07b 100644
--- a/src/vdl/types.js
+++ b/src/vdl/types.js
@@ -21,73 +21,89 @@
  */
 var types = {
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   ANY: primitiveType(kind.ANY),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   BOOL: primitiveType(kind.BOOL),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   BYTE: primitiveType(kind.BYTE),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   UINT16: primitiveType(kind.UINT16),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   UINT32: primitiveType(kind.UINT32),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   UINT64: primitiveType(kind.UINT64),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   INT16: primitiveType(kind.INT16),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   INT32: primitiveType(kind.INT32),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   INT64: primitiveType(kind.INT64),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   FLOAT32: primitiveType(kind.FLOAT32),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   FLOAT64: primitiveType(kind.FLOAT64),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   COMPLEX64: primitiveType(kind.COMPLEX64),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   COMPLEX128: primitiveType(kind.COMPLEX128),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   STRING: primitiveType(kind.STRING),
   /**
+   * @type {module:vanadium.vdl.Type}
    * @const
    */
   TYPEOBJECT: Type.prototype._type // So that === works for types.TypeObject
 };
 /**
- * Defines the wire error format
+ * @type {module:vanadium.vdl.Type}
  * @const
  */
 types.ERROR = defineOptionalErrorType();
 
 /**
+ * @type {module:vanadium.vdl.Type}
  * @const
  */
 types.JSVALUE = defineJSValueType();
diff --git a/src/vom/binary-reader.js b/src/vom/binary-reader.js
index 33d274d..3cf95b1 100644
--- a/src/vom/binary-reader.js
+++ b/src/vom/binary-reader.js
@@ -60,3 +60,7 @@
   }
   return arr;
 };
+
+BinaryReader.prototype.hasData = function() {
+  return this.pos < this.buf.length;
+};
diff --git a/src/vom/byte-array-message-writer.js b/src/vom/byte-array-message-writer.js
index ea815cb..ac8209e 100644
--- a/src/vom/byte-array-message-writer.js
+++ b/src/vom/byte-array-message-writer.js
@@ -64,3 +64,7 @@
 ByteArrayMessageWriter.prototype.getBytes = function() {
   return this.rawWriter.getBytes();
 };
+
+ByteArrayMessageWriter.prototype.reset = function() {
+  this.rawWriter = new RawVomWriter();
+};
diff --git a/src/vom/byte-stream-message-reader.js b/src/vom/byte-stream-message-reader.js
new file mode 100644
index 0000000..5794bbb
--- /dev/null
+++ b/src/vom/byte-stream-message-reader.js
@@ -0,0 +1,74 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/**
+ * @fileoverview Represents a read stream of VOM messages backed by a byte
+ * array.
+ * @private
+ */
+
+module.exports = ByteStreamMessageReader;
+
+var RawVomReader = require('./raw-vom-reader.js');
+var TypeUtil = require('../vdl/type-util.js');
+
+/**
+ * Create a VOM message reader backed by a byte stream.
+ * @param {Uint8Array} bytes The initial byte stream.
+ * @constructor
+ * @memberof module:vanadium.vom
+ */
+function ByteStreamMessageReader(bytes) {
+  this.rawReader = new RawVomReader(bytes);
+  var header = this.rawReader._readRawBytes(1);
+  if (header[0] !== 0x80) {
+    throw new Error('Improperly formatted bytes. Must start with 0x80');
+  }
+}
+
+/**
+ * Get the the type of the next value message.
+ * @private
+ * @param {TypeDecoder} typeDecoder The current type decoder.
+ * @return {Type} The type of the next message or null if the stream has ended.
+ */
+ByteStreamMessageReader.prototype.nextMessageType = function(typeDecoder) {
+  while (true) {
+    var typeId;
+    try {
+      typeId = this.rawReader.readInt();
+    } catch (error) {
+      // Hopefully EOF.
+      // TODO(bprosnitz) Make this a more accurate check.
+      return null;
+    }
+    if (typeId < 0) {
+      // Type message.
+      var len = this.rawReader.readUint();
+      var body = this.rawReader._readRawBytes(len);
+      typeDecoder.defineType(-typeId, body);
+    } else {
+      // Value message.
+      var type = typeDecoder.lookupType(typeId);
+      if (TypeUtil.shouldSendLength(type)) {
+        // length
+        this.rawReader.readUint();
+      }
+      return type;
+    }
+  }
+};
+
+ByteStreamMessageReader.prototype.clear = function() {
+  this.rawReader = null;
+};
+
+ByteStreamMessageReader.prototype.addBytes = function(bytes) {
+  // TODO(bjornick): Implement a real stream reader.
+  if (this.rawReader && this.rawReader.hasData()) {
+    throw new Error('Can\'t addBytes if all the previous bytes ' +
+                    'haven\'t been read');
+  }
+  this.rawReader = new RawVomReader(bytes);
+};
diff --git a/src/vom/byte-stream-message-writer.js b/src/vom/byte-stream-message-writer.js
new file mode 100644
index 0000000..23ff0fb
--- /dev/null
+++ b/src/vom/byte-stream-message-writer.js
@@ -0,0 +1,68 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/**
+ * @fileoverview Represents a write stream of VOM messages backed by a byte
+ * array.
+ * @private
+ */
+
+module.exports = ByteStreamMessageWriter;
+
+var RawVomWriter = require('./raw-vom-writer.js');
+
+/**
+ * Create a VOM message writer that writes to a byte array.
+ * @constructor
+ * @memberof module:vanadium.vom
+ */
+function ByteStreamMessageWriter() {
+  this.rawWriter = new RawVomWriter();
+  this.rawWriter._writeRawBytes(new Uint8Array([0x80]));
+}
+
+/**
+ * Write a value message.
+ * @private
+ * @param {number} typeId The type ID of the message.
+ * @param {boolean} sendLength true if the message length should be sent in the
+ * header, false otherwise.
+ * @param {Uint8Array} message The body of the message.
+ */
+ByteStreamMessageWriter.prototype.writeValueMessage = function(
+  typeId, sendLength, message) {
+  if (typeId <= 0) {
+    throw new Error('Type ids should be positive integers.');
+  }
+  this.rawWriter.writeInt(typeId);
+  if (sendLength) {
+    this.rawWriter.writeUint(message.length);
+  }
+  this.rawWriter._writeRawBytes(message);
+};
+
+/**
+ * Write a type message.
+ * @private
+ * @param {number} typeId The type ID to define.
+ * @param {Uint8Array} message The body of the type description message.
+ */
+ByteStreamMessageWriter.prototype.writeTypeMessage = function(typeId, message) {
+  if (typeId <= 0) {
+    throw new Error('Type ids should be positive integers.');
+  }
+  this.rawWriter.writeInt(-typeId);
+  this.rawWriter.writeUint(message.length);
+  this.rawWriter._writeRawBytes(message);
+};
+
+/**
+ * Get the written bytes.
+ * @return {Uint8Array} The bytes that were written.
+ */
+ByteStreamMessageWriter.prototype.consumeBytes = function() {
+  var bytes = this.rawWriter.getBytes();
+  this.rawWriter = new RawVomWriter();
+  return bytes;
+};
diff --git a/src/vom/raw-vom-reader.js b/src/vom/raw-vom-reader.js
index eee85c8..f38d683 100644
--- a/src/vom/raw-vom-reader.js
+++ b/src/vom/raw-vom-reader.js
@@ -166,3 +166,7 @@
 RawVomReader.prototype._readRawBytes = function(amt) {
   return this._reader.readByteArray(amt);
 };
+
+RawVomReader.prototype.hasData = function() {
+  return this._reader.hasData();
+};
diff --git a/src/vom/type-encoder.js b/src/vom/type-encoder.js
index c2e00df..c3caf0a 100644
--- a/src/vom/type-encoder.js
+++ b/src/vom/type-encoder.js
@@ -51,7 +51,9 @@
   }
 
   // This isn't a bootstrap type, so it needs to be canonicalized.
-  type = canonicalize.type(type);
+  if (!Object.isFrozen(type)) {
+    type = canonicalize.type(type);
+  }
 
   // Check the cache of types that have been encoded already.
   var stringifiedType = stringify(type);
diff --git a/test/integration/test-authorizer.js b/test/integration/test-authorizer.js
index ef9da8e..895ead4 100644
--- a/test/integration/test-authorizer.js
+++ b/test/integration/test-authorizer.js
@@ -2,15 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+var vanadium = require('../..');
 var test = require('prova');
-var access = require('../../src/gen-vdl/v.io/v23/security/access');
 var Deferred = require('../../src/lib/deferred');
-var permissionsAuthorizer =
-  require('../../src/security/access/permissions-authorizer');
-var allowEveryoneAuthorizer =
-  require('../../src/security/access/allow-everyone-authorizer');
 var serve = require('./serve');
-
+var access = vanadium.security.access;
+var permissionsAuthorizer = vanadium.security.access.permissionsAuthorizer;
+var allowEveryoneAuthorizer = vanadium.security.access.allowEveryoneAuthorizer;
 
 var service = {
   call: function(ctx, serverCall, arg) {
@@ -18,7 +16,6 @@
   }
 };
 
-
 function createPromiseDispatcher(authorizer, tags) {
   function auth(ctx, call) {
     if (call.method === '__Signature') {
diff --git a/test/integration/test-bless.js b/test/integration/test-bless.js
index 6880bda..1c03b5b 100644
--- a/test/integration/test-bless.js
+++ b/test/integration/test-bless.js
@@ -5,11 +5,10 @@
 var test = require('prova');
 var vanadium = require('../../');
 var config = require('./default-config');
-var caveats = require('../../src/security/caveats');
 var leafDispatcher = require('../../src/rpc/leaf-dispatcher');
-var serve = require('./serve');
 var Blessings = require('../../src/security/blessings');
-var SharedContextKeys = require('../../src/runtime/shared-context-keys');
+var serve = require('./serve');
+var security = vanadium.security;
 
 function validateBlessings(t, blessings) {
   t.ok(blessings instanceof Blessings, 'Blessings have correct type');
@@ -50,7 +49,7 @@
     rt = runtime;
 
     runtime.principal.blessSelf(runtime.getContext(), 'blessedname',
-      caveats.createExpiryCaveat(new Date()),
+      security.createExpiryCaveat(new Date()),
       function(err, blessings) {
       t.error(err);
       validateBlessings(t, blessings);
@@ -63,11 +62,11 @@
   var service = {
     method: function(ctx, serverCall, cb) {
       var secCall = serverCall.securityCall;
-      var rt = ctx.value(SharedContextKeys.RUNTIME);
+      var rt = vanadium.runtimeForContext(ctx);
       var remoteKey = secCall.remoteBlessings.publicKey;
       rt.principal.bless(ctx, remoteKey, secCall.localBlessings,
        'ext', function(err) {
-         t.ok(err, 'Expected at least one caveat must be specfied error');
+         t.ok(err, 'Expected at least one caveat must be specified error');
          cb(null, null);
        });
     }
@@ -90,12 +89,12 @@
 test('Test bless with Caveat from server', function(t) {
   var service = {
     method: function(ctx, serverCall, cb) {
-      var rt = ctx.value(SharedContextKeys.RUNTIME);
+      var rt = vanadium.runtimeForContext(ctx);
       var secCall = serverCall.securityCall;
       var remoteKey = secCall.remoteBlessings.publicKey;
       rt.principal.bless(ctx, remoteKey, secCall.localBlessings,
-       'ext', caveats.createExpiryCaveat(new Date(Date.now() - 1000)),
-       caveats.createConstCaveat(true), function(err, blessings) {
+       'ext', security.createExpiryCaveat(new Date(Date.now() - 1000)),
+       security.createConstCaveat(true), function(err, blessings) {
          t.notOk(err, 'No error expected during bless');
          validateBlessings(t, blessings);
          cb(null, null);
@@ -146,7 +145,7 @@
             call.remoteBlessings.publicKey,
             call.localBlessings,
             'ext',
-            caveats.createExpiryCaveat(fiveSecondsInFuture),
+            security.createExpiryCaveat(fiveSecondsInFuture),
             function(err, blessing) {
               expectedBlessing = blessing;
               cb(err, blessing);
diff --git a/test/integration/test-blessings-util.js b/test/integration/test-blessings-util.js
index 52f907b..0f55cea 100644
--- a/test/integration/test-blessings-util.js
+++ b/test/integration/test-blessings-util.js
@@ -5,7 +5,7 @@
 var test = require('prova');
 var vanadium = require('../../');
 var config = require('./default-config');
-var security = require('../../src/security');
+var security = vanadium.security;
 
 test('Test union of blessings (promise case)', function(t) {
   vanadium.init(config, function(err, runtime) {
diff --git a/test/integration/test-cancellation.js b/test/integration/test-cancellation.js
index a4f40f2..ec9b9c1 100644
--- a/test/integration/test-cancellation.js
+++ b/test/integration/test-cancellation.js
@@ -3,11 +3,12 @@
 // license that can be found in the LICENSE file.
 
 var test = require('prova');
+var vanadium = require('../../');
 var service = require('./get-service');
 var serve = require('./serve');
 var leafDispatcher = require('../../src/rpc/leaf-dispatcher');
 var NO_TIMEOUT = require('../../src/rpc/constants').NO_TIMEOUT;
-var CanceledError = require('../../src/gen-vdl/v.io/v23/verror').CanceledError;
+var CanceledError = vanadium.verror.CanceledError;
 
 var errorId = new CanceledError(null).id;
 
diff --git a/test/integration/test-caveat-validation.js b/test/integration/test-caveat-validation.js
index ba379a7..72feb3d 100644
--- a/test/integration/test-caveat-validation.js
+++ b/test/integration/test-caveat-validation.js
@@ -3,11 +3,11 @@
 // license that can be found in the LICENSE file.
 
 var test = require('prova');
+var vanadium = require('../../');
 var serve = require('./serve');
-var vdl = require('../../src/vdl');
 var leafDispatcher = require('../../src/rpc/leaf-dispatcher');
-
 var testService = require('../vdl-out/v.io/x/js.core/test_service');
+var vdl = vanadium.vdl;
 
 // Service to be invoked
 function aServiceDef() {
diff --git a/test/integration/test-client-call-opts.js b/test/integration/test-client-call-opts.js
index 41c7467..3f83f05 100644
--- a/test/integration/test-client-call-opts.js
+++ b/test/integration/test-client-call-opts.js
@@ -3,9 +3,8 @@
 // license that can be found in the LICENSE file.
 
 var test = require('prova');
-
-var config = require('./default-config');
 var vanadium = require('../../');
+var config = require('./default-config');
 var verror = vanadium.verror;
 
 function end(t, rt, err) {
diff --git a/test/integration/test-js-client-server.js b/test/integration/test-js-client-server.js
index 3a14b2c..e7f175a 100644
--- a/test/integration/test-js-client-server.js
+++ b/test/integration/test-js-client-server.js
@@ -3,10 +3,11 @@
 // license that can be found in the LICENSE file.
 
 var test = require('prova');
+var vanadium = require('../../');
 var serve = require('./serve');
 var leafDispatcher = require('../../src/rpc/leaf-dispatcher');
 var Deferred = require('../../src/lib/deferred');
-var vdl = require('../../src/vdl');
+
 var builtins = require('../../src/vdl/builtins');
 var stringify = require('../../src/vdl/stringify');
 var TypeUtil = require('../../src/vdl/type-util');
@@ -15,6 +16,8 @@
 var typedStreamingServiceVdl =
   require('../vdl-out/javascript-test/services/typed-streaming-service');
 
+var vdl = vanadium.vdl;
+
 // TODO(bprosnitz) Combine CacheService and CacheServicePromises so there
 // isn't as much duplicated code.
 
diff --git a/test/integration/test-namespace.js b/test/integration/test-namespace.js
index e7d6f73..a2cbccb 100644
--- a/test/integration/test-namespace.js
+++ b/test/integration/test-namespace.js
@@ -5,18 +5,18 @@
 var test = require('prova');
 var Promise = require('../../src/lib/promise');
 
-var access = require('../../src/gen-vdl/v.io/v23/security/access');
-var reserved = require('../../src/gen-vdl/v.io/v23/rpc/reserved');
 var config = require('./default-config');
-var MINUTE = 60 * 1000; // a minute
 var Promise = require('../../src/lib/promise');
 var random = require('../../src/lib/random');
 var timeouts = require('./timeouts');
 var vanadium = require('../../');
 var verror = vanadium.verror;
+var access = vanadium.security.access;
+var reserved = vanadium.rpc.reserved;
 
 var namespaceRoot = process.env.V23_NAMESPACE;
 var PREFIX = 'namespace-testing/';
+var MINUTE = 60 * 1000; // a minute
 
 test('Test globbing children - glob(' + PREFIX + '*)', function(assert) {
   var runtime;
diff --git a/test/integration/test-sending-blessings.js b/test/integration/test-sending-blessings.js
index 9388767..6a62c88 100644
--- a/test/integration/test-sending-blessings.js
+++ b/test/integration/test-sending-blessings.js
@@ -3,24 +3,22 @@
 // license that can be found in the LICENSE file.
 
 var test = require('prova');
+var vanadium = require('../../');
 var serve = require('./serve');
 var leafDispatcher = require('../../src/rpc/leaf-dispatcher');
-var runtimeFromContext = require('../../src/runtime/runtime-from-context');
-var types = require('../../src/vdl/types');
-var WireBlessings =
-  require('../../src/gen-vdl/v.io/v23/security').WireBlessings;
-var caveats = require('../../src/security/caveats');
+var WireBlessings = vanadium.security.WireBlessings;
 var Blessings = require('../../src/security/blessings');
-
+var security = vanadium.security;
+var types = vanadium.vdl.types;
 
 var blessingsService = {
   createBlessings: function(ctx, serverCall, publicKey) {
-    var principal = runtimeFromContext(ctx).principal;
+    var principal = vanadium.runtimeForContext(ctx).principal;
     var expiryDate = new Date((new Date()).getTime() + 6000000);
 
     return principal.blessingStore.getDefault(ctx).then(function(defaultBless) {
       return principal.bless(ctx, publicKey, defaultBless, 'friend',
-                           caveats.createExpiryCaveat(expiryDate));
+                           security.createExpiryCaveat(expiryDate));
     });
   },
   verifyBlessings: function(ctx, serverCall) {
diff --git a/test/integration/test-server-glob.js b/test/integration/test-server-glob.js
index c7273a1..cca52c5 100644
--- a/test/integration/test-server-glob.js
+++ b/test/integration/test-server-glob.js
@@ -5,10 +5,9 @@
 var test = require('prova');
 var serve = require('./serve');
 var Promise = require('../../src/lib/promise');
-var naming = require('../../src/gen-vdl/v.io/v23/naming');
-var namespaceUtil = require('../../src/naming/util');
-var verror = require('../../src/gen-vdl/v.io/v23/verror');
-
+var vanadium = require('../../');
+var naming = vanadium.naming;
+var verror = vanadium.verror;
 
 var ALBUMS = [
   'public',
@@ -250,7 +249,7 @@
 
 FullGlobber.prototype.__glob = function(ctx, serverCall, glob, $stream) {
     var mountEntry = new naming.MountEntry({
-      name: namespaceUtil.join(serverCall.securityCall.suffix, glob),
+      name: naming.join(serverCall.securityCall.suffix, glob),
     });
     $stream.write(new naming.GlobReply({
       entry: mountEntry
diff --git a/test/integration/test-service-errors.js b/test/integration/test-service-errors.js
index 061a78f..1e6f31e 100644
--- a/test/integration/test-service-errors.js
+++ b/test/integration/test-service-errors.js
@@ -3,9 +3,10 @@
 // license that can be found in the LICENSE file.
 
 var test = require('prova');
+var vanadium = require('../../');
 var service = require('./get-service');
-var verror = require('../../src/gen-vdl/v.io/v23/verror');
-var VanadiumError = require('../../src/verror/vanadium-error');
+var verror = vanadium.verror;
+var VanadiumError = verror.VanadiumError;
 
 test('Test Go service returning Aborted error - ' +
   'errorThrower.method(callback)', function(assert) {
diff --git a/test/integration/test-service-native.js b/test/integration/test-service-native.js
index 4a7b9a9..242ee53 100644
--- a/test/integration/test-service-native.js
+++ b/test/integration/test-service-native.js
@@ -3,9 +3,10 @@
 // license that can be found in the LICENSE file.
 
 var test = require('prova');
+var vanadium = require('../../');
 var service = require('./get-service');
-var makeError = require('../../src/verror/make-errors');
-var actions = require('../../src/verror/actions');
+var makeError = vanadium.verror.makeError;
+var actions = vanadium.verror.actions;
 
 var E = makeError('randomPrefix.verror', actions.NO_RETRY,
                   '{1} {2}: RandomError: {_}');
diff --git a/test/integration/test-vtrace.js b/test/integration/test-vtrace.js
index ce9bafd..6da7720 100644
--- a/test/integration/test-vtrace.js
+++ b/test/integration/test-vtrace.js
@@ -4,9 +4,10 @@
 
 var test = require('prova');
 var service = require('./get-service');
-var vtrace = require('../../src/vtrace');
+var vanadium = require('../../');
 var serve = require('./serve');
 var leafDispatcher = require('../../src/rpc/leaf-dispatcher');
+var vtrace = vanadium.vtrace;
 
 function findSpan(name, trace) {
   for (var i = 0; i < trace.spans.length; i++) {
diff --git a/test/load/test-echo.js b/test/load/test-echo.js
new file mode 100644
index 0000000..dc7d6fd
--- /dev/null
+++ b/test/load/test-echo.js
@@ -0,0 +1,45 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var service = require('../integration/get-service');
+var test = require('prova');
+
+test.timeout(60 * 5 * 1000);
+
+var PAYLOAD_SIZE = 1000;
+var DURATION = 1 * 60 * 1000;
+test('load test echo', function(assert) {
+  service('/localhost:8141', function(err, ctx, echoer, end, rt) {
+    assert.error(err);
+    var payload = new Uint8Array(PAYLOAD_SIZE);
+    for (var i = 0; i < PAYLOAD_SIZE; i++) {
+      payload[i] = i && 0xff;
+    }
+    var iterations = 0;
+    var start = Date.now();
+    callEcho();
+    function callEcho() {
+      iterations++;
+      if ((iterations % 500) === 0) {
+        assert.ok(true, 'done with ' + iterations);
+      }
+      if ((Date.now() - start) > DURATION) {
+        return finish();
+      }
+      echoer.echo(ctx, payload).then(callEcho).catch(finish);
+    }
+
+    function finish(err) {
+      assert.error(err);
+      var duration = (Date.now() - start) / 1000;
+      var data = {
+        qps: iterations/duration,
+        iterations: iterations,
+      };
+      data.msecsPerRPC = 1000/data.qps;
+      assert.ok(true, JSON.stringify(data));
+      end(assert);
+    }
+  });
+});
diff --git a/test/services/config-stressd.js b/test/services/config-stressd.js
new file mode 100644
index 0000000..7473093
--- /dev/null
+++ b/test/services/config-stressd.js
@@ -0,0 +1,9 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+module.exports = {
+  flags: {
+    'v23.tcp.address': ':8141'
+  }
+};