Skip to content

Commit

Permalink
Fix flaky websocket tests
Browse files Browse the repository at this point in the history
Even though this is going away in AS3, it's gotten really annoying. We can't
just assume that adding one to a port gives a listenable port. Fortunately we
can get the OS to choose a port for us. It was easier to make this fix by
rewriting the test to be async.

Fixes #5101
  • Loading branch information
glasser committed Apr 9, 2021
1 parent 3a369c3 commit 980786a
Showing 1 changed file with 43 additions and 37 deletions.
80 changes: 43 additions & 37 deletions packages/apollo-server-integration-testsuite/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import { PubSub } from 'graphql-subscriptions';
import { SubscriptionClient } from 'subscriptions-transport-ws';
import WebSocket from 'ws';
import resolvable from '@josephg/resolvable';

import { execute } from 'apollo-link';
import { createHttpLink } from 'apollo-link-http';
Expand Down Expand Up @@ -2099,8 +2100,8 @@ export function testApolloServer<AS extends ApolloServerBase>(
.catch(done.fail);
});

it('takes websocket server subscriptions configuration', done => {
const onConnect = jest.fn(connectionParams => ({
it('takes websocket server subscriptions configuration', async () => {
const onConnect = jest.fn((connectionParams) => ({
...connectionParams,
}));
const typeDefs = gql`
Expand Down Expand Up @@ -2136,47 +2137,52 @@ export function testApolloServer<AS extends ApolloServerBase>(
};

const path = '/sub';
createApolloServer({
const { server } = await createApolloServer({
typeDefs,
resolvers,
subscriptions: { onConnect, path },
})
.then(({ port, server }) => {
const subPort = (typeof port === "number" ? port : parseInt(port)) + 1
const websocketServer = new WebSocket.Server({port: subPort})
server.installSubscriptionHandlers(websocketServer);
expect(onConnect).not.toBeCalled();
});
const listening = resolvable();
const websocketServer = new WebSocket.Server({ port: 0 }, () =>
listening.resolve(),
);
await listening;
server.installSubscriptionHandlers(websocketServer);
expect(onConnect).not.toBeCalled();

expect(server.subscriptionsPath).toEqual(path);
const client = new SubscriptionClient(
`ws://localhost:${
(websocketServer.address() as WebSocket.AddressInfo).port
}${server.subscriptionsPath}`,
{},
WebSocket,
);

expect(server.subscriptionsPath).toEqual(path);
const client = new SubscriptionClient(
`ws://localhost:${subPort}${server.subscriptionsPath}`,
{},
WebSocket,
);
const observable = client.request({ query });

const observable = client.request({ query });
const p = resolvable();

let i = 1;
subscription = observable.subscribe({
next: ({ data }) => {
try {
expect(onConnect).toHaveBeenCalledTimes(1);
expect(data.num).toEqual(i);
if (i === 3) {
done();
}
i++;
} catch (e) {
done.fail(e);
}
},
error: done.fail,
complete: () => {
done.fail(new Error('should not complete'));
},
});
})
.catch(done.fail);
let i = 1;
subscription = observable.subscribe({
next: ({ data }) => {
try {
expect(onConnect).toHaveBeenCalledTimes(1);
expect(data.num).toEqual(i);
if (i === 3) {
p.resolve();
}
i++;
} catch (e) {
p.reject(e);
}
},
error: p.reject,
complete: () => {
p.reject(new Error('should not complete'));
},
});
await p;
});

it('allows introspection when introspection is enabled on ApolloServer', done => {
Expand Down

0 comments on commit 980786a

Please sign in to comment.