Skip to content

Commit

Permalink
Merge pull request #37 from pioardi/develop
Browse files Browse the repository at this point in the history
Integration tests
  • Loading branch information
pioardi authored Nov 16, 2019
2 parents 3ba943c + 64bf778 commit 2d77492
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 50 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
<strong> Try it out ! </strong>

```bash
docker image build -t ring-election .
docker-compose up
```
Check assigned partitions to local:9000/status or change the port to 9001/9002 <br>
Expand Down Expand Up @@ -138,7 +137,14 @@ Tag 1.0 and public on npm<br>
<h2 id="contribute">How to contribute</h2>
Take tasks from todo list, develop a new feature or fix a bug and do a pull request.<br>
<strong>How to run tests</strong><br>
npm run test
<strong>Unit tests </strong> <br>
npm run test <br><br>
<strong>Integration tests</strong><br>
cd test/integration <br>
./integration.sh <br>
npm run integration-test<br>



<h2 id="versioning">Versioning</h2>
We use (http://semver.org/) for versioning.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ring-election",
"version": "0.0.16",
"version": "1.0.0",
"description": "Leader and followers algorithm to make partitioning easy.",
"main": "index.js",
"engines": {
Expand Down
4 changes: 2 additions & 2 deletions test/hearthbeat.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('Hearth beat', () => {
setTimeout(() => {
expect(count >= 10).toBeTruthy();
done();
}, 20);
}, 200);
});

it('Should do an hearth check with correct frequency', done => {
Expand All @@ -33,6 +33,6 @@ describe('Hearth beat', () => {
setTimeout(() => {
expect(count).toBe(0);
done();
}, 20);
}, 200);
});
});
128 changes: 83 additions & 45 deletions test/integration/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,102 @@ const expect = require('expect');
const request = require('request');
var exec = require('child_process').exec;

let shouldStartWell = (err, response, body , done , nodeNumber) => {
expect(response.statusCode).toBe(200);
expect(body).toBeDefined();
let resp = JSON.parse(body);
expect(resp.length).toBe(3);
// actually the leader has not assigned to any partition.
let leader = resp.find(node => node.partitions.length == 0);
expect(leader).toBeDefined();
// expect other two nodes to have 5 partitions assigned per each.
resp
.filter(node => node.partitions.length > 0)
.forEach(n => {
expect(n.partitions.length).toBe(5);
});
if(nodeNumber == 3)
done();
};
let basicCheck =(response, body,expectedPartitions,expectedNodes) => {
expect(response.statusCode).toBe(200);
expect(body).toBeDefined();
let resp = JSON.parse(body);
expect(resp.length).toBe(expectedNodes);
// actually the leader has not assigned to any partition.
let leader = resp.find(node => node.partitions.length == 0);
expect(leader).toBeDefined();
// expect other node to have 10 partitions assigned per each.
resp
.filter(node => node.partitions.length > 0)
.forEach(n => {
expect(n.partitions.length).toBe(expectedPartitions);
});
};

describe('Integration test', () => {

let shouldStartWell = (err, response, body, done, nodeNumber) => {
basicCheck(response, body,5 , 3);
if (nodeNumber == 3) done();
};

let shouldReassignPartitions = (err, response, body, done, nodeNumber) => {
basicCheck(response, body , 10 , 2);
// restart container
if (nodeNumber == 2) {
exec('docker container restart ring-election_node-2_1', error => {
expect(error).toBeFalsy();
if (!error) done();
});
}
};

let shouldHandleLeaderFailure = (err, response, body, done, nodeNumber) => {
basicCheck(response, body , 10 , 2);
// restart container
if (nodeNumber == 2) {
exec('docker container restart ring-election_node-0_1', error => {
expect(error).toBeFalsy();
if (!error) done();
});
}
};

describe('Integration test', () => {
it('Should start well', done => {
request('http://localhost:9000/status', (err,resp,body) => {
shouldStartWell(err,resp,body,done,1);
request('http://localhost:9000/status', (err, resp, body) => {
shouldStartWell(err, resp, body, done, 1);
});
request('http://localhost:9001/status', (err,resp,body) => {
shouldStartWell(err,resp,body,done,2);
request('http://localhost:9001/status', (err, resp, body) => {
shouldStartWell(err, resp, body, done, 2);
});
request('http://localhost:9002/status', (err,resp,body) => {
shouldStartWell(err,resp,body,done,3);
request('http://localhost:9002/status', (err, resp, body) => {
shouldStartWell(err, resp, body, done, 3);
});
});



it('Should reassign partitions when a node is down', done => {

exec('docker container stop ring-election_node-2_1', err => {
expect(err).toBeFalsy();
setTimeout(() => {
request('http://localhost:9000/status', (err, response, body) => {
expect(response.statusCode).toBe(200);
expect(body).toBeDefined();
let resp = JSON.parse(body);
expect(resp.length).toBe(2);
// actually the leader has not assigned to any partition.
let leader = resp.find((node) => node.partitions.length == 0);
expect(leader).toBeDefined();
// expect other node to have 5 partitions assigned per each.
resp.filter(node => node.partitions.length > 0).forEach(n => {
expect(n.partitions.length).toBe(10);
});
exec('docker container restart ring-election_node-2_1', err => {
if(!err)
done();
else
console.error(err);
});
request('http://localhost:9000/status', (error, resp, body) => {
shouldReassignPartitions(error, resp, body, done, 1);
});
request('http://localhost:9001/status', (error, resp, body) => {
shouldReassignPartitions(error, resp, body, done, 2);
});
}, 15000);
});
});

it('Another node should become leader if the leader fail', done => {
// assume that the node-0 is the leader, it should always be the leader
exec('docker container stop ring-election_node-0_1', err => {
expect(err).toBeFalsy();
setTimeout(() => {
// another node must become the leader.
request('http://localhost:9001/status', (error, resp, body) => {
shouldHandleLeaderFailure(error, resp, body, done, 1);
});
request('http://localhost:9002/status', (error, resp, body) => {
shouldHandleLeaderFailure(error, resp, body, done, 2);
});
// when leader is added again , it should be a follower
setTimeout(() => {
request('http://localhost:9000/status', (error, resp, body) => {
shouldReassignPartitions(error, resp, body, done);
});
request('http://localhost:9001/status', (error, resp, body) => {
shouldReassignPartitions(error, resp, body, done);
});
request('http://localhost:9002/status', (error, resp, body) => {
shouldReassignPartitions(error, resp, body, done);
done();
});
}, 10000);
}, 15000);
});
});
Expand Down

0 comments on commit 2d77492

Please sign in to comment.