2013-07-19 30 views
5

Đây là một phiên bản đơn giản của ứng dụng nhanh cụm tôi:Làm cách nào để kiểm tra ứng dụng Express được phân cụm với Mocha?

/index.js

module.exports = process.env.CODE_COV 
    ? require('./lib-cov/app') 
    : require('./lib/app'); 

/lib/app.js

var cluster = require('cluster'), 
    express = require('express'), 
    app = module.exports = express.createServer(); 

if (cluster.isMaster) { 
    // Considering I have 4 cores. 
    for (var i = 0; i < 4; ++i) { 
     cluster.fork(); 
    } 
} else { 
    // do app configurations, then... 

    // Don't listen to this port if the app is required from a test script. 
    if (!module.parent.parent) { 
     app.listen(8080); 
    } 
} 

/test/test1 .js

var app = require('../'); 

app.listen(7777); 

// send requests to app, then assert the response. 

Câu hỏi:

  1. var app = require('../'); sẽ không làm việc trong môi trường cụm này. Ứng dụng công nhân nào sẽ trở lại? Nó có nên trả về đối tượng cụm thay vì ứng dụng Express không?
  2. Bây giờ, thiết lập rõ ràng cổng trong tập lệnh thử nghiệm sẽ không hoạt động. Bạn sẽ đặt một cổng trong một tập lệnh thử nghiệm thành một nhóm ứng dụng như thế nào?
  3. Bạn sẽ gửi yêu cầu tới nhóm ứng dụng này như thế nào?

Giải pháp duy nhất tôi có thể nghĩ là tắt tính năng phân cụm theo điều kiện và chỉ chạy một ứng dụng nếu ứng dụng được yêu cầu từ tập lệnh thử nghiệm (if (module.parent.parent) ...).

Bất kỳ cách nào khác để kiểm tra ứng dụng Express được phân cụm với Mocha?

Trả lời

8

Đã khá lâu rồi kể từ khi tôi đăng câu hỏi này. Vì không ai trả lời, tôi sẽ tự trả lời câu hỏi này.

tôi giữ /index.js vì nó là:

module.exports = process.env.CODE_COV 
    ? require('./lib-cov/app') 
    : require('./lib/app'); 

Trong /lib/app.js mà bắt đầu các cụm, tôi đã đoạn mã sau. Tóm lại, tôi bắt đầu cụm chỉ trong môi trường không kiểm tra. Trong môi trường thử nghiệm cụm không bắt đầu nhưng chỉ có một ứng dụng/nhân viên được bắt đầu như được định nghĩa trong điều kiện cluster.isMaster && !module.parent.parent.

var cluster = require('cluster'), 
    express = require('express'), 
    app = module.exports = express.createServer(); 

if (cluster.isMaster && !module.parent.parent) { 
    // Considering I have 4 cores. 
    for (var i = 0; i < 4; ++i) { 
     cluster.fork(); 
    } 
} else { 
    // do app configurations, then... 

    // Don't listen to this port if the app is required from a test script. 
    if (!module.parent.parent) { 
     app.listen(8080); 
    } 
} 

Trong trường hợp trên !module.parent.parent sẽ được đánh giá là đối tượng trung thực nếu ứng dụng không được bắt đầu bằng tập lệnh thử nghiệm.

  1. module là hiện /lib/app.js kịch bản.
  2. module.parent là phụ huynh /index.js tập lệnh.
  3. module.parent.parentundefined nếu ứng dụng được bắt đầu trực tiếp qua node index.js.
  4. module.parent.parent là tập lệnh thử nghiệm nếu ứng dụng được bắt đầu qua một trong các tập lệnh.

Vì vậy, tôi có thể khởi động kịch bản một cách an toàn nơi tôi có thể đặt cổng tùy chỉnh.

/test/test1.js

var app = require('../'); 

app.listen(7777); 

// send requests to app, then assert the response. 

