Skip to content

Commit

Permalink
[FABN-1396] hoist typescript tests to cucumber
Browse files Browse the repository at this point in the history
- Add error case testing to submit/evaluate
- Add handler options to submit/evaluate
- Add transient data to submit/evaluate
- Delete obsolete typescript test suite and references

Change-Id: I8db78aedfad044597769acb0d9a44e5299b4d7c5
Signed-off-by: [email protected] <[email protected]>
  • Loading branch information
nklincoln committed Oct 31, 2019
1 parent 39b44e0 commit 6ea632c
Show file tree
Hide file tree
Showing 21 changed files with 554 additions and 1,562 deletions.
1 change: 0 additions & 1 deletion build/tasks/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ gulp.task('eslint', () => {
'!fabric-common/node_modules/**',
'!fabric-common/coverage/**',
'!node_modules/**',
'!test/typescript/**/*.js',
'!fabric-protos/**',
]).pipe(eslint())
.pipe(eslint.format())
Expand Down
2 changes: 1 addition & 1 deletion build/tasks/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ gulp.task('test-fv-scenario', shell.task('npx nyc gulp run-test-fv-scenario'));

// run fv only with code coverage
// override the global nyc configuration
gulp.task('test-fv-only', shell.task('npx nyc --check-coverage --statements 54 --branches 43 --functions 56 --lines 54 gulp run-tape-e2e'));
gulp.task('test-fv-only', shell.task('npx nyc --check-coverage --statements 53 --branches 42 --functions 53 --lines 53 gulp run-tape-e2e'));

