Skip to content

Commit d465f83

Browse files
committed
Add pick_first requestReresolution tests
1 parent 2f5ddc7 commit d465f83

File tree

1 file changed

+89
-1
lines changed

1 file changed

+89
-1
lines changed

packages/grpc-js/test/test-pick-first.ts

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ function updateStateCallBackForExpectedStateSequence(
4141
) {
4242
const actualStateSequence: ConnectivityState[] = [];
4343
let lastPicker: Picker | null = null;
44+
let finished = false;
4445
return (connectivityState: ConnectivityState, picker: Picker) => {
46+
if (finished) {
47+
return;
48+
}
4549
// Ignore duplicate state transitions
4650
if (
4751
connectivityState === actualStateSequence[actualStateSequence.length - 1]
@@ -60,6 +64,7 @@ function updateStateCallBackForExpectedStateSequence(
6064
if (
6165
expectedStateSequence[actualStateSequence.length] !== connectivityState
6266
) {
67+
finished = true;
6368
done(
6469
new Error(
6570
`Unexpected state ${
@@ -69,10 +74,12 @@ function updateStateCallBackForExpectedStateSequence(
6974
)}]`
7075
)
7176
);
77+
return;
7278
}
7379
actualStateSequence.push(connectivityState);
7480
lastPicker = picker;
7581
if (actualStateSequence.length === expectedStateSequence.length) {
82+
finished = true;
7683
done();
7784
}
7885
};
@@ -90,7 +97,7 @@ describe('Shuffler', () => {
9097
});
9198
});
9299

93-
describe('pick_first load balancing policy', () => {
100+
describe.only('pick_first load balancing policy', () => {
94101
const config = new PickFirstLoadBalancingConfig(false);
95102
let subchannels: MockSubchannel[] = [];
96103
const baseChannelControlHelper: ChannelControlHelper = {
@@ -462,6 +469,87 @@ describe('pick_first load balancing policy', () => {
462469
});
463470
});
464471
});
472+
it('Should request reresolution every time each child reports TF', done => {
473+
let reresolutionRequestCount = 0;
474+
const targetReresolutionRequestCount = 3;
475+
const currentStartState = ConnectivityState.IDLE;
476+
const channelControlHelper = createChildChannelControlHelper(
477+
baseChannelControlHelper,
478+
{
479+
createSubchannel: (subchannelAddress, subchannelArgs) => {
480+
const subchannel = new MockSubchannel(
481+
subchannelAddressToString(subchannelAddress),
482+
currentStartState
483+
);
484+
subchannels.push(subchannel);
485+
return subchannel;
486+
},
487+
updateState: updateStateCallBackForExpectedStateSequence(
488+
[ConnectivityState.CONNECTING, ConnectivityState.TRANSIENT_FAILURE],
489+
err => setImmediate(() => {
490+
assert.strictEqual(reresolutionRequestCount, targetReresolutionRequestCount);
491+
done(err);
492+
})
493+
),
494+
requestReresolution: () => {
495+
reresolutionRequestCount += 1;
496+
}
497+
}
498+
);
499+
const pickFirst = new PickFirstLoadBalancer(channelControlHelper);
500+
pickFirst.updateAddressList([{ host: 'localhost', port: 1 }], config);
501+
process.nextTick(() => {
502+
subchannels[0].transitionToState(ConnectivityState.TRANSIENT_FAILURE);
503+
process.nextTick(() => {
504+
pickFirst.updateAddressList([{ host: 'localhost', port: 2 }], config);
505+
process.nextTick(() => {
506+
subchannels[1].transitionToState(ConnectivityState.TRANSIENT_FAILURE);
507+
process.nextTick(() => {
508+
pickFirst.updateAddressList([{ host: 'localhost', port: 3 }], config);
509+
process.nextTick(() => {
510+
subchannels[2].transitionToState(ConnectivityState.TRANSIENT_FAILURE);
511+
});
512+
});
513+
});
514+
});
515+
});
516+
});
517+
it('Should request reresolution if the new subchannels are already in TF', done => {
518+
let reresolutionRequestCount = 0;
519+
const targetReresolutionRequestCount = 3;
520+
const currentStartState = ConnectivityState.TRANSIENT_FAILURE;
521+
const channelControlHelper = createChildChannelControlHelper(
522+
baseChannelControlHelper,
523+
{
524+
createSubchannel: (subchannelAddress, subchannelArgs) => {
525+
const subchannel = new MockSubchannel(
526+
subchannelAddressToString(subchannelAddress),
527+
currentStartState
528+
);
529+
subchannels.push(subchannel);
530+
return subchannel;
531+
},
532+
updateState: updateStateCallBackForExpectedStateSequence(
533+
[ConnectivityState.TRANSIENT_FAILURE],
534+
err => setImmediate(() => {
535+
assert.strictEqual(reresolutionRequestCount, targetReresolutionRequestCount);
536+
done(err);
537+
})
538+
),
539+
requestReresolution: () => {
540+
reresolutionRequestCount += 1;
541+
}
542+
}
543+
);
544+
const pickFirst = new PickFirstLoadBalancer(channelControlHelper);
545+
pickFirst.updateAddressList([{ host: 'localhost', port: 1 }], config);
546+
process.nextTick(() => {
547+
pickFirst.updateAddressList([{ host: 'localhost', port: 2 }], config);
548+
process.nextTick(() => {
549+
pickFirst.updateAddressList([{ host: 'localhost', port: 2 }], config);
550+
});
551+
});
552+
});
465553
describe('Address list randomization', () => {
466554
const shuffleConfig = new PickFirstLoadBalancingConfig(true);
467555
it('Should pick different subchannels after multiple updates', done => {

0 commit comments

Comments
 (0)