UNPKG

gpii-universal

Version:

Cross platform, core components of the GPII personalization infrastructure.

210 lines (181 loc) 6.93 kB
/* * singleInstance Tests * * Copyright 2017 Raising the Floor - International * * Licensed under the New BSD license. You may not use this file except in * compliance with this License. * * The R&D leading to these results received funding from the * Department of Education - Grant H421A150005 (GPII-APCP). However, * these results do not necessarily represent the policy of the * Department of Education, and you should not assume endorsement by the * Federal Government. * * You may obtain a copy of the License at * https://github.com/GPII/universal/blob/master/LICENSE.txt */ "use strict"; var fluid = require("infusion"), fs = require("fs"), os = require("os"), child_process = require("child_process"); var jqUnit = fluid.require("node-jqunit"); var gpii = fluid.registerNamespace("gpii"); fluid.registerNamespace("gpii.tests.singleInstance"); fluid.require("%gpii-universal"); require("singleInstance"); jqUnit.module("gpii.tests.singleInstance"); gpii.tests.singleInstance.testDefs = fluid.freezeRecursive([ { // no pidfile testData: null, expected: { checkInstance: null, registerInstance: true, file: "$processes.own.pid", deregisterInstance: false } }, { // junk content testData: "not a pid", expected: { checkInstance: null, registerInstance: true, file: "$processes.own.pid", deregisterInstance: false } }, { // non-running pid testData: "-100", expected: { checkInstance: null, registerInstance: true, file: "$processes.own.pid", deregisterInstance: false } }, { // this process testData: "$processes.own.pid", expected: { checkInstance: "$processes.own.pid", registerInstance: true, file: "$processes.own.pid", deregisterInstance: true } }, { // another process testData: "$processes.other.pid", expected: { checkInstance: "$processes.other.pid", // If the implementation was complete, then registerInstance should succeed because the test process // isn't another GPII instance. registerInstance: false, file: null, deregisterInstance: false } } ]); fluid.defaults("gpii.tests.singleInstance.testData", { gradeNames: "fluid.modelComponent", model: { processes: {} } }); /** * Extracts the test items from model, performing look-ups from it ("$like.this") * * @param {Object} model - The object to resolve from. * @param {Object} value - The value (or values) to resolve. * @return {Array} The test items. */ gpii.tests.singleInstance.resolveReferences = function (model, value) { if (typeof(value) === "string") { return value.charAt(0) === "$" ? fluid.get(model, value.substring(1)) : value; } else { return fluid.transform(value, function (obj) { return gpii.tests.singleInstance.resolveReferences(model, obj); }); } }; /** * Deletes the pid file, hiding errors if the file doesn't exist. * * @param {String} pidFile - The pid file. */ gpii.tests.singleInstance.deletePidFile = function (pidFile) { try { fs.unlinkSync(pidFile); } catch (e) { // Don't care if it failed, as long as it's gone. if (fs.existsSync(pidFile)) { throw e; } } }; jqUnit.test("Testing checkInstance, registerGpiiInstance, and deregisterInstance", function () { var pidFile = os.tmpdir() + "/gpii-test-pid" + Date.now(); // Start another process (a cross-platform "sleep"), to test against a live pid. var otherProcess = child_process.exec("node -e \"setTimeout(console.log, 5000)\""); var testData = gpii.tests.singleInstance.testData(); testData.applier.change("processes", { own: process, other: otherProcess }); var tests = gpii.tests.singleInstance.resolveReferences(testData.model, gpii.tests.singleInstance.testDefs); var funcs = [ "checkInstance", "registerInstance", "deregisterInstance" ]; try { while (funcs.length > 0) { var func = funcs.shift(); for (var n = 0; n < tests.length; n++) { var test = tests[n]; var testName = func + " test " + n + ": "; // Set the pid file. if (test.testData === null) { gpii.tests.singleInstance.deletePidFile(pidFile); } else { fs.writeFileSync(pidFile, test.testData); } // Call the function var returnValue = gpii.singleInstance[func](pidFile); jqUnit.assertEquals(testName + " return", test.expected[func], returnValue); var exists = fs.existsSync(pidFile); if (func === "registerInstance") { if (test.expected.file !== null) { jqUnit.assertTrue(testName + "pid file should exist", exists); // Check the new pid file var content = fs.readFileSync(pidFile, {encoding: "utf8"}); var value = parseInt(content); jqUnit.assertEquals(testName + "pidfile content", test.expected.file, value); } } else if (func === "deregisterInstance") { if (returnValue) { jqUnit.assertTrue(testName + "pidFile should not exist after a successful deregisterInstance", !exists); } } gpii.tests.singleInstance.deletePidFile(pidFile); } } } finally { gpii.tests.singleInstance.deletePidFile(pidFile); testData.destroy(); } }); jqUnit.test("Testing singleInstance end-to-end", function () { var pidFile = os.tmpdir() + "/gpii-test-pid" + Date.now(); // perform an end-to-end test var pid = gpii.singleInstance.checkInstance(pidFile); jqUnit.assertEquals("Another instance should not be detected before registering", null, pid); var registered = gpii.singleInstance.registerInstance(pidFile); jqUnit.assertTrue("This instance should have been registered", registered); pid = gpii.singleInstance.checkInstance(pidFile); jqUnit.assertEquals("The current instance should be this one", process.pid, pid); var deregistered = gpii.singleInstance.deregisterInstance(pidFile); jqUnit.assertTrue("This instance should have been deregistered", deregistered); pid = gpii.singleInstance.checkInstance(pidFile); jqUnit.assertEquals("Another instance should not be detected after deregistering", null, pid); });