Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #18 from liangji101/develop

add switch to enable yui loader
  • Loading branch information...
commit 83c75084658298479139895bcb34a53340c14a83 2 parents 874d952 + 49a85f7
@liangji101 liangji101 authored
View
235 arrow_server/server.js
@@ -37,7 +37,7 @@ global.appRoot = path.resolve(__dirname, "..");
function showHelp() {
console.info("\nOPTIONS :" + "\n" +
" --host : (optional) Fully qualified name of host where arrow server is running. (default: localhost)" + "\n" +
- " --port : (optional) Arrow Server Port. (default: 4459) " + "\n\n"
+ " --port : (optional) Arrow Server Port. (default: 4459) " + "\n\n"
);
console.log("\nEXAMPLES :" + "\n" +
@@ -55,6 +55,10 @@ if (parsed.help) {
if (parsed["host"]) {
arrowHost = parsed["host"];
}
+if (!arrowHost || arrowHost === "localhost") {
+ var servermanager=require("../lib/util/arrowservermanager");
+ arrowHost = servermanager.getProperIPAddressForArrowServer() || "localhost" ;
+}
if (parsed["port"]) {
var port = String(parsed["port"]);
@@ -77,15 +81,15 @@ app.use(express.cookieParser());
app.use(express.bodyParser());
var mimes = {
- "css": "text/css",
- "js": "text/javascript",
- "htm": "text/html",
- "html": "text/html",
- "ico": "image/vnd.microsoft.icon",
- "jpg": "image/jpeg",
- "gif": "image/gif",
- "png": "image/png",
- "xml": "text/xml"
+ "css":"text/css",
+ "js":"text/javascript",
+ "htm":"text/html",
+ "html":"text/html",
+ "ico":"image/vnd.microsoft.icon",
+ "jpg":"image/jpeg",
+ "gif":"image/gif",
+ "png":"image/png",
+ "xml":"text/xml"
};
function serveStatic(pathname, req, res) {
@@ -102,18 +106,18 @@ function serveStatic(pathname, req, res) {
ext = pathname.substring((tmp + 1));
mime = mimes[ext] || "text/plain";
- res.writeHead(200, {"Content-Type": mime});
+ res.writeHead(200, {"Content-Type":mime});
res.end(content);
}
});
}
-
function cleanUp() {
try {
fs.unlinkSync(global.appRoot + "/tmp/arrow_server.status");
- } catch (ex) {}
+ } catch (ex) {
+ }
console.log("Good bye!");
}
@@ -128,7 +132,7 @@ app.get("/arrow/static/*", function (req, res) {
// selenium ip hookup
app.get("/arrow/wd/:selPort", function (req, res) {
- var selUrl = "http://" + req.connection.remoteAddress + ":" + req.params.selPort + "/wd/hub";
+ var selUrl = "http://" + req.connection.remoteAddress + ":" + req.params.selPort + "/wd/hub";
fs.writeFileSync("/tmp/arrow_sel_server.status", selUrl);
res.end("Selenium captured at: " + selUrl, "utf-8");
});
@@ -142,11 +146,13 @@ function validateSession(req, res) {
var sessionId = req.params.sessionId,
body;
- if (sessions.hasOwnProperty(sessionId)) { return true; }
+ if (sessions.hasOwnProperty(sessionId)) {
+ return true;
+ }
body = {
- status: 9,
- value: "No such sessionId: " + sessionId
+ status:9,
+ value:"No such sessionId: " + sessionId
};
res.send(body, 404);
return false;
@@ -164,8 +170,8 @@ function queueWdTask(params, req, res) {
curTask = wdtasks[sessionId];
if (curTask) {
body = {
- status: 9,
- value: "A command is still running for sessionId: " + sessionId
+ status:9,
+ value:"A command is still running for sessionId: " + sessionId
};
res.send(body, 500);
return false;
@@ -173,15 +179,15 @@ function queueWdTask(params, req, res) {
}
task = {
- "id": "taskid-" + wdTaskCounter,
- "params": params,
- "statusCode": 0,
- "httpCode": 200
+ "id":"taskid-" + wdTaskCounter,
+ "params":params,
+ "statusCode":0,
+ "httpCode":200
};
wdtasks[sessionId] = {
- "request": req,
- "response": res,
- "task": task
+ "request":req,
+ "response":res,
+ "task":task
};
wdTaskCounter += 1;
@@ -225,9 +231,9 @@ app.post("/arrow/slave/:sessionId", function (req, res) {
delete wdtasks[sessionId];
resBody = {
- "status": prevTask.statusCode,
- "sessionId": sessionId,
- "value": prevTask.result
+ "status":prevTask.statusCode,
+ "sessionId":sessionId,
+ "value":prevTask.result
};
if (debug) {
console.log("Task result:");
@@ -237,7 +243,9 @@ app.post("/arrow/slave/:sessionId", function (req, res) {
}
if (sessions.hasOwnProperty(sessionId)) {
- if (debug) { console.log("Killing old connection for session: " + sessionId); }
+ if (debug) {
+ console.log("Killing old connection for session: " + sessionId);
+ }
oldSession = sessions[sessionId];
oldSession.response.end();
delete sessions[sessionId];
@@ -245,10 +253,10 @@ app.post("/arrow/slave/:sessionId", function (req, res) {
console.log("Session registered: " + sessionId);
sessions[sessionId] = {
- "sessionId": sessionId,
- "timestamp": timestamp,
- "request": req,
- "response": res
+ "sessionId":sessionId,
+ "timestamp":timestamp,
+ "request":req,
+ "response":res
};
conn = req.connection;
@@ -256,10 +264,14 @@ app.post("/arrow/slave/:sessionId", function (req, res) {
if (sessions.hasOwnProperty(sessionId)) {
oldSession = sessions[sessionId];
if (oldSession.timestamp === timestamp) {
- if (debug) { console.log("Session deleted: " + sessionId); }
+ if (debug) {
+ console.log("Session deleted: " + sessionId);
+ }
delete sessions[sessionId];
} else {
- if (debug) { console.log("Session already recaptured: " + sessionId); }
+ if (debug) {
+ console.log("Session already recaptured: " + sessionId);
+ }
}
}
});
@@ -272,8 +284,8 @@ app.get("/wd/hub/status", function (req, res) {
res.contentType("application/json");
body = {
- build: { version: "1.0" },
- os: { name: "rhel" }
+ build:{ version:"1.0" },
+ os:{ name:"rhel" }
};
res.send(body);
});
@@ -281,7 +293,7 @@ app.get("/wd/hub/status", function (req, res) {
// Create a new session
app.post("/wd/hub/session", function (req, res) {
res.contentType("application/json");
- res.send({status: 9, value: "Create session: Not Implemented"}, 501);
+ res.send({status:9, value:"Create session: Not Implemented"}, 501);
});
// Get all sessions
@@ -294,12 +306,12 @@ app.get("/wd/hub/sessions", function (req, res) {
sessionIds = [];
for (sessionId in sessions) {
- sessionIds.push({"id": sessionId});
+ sessionIds.push({"id":sessionId});
}
body = {
- status: 0,
- value: sessionIds
+ status:0,
+ value:sessionIds
};
res.send(body);
});
@@ -310,20 +322,22 @@ app.get("/wd/hub/session/:sessionId", function (req, res) {
session;
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
session = sessions[req.params.sessionId];
body = {
- status: 0,
- sessionId: req.params.sessionId,
- value: {
- platform: "ANY",
- cssSelectorsEnabled: true,
- javascriptEnabled: true,
- browserName: session.request.headers["user-agent"],
- nativeEvents: true,
- takesScreenshot: false,
- version: 1
+ status:0,
+ sessionId:req.params.sessionId,
+ value:{
+ platform:"ANY",
+ cssSelectorsEnabled:true,
+ javascriptEnabled:true,
+ browserName:session.request.headers["user-agent"],
+ nativeEvents:true,
+ takesScreenshot:false,
+ version:1
}
};
@@ -333,23 +347,27 @@ app.get("/wd/hub/session/:sessionId", function (req, res) {
// Delete the session
app.del("/wd/hub/session/:sessionId", function (req, res) {
res.contentType("application/json");
- res.send({status: 9, value: "Delete session: Not Implemented"}, 501);
+ res.send({status:9, value:"Delete session: Not Implemented"}, 501);
});
// Get the current page title
app.get("/wd/hub/session/:sessionId/title", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "title"}, req, res);
+ queueWdTask({"type":"title"}, req, res);
});
// Get the current page url
app.get("/wd/hub/session/:sessionId/url", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "url"}, req, res);
+ queueWdTask({"type":"url"}, req, res);
});
var revProxyHost = "";
@@ -362,15 +380,21 @@ app.post("/wd/hub/session/:sessionId/url", function (req, res) {
reqPort;
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
url = req.body.url;
reqParams = urlParser.parse(url);
reqHost = reqParams.hostname;
reqPort = 80;
- if (reqParams.port) { reqPort = reqParams.port; }
+ if (reqParams.port) {
+ reqPort = reqParams.port;
+ }
if ((reqHost === arrowHost) && (reqPort === arrowPort)) {
- if (debug) { console.log("Reverse proxy disabled"); }
+ if (debug) {
+ console.log("Reverse proxy disabled");
+ }
revProxyHost = "";
} else {
console.log("Reverse proxy enabled for: " + reqHost + ":" + reqPort);
@@ -379,7 +403,7 @@ app.post("/wd/hub/session/:sessionId/url", function (req, res) {
url = arrowAddress + reqParams.pathname;
}
- queueWdTask({"type": "navigate", "url": url}, req, res);
+ queueWdTask({"type":"navigate", "url":url}, req, res);
});
// Execute sync script
@@ -387,96 +411,118 @@ app.post("/wd/hub/session/:sessionId/execute", function (req, res) {
var script;
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
script = req.body.script;
- queueWdTask({"type": "execute", "script": script}, req, res);
+ queueWdTask({"type":"execute", "script":script}, req, res);
});
// Execute async script
app.post("/wd/hub/session/:sessionId/execute_async", function (req, res) {
res.contentType("application/json");
- res.send({status: 9, value: "execute_async: Not Implemented"}, 501);
+ res.send({status:9, value:"execute_async: Not Implemented"}, 501);
});
// find an element
app.post("/wd/hub/session/:sessionId/element", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "element", "using": req.body.using, "value": req.body.value}, req, res);
+ queueWdTask({"type":"element", "using":req.body.using, "value":req.body.value}, req, res);
});
// find an element starting from
app.post("/wd/hub/session/:sessionId/element/:id/element", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "element", "element": req.params.id, "using": req.body.using, "value": req.body.value}, req, res);
+ queueWdTask({"type":"element", "element":req.params.id, "using":req.body.using, "value":req.body.value}, req, res);
});
// find elements
app.post("/wd/hub/session/:sessionId/elements", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "elements", "using": req.body.using, "value": req.body.value}, req, res);
+ queueWdTask({"type":"elements", "using":req.body.using, "value":req.body.value}, req, res);
});
// find elements starting from
app.post("/wd/hub/session/:sessionId/elements/:id/element", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "elements", "element": req.params.id, "using": req.body.using, "value": req.body.value}, req, res);
+ queueWdTask({"type":"elements", "element":req.params.id, "using":req.body.using, "value":req.body.value}, req, res);
});
// get text of an element
app.get("/wd/hub/session/:sessionId/element/:id/text", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "text", "element": req.params.id}, req, res);
+ queueWdTask({"type":"text", "element":req.params.id}, req, res);
});
// get tag of an element
app.get("/wd/hub/session/:sessionId/element/:id/name", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "name", "element": req.params.id}, req, res);
+ queueWdTask({"type":"name", "element":req.params.id}, req, res);
});
// get attribute of an element
app.get("/wd/hub/session/:sessionId/element/:id/attribute/:name", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "attribute", "element": req.params.id, "name": req.params.name}, req, res);
+ queueWdTask({"type":"attribute", "element":req.params.id, "name":req.params.name}, req, res);
});
// click on an element
app.post("/wd/hub/session/:sessionId/element/:id/click", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "click", "element": req.params.id}, req, res);
+ queueWdTask({"type":"click", "element":req.params.id}, req, res);
});
// submit a form
app.post("/wd/hub/session/:sessionId/element/:id/submit", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "submit", "element": req.params.id}, req, res);
+ queueWdTask({"type":"submit", "element":req.params.id}, req, res);
});
// send key strokes to an element
app.post("/wd/hub/session/:sessionId/element/:id/value", function (req, res) {
res.contentType("application/json");
- if (!validateSession(req, res)) { return; }
+ if (!validateSession(req, res)) {
+ return;
+ }
- queueWdTask({"type": "value", "element": req.params.id, "value": req.body.value}, req, res);
+ queueWdTask({"type":"value", "element":req.params.id, "value":req.body.value}, req, res);
});
function serveRevProxy(req, res) {
@@ -490,11 +536,11 @@ function serveRevProxy(req, res) {
req.headers["X-Forwarded-For"] = req.connection.remoteAddress;
req.headers["Host"] = revProxyHost;
options = {
- host: revProxyHost,
- port: revProxyPort,
- path: req.url,
- method: req.method,
- headers: req.headers
+ host:revProxyHost,
+ port:revProxyPort,
+ path:req.url,
+ method:req.method,
+ headers:req.headers
};
proxy_request = http.request(options, function (proxy_response) {
//send headers and data as received
@@ -529,7 +575,9 @@ app.get("*", function (req, res) {
serveRevProxy(req, res);
} else {
docRoot = process.cwd();
- if ("/" === docRoot) { docRoot = ""; }
+ if ("/" === docRoot) {
+ docRoot = "";
+ }
serveStatic(docRoot + req.url, req, res);
}
});
@@ -544,11 +592,11 @@ function runArrowServer(port) {
}
//starting arrow server
-portchecker.getFirstAvailable(arrowPortMin, arrowPortMax, "localhost", function(p, host) {
+portchecker.getFirstAvailable(arrowPortMin, arrowPortMax, "localhost", function (p, host) {
if (p === -1) {
console.log('No free ports found for arrow server on ' + host + ' between ' + arrowPortMin + ' and ' + arrowPortMax);
} else {
- // console.log('The first free port found for arrow server on ' + host + ' between ' + arrowPortMin + ' and ' + arrowPortMax + ' is ' + p);
+ // console.log('The first free port found for arrow server on ' + host + ' between ' + arrowPortMin + ' and ' + arrowPortMax + ' is ' + p);
arrowPort = p;
runArrowServer(p);
}
@@ -559,6 +607,7 @@ process.on("uncaughtException", function (err) {
process.exit();
});
process.on("SIGINT", function () {
+ console.log("sigINT caught");
process.exit();
});
process.on("exit", function (err) {
View
11 config/config.js
@@ -25,15 +25,20 @@ config.testRunner = config.arrowModuleRoot + "lib/client/yuitest-runner.js";
config.autolib = config.arrowModuleRoot + "lib/common";
// config for share lib
-config.scanShareLibPath = []; // Arrow will scan all given path for share lib. Example: [config.arrowModuleRoot + "../"]
+
+config.shareLibPath = []; // Arrow will scan all given path for share lib. Example: [config.arrowModuleRoot + "../"]
// You can modify this to add multiple share lib path.
config.scanShareLibPrefix = []; // Arrow will only scan share lib with given prefix "martini_" if configured as ["martini_"]
// Or it will scan all folders for share lib under given path if it is empty : []
// You can modify this to add multiple prefix.
config.scanShareLibRecursive = true; // Only scan top level folders for the given prefix and given scan path if false,
// Otherwise it will scan recursively with the given path.
-config.serverConfigName = "server_seed.js";
-config.clientConfigName = "client_seed.js";
+config.enableShareLibYUILoader = false; // Default false , inject all necessary share lib source code into test cases .
+ // If true, generate and inject YUI group/modules info and let YUI loader to load modules.
+ // the reason we need this is because in yahoo network lot of time
+ // lab manager windows VM's don't have access to any non-80 port of hudson slaves.
+ // In those scenarios, YUI config would be a blocker and YUI loader wont work.
+
config.descriptorName = "test_descriptor.json";
config.minPort = 10000;
View
14 docs/arrow_cookbook/arrow_in-depth.rst
@@ -643,13 +643,25 @@ If installed more than one share lib packages globally, like martini_testlib2, w
"controller": "martini_testlib1.my-test-controller"
-**Note:** if want to let ``--shareLibPath`` to scan some directory other than martini_xxx, you can configure
+**Note:**
+1. if want to let ``--shareLibPath`` to scan some directory other than martini_xxx, you can configure
it on */path/to/arrow/install/path/config/config.js*, for example, to scan dev_xxx directory, you can configure it as below:
::
config.scanShareLibPrefix = ["martini_", "dev_"];
+2.Another config is config.scanShareLibRecursive , if set to false, arrow will only scan top level folders for the given prefix and given scan path,Otherwise it will scan recursively with the given path.
+
+3.And the next config: config.enableShareLibYUILoader ,this is important configuration,
+ By default false ,arrow will inject all necessary share lib source code into test cases .
+ If true, arrow will generate and inject YUI group/modules info and let YUI loader to load modules.To ensure YUI loader to get these modules,arrow will auto detect if arrow server is running and will restart it for YUI loader if not.
+ The reason we need this switch is because in yahoo network lot of time lab manager windows VM's don't have access to any non-80 port of hudson slaves.In those scenarios, YUI config would be a blocker and YUI loader wont work.So if you can make sure the pages
+ you are testing have access to your host where arrow server runs, you can make enableShareLibYUILoader true to improve performance.
+
+ ::
+ arrow test-unit.js --shareLibPath=/usr/local/lib/node_modules/ --enableShareLibYUILoader=true
+
Parallelism
-----------
View
5 index.js
@@ -33,6 +33,7 @@ var knownOpts = {
"browser": [String, null],
"lib": [String, null],
"shareLibPath": [String, null],
+ "enableShareLibYUiLoader":Boolean,
"page": [String, null],
"driver": [String, null],
"controller": [String, null],
@@ -212,10 +213,10 @@ global.color = config.color;
// scan libraries
-if (config.scanShareLibPath !== undefined || argv.shareLibPath !== undefined)
+if (config.shareLibPath !== undefined)
{
var libScanner = require('./lib/util/sharelibscanner');
- new libScanner().genSeedFile(argv.shareLibPath, startArrow);
+ new libScanner(config).genSeedFile(config.shareLibPath, startArrow);
} else {
startArrow();
}
View
8 lib/client/yuitest-seed.js
@@ -146,16 +146,12 @@ if ((typeof window !== "undefined") && !window.onerror) {
var fs = require('fs');
if (ARROW.shareLibServerSeed !== undefined) {
try {
- if (fs.statSync(ARROW.shareLibServerSeed).isFile()) {
- var globalConf = fs.readFileSync(ARROW.shareLibServerSeed, "utf-8");
- eval(globalConf);
- }
+ eval(ARROW.shareLibServerSeed);
} catch (e) {
- console.log("Martini seed cannot be injected");
+ console.log("share lib server side seed cannot be injected");
console.log(e);
}
}
-
onYUIAvailable();
} else {
//console.log("Injecting YUI");
View
9 lib/driver/node.js
@@ -11,6 +11,7 @@ var childProcess = require("child_process");
var log4js = require("log4js");
var Driver = require("../interface/driver");
var coverage = require("../util/coverage");
+var libscanner = require("../util/sharelibscanner");
/**
* Driver wrapping nodejs that can only run javascript unit tests
@@ -58,11 +59,9 @@ NodeDriver.prototype.createNodeArgs = function (testParams, callback) {
runner = self.config["testRunner"];
libs = testParams.lib;
- try{
- shareLibServerSeed = require('path').join(self.config["arrowModuleRoot"] ,"tmp", self.config["serverConfigName"]);
- }catch(e){
- self.logger.debug("no server side share lib seed found");
- }
+ // in server side(run with nodejs),we can always enable yui loader to load server seed.
+ // Unlike client side, we don't need to inject src code.
+ shareLibServerSeed=libscanner.getShareLibServerSideModulesMeta();
nodeArgs = {
"seed": seed,
View
107 lib/driver/selenium.js
@@ -2,10 +2,10 @@
/*jslint undef: true*/
/*
-* Copyright (c) 2012, Yahoo! Inc. All rights reserved.
-* Copyrights licensed under the New BSD License.
-* See the accompanying LICENSE file for terms.
-*/
+ * Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ * Copyrights licensed under the New BSD License.
+ * See the accompanying LICENSE file for terms.
+ */
var fs = require("fs");
var util = require("util");
@@ -14,6 +14,7 @@ var log4js = require("log4js");
var Driver = require("../interface/driver");
var CapabilityManager = require("../util/capabilitymanager");
var coverage = require("../util/coverage");
+var libscanner = require("../util/sharelibscanner");
var uglifyParser = require("uglify-js").parser;
var uglify = require("uglify-js").uglify;
@@ -44,9 +45,9 @@ SeleniumDriver.prototype.getCapabilities = function () {
var self = this,
caps = {
- "platform" : "ANY",
- "javascriptEnabled" : true,
- "seleniumProtocol" : "WebDriver"
+ "platform":"ANY",
+ "javascriptEnabled":true,
+ "seleniumProtocol":"WebDriver"
},
tmpCaps,
browserInfo,
@@ -57,7 +58,7 @@ SeleniumDriver.prototype.getCapabilities = function () {
if (self.args.proxy || self.args.proxy === undefined) {
self.logger.debug("Adding Proxy Setting to the Browser");
- caps.proxy = {"httpProxy" : self.config.proxyUrl, "proxyType" : "manual"};
+ caps.proxy = {"httpProxy":self.config.proxyUrl, "proxyType":"manual"};
} else {
self.logger.debug("Descriptor overridden proxy param. Not setting proxy in browser");
}
@@ -117,7 +118,7 @@ SeleniumDriver.prototype.start = function (callback) {
self.logger.trace("Capabilities :");
self.logger.trace(capabilities);
- if ("phantomjs" === capabilities.browserName ) {
+ if ("phantomjs" === capabilities.browserName) {
wdHubHost = self.config["phantomHost"];
self.sessionId = "";
} else {
@@ -152,7 +153,7 @@ SeleniumDriver.prototype.start = function (callback) {
wd = require('../../ext-lib/webdriver');
wd.promise.Application.getInstance().on("uncaughtException", function (e) {
- errorMsg = "Uncaught exception: " + e.message;
+ errorMsg = "Uncaught exception: " + e.message;
if (self.testCallback) {
self.errorCallback(self.logger, errorMsg, self.testCallback);
} else {
@@ -184,7 +185,7 @@ SeleniumDriver.prototype.stop = function (callback) {
}
} else {
// we were not given a session id
- this.webdriver.quit().then(function() {
+ this.webdriver.quit().then(function () {
if (callback) {
callback(null);
}
@@ -228,7 +229,8 @@ SeleniumDriver.prototype.createDriverJs = function (testParams, callback) {
driverJs,
libCode,
instCode,
- i;
+ i,
+ enableYUILoader;
testJs = testParams.test;
actionJs = testParams.action;
@@ -242,11 +244,7 @@ SeleniumDriver.prototype.createDriverJs = function (testParams, callback) {
appSeedUrl = self.config["defaultAppSeed"];
- try{
- shareLibClientSeedJs = fs.readFileSync(path.join(self.config["arrowModuleRoot"] ,"tmp", self.config["clientConfigName"]), "utf-8");
- }catch(e){
- self.logger.info("No client side share lib seed file found");
- }
+ enableYUILoader = self.config["enableShareLibYUILoader"] || false;
seed = self.config["testSeed"];
runner = self.config["testRunner"];
@@ -261,6 +259,15 @@ SeleniumDriver.prototype.createDriverJs = function (testParams, callback) {
testParamsJs = JSON.stringify(testParams);
+ // get client side share lib modules meta to let yui loader load share lib
+ shareLibClientSeedJs = "";
+ if (enableYUILoader) {
+ shareLibClientSeedJs = libscanner.getShareLibClientSideModulesMeta();
+ this.logger.trace("share lib client js: " + shareLibClientSeedJs);
+ }
+
+ testLibsJs += shareLibClientSeedJs;
+
// html tests run themselves
if (testJs && (".html" === path.extname(testJs))) {
autoTest = true;
@@ -272,6 +279,7 @@ SeleniumDriver.prototype.createDriverJs = function (testParams, callback) {
// if (false === serverBase) {
try {
+ var deplibs=[];
for (i = 0; i < arrLib.length; i += 1) {
lib = arrLib[i];
if (0 === lib.length) {
@@ -279,6 +287,11 @@ SeleniumDriver.prototype.createDriverJs = function (testParams, callback) {
}
self.logger.info("Loading dependency: " + lib);
libCode = fs.readFileSync(lib, "utf-8");
+
+ if (!enableYUILoader){
+ deplibs = deplibs.concat(libscanner.getShareLibSrcByPath(lib, "client"));
+ }
+
if (self.config.coverage) {
instCode = coverage.instrumentCode(libCode, lib);
testLibsJs += instCode;
@@ -290,10 +303,37 @@ SeleniumDriver.prototype.createDriverJs = function (testParams, callback) {
if (testJs) {
self.logger.info("Loading test: " + testJs);
testLibsJs += fs.readFileSync(testJs, "utf-8");
+ if (!enableYUILoader){
+ deplibs = deplibs.concat(libscanner.getShareLibSrcByPath(testJs, "client"));
+ }
+
} else {
self.logger.info("Loading action: " + actionJs);
testLibsJs += fs.readFileSync(actionJs, "utf-8");
+ if (!enableYUILoader){
+ deplibs = deplibs.concat(libscanner.getShareLibSrcByPath(actionJs, "client"));
+ }
}
+ if (deplibs && deplibs.length > 0){
+
+ // Remove Duplicates
+ deplibs = deplibs.filter(function (elem, pos) {
+ return deplibs.indexOf(elem) == pos;
+ });
+
+ self.logger.debug("Found share libs to load are:");
+ self.logger.debug(deplibs);
+
+ for (var i = 0; i < deplibs.length; i++) {
+ try {
+ testLibsJs += fs.readFileSync(deplibs[i], 'utf8');
+ testLibsJs += "\n";
+ } catch (e) {
+ self.logger.debug("Can't read file : " + deplibs[i]);
+ }
+ }
+ };
+
} catch (e) {
callback(e);
return false;
@@ -319,14 +359,14 @@ SeleniumDriver.prototype.createDriverJs = function (testParams, callback) {
driverJs =
"ARROW = {};" +
- "ARROW.autoTest = " + autoTest + ";" +
- "ARROW.testParams = " + testParamsJs + ";" +
- "ARROW.appSeed = \"" + appSeedUrl + "\";" +
- "ARROW.testLibs = " + testLibsUrl + ";" +
- "ARROW.scriptType = \"" + scriptType + "\";" +
- "ARROW.testScript = \"" + testJsUrl + "\";" +
- "ARROW.actionScript = \"" + actionJsUrl + "\";" +
- "ARROW.onSeeded = function() { " + shareLibClientSeedJs + testLibsJs + runnerJs + " };" + seedJs;
+ "ARROW.autoTest = " + autoTest + ";" +
+ "ARROW.testParams = " + testParamsJs + ";" +
+ "ARROW.appSeed = \"" + appSeedUrl + "\";" +
+ "ARROW.testLibs = " + testLibsUrl + ";" +
+ "ARROW.scriptType = \"" + scriptType + "\";" +
+ "ARROW.testScript = \"" + testJsUrl + "\";" +
+ "ARROW.actionScript = \"" + actionJsUrl + "\";" +
+ "ARROW.onSeeded = function() { " + testLibsJs + runnerJs + " };" + seedJs;
this.logger.trace("Driver js: " + driverJs);
@@ -377,7 +417,9 @@ SeleniumDriver.prototype.executeAction = function (testConfig, testParams, callb
actionJs = testParams.action;
page = testParams.page;
- if (!testParams.lib && self.args.params && self.args.params.lib) { testParams.lib = self.args.params.lib; }
+ if (!testParams.lib && self.args.params && self.args.params.lib) {
+ testParams.lib = self.args.params.lib;
+ }
self.testCallback = callback; // save it so that async wd exception can be reported back
driverJs = this.createDriverJs(testParams, callback);
@@ -460,7 +502,9 @@ SeleniumDriver.prototype.executeTest = function (testConfig, testParams, callbac
testJs = testParams.test;
page = testParams.page;
- if (!testParams.lib && self.args.params && self.args.params.lib) { testParams.lib = self.args.params.lib; }
+ if (!testParams.lib && self.args.params && self.args.params.lib) {
+ testParams.lib = self.args.params.lib;
+ }
self.testCallback = callback; // save it so that async wd exception can be reported back
driverJs = this.createDriverJs(testParams, callback);
@@ -477,7 +521,6 @@ SeleniumDriver.prototype.executeTest = function (testConfig, testParams, callbac
}
-
function collectTestReport() {
retryCount += 1;
logger.debug("Waiting for the test report, attempt: " + retryCount);
@@ -490,11 +533,11 @@ SeleniumDriver.prototype.executeTest = function (testConfig, testParams, callbac
});
- showYUIConsoleLog(function() {
+ showYUIConsoleLog(function () {
if (self.config.coverage) {
try {
webdriver.executeScript("return window.__coverage__").then(function (cov) {
- // console.log( cov);
+ // console.log( cov);
coverage.addCoverage(cov);
callback(null, report);
});
@@ -507,7 +550,7 @@ SeleniumDriver.prototype.executeTest = function (testConfig, testParams, callbac
}
});
} else if (retryCount >= SeleniumDriver.maxAttempt) {
- showYUIConsoleLog(function() {
+ showYUIConsoleLog(function () {
self.errorCallback(logger, "Failed to collect the test report", callback);
});
} else {
@@ -528,7 +571,7 @@ SeleniumDriver.prototype.executeTest = function (testConfig, testParams, callbac
}
});
} catch (e) {
- self.logger.trace("Error :" + e.toString());
+ self.logger.trace("Error :" + e.toString());
callback();
}
}
View
117 lib/util/arrowservermanager.js
@@ -0,0 +1,117 @@
+var path = require('path'),
+ fs = require('fs');
+
+var log4js = require("log4js");
+var serverManagerLogger = new log4js.getLogger("arrowServerManager");
+var arrowConfig = require('../../config/config');
+var portchecker=require('../../ext-lib/portchecker');
+var child;
+
+var servermanager=module.exports={};
+
+servermanager.getLocalhostIPAddress =function() {
+ var os = require('os'),
+ interfaces = os.networkInterfaces(),
+ addresses = [];
+ for (k in interfaces) {
+ for (k2 in interfaces[k]) {
+ var address = interfaces[k][k2];
+ if (address.family == 'IPv4' && !address.internal) {
+ addresses.push(address.address)
+ }
+ }
+ }
+ if (addresses.length > 0)
+ return addresses[0];
+}
+
+/**
+ * get ip address from arrow server
+ * @return {*}
+ */
+servermanager.getArrowServerHost =function() {
+ var statusfile = path.join(arrowConfig['arrowModuleRoot'], "tmp", "arrow_server.status"), ip;
+ try {
+ if (fs.statSync(statusfile).isFile()) {
+ var file = fs.readFileSync(statusfile, 'utf8'),
+ ipreg = /^((http|https):\/\/)?((.*?):(.*?)@)?([a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])((\.[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])*)(:([0-9]{1,5}))?/;
+ // like http://10.82.133.96:10000 or https://localhost:10000
+ if (file.match(ipreg)) {
+ ip = file.match(ipreg)[0]; //extract ip address
+ }
+ }
+ } catch (e) {
+ serverManagerLogger.warn("Arrow server status does not exist");
+ }
+ return ip;
+}
+
+servermanager.getProperIPAddressForArrowServer = function () {
+ // maybe we should add method to get "proper" ip if the local host has multiply ip address
+ return this.getLocalhostIPAddress();
+};
+
+
+servermanager.getArrowServerStatus = function (cb) {
+
+ var serverip = this.getArrowServerHost();
+ if(!serverip)return cb(false);
+
+ var ipreg = /[^((http|https):\/\/)](([a-zA-Z0-9][a-zA-Z0-9\-]{0,61})((\.[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])*)(:([0-9]{1,5}))+)/;
+ // like http://10.82.133.96:10000 or https://localhost:10000
+ if (serverip.match(ipreg)) {
+ serverip = serverip.match(ipreg)[0]; //extract ip address
+ }
+
+ var split=serverip.split(":");
+ if(!split || !split.length >= 2)return cb(false);
+ portchecker.isOpen(split[split.length-1],split[split.length-2],function(opened,port,host){
+ if(opened){
+ serverManagerLogger.info("server is running at:"+serverip);
+ }else{
+ serverManagerLogger.info("server is not running at:"+serverip);
+ }
+ return cb(opened)
+ });
+};
+
+servermanager.startArrowServer = function () {
+
+ // var forever = require("forever");
+ // forever.start(path.join(self.config['arrowModuleRoot'], "arrow_server", "server.js"), {debug:true});
+
+ var childProcess = require("child_process");
+ child = childProcess.fork(path.join(arrowConfig['arrowModuleRoot'], "arrow_server", "server.js"), [], {});
+ child.on('message', function (m) {
+ serverManagerLogger.info("arrow server message:" + m);
+ });
+ child.on("exit", function () {
+ serverManagerLogger.info("arrow server exit!");
+ });
+
+};
+
+/**
+ * stop arrow server,default kill the server started by this manager
+ * if killall is given ,will kill all arrow_server
+ * @param force force kill
+ */
+servermanager.stopArrowServer = function (killall) {
+
+ if(child){
+ child.kill();
+ serverManagerLogger.info("kill arrow server !");
+ }
+ if(killall){
+ var exec = require('child_process').exec;
+ exec('ps aux|grep '+path.join(arrowConfig['arrowModuleRoot'], "arrow_server", "server.js")+'|grep -v \'grep\'|awk \'{print $2}\'|xargs kill -9',
+ function (error, stdout, stderr) {
+ serverManagerLogger.debug('stdout: ' + stdout);
+ serverManagerLogger.debug('stderr: ' + stderr);
+ if (error !== null) {
+ serverManagerLogger.debug('exec error: ' + error);
+ }
+ });
+ }
+
+};
View
416 lib/util/sharelibscanner.js
@@ -12,24 +12,28 @@ var path = require('path'),
var sync = require('async');
var log4js = require("log4js");
+var shareLibLogger = new log4js.getLogger("sharelibScanner");
-var arrowConfig = require('../../config/config');
+var servermgr = require('./arrowservermanager');
var SHARE_LIB_CONTROLLER_DIR = "controller";
var SHARE_LIB_YUILIB_DIR = "lib";
var SHARE_LIB_MODULES_DIR = ["server", "client", "common"];
var CUSTOM_CONTROLLER_META = "custom_controller.json";
-var CLIENT_CONFIG_NAME = arrowConfig.clientConfigName || "client_seed.js";
-var SERVER_CONFIG_NAME = arrowConfig.serverConfigName || "server_seed.js";
+var CLIENT_CONFIG_NAME = "client_config.json"
+var SERVER_CONFIG_NAME = "server_config.json"
+
+var arrowConfig = require('../../config/config');
+var ARROW_MODULES_ROOT = arrowConfig.arrowModuleRoot || path.join(__dirname, "../");
var SHARE_LIB_DIR_PREFIX = arrowConfig.scanShareLibPrefix || [];
var SHARE_LIB_SCAN_RECURSIVE = arrowConfig.scanShareLibRecursive || false;
-var BUILD_IN_SHARE_LIB_PATH = path.join(arrowConfig.arrowModuleRoot, "sharelib");
+var BUILD_IN_SHARE_LIB_PATH = path.join(ARROW_MODULES_ROOT, "sharelib");
-var scanlibpath = arrowConfig.scanShareLibPath || path.join(__dirname, "../../");
-var shareLibMetaPath = path.join(arrowConfig.arrowModuleRoot, "tmp");
-var arrowServerHost = getArrowServerHost();
+var scanlibpath = arrowConfig.shareLibPath || [];
+var shareLibMetaPath = path.join(ARROW_MODULES_ROOT, "tmp");
+var arrowServerHost;
var config_client;
var config_server;
@@ -39,35 +43,23 @@ var custom_controller;
* scan given path for all sharelib moudules and controllers
* @constructor
*/
-function sharelibscanner() {
- this.logger = log4js.getLogger("sharelibScanner");
+function sharelibscanner(config) {
+ this.logger = shareLibLogger;
+ this.config = config || {};
+
+ ARROW_MODULES_ROOT = this.config['arrowModuleRoot'] || path.join(__dirname, "../");
+ SHARE_LIB_DIR_PREFIX = this.config['scanShareLibPrefix'] || [];
+ SHARE_LIB_SCAN_RECURSIVE = this.config['scanShareLibRecursive'] || false;
+ BUILD_IN_SHARE_LIB_PATH = path.join(ARROW_MODULES_ROOT, "sharelib");
+ scanlibpath = this.config['shareLibPath'] || [];
+ shareLibMetaPath = path.join(ARROW_MODULES_ROOT, "tmp");
+
config_client = {};
config_server = {};
custom_controller = {};
}
/**
- * get ip address from arrow server
- * @return {*}
- */
-function getArrowServerHost() {
- var statusfile = path.join(shareLibMetaPath, "arrow_server.status"), ip;
- try {
- if (fs.statSync(statusfile).isFile()) {
- var file = fs.readFileSync(statusfile, 'utf8'),
- ipreg = /^((http|https):\/\/)?((.*?):(.*?)@)?([a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])((\.[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])*)(:([0-9]{1,5}))?/;
- // like http://10.82.133.96:10000 or https://localhost:10000
- if (file.match(ipreg)) {
- ip = file.match(ipreg)[0]; //extract ip address
- }
- }
- } catch (e) {
- console.info("Arrow server status does not exist");
- }
- return ip;
-}
-
-/**
* show help
*/
function showHelp() {
@@ -174,6 +166,8 @@ function isHiddenFile(f) {
*/
sharelibscanner.prototype.genSeedFile = function (scanFolder, callback) {
+ var self = this;
+
var tmpPath = scanFolder || scanlibpath;
tmpPath = Array.isArray(tmpPath) ? tmpPath : [tmpPath];
@@ -188,66 +182,98 @@ sharelibscanner.prototype.genSeedFile = function (scanFolder, callback) {
return showHelp();
}
- var start = new Date().getTime();
-
- var self = this;
-
- var doscan = function (scanpath, finishone) {
-
- var fspath = path.normalize(scanpath);
-
- self.logger.info('Start scan share lib from : ' + fspath);
-
- try {
- if (!fs.statSync(fspath).isDirectory()) {
- self.logger.error('Please make sure the lib folder ' + fspath + ' exist!');
+ function startGenerateProcess() {
+ var start = new Date().getTime();
+ var doscan = function (scanpath, finishone) {
+ var fspath = path.normalize(scanpath);
+ self.logger.info('Start scan share lib from : ' + fspath);
+ try {
+ if (!fs.statSync(fspath).isDirectory()) {
+ self.logger.error('Please make sure the lib folder ' + fspath + ' exist!');
+ showHelp();
+ return finishone();
+ }
+ } catch (e) {
+ self.logger.error('Please make sure the lib folder ' + fspath + 'exist');
showHelp();
return finishone();
}
- } catch (e) {
- self.logger.error('Please make sure the lib folder ' + fspath + 'exist');
- showHelp();
- return finishone();
- }
-
- // if fspath self is sharelib modules,generate meta info directly
- if (isShareLib(fspath)) {
- generateMetaData(path.basename(fspath), fspath, function (e, message) {
- if (e) {
- self.logger.info(e);
- } else {
- self.logger.info(message);
- finishone();
- }
- });
- } else { // do scan
- scan(fspath, function (e, message) {
- if (e) {
- self.logger.info(e);
- } else {
- self.logger.info(message);
- finishone();
- }
- });
+ // if fspath self is sharelib modules,generate meta info directly
+ if (isShareLib(fspath)) {
+ generateMetaData(path.basename(fspath), fspath, function (e, message) {
+ if (e) {
+ self.logger.info(e);
+ } else {
+ self.logger.info(message);
+ finishone();
+ }
+ });
+ } else { // do scan
+ scan(fspath, function (e, message) {
+ if (e) {
+ self.logger.info(e);
+ } else {
+ self.logger.info(message);
+ finishone();
+ }
+ });
+ }
}
+ sync.forEachSeries(pathForScan, doscan, function () {
+ self.logger.info("Total time of Scan :" + (new Date().getTime() - start) / 1000 + " s");
+ //write modules info
+ writeSeedFile(function (err, message) {
+ if (err) {
+ self.logger.error(err);
+ } else {
+ self.logger.debug("-- Sharelib meta info:");
+ self.logger.debug(JSON.stringify(config_client));
+ self.logger.debug(JSON.stringify(config_server));
+ self.logger.debug(JSON.stringify(custom_controller));
+ self.logger.info(message);
+ }
+ callback();
+ })
+ }
+ );
}
- sync.forEachSeries(pathForScan, doscan, function () {
- self.logger.info("Total time of Scan :" + (new Date().getTime() - start) / 1000 + " s");
- //write modules info
- writeSeedFile(function (err, message) {
- if (err) {
- self.logger.error(err);
- } else {
- self.logger.debug("-- Sharelib meta info:");
- self.logger.debug(JSON.stringify(config_client));
- self.logger.debug(JSON.stringify(config_server));
- self.logger.info(message);
- }
- callback();
- })
- }
- );
+ // if you want to enable Share Lib YUI Loader,you must have arrow_server start
+
+ if (self.config['enableShareLibYUILoader']) {
+ servermgr.getArrowServerStatus(function (isrunning) {
+ if (isrunning) {
+ startGenerateProcess();
+ } else {
+
+ self.logger.info(" Arrow will start arrow_server for you to use share lib YUI Loader");
+ servermgr.startArrowServer();
+
+ var tid, maxTry = 10, checkServerStatusimeout = 500;
+ tid = setInterval(function () {
+ if ((maxTry--) === 0) {
+ clearInterval(tid);
+ arrowServerHost = servermgr.getArrowServerHost();
+ if (arrowServerHost != undefined) {
+ startGenerateProcess();
+ } else {
+ self.logger.error(" Start arrow server failed ");
+ return;
+ }
+ } else {
+ arrowServerHost = servermgr.getArrowServerHost();
+ if (arrowServerHost !== undefined) {
+ startGenerateProcess();
+ clearInterval(tid);
+ }
+ }
+ }, checkServerStatusimeout);
+ // should we stop it ?
+ }
+ });
+ } else {
+ startGenerateProcess();
+ }
}
/**
@@ -267,29 +293,28 @@ function writeSeedFile(cb) {
}
}
- var client_template =
- 'var SCANNED_YUI_GROUP=%client%;' +
- 'if(!YUI){' +
- 'YUI_config={' +
- 'groups:SCANNED_YUI_GROUP' + '}' +
- '}' + 'else{' +
- 'YUI.GlobalConfig = {' +
- 'groups:SCANNED_YUI_GROUP' +
- '}}';
+ if (Object.keys(config_client) !== 0) {
+ removeEmptyModulesOfConfig(config_client);
+ }
+ if (Object.keys(config_server) !== 0) {
+ removeEmptyModulesOfConfig(config_server);
+ }
- var server_template = 'YUI = YUI ? YUI : require(\'yui\').YUI;' +
- 'YUI.GlobalConfig = {' +
- 'groups:%server%' +
- '}';
+ try {
+ // client seed
+ fs.writeFileSync(path.join(shareLibMetaPath, CLIENT_CONFIG_NAME), JSON.stringify(config_client));
+ // server seed
+ fs.writeFileSync(path.join(shareLibMetaPath, SERVER_CONFIG_NAME), JSON.stringify(config_server));
+ // share lib controller
+ fs.writeFileSync(path.join(shareLibMetaPath, CUSTOM_CONTROLLER_META), JSON.stringify(custom_controller));
- removeEmptyModulesOfConfig(config_client);
- removeEmptyModulesOfConfig(config_server);
+ cb(null, "Write sharelib modules meta done!");
+
+ } catch (e) {
+ cb("write seed file err:" + e);
+ }
- fs.writeFileSync(path.join(shareLibMetaPath, CLIENT_CONFIG_NAME), client_template.replace(/%client%/g, JSON.stringify(config_client)));
- fs.writeFileSync(path.join(shareLibMetaPath, SERVER_CONFIG_NAME), server_template.replace(/%server%/g, JSON.stringify(config_server)));
- fs.writeFileSync(path.join(shareLibMetaPath, CUSTOM_CONTROLLER_META), JSON.stringify(custom_controller));
- cb(null, "Write sharelib modules meta done!");
}
/**
@@ -300,7 +325,7 @@ function initMetaData(libname) {
var GROUP_ROOT = "";
// set up for client side base and root
-
+ arrowServerHost = arrowServerHost || servermgr.getArrowServerHost();
var GROUP_BASE = arrowServerHost || "http://localhost:10000"; //to be replace if arrow server not started
config_client[libname] = config_client[libname] || {};
config_client[libname].base = config_client[libname].base || GROUP_BASE + "/arrow/static";
@@ -590,8 +615,13 @@ var contextForRunInContext = libvm.createContext({
function captureYUIModuleDetails(filePath) {
var file,
yui = {};
- file = fs.readFileSync(filePath, 'utf8');
- // setting up the fake YUI before executing the file
+ try{
+ file = fs.readFileSync(filePath, 'utf8');
+ }catch(e){
+ console.error(e);
+ return null;
+ }
+ // setting up the fake YUI before executing the file
contextForRunInContext.YUI = {
ENV:{},
config:{},
@@ -615,4 +645,178 @@ function captureYUIModuleDetails(filePath) {
return yui;
}
+
+/**
+ * get yui modules details if the file has mutiple yui add/use
+ * @param filePath file path to js file
+ * @return {Object}
+ */
+function captureMutipleYUIModuleDetails(filePath) {
+ var file,
+ yui = {},
+ yreq = [];
+ try{
+ file = fs.readFileSync(filePath, 'utf8');
+ }catch(e){
+ console.error(e);
+ return null;
+ }
+ // setting up the fake YUI before executing the file
+ contextForRunInContext.YUI = {
+ ENV:{},
+ config:{},
+ use:function () {
+ },
+ add:function (name, fn, version, meta) {
+ yui.name = name;
+ yui.version = version;
+ yui.meta = meta || {};
+ if (!yui.meta.requires) {
+ yui.meta.requires = [];
+ }
+ yreq = yreq.concat(yui.meta.requires);
+ }
+ };
+ try {
+ libvm.runInContext(file, contextForRunInContext, filePath);
+ } catch (e) {
+ yreq = [];
+ console.error('Failed to parse javascript(YUI) file: ' + filePath + '\n' + e.message, 'error');
+ }
+ return yreq;
+}
+
+
+/**
+ * get the source code by given a libname and affnity
+ * @param libname
+ * @param affnity
+ */
+function getShareLibSourcePath(libname, affnity) {
+
+ var server_config = {};
+ try {
+ var server_config = require(path.join(shareLibMetaPath, SERVER_CONFIG_NAME));
+ } catch (e) {
+ shareLibLogger.debug("Can't find server config file :" + SERVER_CONFIG_NAME + " in: " + shareLibMetaPath);
+ shareLibLogger.debug(e);
+ }
+ var client_config = {};
+ try {
+ var client_config = require(path.join(shareLibMetaPath, CLIENT_CONFIG_NAME));
+
+ } catch (e) {
+ shareLibLogger.debug("Can't find client config file :" + CLIENT_CONFIG_NAME + " in: " + shareLibMetaPath);
+ shareLibLogger.debug(e);
+ }
+
+ function findSrcFromSeed(libname, affnity) {
+
+ shareLibLogger.debug("getting source by libname: " + libname + " , affnity: " + affnity);
+
+ var findLibInConfig = function (config, libname, affnity) {
+ var libs = [];
+ for (var key in config) {
+ if (config.hasOwnProperty(key) &&
+ config[key]['modules'] &&
+ config[key]['modules'][libname]) { //find libname
+ libs.push(config[key]['modules'][libname].path);
+ if (config[key]['modules'][libname].requires) {
+ for (var i = 0; i < config[key]['modules'][libname].requires.length; i++) {
+ libs = libs.concat(findLibInConfig(config, config[key]['modules'][libname].requires[i], affnity));
+ }
+ return libs;
+ }
+ return libs;
+ }
+ }
+ };
+
+ if (affnity === "server" || affnity === "common") {
+ if (server_config) {
+ return findLibInConfig(server_config, libname, affnity);
+ }
+ } else if (affnity === "client") {
+ if (client_config) {
+ return findLibInConfig(client_config, libname, affnity);
+ }
+ } else {
+ shareLibLogger.debug("Unknown affnity");
+ }
+ return [];
+ }
+
+ if (!libname)return shareLibLogger.error("lib name not given");
+
+ var foundLibs = findSrcFromSeed(libname, affnity ? affnity : "common");
+ shareLibLogger.debug(foundLibs);
+ return foundLibs ? foundLibs : [];
+}
+
+/**
+ * get lib's dependency and get its content from share lib;
+ * @param libpath
+ * @return {String}
+ */
+function getShareLibSrcByPath(libpath, affnity) {
+
+ var testLibsJs = [];
+ var yreq = captureMutipleYUIModuleDetails(libpath);
+ if (yreq && yreq.length > 0) {
+ for (var i = 0; i < yreq.length; i++) {
+ testLibsJs = testLibsJs.concat(getShareLibSourcePath(yreq[i], affnity));
+ }
+ }
+ return testLibsJs ? testLibsJs : [];
+}
+
+/**
+ * get Share Lib Client Side Modules Meta
+ * @return {*}
+ */
+function getShareLibClientSideModulesMeta() {
+
+ var client_template =
+ 'var SCANNED_YUI_GROUP=%client%;' +
+ 'if(!YUI){' +
+ 'YUI_config={' +
+ 'groups:SCANNED_YUI_GROUP' + '}' +
+ '}' + 'else{' +
+ 'YUI.GlobalConfig = {' +
+ 'groups:SCANNED_YUI_GROUP' +
+ '}}' + "\n";
+
+ try {
+ var shareLibClientSeedJs = fs.readFileSync(path.join(shareLibMetaPath, CLIENT_CONFIG_NAME), "utf-8");
+ return client_template.replace(/%client%/g, shareLibClientSeedJs);
+ } catch (e) {
+ shareLibLogger.error("No client side share lib seed file found");
+ }
+ return "";
+}
+
+/**
+ * get Share Lib Server Side Modules Meta
+ * @return {*}
+ */
+function getShareLibServerSideModulesMeta() {
+
+ var server_template = 'YUI = YUI ? YUI : require(\'yui\').YUI;' +
+ 'YUI.GlobalConfig = {' +
+ 'groups:%server%' +
+ '}' + "\n";
+
+ try {
+ var shareLibServerSeedJs = fs.readFileSync(path.join(shareLibMetaPath, SERVER_CONFIG_NAME), "utf-8");
+ return server_template.replace(/%server%/g, shareLibServerSeedJs);
+ } catch (e) {
+ shareLibLogger.error("No server side share lib seed file found");
+ }
+ return "";
+}
+
module.exports = sharelibscanner;
+
+module.exports.getShareLibSrcByPath = getShareLibSrcByPath;
+module.exports.getShareLibClientSideModulesMeta = getShareLibClientSideModulesMeta;
+module.exports.getShareLibServerSideModulesMeta = getShareLibServerSideModulesMeta;
View
12 tests/functional/arrow_commands.sh
@@ -234,4 +234,16 @@ if [ $? != 0 ]; then
echo "ERROR!"
echo "CMD: $CMD"
echo "RESULT: $RESULT"
+} fi
+
+echo "TEST26: "
+# for scan lib test with enable ShareLib YUI Loader
+# this will auto start arrow server
+# --browser=chrome --driver=selenium
+CMD=`$ARROWCI ./data/arrow_test/sharelib-test-unit-no-lib.js --browser=$BROWSERNAME --shareLibPath=./data/arrow_test/martini_lib/ --enableShareLibYUILoader=true --seleniumHost=$HUBHOST --capabilities=./data/arrow_test/cap.json | tail -2 | head -1 >./data/actual_op/test26.txt`
+if [ $? != 0 ]; then
+{
+ echo "ERROR!"
+ echo "CMD: $CMD"
+ echo "RESULT: $RESULT"
} fi
View
2  tests/functional/data/expected_op/expected_test23.txt
@@ -1 +1 @@
-Please make sure the lib folder exist
+Please make sure the lib folder
View
1  tests/functional/data/expected_op/expected_test26.txt
@@ -0,0 +1 @@
+Passed:1 Failed:0 Total:1 (0 ignored)
View
18 tests/functional/tests/nodeunit/test26.js
@@ -0,0 +1,18 @@
+/**
+ * Created with JetBrains WebStorm.
+ * User: payshah
+ * Date: 7/26/12
+ * Time: 1:47 PM
+ * To change this template use File | Settings | File Templates.
+ */
+
+var fs = require('fs');
+
+exports.testunitwithScanPath = function(test){
+
+ var test26 = fs.readFileSync("data/actual_op/test26.txt", "utf-8")
+ var expected_test26 = fs.readFileSync("data/expected_op/expected_test26.txt", "utf-8")
+
+ test.equal(test26,expected_test26,"The expected output for config.js should be "+expected_test26+ " but it is " +test26);
+ test.done();
+};
View
65 tests/unit/lib/util/arrowservermanager-tests.js
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ * Copyrights licensed under the New BSD License.
+ * See the accompanying LICENSE file for terms.
+ */
+
+
+YUI.add('arrowservermanager-tests', function (Y) {
+
+ var path = require('path');
+ global.appRoot = path.join(__dirname, '../../../..');
+ var fs = require('fs'),
+ arrowRoot = global.appRoot,
+ servermanager = require(arrowRoot + '/lib/util/arrowservermanager.js'),
+ suite = new Y.Test.Suite("arrow server manager test suite");
+
+ suite.add(new Y.Test.Case({
+
+ "Test get localhost ip":function () {
+
+ Y.Assert.isTrue(/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/.test(servermanager.getLocalhostIPAddress()));
+ Y.Assert.isTrue(/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/.test(servermanager.getProperIPAddressForArrowServer()));
+
+ },
+ "Test server host":function () {
+
+ Y.Assert.isTrue(servermanager.getArrowServerHost()==undefined);
+
+ servermanager.getArrowServerStatus(function(res){
+ Y.Assert.isFalse(res);
+ });
+ },
+
+ "ignore:Test start/stop server":function () {
+
+ var self =this;
+
+ servermanager.startArrowServer();
+ var exec = require('child_process').exec;
+ exec('ps aux|grep arrow_server/server.js | grep -v \'grep\'',
+ function (error, stdout, stderr) {
+ self.resume(function(){
+ console.log(stdout);
+ Y.Assert.isTrue(stdout.length>0);
+ })
+ });
+ self.wait(5000);
+
+ servermanager.stopArrowServer(true);
+
+ self.wait(5000,function(){
+ var exec = require('child_process').exec;
+ exec('ps aux|grep arrow_server/server.js | grep -v \'grep\'',
+ function (error, stdout, stderr) {
+ console.log(stdout);
+ Y.Assert.isFalse(stdout.length>0);
+ });
+ });
+ }
+ }));
+
+ Y.Test.Runner.add(suite);
+
+}, '0.0.1', {requires:['test']});
+
View
59 tests/unit/lib/util/sharelibscanner-tests.js
@@ -20,8 +20,8 @@ YUI.add('sharelibscanner-tests', function (Y) {
function setup() {
try {
- fs.unlinkSync(path.join(metaPath, 'client_seed.js'));
- fs.unlinkSync(path.join(metaPath, 'server_seed.js'));
+ fs.unlinkSync(path.join(metaPath, 'client_config.json'));
+ fs.unlinkSync(path.join(metaPath, 'server_config.json'));
fs.unlinkSync(path.join(metaPath, 'custom_controller.json'));
} catch (e) {
}
@@ -35,10 +35,10 @@ YUI.add('sharelibscanner-tests', function (Y) {
}
function assertFileExsit(filelist) {
- var isTrue = contains(filelist, 'client_seed.js');
- Y.Assert.areEqual(true, isTrue, "Confirm client_seed.js is generated");
- isTrue = contains(filelist, 'server_seed.js');
- Y.Assert.areEqual(true, isTrue, "Confirm server_seed.js is generated");
+ var isTrue = contains(filelist, 'client_config.json');
+ Y.Assert.areEqual(true, isTrue, "Confirm client_config.json is generated");
+ isTrue = contains(filelist, 'server_config.json');
+ Y.Assert.areEqual(true, isTrue, "Confirm server_config.json is generated");
isTrue = contains(filelist, 'custom_controller.json');
Y.Assert.areEqual(true, isTrue, "Confirm custom_controller.json is generated");
}
@@ -53,13 +53,13 @@ YUI.add('sharelibscanner-tests', function (Y) {
console.log(e);
}
}
- readseed('client_seed.js', function (data) {
+ readseed('client_config.json', function (data) {
console.log("~~~~~~~ read client seed");
Y.Assert.isTrue(data.indexOf("mymartini.client.js") != -1
&& data.indexOf("mymartini.common.js") != -1);
});
- readseed('server_seed.js', function (data) {
+ readseed('server_config.json', function (data) {
console.log("~~~~~~~ read server seed");
Y.Assert.isTrue(data.indexOf("mymartini.server.js") != -1
&& data.indexOf("mymartini.common.js") != -1);
@@ -72,7 +72,7 @@ YUI.add('sharelibscanner-tests', function (Y) {
});
}
-
+ global.appRoot = path.join(__dirname, '../../../..');
suite.add(new Y.Test.Case({
"Test generate Seed File given no scan path":function () {
setup();
@@ -82,7 +82,7 @@ YUI.add('sharelibscanner-tests', function (Y) {
"Test generate Non-Exsit-Path Seed File":function () {
var self = this;
setup();
- new sharelibScanner().genSeedFile(["Non-Exsit-Path", scanMartiniFolder + '/lib/common/mymartini.common.js'], function () {
+ new sharelibScanner({arrowModuleRoot:arrowRoot}).genSeedFile(["Non-Exsit-Path", scanMartiniFolder + '/lib/common/mymartini.common.js'], function () {
console.log("~~~~~~~~~~Non-exist-path");
fs.readdir(metaPath, function (err, list) {
self.resume(function () {
@@ -95,7 +95,7 @@ YUI.add('sharelibscanner-tests', function (Y) {
"Test generate default Seed File":function () {
var self = this;
setup();
- new sharelibScanner().genSeedFile(undefined, function () {
+ new sharelibScanner({arrowModuleRoot:arrowRoot}).genSeedFile(undefined, function () {
self.resume(function () {
console.log("~~~~~~~~~~default");
fs.readdir(metaPath, function (err, list) {
@@ -112,7 +112,7 @@ YUI.add('sharelibscanner-tests', function (Y) {
"Test generate specified folder Seed File":function () {
var self = this;
setup();
- new sharelibScanner().genSeedFile(scanFolder, function () {
+ new sharelibScanner({arrowModuleRoot:arrowRoot}).genSeedFile(scanFolder, function () {
self.resume(function () {
console.log("~~~~~~~~~~specified folder");
fs.readdir(metaPath, function (err, list) {
@@ -130,7 +130,7 @@ YUI.add('sharelibscanner-tests', function (Y) {
"Test generate specified martini modules Seed File":function () {
var self = this;
setup();
- new sharelibScanner().genSeedFile(scanMartiniFolder, function () {
+ new sharelibScanner({arrowModuleRoot:arrowRoot}).genSeedFile(scanMartiniFolder, function () {
self.resume(function () {
console.log("~~~~~~~~~~ matini folder");
fs.readdir(metaPath, function (err, list) {
@@ -145,6 +145,39 @@ YUI.add('sharelibscanner-tests', function (Y) {
});
self.wait(5000);
}
+ ,
+ "Test get generated Seed File":function () {
+ var self = this;
+ new sharelibScanner({arrowModuleRoot:arrowRoot}).genSeedFile(scanMartiniFolder, function () {
+ self.resume(function () {
+ console.log("~~~~~~~~~~ matini folder");
+ fs.readdir(metaPath, function (err, list) {
+ self.resume(function () {
+ console.log("++++++++++++++++ assert file");
+ assertFileExsit(list);
+ assertFileContentExsit();
+
+ var data=sharelibScanner.getShareLibClientSideModulesMeta();
+ Y.Assert.isTrue(data.indexOf("mymartini.client.js") != -1
+ && data.indexOf("mymartini.common.js") != -1);
+
+ data=sharelibScanner.getShareLibServerSideModulesMeta();
+ Y.Assert.isTrue(data.indexOf("mymartini.server.js") != -1
+ && data.indexOf("mymartini.common.js") != -1);
+
+ var libs=sharelibScanner.getShareLibSrcByPath('test-martini-lib-client','client');
+ console.log(libs);
+ Y.Assert.isFalse(libs==null);
+
+ Y.Assert.isTrue(sharelibScanner.getShareLibSrcByPath(__dirname+'/sharelibtestdata/martini_lib/lib/client/mymartini.client.js','client')!=null);
+
+ });
+ });
+ self.wait(1000);
+ });
+ });
+ self.wait(5000);
+ }
}));
Y.Test.Runner.add(suite);
Please sign in to comment.
Something went wrong with that request. Please try again.