Cùng lúc đó nếu tôi cần phải chạy các ứng dụng trong thực tế, tức là không để thử nghiệm, sau đó tôi chạy node index.js và nó sẽ khởi động cụm các ứng dụng.

0

Tôi thích giải pháp của bạn vì nó đơn giản, tuy nhiên, trong một môi trường như khung MVC cho nút, bạn có thể kết thúc chuỗi mô-đun.bên trong tối đa 11 lần (nghiêm túc).

Tôi nghĩ cách tiếp cận tốt hơn là chỉ cần kiểm tra xem nút script nào đã bắt đầu xử lý. Các đối số dòng lệnh của nút có sẵn tại process.argv. Mục đầu tiên trong mảng này sẽ là 'nút', tệp thực thi và đối số thứ hai sẽ là đường dẫn đến tệp mà nút bắt đầu thực hiện. Đây sẽ là index.js trong trường hợp của bạn.

Vì vậy, thay vì kiểm tra

    module.parent.parent 
          ^ ^  
         (app.js) | 
           (index.js) 

Bạn có thể làm một cái gì đó như thế này

var starter = process.argv[1].split(path.sep).pop(); 

đâu starter sẽ index hoặc index.js tùy thuộc vào những gì bạn bắt đầu máy chủ của bạn với. node index.js vs node index

Vui lòng cung sau đó sẽ như thế nào:

if (cluster.isMaster && starter === 'index.js') { 
    cluster.fork(); 
} 

Làm việc trong môi trường của tôi-Tôi hy vọng điều này sẽ giúp!

+0

Đây là loại giả trông nguy hiểm bởi vì tôi don' t biết làm thế nào các danh sách đối số sẽ hành xử nếu, ví dụ, ứng dụng được thực hiện trong suốt mãi mãi hoặc pm2 như daemon. – Eye

+0

Bạn biết cách danh sách đối số sẽ hoạt động. [process.argv] (http://nodejs.org/docs/latest/api/process.html#process_process_argv) sẽ luôn chứa 0: "nút" và 1: tập lệnh mà nút đang xử lý. – jbielick

+0

Tôi nghĩ rằng bạn đang bối rối một sợi cpu với một quá trình con nút. Nếu bạn sử dụng màn hình daemon chẳng hạn như mãi mãi, mãi mãi sẽ bắt đầu quy trình tổng thể phù hợp, sau đó sẽ ủy quyền các nhánh khác nhau để chạy ứng dụng của bạn. Nếu một ngã ba vĩnh viễn khởi động ứng dụng của bạn, nó vẫn chạy 'nút app.js' ở trung tâm. Mà sẽ bắt đầu một quá trình nút với 'process.argv' như ['node', 'path/to/app.js']. Nếu bạn sử dụng mocha và viết một đơn vị thử nghiệm để làm một cái gì đó như 'exec ('nút app.js')', process.argv sẽ vẫn là '['nút', 'đường dẫn/đến/app.js' ] '. – jbielick

2

Tôi có một cách đơn giản hơn nhiều để làm điều này

if (process.env.NODE_ENV !== 'test') { 
    if (cluster.isMaster) { 
     var numCPUs = require('os').cpus().length; 
     console.log('total cpu cores on this host: ', numCPUs); 
     for (var i = 0; i < numCPUs; i++) { 
      console.log('forking worker...'); 
      cluster.fork(); 
     } 

     cluster.on('online', function(worker) { 
      console.log('Worker ' + worker.process.pid + ' is online.'); 
     }); 
     cluster.on('exit', function(worker, code, signal) { 
      console.log('worker ' + worker.process.pid + ' died.'); 
     }); 
    } else { 
     console.log('Im a worker'); 
     // application code 
     setupServer() 
    } 
} else { 
    // when running tests 
    setupServer(); 
    } 

Chỉ cần chắc chắn để thiết lập env để test khi chạy các bài kiểm tra ví dụ: NODE_ENV=test grunt test

Các vấn đề liên quan