test: don't compute knownGlobals lazily
authorBen Noordhuis <info@bnoordhuis.nl>
Thu, 30 Jan 2014 12:02:58 +0000 (13:02 +0100)
committerFedor Indutny <fedor.indutny@gmail.com>
Thu, 6 Feb 2014 11:30:38 +0000 (15:30 +0400)
Conditional globals like 'gc' should only be recognized when --expose_gc
is set.  The global.gc feature check works only when done eagerly, else
it lets through a leaked variable called 'gc'.

test/common.js
test/simple/test-common.js [new file with mode: 0644]

index e902997..97de6d8 100644 (file)
@@ -89,75 +89,76 @@ exports.spawnPwd = function(options) {
   }
 };
 
+var knownGlobals = [setTimeout,
+                    setInterval,
+                    setImmediate,
+                    clearTimeout,
+                    clearInterval,
+                    clearImmediate,
+                    console,
+                    constructor, // Enumerable in V8 3.21.
+                    Buffer,
+                    process,
+                    global];
+
+if (global.gc) {
+  knownGlobals.push(gc);
+}
 
-// Turn this off if the test should not check for global leaks.
-exports.globalCheck = true;
+if (global.DTRACE_HTTP_SERVER_RESPONSE) {
+  knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
+  knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
+  knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE);
+  knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST);
+  knownGlobals.push(DTRACE_NET_STREAM_END);
+  knownGlobals.push(DTRACE_NET_SERVER_CONNECTION);
+  knownGlobals.push(DTRACE_NET_SOCKET_READ);
+  knownGlobals.push(DTRACE_NET_SOCKET_WRITE);
+}
 
-process.on('exit', function() {
-  if (!exports.globalCheck) return;
-  var knownGlobals = [setTimeout,
-                      setInterval,
-                      setImmediate,
-                      clearTimeout,
-                      clearInterval,
-                      clearImmediate,
-                      console,
-                      constructor, // Enumerable in V8 3.21.
-                      Buffer,
-                      process,
-                      global];
-
-  if (global.gc) {
-    knownGlobals.push(gc);
-  }
+if (global.COUNTER_NET_SERVER_CONNECTION) {
+  knownGlobals.push(COUNTER_NET_SERVER_CONNECTION);
+  knownGlobals.push(COUNTER_NET_SERVER_CONNECTION_CLOSE);
+  knownGlobals.push(COUNTER_HTTP_SERVER_REQUEST);
+  knownGlobals.push(COUNTER_HTTP_SERVER_RESPONSE);
+  knownGlobals.push(COUNTER_HTTP_CLIENT_REQUEST);
+  knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE);
+}
 
-  if (global.DTRACE_HTTP_SERVER_RESPONSE) {
-    knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
-    knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
-    knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE);
-    knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST);
-    knownGlobals.push(DTRACE_NET_STREAM_END);
-    knownGlobals.push(DTRACE_NET_SERVER_CONNECTION);
-    knownGlobals.push(DTRACE_NET_SOCKET_READ);
-    knownGlobals.push(DTRACE_NET_SOCKET_WRITE);
-  }
-  if (global.COUNTER_NET_SERVER_CONNECTION) {
-    knownGlobals.push(COUNTER_NET_SERVER_CONNECTION);
-    knownGlobals.push(COUNTER_NET_SERVER_CONNECTION_CLOSE);
-    knownGlobals.push(COUNTER_HTTP_SERVER_REQUEST);
-    knownGlobals.push(COUNTER_HTTP_SERVER_RESPONSE);
-    knownGlobals.push(COUNTER_HTTP_CLIENT_REQUEST);
-    knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE);
-  }
+if (global.ArrayBuffer) {
+  knownGlobals.push(ArrayBuffer);
+  knownGlobals.push(Int8Array);
+  knownGlobals.push(Uint8Array);
+  knownGlobals.push(Uint8ClampedArray);
+  knownGlobals.push(Int16Array);
+  knownGlobals.push(Uint16Array);
+  knownGlobals.push(Int32Array);
+  knownGlobals.push(Uint32Array);
+  knownGlobals.push(Float32Array);
+  knownGlobals.push(Float64Array);
+  knownGlobals.push(DataView);
+}
 
-  if (global.ArrayBuffer) {
-    knownGlobals.push(ArrayBuffer);
-    knownGlobals.push(Int8Array);
-    knownGlobals.push(Uint8Array);
-    knownGlobals.push(Uint8ClampedArray);
-    knownGlobals.push(Int16Array);
-    knownGlobals.push(Uint16Array);
-    knownGlobals.push(Int32Array);
-    knownGlobals.push(Uint32Array);
-    knownGlobals.push(Float32Array);
-    knownGlobals.push(Float64Array);
-    knownGlobals.push(DataView);
-  }
+function leakedGlobals() {
+  var leaked = [];
 
-  for (var x in global) {
-    var found = false;
+  for (var val in global)
+    if (-1 === knownGlobals.indexOf(global[val]))
+      leaked.push(val);
 
-    for (var y in knownGlobals) {
-      if (global[x] === knownGlobals[y]) {
-        found = true;
-        break;
-      }
-    }
+  return leaked;
+};
+exports.leakedGlobals = leakedGlobals;
 
-    if (!found) {
-      console.error('Unknown global: %s', x);
-      assert.ok(false, 'Unknown global found');
-    }
+// Turn this off if the test should not check for global leaks.
+exports.globalCheck = true;
+
+process.on('exit', function() {
+  if (!exports.globalCheck) return;
+  var leaked = leakedGlobals();
+  if (leaked.length > 0) {
+    console.error('Unknown globals: %s', leaked);
+    assert.ok(false, 'Unknown global found');
   }
 });
 
diff --git a/test/simple/test-common.js b/test/simple/test-common.js
new file mode 100644 (file)
index 0000000..420bd52
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var common = require('../common');
+var assert = require('assert');
+
+common.globalCheck = false;
+global.gc = 42;  // Not a valid global unless --expose_gc is set.
+assert.deepEqual(common.leakedGlobals(), ['gc']);