gulp.task('run-test-fv-scenario', (done) => {
const tasks = ['run-tape-e2e', 'docker-clean', 'run-test:cucumber', 'docker-clean', 'run-test:ts-cucumber'];
Expand Down
10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@
"test:network": "npm run compile-src && npm run coverage -- 'fabric-network/test/**/*.{js,ts}'",
"test:protos": "npm run coverage -- 'fabric-protos/test/**/*.{js,ts}",
"test:cucumber": "cucumber-js ./test/scenario/features/*.feature",
"test:ts-cucumber": "cucumber-js ./test/ts-scenario/features/*.feature --require './test/ts-scenario/steps/**/*.ts' --require './test/ts-scenario/support/**/*.ts' --require-module ts-node/register",
"test:ts-cucumber-tagged": "cucumber-js ./test/ts-scenario/features/*.feature --require './test/ts-scenario/steps/**/*.ts' --require './test/ts-scenario/support/**/*.ts' --require-module ts-node/register --tags @lifecycle",
"test:all": "nyc npm run unit-test:all",
"test:ts-cucumber": "cucumber-js ./test/ts-scenario/features/*.feature --require './test/ts-scenario/steps/**/*.ts' --require './test/ts-scenario/support/**/*.ts' --require-module ts-node/register",
"test:ts-cucumber-tagged": "cucumber-js ./test/ts-scenario/features/*.feature --require './test/ts-scenario/steps/**/*.ts' --require './test/ts-scenario/support/**/*.ts' --require-module ts-node/register --tags @discovery",
"test:all": "nyc npm run unit-test:all",
"unit-test:all": "npm run unit-test -- 'fabric-common/test/**/*.{js,ts}' && npm run unit-test -- 'fabric-ca-client/test/**/*.{js,ts}' && npm run unit-test -- 'fabric-client/test/**/*.{js,ts}' && npm run unit-test -- 'fabric-network/test/**/*.{js,ts}'",
"unit-test": "mocha --require ts-node/register --exclude 'fabric-client/test/data/**'",
"compile": "npm run compile-src && npm run compile-test",
"compile": "npm run compile-src",
"compile-src": "tsc --project fabric-network/tsconfig-declaration.json && tsc --project fabric-network/tsconfig.json",
"compile-src:w": "tsc --project fabric-network --watch",
"compile-test": "tsc --project test/typescript",
"compile-test:w": "tsc --project test/typescript --watch",
"coverage": "nyc npm run unit-test",
"retrieve-images": "./scripts/utility/fabric_images.sh amd64 2.0.0-stable"
},
Expand Down
11 changes: 4 additions & 7 deletions test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Unit tests are located in a `package/test` directory that mirrors the `package/l

The functional tests are currently written in [Tape](https://github.com/substack/tape), with the intention of testing the Fabric-SDK-Node package capabilities from a user perspective against a live Hyperledger Fabric Network.

The scenario tests are written in [Cucumber](https://github.com/cucumber/cucumber-js), with the intention of providing high level test coverage from a scenario perspective. For more information, please refer to the [README](./scenario/README.md) within the scenario directory.
The scenario tests are written in typescript and use [Cucumber](https://github.com/cucumber/cucumber-js), with the intention of providing high level test coverage from a scenario perspective. For more information, please refer to the [README](./ts-scenario/README.md) within the scenario directory.

Test certificates are set to expire a year after generation. Due to this the test suite generates new certificates as part of the build process, and is a manual requirement prior to running the tests locally. This process is orchestrated using gulp files that:
- Download, install and export the path to the 1.4 Hyperledger Fabric binaries used for generating crypto material
Expand All @@ -29,15 +29,12 @@ test
└───fixtures
└───integration
└───scenario
└───typescript
└───unit
└───ts-scenario
```

- `fixtures` holds all the configuration files used by the integration and scenario tests
- `integration` contains the interation test suite
- `scenario` contains the sceanrio test suite
- `typescript` contains the typescript test suite
- `integration` contains the integration test suite
- `ts-scenario` contains the typescripts scenario test suite
- `unit` contains the deprecated unit test suite

## Configuring and running Hardware Security Module tests
Expand Down
4 changes: 0 additions & 4 deletions test/integration/network-e2e/e2e-hsm.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

const tsPath = '../../typescript/integration/network-e2e';

require('../e2e/create-channel.js');
require('../e2e/join-channel.js');
require('./install-chaincode.js');
require('./instantiate-chaincode.js');
require('./invoke-hsm.js');
require(tsPath + '/invoke.js');
require(tsPath + '/query.js');
5 changes: 0 additions & 5 deletions test/integration/network-e2e/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

const tsPath = '../../typescript/integration/network-e2e';

require('../e2e/create-channel.js');
require('../e2e/join-channel.js');
require('./install-chaincode.js');
require('./instantiate-chaincode.js');
// require(tsPath + '/updateAnchorPeers');
require(tsPath + '/invoke.js');
require(tsPath + '/query.js');
12 changes: 12 additions & 0 deletions test/ts-fixtures/chaincode/node/fabcar/lib/fabcar.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class FabCar extends Contract {
}

async queryCar(ctx, carNumber) {
console.info('============= START : queryCar ==========='); // eslint-disable-line
const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
if (!carAsBytes || carAsBytes.length === 0) {
throw new Error(`${carNumber} does not exist`);
Expand All @@ -106,6 +107,7 @@ class FabCar extends Contract {
}

async queryAllCars(ctx) {
console.info('============= START : queryAllCars ==========='); // eslint-disable-line
const startKey = 'CAR0';
const endKey = 'CAR999';

Expand Down Expand Up @@ -150,6 +152,16 @@ class FabCar extends Contract {
console.info('============= END : changeCarOwner ==========='); // eslint-disable-line
}

async getTransient(ctx) {
console.info('============= START : getTransient ==========='); // eslint-disable-line
const transientMap = ctx.stub.getTransient();
const result = {};
transientMap.forEach((value, key) => {
result[key] = value.toString('utf8');
});
return JSON.stringify(result);
}

}

module.exports = FabCar;
12 changes: 12 additions & 0 deletions test/ts-fixtures/chaincode/node/fabcarUpgrade/lib/fabcar.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class FabCar extends Contract {
}

async querySingleCar(ctx, carNumber) {
console.info('============= START : querySingleCar ==========='); // eslint-disable-line
const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
if (!carAsBytes || carAsBytes.length === 0) {
throw new Error(`${carNumber} does not exist`);
Expand All @@ -38,6 +39,7 @@ class FabCar extends Contract {
}

async queryAllCars(ctx) {
console.info('============= START : queryAllCars ==========='); // eslint-disable-line
const startKey = 'CAR0';
const endKey = 'CAR999';

Expand Down Expand Up @@ -82,6 +84,16 @@ class FabCar extends Contract {
console.info('============= END : changeCarOwner ==========='); // eslint-disable-line
}

async getTransient(ctx) {
console.info('============= START : getTransient ==========='); // eslint-disable-line
const transientMap = ctx.stub.getTransient();
const result = {};
transientMap.forEach((value, key) => {
result[key] = value.toString('utf8');
});
return JSON.stringify(result);
}

}

module.exports = FabCar;
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,12 @@
// Sample query handler that will use all queryable peers within the network to evaluate transactions, with preference
// given to peers within the same organization.

// tslint:disable:typedef
import { Network, Query, QueryHandler, QueryHandlerFactory, QueryResults } from 'fabric-network';

import {
Network,
Query,
QueryHandler,
QueryHandlerFactory,
} from 'fabric-network';

import {
ChannelPeer,
} from 'fabric-client';
import { ChannelPeer } from 'fabric-client';

import util = require('util');
import Client = require('fabric-client');

/**
* Query handler implementation that simply tries all the peers it is given in order until it gets a result.
Expand All @@ -36,8 +28,8 @@ class SampleQueryHandler implements QueryHandler {
const errorMessages: string[] = [];

for (const peer of this.peers) {
const results = await query.evaluate([peer]);
const result = results[peer.getName()];
const results: QueryResults = await query.evaluate([peer]);
const result: Buffer | Client.ProposalErrorResponse = results[peer.getName()];

if (!(result instanceof Error)) {
// Good response from peer
Expand All @@ -51,27 +43,27 @@ class SampleQueryHandler implements QueryHandler {
errorMessages.push(result.message);
}

const message = util.format('Evaluate failed with the following errors: %j', errorMessages);
const message: string = util.format('Evaluate failed with the following errors: %j', errorMessages);
throw new Error(message);
}
}

function filterQueryablePeers(peers: ChannelPeer[]): ChannelPeer[] {
return peers.filter((peer) => peer.isInRole('chaincodeQuery'));
return peers.filter((peer: ChannelPeer) => peer.isInRole('chaincodeQuery'));
}

/**
* Factory function for creating sample query handlers.
* @param {Network} network The network where transactions are to be evaluated.
* @returns {QueryHandler} A query handler implementation.
*/
const createQueryHandler: QueryHandlerFactory = (network: Network) => {
const channel = network.getChannel();
const orgPeers = filterQueryablePeers(channel.getPeersForOrg());
const networkPeers = filterQueryablePeers(channel.getChannelPeers())
.filter((peer) => !orgPeers.includes(peer)); // Exclude peers already in the orgPeer array
const createQueryHandler: QueryHandlerFactory = (network: Network): SampleQueryHandler => {
const channel: Client.Channel = network.getChannel();
const orgPeers: ChannelPeer[] = filterQueryablePeers(channel.getPeersForOrg());
const networkPeers: ChannelPeer[] = filterQueryablePeers(channel.getChannelPeers())
.filter((peer: ChannelPeer) => !orgPeers.includes(peer)); // Exclude peers already in the orgPeer array

const allPeers = orgPeers.concat(networkPeers); // Peers in our organization first
const allPeers: ChannelPeer[] = orgPeers.concat(networkPeers); // Peers in our organization first
return new SampleQueryHandler(allPeers);
};

Expand Down
Loading

0 comments on commit 6ea632c

Please sign in to comment.