reloadConfiguration-test.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. "use strict";
  2. var vows = require('vows')
  3. , assert = require('assert')
  4. , sandbox = require('sandboxed-module');
  5. function setupConsoleTest() {
  6. var fakeConsole = {}
  7. , logEvents = []
  8. , log4js;
  9. ['trace','debug','log','info','warn','error'].forEach(function(fn) {
  10. fakeConsole[fn] = function() {
  11. throw new Error("this should not be called.");
  12. };
  13. });
  14. log4js = sandbox.require(
  15. '../lib/log4js',
  16. {
  17. globals: {
  18. console: fakeConsole
  19. }
  20. }
  21. );
  22. log4js.clearAppenders();
  23. log4js.addAppender(function(evt) {
  24. logEvents.push(evt);
  25. });
  26. return { log4js: log4js, logEvents: logEvents, fakeConsole: fakeConsole };
  27. }
  28. vows.describe('reload configuration').addBatch({
  29. 'with config file changing' : {
  30. topic: function() {
  31. var pathsChecked = [],
  32. logEvents = [],
  33. logger,
  34. modulePath = 'path/to/log4js.json',
  35. fakeFS = {
  36. lastMtime: Date.now(),
  37. config: {
  38. appenders: [
  39. { type: 'console', layout: { type: 'messagePassThrough' } }
  40. ],
  41. levels: { 'a-test' : 'INFO' }
  42. },
  43. readFileSync: function (file, encoding) {
  44. assert.equal(file, modulePath);
  45. assert.equal(encoding, 'utf8');
  46. return JSON.stringify(fakeFS.config);
  47. },
  48. statSync: function (path) {
  49. pathsChecked.push(path);
  50. if (path === modulePath) {
  51. fakeFS.lastMtime += 1;
  52. return { mtime: new Date(fakeFS.lastMtime) };
  53. } else {
  54. throw new Error("no such file");
  55. }
  56. }
  57. },
  58. fakeConsole = {
  59. 'name': 'console',
  60. 'appender': function () {
  61. return function(evt) { logEvents.push(evt); };
  62. },
  63. 'configure': function (config) {
  64. return fakeConsole.appender();
  65. }
  66. },
  67. setIntervalCallback,
  68. fakeSetInterval = function(cb, timeout) {
  69. setIntervalCallback = cb;
  70. },
  71. log4js = sandbox.require(
  72. '../lib/log4js',
  73. {
  74. requires: {
  75. 'fs': fakeFS,
  76. './appenders/console': fakeConsole
  77. },
  78. globals: {
  79. 'console': fakeConsole,
  80. 'setInterval' : fakeSetInterval,
  81. }
  82. }
  83. );
  84. log4js.configure('path/to/log4js.json', { reloadSecs: 30 });
  85. logger = log4js.getLogger('a-test');
  86. logger.info("info1");
  87. logger.debug("debug2 - should be ignored");
  88. fakeFS.config.levels['a-test'] = "DEBUG";
  89. setIntervalCallback();
  90. logger.info("info3");
  91. logger.debug("debug4");
  92. return logEvents;
  93. },
  94. 'should configure log4js from first log4js.json found': function(logEvents) {
  95. assert.equal(logEvents[0].data[0], 'info1');
  96. assert.equal(logEvents[1].data[0], 'info3');
  97. assert.equal(logEvents[2].data[0], 'debug4');
  98. assert.equal(logEvents.length, 3);
  99. }
  100. },
  101. 'with config file staying the same' : {
  102. topic: function() {
  103. var pathsChecked = [],
  104. fileRead = 0,
  105. logEvents = [],
  106. logger,
  107. modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
  108. mtime = new Date(),
  109. fakeFS = {
  110. config: {
  111. appenders: [
  112. { type: 'console', layout: { type: 'messagePassThrough' } }
  113. ],
  114. levels: { 'a-test' : 'INFO' }
  115. },
  116. readFileSync: function (file, encoding) {
  117. fileRead += 1;
  118. assert.isString(file);
  119. assert.equal(file, modulePath);
  120. assert.equal(encoding, 'utf8');
  121. return JSON.stringify(fakeFS.config);
  122. },
  123. statSync: function (path) {
  124. pathsChecked.push(path);
  125. if (path === modulePath) {
  126. return { mtime: mtime };
  127. } else {
  128. throw new Error("no such file");
  129. }
  130. }
  131. },
  132. fakeConsole = {
  133. 'name': 'console',
  134. 'appender': function () {
  135. return function(evt) { logEvents.push(evt); };
  136. },
  137. 'configure': function (config) {
  138. return fakeConsole.appender();
  139. }
  140. },
  141. setIntervalCallback,
  142. fakeSetInterval = function(cb, timeout) {
  143. setIntervalCallback = cb;
  144. },
  145. log4js = sandbox.require(
  146. '../lib/log4js',
  147. {
  148. requires: {
  149. 'fs': fakeFS,
  150. './appenders/console': fakeConsole
  151. },
  152. globals: {
  153. 'console': fakeConsole,
  154. 'setInterval' : fakeSetInterval,
  155. }
  156. }
  157. );
  158. log4js.configure(modulePath, { reloadSecs: 3 });
  159. logger = log4js.getLogger('a-test');
  160. logger.info("info1");
  161. logger.debug("debug2 - should be ignored");
  162. setIntervalCallback();
  163. logger.info("info3");
  164. logger.debug("debug4");
  165. return [ pathsChecked, logEvents, modulePath, fileRead ];
  166. },
  167. 'should only read the configuration file once': function(args) {
  168. var fileRead = args[3];
  169. assert.equal(fileRead, 1);
  170. },
  171. 'should configure log4js from first log4js.json found': function(args) {
  172. var logEvents = args[1];
  173. assert.equal(logEvents.length, 2);
  174. assert.equal(logEvents[0].data[0], 'info1');
  175. assert.equal(logEvents[1].data[0], 'info3');
  176. }
  177. },
  178. 'when config file is removed': {
  179. topic: function() {
  180. var pathsChecked = [],
  181. fileRead = 0,
  182. logEvents = [],
  183. logger,
  184. modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
  185. mtime = new Date(),
  186. fakeFS = {
  187. config: {
  188. appenders: [
  189. { type: 'console', layout: { type: 'messagePassThrough' } }
  190. ],
  191. levels: { 'a-test' : 'INFO' }
  192. },
  193. readFileSync: function (file, encoding) {
  194. fileRead += 1;
  195. assert.isString(file);
  196. assert.equal(file, modulePath);
  197. assert.equal(encoding, 'utf8');
  198. return JSON.stringify(fakeFS.config);
  199. },
  200. statSync: function (path) {
  201. this.statSync = function() {
  202. throw new Error("no such file");
  203. };
  204. return { mtime: new Date() };
  205. }
  206. },
  207. fakeConsole = {
  208. 'name': 'console',
  209. 'appender': function () {
  210. return function(evt) { logEvents.push(evt); };
  211. },
  212. 'configure': function (config) {
  213. return fakeConsole.appender();
  214. }
  215. },
  216. setIntervalCallback,
  217. fakeSetInterval = function(cb, timeout) {
  218. setIntervalCallback = cb;
  219. },
  220. log4js = sandbox.require(
  221. '../lib/log4js',
  222. {
  223. requires: {
  224. 'fs': fakeFS,
  225. './appenders/console': fakeConsole
  226. },
  227. globals: {
  228. 'console': fakeConsole,
  229. 'setInterval' : fakeSetInterval,
  230. }
  231. }
  232. );
  233. log4js.configure(modulePath, { reloadSecs: 3 });
  234. logger = log4js.getLogger('a-test');
  235. logger.info("info1");
  236. logger.debug("debug2 - should be ignored");
  237. setIntervalCallback();
  238. logger.info("info3");
  239. logger.debug("debug4");
  240. return [ pathsChecked, logEvents, modulePath, fileRead ];
  241. },
  242. 'should only read the configuration file once': function(args) {
  243. var fileRead = args[3];
  244. assert.equal(fileRead, 1);
  245. },
  246. 'should not clear configuration when config file not found': function(args) {
  247. var logEvents = args[1];
  248. assert.equal(logEvents.length, 3);
  249. assert.equal(logEvents[0].data[0], 'info1');
  250. assert.equal(logEvents[1].level.toString(), 'WARN');
  251. assert.include(logEvents[1].data[0], 'Failed to load configuration file');
  252. assert.equal(logEvents[2].data[0], 'info3');
  253. }
  254. },
  255. 'when passed an object': {
  256. topic: function() {
  257. var test = setupConsoleTest();
  258. test.log4js.configure({}, { reloadSecs: 30 });
  259. return test.logEvents;
  260. },
  261. 'should log a warning': function(events) {
  262. assert.equal(events[0].level.toString(), 'WARN');
  263. assert.equal(
  264. events[0].data[0],
  265. 'Ignoring configuration reload parameter for "object" configuration.'
  266. );
  267. }
  268. },
  269. 'when called twice with reload options': {
  270. topic: function() {
  271. var modulePath = require('path').normalize(__dirname + '/../lib/log4js.json'),
  272. fakeFS = {
  273. readFileSync: function (file, encoding) {
  274. return JSON.stringify({});
  275. },
  276. statSync: function (path) {
  277. return { mtime: new Date() };
  278. }
  279. },
  280. fakeConsole = {
  281. 'name': 'console',
  282. 'appender': function () {
  283. return function(evt) { };
  284. },
  285. 'configure': function (config) {
  286. return fakeConsole.appender();
  287. }
  288. },
  289. setIntervalCallback,
  290. intervalCleared = false,
  291. clearedId,
  292. fakeSetInterval = function(cb, timeout) {
  293. setIntervalCallback = cb;
  294. return 1234;
  295. },
  296. log4js = sandbox.require(
  297. '../lib/log4js',
  298. {
  299. requires: {
  300. 'fs': fakeFS,
  301. './appenders/console': fakeConsole
  302. },
  303. globals: {
  304. 'console': fakeConsole,
  305. 'setInterval' : fakeSetInterval,
  306. 'clearInterval': function(interval) {
  307. intervalCleared = true;
  308. clearedId = interval;
  309. }
  310. }
  311. }
  312. );
  313. log4js.configure(modulePath, { reloadSecs: 3 });
  314. log4js.configure(modulePath, { reloadSecs: 15 });
  315. return { cleared: intervalCleared, id: clearedId };
  316. },
  317. 'should clear the previous interval': function(result) {
  318. assert.isTrue(result.cleared);
  319. assert.equal(result.id, 1234);
  320. }
  321. }
  322. }).exportTo(module);