mirror of https://github.com/grpc/grpc-web.git
Refactor interop tests to be automated
This commit is contained in:
parent
ea88b10600
commit
17fbe35265
15
advanced.yml
15
advanced.yml
|
|
@ -30,6 +30,15 @@ services:
|
||||||
image: grpcweb/node-server
|
image: grpcweb/node-server
|
||||||
ports:
|
ports:
|
||||||
- "9090:9090"
|
- "9090:9090"
|
||||||
|
node-interop-server:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: ./net/grpc/gateway/docker/node_interop_server/Dockerfile
|
||||||
|
depends_on:
|
||||||
|
- common
|
||||||
|
image: grpcweb/node-interop-server
|
||||||
|
ports:
|
||||||
|
- "7074:7074"
|
||||||
envoy:
|
envoy:
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
|
|
@ -95,12 +104,12 @@ services:
|
||||||
image: grpcweb/binary-client
|
image: grpcweb/binary-client
|
||||||
ports:
|
ports:
|
||||||
- "8081:8081"
|
- "8081:8081"
|
||||||
interop:
|
interop-client:
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: ./net/grpc/gateway/docker/interop/Dockerfile
|
dockerfile: ./net/grpc/gateway/docker/interop_client/Dockerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
- prereqs
|
- prereqs
|
||||||
image: grpcweb/interop
|
image: grpcweb/interop-client
|
||||||
ports:
|
ports:
|
||||||
- "8081:8081"
|
- "8081:8081"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Copyright 2018 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
FROM grpcweb/common
|
||||||
|
|
||||||
|
WORKDIR /github/grpc-node
|
||||||
|
|
||||||
|
RUN git clone https://github.com/grpc/grpc-node . && \
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
RUN cd packages/grpc-native-core && \
|
||||||
|
npm install --build-from-source --unsafe-perm && \
|
||||||
|
npm link
|
||||||
|
|
||||||
|
RUN cd packages/proto-loader && \
|
||||||
|
npm install @types/mocha && \
|
||||||
|
npm install --unsafe-perm
|
||||||
|
|
||||||
|
WORKDIR /github/grpc-node/test
|
||||||
|
|
||||||
|
RUN npm install node-pre-gyp && \
|
||||||
|
npm install && \
|
||||||
|
npm link grpc
|
||||||
|
|
||||||
|
EXPOSE 7074
|
||||||
|
CMD ["node", "--require", "./fixtures/native_native", "./interop/interop_server.js", "--port=7074"]
|
||||||
|
|
@ -21,6 +21,14 @@ cd "${REPO_DIR}"
|
||||||
./scripts/init_submodules.sh
|
./scripts/init_submodules.sh
|
||||||
make clean
|
make clean
|
||||||
|
|
||||||
|
# These programs need to be already installed
|
||||||
|
progs=(docker docker-compose npm curl)
|
||||||
|
for p in "${progs[@]}"
|
||||||
|
do
|
||||||
|
command -v "$p" > /dev/null 2>&1 || \
|
||||||
|
{ echo >&2 "$p is required but not installed. Aborting."; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
# Lint bazel files.
|
# Lint bazel files.
|
||||||
BUILDIFIER_VERSION=1.0.0
|
BUILDIFIER_VERSION=1.0.0
|
||||||
BUILDIFIER_SUFFIX=""
|
BUILDIFIER_SUFFIX=""
|
||||||
|
|
@ -33,17 +41,6 @@ chmod +x "./buildifier"
|
||||||
./buildifier --mode=check --lint=warn --warnings=all -r bazel javascript net
|
./buildifier --mode=check --lint=warn --warnings=all -r bazel javascript net
|
||||||
rm ./buildifier
|
rm ./buildifier
|
||||||
|
|
||||||
# These programs need to be already installed
|
|
||||||
progs=(docker docker-compose npm curl)
|
|
||||||
for p in "${progs[@]}"
|
|
||||||
do
|
|
||||||
command -v "$p" > /dev/null 2>&1 || \
|
|
||||||
{ echo >&2 "$p is required but not installed. Aborting."; exit 1; }
|
|
||||||
done
|
|
||||||
|
|
||||||
# Build all relevant docker images. They should all build successfully.
|
|
||||||
docker-compose -f advanced.yml build
|
|
||||||
|
|
||||||
# Run all bazel unit tests
|
# Run all bazel unit tests
|
||||||
BAZEL_VERSION=2.2.0
|
BAZEL_VERSION=2.2.0
|
||||||
BAZEL_OS="linux"
|
BAZEL_OS="linux"
|
||||||
|
|
@ -60,12 +57,19 @@ $HOME/bin/bazel test \
|
||||||
//javascript/net/grpc/web/... \
|
//javascript/net/grpc/web/... \
|
||||||
//net/grpc/gateway/examples/...
|
//net/grpc/gateway/examples/...
|
||||||
|
|
||||||
|
# Build the protoc plugin
|
||||||
|
make plugin
|
||||||
|
|
||||||
# Build the grpc-web npm package
|
# Build the grpc-web npm package
|
||||||
cd packages/grpc-web && \
|
cd packages/grpc-web && \
|
||||||
npm install && \
|
npm install && \
|
||||||
npm run build && \
|
npm run build && \
|
||||||
|
npm link && \
|
||||||
cd ../..
|
cd ../..
|
||||||
|
|
||||||
|
# Build all relevant docker images. They should all build successfully.
|
||||||
|
docker-compose -f advanced.yml build
|
||||||
|
|
||||||
# Bring up the Echo server and the Envoy proxy (in background).
|
# Bring up the Echo server and the Envoy proxy (in background).
|
||||||
# The 'sleep' seems necessary for the docker containers to be fully up
|
# The 'sleep' seems necessary for the docker containers to be fully up
|
||||||
# and listening before we test the with curl requests
|
# and listening before we test the with curl requests
|
||||||
|
|
@ -80,3 +84,26 @@ docker-compose down
|
||||||
# Run unit tests from npm package
|
# Run unit tests from npm package
|
||||||
docker run --rm grpcweb/prereqs /bin/bash \
|
docker run --rm grpcweb/prereqs /bin/bash \
|
||||||
/github/grpc-web/scripts/docker-run-tests.sh
|
/github/grpc-web/scripts/docker-run-tests.sh
|
||||||
|
|
||||||
|
# Run interop tests
|
||||||
|
pid1=$(docker run -d -v $(pwd)/test/interop/envoy.yaml:/etc/envoy/envoy.yaml:ro \
|
||||||
|
--network=host -p 8080:8080 envoyproxy/envoy:v1.14.1)
|
||||||
|
pid2=$(docker run -d --network=host -p 7074:7074 grpcweb/node-interop-server)
|
||||||
|
|
||||||
|
cd test/interop && \
|
||||||
|
npm install && \
|
||||||
|
npm link grpc-web && \
|
||||||
|
protoc -I=../.. src/proto/grpc/testing/test.proto \
|
||||||
|
src/proto/grpc/testing/empty.proto \
|
||||||
|
src/proto/grpc/testing/messages.proto \
|
||||||
|
--plugin=protoc-gen-grpc-web=$(pwd)/../../javascript/net/grpc/web/protoc-gen-grpc-web \
|
||||||
|
--js_out=import_style=commonjs:. \
|
||||||
|
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:. && \
|
||||||
|
npm test && \
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
docker rm -f $pid1
|
||||||
|
docker rm -f $pid2
|
||||||
|
git clean -f -d -x
|
||||||
|
echo 'Completed'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
src/
|
||||||
|
|
@ -9,14 +9,20 @@ for details about gRPC interop tests in general and the list of test cases.
|
||||||
Run interop tests
|
Run interop tests
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
### Build some docker images
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ cd grpc-web
|
||||||
|
$ docker-compose -f advanced.yml build common prereqs node-interop-server interop-client
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Run the Node interop server
|
### Run the Node interop server
|
||||||
|
|
||||||
An interop server implemented in Node is hosted in the `grpc/grpc-node` repo.
|
An interop server implemented in Node is hosted in the `grpc/grpc-node` repo.
|
||||||
There might be a bit of set up you need to do before running the command below.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ cd grpc-node/test
|
$ docker run -d --network=host -p 7074:7074 grpcweb/node-interop-server
|
||||||
$ node --require ./fixtures/native_native interop/interop_server.js --port=7074
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -26,19 +32,25 @@ An `envoy.yaml` file is provided in this directory to direct traffic for these
|
||||||
tests.
|
tests.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ cd grpc-web
|
$ docker run -d -v $(pwd)/test/interop/envoy.yaml:/etc/envoy/envoy.yaml:ro \
|
||||||
$ docker run -it --rm -v $(pwd)/test/interop/envoy.yaml:/etc/envoy/envoy.yaml:ro \
|
--network=host -p 8080:8080 envoyproxy/envoy:v1.14.1
|
||||||
--network=host -p 8080:8080 envoyproxy/envoy:latest
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Run the gRPC-Web browser client
|
### Run the gRPC-Web browser client
|
||||||
|
|
||||||
|
You can either run the interop client as `npm test`, like this:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ cd grpc-web
|
$ cd test/interop
|
||||||
$ docker-compose -f advanced.yml build common prereqs interop
|
$ npm install
|
||||||
$ docker-compose -f advanced.yml up interop
|
$ npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
Or from the browser:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ docker-compose -f advanced.yml up interop-client
|
||||||
```
|
```
|
||||||
|
|
||||||
Open up the browser and go to `http://localhost:8081/index.html` and open up
|
Open up the browser and go to `http://localhost:8081/index.html` and open up
|
||||||
|
|
|
||||||
|
|
@ -25,32 +25,32 @@ const {SimpleRequest,
|
||||||
require('./src/proto/grpc/testing/messages_pb.js');
|
require('./src/proto/grpc/testing/messages_pb.js');
|
||||||
const {TestServiceClient} =
|
const {TestServiceClient} =
|
||||||
require('./src/proto/grpc/testing/test_grpc_web_pb.js');
|
require('./src/proto/grpc/testing/test_grpc_web_pb.js');
|
||||||
|
var assert = require('assert');
|
||||||
const grpc = {};
|
const grpc = {};
|
||||||
grpc.web = require('grpc-web');
|
grpc.web = require('grpc-web');
|
||||||
|
|
||||||
var testService = new TestServiceClient(
|
const SERVER_HOST = 'http://localhost:8080';
|
||||||
'http://'+window.location.hostname+':8080', null, null);
|
|
||||||
|
|
||||||
function doEmptyUnary() {
|
function multiDone(done, count) {
|
||||||
return new Promise((resolve, reject) => {
|
return function() {
|
||||||
|
count -= 1;
|
||||||
|
if (count <= 0) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function doEmptyUnary(done) {
|
||||||
|
var testService = new TestServiceClient(SERVER_HOST, null, null);
|
||||||
testService.emptyCall(new Empty(), null, (err, response) => {
|
testService.emptyCall(new Empty(), null, (err, response) => {
|
||||||
if (err) {
|
assert.ifError(err);
|
||||||
reject('EmptyUnary failed: Received unexpected error "'+
|
assert(response instanceof Empty);
|
||||||
err.message+'"');
|
done();
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (!(response instanceof Empty)) {
|
|
||||||
reject('EmptyUnary failed: Response not of Empty type');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve('EmptyUnary: passed');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doLargeUnary() {
|
function doLargeUnary(done) {
|
||||||
return new Promise((resolve, reject) => {
|
var testService = new TestServiceClient(SERVER_HOST, null, null);
|
||||||
var req = new SimpleRequest();
|
var req = new SimpleRequest();
|
||||||
var size = 314159;
|
var size = 314159;
|
||||||
|
|
||||||
|
|
@ -61,23 +61,14 @@ function doLargeUnary() {
|
||||||
req.setResponseSize(size);
|
req.setResponseSize(size);
|
||||||
|
|
||||||
testService.unaryCall(req, null, (err, response) => {
|
testService.unaryCall(req, null, (err, response) => {
|
||||||
if (err) {
|
assert.ifError(err);
|
||||||
reject('LargeUnary failed: Received unexpected error "'+
|
assert.equal(response.getPayload().getBody().length, size);
|
||||||
err.message+'"');
|
done();
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (response.getPayload().getBody().length != size) {
|
|
||||||
rejecet('LargeUnary failed: Received incorrect size payload');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve('LargeUnary: passed');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doServerStreaming() {
|
function doServerStreaming(done) {
|
||||||
return new Promise((resolve, reject) => {
|
var testService = new TestServiceClient(SERVER_HOST, null, null);
|
||||||
var sizes = [31415, 9, 2653, 58979];
|
var sizes = [31415, 9, 2653, 58979];
|
||||||
|
|
||||||
var responseParams = sizes.map((size, idx) => {
|
var responseParams = sizes.map((size, idx) => {
|
||||||
|
|
@ -92,28 +83,19 @@ function doServerStreaming() {
|
||||||
|
|
||||||
var stream = testService.streamingOutputCall(req);
|
var stream = testService.streamingOutputCall(req);
|
||||||
|
|
||||||
|
done = multiDone(done, sizes.length);
|
||||||
var numCallbacks = 0;
|
var numCallbacks = 0;
|
||||||
stream.on('data', (response) => {
|
stream.on('data', (response) => {
|
||||||
if (response.getPayload().getBody().length != sizes[numCallbacks]) {
|
assert.equal(response.getPayload().getBody().length, sizes[numCallbacks]);
|
||||||
reject('ServerStreaming failed: Received incorrect size payload');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
numCallbacks++;
|
numCallbacks++;
|
||||||
});
|
done();
|
||||||
// TODO(stanleycheung): is there a better way to do this?
|
|
||||||
setTimeout(() => {
|
|
||||||
if (numCallbacks != sizes.length) {
|
|
||||||
reject('ServerStreaming failed: data callback called '+
|
|
||||||
numCallbacks+' times. Should be '+sizes.length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve('ServerStreaming: passed');
|
|
||||||
}, 200);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doCustomMetadata() {
|
function doCustomMetadata(done) {
|
||||||
return new Promise((resolve, reject) => {
|
var testService = new TestServiceClient(SERVER_HOST, null, null);
|
||||||
|
done = multiDone(done, 3);
|
||||||
|
|
||||||
var req = new SimpleRequest();
|
var req = new SimpleRequest();
|
||||||
const size = 314159;
|
const size = 314159;
|
||||||
const ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
|
const ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
|
||||||
|
|
@ -131,55 +113,27 @@ function doCustomMetadata() {
|
||||||
[ECHO_INITIAL_KEY]: ECHO_INITIAL_VALUE,
|
[ECHO_INITIAL_KEY]: ECHO_INITIAL_VALUE,
|
||||||
[ECHO_TRAILING_KEY]: ECHO_TRAILING_VALUE
|
[ECHO_TRAILING_KEY]: ECHO_TRAILING_VALUE
|
||||||
}, (err, response) => {
|
}, (err, response) => {
|
||||||
if (err) {
|
assert.ifError(err);
|
||||||
reject('CustomMetadata failed: Received unexpected error "'+
|
assert.equal(response.getPayload().getBody().length, size);
|
||||||
err.message+'"');
|
done();
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (response.getPayload().getBody().length != size) {
|
|
||||||
rejecet('CustomMetadata failed: Received incorrect size payload');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
var metadataCallbackVerified = false;
|
|
||||||
var statusCallbackVerified = false;
|
|
||||||
call.on('metadata', (metadata) => {
|
call.on('metadata', (metadata) => {
|
||||||
if (!(ECHO_INITIAL_KEY in metadata)) {
|
assert(ECHO_INITIAL_KEY in metadata);
|
||||||
reject('CustomMetadata failed: initial metadata does not '+
|
assert.equal(metadata[ECHO_INITIAL_KEY], ECHO_INITIAL_VALUE);
|
||||||
'contain '+ECHO_INITIAL_KEY);
|
done();
|
||||||
} else if (metadata[ECHO_INITIAL_KEY] != ECHO_INITIAL_VALUE) {
|
|
||||||
reject('CustomMetadata failed: initial metadata value for '+
|
|
||||||
ECHO_INITIAL_KEY+' is incorrect');
|
|
||||||
} else {
|
|
||||||
metadataCallbackVerified = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
call.on('status', (status) => {
|
call.on('status', (status) => {
|
||||||
if (!('metadata' in status)) {
|
assert('metadata' in status);
|
||||||
reject('CustomMetadata failed: status callback does not '+
|
assert(ECHO_TRAILING_KEY in status.metadata);
|
||||||
'contain metadata');
|
assert.equal(status.metadata[ECHO_TRAILING_KEY], ECHO_TRAILING_VALUE);
|
||||||
} else if (!(ECHO_TRAILING_KEY in status.metadata)) {
|
done();
|
||||||
reject('CustomMetadata failed: trailing metadata does not '+
|
|
||||||
'contain '+ECHO_TRAILING_KEY);
|
|
||||||
} else if (status.metadata[ECHO_TRAILING_KEY] != ECHO_TRAILING_VALUE) {
|
|
||||||
reject('CustomMetadata failed: trailing metadata value for '+
|
|
||||||
ECHO_TRAILING_KEY+' is incorrect');
|
|
||||||
} else {
|
|
||||||
statusCallbackVerified = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!metadataCallbackVerified || !statusCallbackVerified) {
|
|
||||||
reject('CustomMetadata failed: some callback failed to verify');
|
|
||||||
}
|
|
||||||
resolve('CustomMetadta passed');
|
|
||||||
}, 200);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doStatusCodeAndMessage() {
|
function doStatusCodeAndMessage(done) {
|
||||||
return new Promise((resolve, reject) => {
|
var testService = new TestServiceClient(SERVER_HOST, null, null);
|
||||||
var req = new SimpleRequest();
|
var req = new SimpleRequest();
|
||||||
|
|
||||||
const TEST_STATUS_MESSAGE = 'test status message';
|
const TEST_STATUS_MESSAGE = 'test status message';
|
||||||
|
|
@ -190,61 +144,66 @@ function doStatusCodeAndMessage() {
|
||||||
req.setResponseStatus(echoStatus);
|
req.setResponseStatus(echoStatus);
|
||||||
|
|
||||||
testService.unaryCall(req, {}, (err, response) => {
|
testService.unaryCall(req, {}, (err, response) => {
|
||||||
if (err) {
|
assert(err);
|
||||||
if (!('code' in err)) {
|
assert('code' in err);
|
||||||
reject('StatusCodeAndMessage failed: status callback does not '+
|
assert('message' in err);
|
||||||
'contain code');
|
assert.equal(err.code, 2);
|
||||||
} else if (!('message' in err)) {
|
assert.equal(err.message, TEST_STATUS_MESSAGE);
|
||||||
reject('StatusCodeAndMessage failed: status callback does not '+
|
done();
|
||||||
'contain message');
|
|
||||||
} else if (err.code != 2) {
|
|
||||||
reject('StatusCodeAndMessage failed: status code is not 2, is '+
|
|
||||||
err.code);
|
|
||||||
} else if (err.message != TEST_STATUS_MESSAGE) {
|
|
||||||
reject('StatusCodeAndMessage failed: status mesage is not '+
|
|
||||||
TEST_STATUS_MESSAGE+', is '+err.message);
|
|
||||||
} else {
|
|
||||||
resolve('StatusCodeAndMessage passed');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reject('StatusCodeAndMessage failed: should not have received a '+
|
|
||||||
'proper response');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doUnimplementedMethod() {
|
function doUnimplementedMethod(done) {
|
||||||
return new Promise((resolve, reject) => {
|
var testService = new TestServiceClient(SERVER_HOST, null, null);
|
||||||
testService.unimplementedCall(new Empty(), {}, (err, response) => {
|
testService.unimplementedCall(new Empty(), {}, (err, response) => {
|
||||||
if (err) {
|
assert(err);
|
||||||
if (!('code' in err)) {
|
assert('code' in err);
|
||||||
reject('UnimplementedMethod failed: status callback does not '+
|
assert.equal(err.code, 12);
|
||||||
'contain code');
|
done();
|
||||||
} else if (!('message' in err)) {
|
|
||||||
reject('UnimplementedMethod failed: status callback does not '+
|
|
||||||
'contain message');
|
|
||||||
} else if (err.code != 12) {
|
|
||||||
reject('UnimplementedMethod failed: status code is not 12'+
|
|
||||||
'(UNIMPLEMENTED), is '+ err.code);
|
|
||||||
} else {
|
|
||||||
resolve('UnimplementedMethod passed');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reject('UnimplementedMethod failed: should not have received a '+
|
|
||||||
'proper respoonse');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var testCases = [doEmptyUnary, doLargeUnary, doServerStreaming,
|
var testCases = {
|
||||||
doCustomMetadata, doStatusCodeAndMessage,
|
'empty_unary': doEmptyUnary,
|
||||||
doUnimplementedMethod];
|
'large_unary': doLargeUnary,
|
||||||
|
'server_streaming': doServerStreaming,
|
||||||
|
'custom_metadata': doCustomMetadata,
|
||||||
|
'status_code_and_message': doStatusCodeAndMessage,
|
||||||
|
'unimplemented_method': doUnimplementedMethod
|
||||||
|
};
|
||||||
|
|
||||||
testCases.reduce((promiseChain, currentTask) => {
|
if (typeof window === 'undefined') {
|
||||||
return promiseChain.then(() => {
|
console.log('Running from Node...');
|
||||||
return currentTask().then(console.log);
|
|
||||||
}).catch(console.error);
|
// Fill in XHR runtime
|
||||||
}, Promise.resolve());
|
global.XMLHttpRequest = require("xhr2");
|
||||||
|
|
||||||
|
describe('grpc-web interop tests', function() {
|
||||||
|
Object.keys(testCases).forEach((testCase) => {
|
||||||
|
it('should pass '+testCase, testCases[testCase]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('Running from browser...');
|
||||||
|
|
||||||
|
Object.keys(testCases).forEach((testCase) => {
|
||||||
|
var test = testCases[testCase];
|
||||||
|
|
||||||
|
var doneCalled = false;
|
||||||
|
test((err) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
doneCalled = true;
|
||||||
|
console.log(testCase+': passed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!doneCalled) {
|
||||||
|
throw testCase+': failed. Not all done() are called';
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,17 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "gRPC-Web Interop Test Client",
|
"description": "gRPC-Web Interop Test Client",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha -b --timeout 500 client.js"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"google-protobuf": "^3.6.1",
|
"google-protobuf": "~3.11.4",
|
||||||
"grpc-web": "^1.0.0"
|
"grpc-web": "~1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"browserify": "^16.2.2",
|
"mocha": "~7.1.1",
|
||||||
"webpack": "^4.16.5",
|
"webpack": "~4.43.0",
|
||||||
"webpack-cli": "^3.1.0"
|
"webpack-cli": "~3.3.11",
|
||||||
|
"xhr2": "~0.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue