Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/lifecycle/test/electron-browser/lifecycleService.test.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import assert from 'assert';
7
import { timeout } from '../../../../../base/common/async.js';
8
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
9
import { runWithFakedTimers } from '../../../../../base/test/common/timeTravelScheduler.js';
10
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
11
import { ShutdownReason, WillShutdownJoinerOrder } from '../../common/lifecycle.js';
12
import { NativeLifecycleService } from '../../electron-browser/lifecycleService.js';
13
import { workbenchInstantiationService } from '../../../../test/electron-browser/workbenchTestServices.js';
14
15
suite('Lifecycleservice', function () {
16
17
let lifecycleService: TestLifecycleService;
18
const disposables = new DisposableStore();
19
20
class TestLifecycleService extends NativeLifecycleService {
21
22
testHandleBeforeShutdown(reason: ShutdownReason): Promise<boolean> {
23
return super.handleBeforeShutdown(reason);
24
}
25
26
testHandleWillShutdown(reason: ShutdownReason): Promise<void> {
27
return super.handleWillShutdown(reason);
28
}
29
}
30
31
setup(async () => {
32
const instantiationService = workbenchInstantiationService(undefined, disposables);
33
lifecycleService = disposables.add(instantiationService.createInstance(TestLifecycleService));
34
});
35
36
teardown(async () => {
37
disposables.clear();
38
});
39
40
test('onBeforeShutdown - final veto called after other vetos', async function () {
41
let vetoCalled = false;
42
let finalVetoCalled = false;
43
44
const order: number[] = [];
45
46
disposables.add(lifecycleService.onBeforeShutdown(e => {
47
e.veto(new Promise<boolean>(resolve => {
48
vetoCalled = true;
49
order.push(1);
50
51
resolve(false);
52
}), 'test');
53
}));
54
55
disposables.add(lifecycleService.onBeforeShutdown(e => {
56
e.finalVeto(() => {
57
return new Promise<boolean>(resolve => {
58
finalVetoCalled = true;
59
order.push(2);
60
61
resolve(true);
62
});
63
}, 'test');
64
}));
65
66
const veto = await lifecycleService.testHandleBeforeShutdown(ShutdownReason.QUIT);
67
68
assert.strictEqual(veto, true);
69
assert.strictEqual(vetoCalled, true);
70
assert.strictEqual(finalVetoCalled, true);
71
assert.strictEqual(order[0], 1);
72
assert.strictEqual(order[1], 2);
73
});
74
75
test('onBeforeShutdown - final veto not called when veto happened before', async function () {
76
let vetoCalled = false;
77
let finalVetoCalled = false;
78
79
disposables.add(lifecycleService.onBeforeShutdown(e => {
80
e.veto(new Promise<boolean>(resolve => {
81
vetoCalled = true;
82
83
resolve(true);
84
}), 'test');
85
}));
86
87
disposables.add(lifecycleService.onBeforeShutdown(e => {
88
e.finalVeto(() => {
89
return new Promise<boolean>(resolve => {
90
finalVetoCalled = true;
91
92
resolve(true);
93
});
94
}, 'test');
95
}));
96
97
const veto = await lifecycleService.testHandleBeforeShutdown(ShutdownReason.QUIT);
98
99
assert.strictEqual(veto, true);
100
assert.strictEqual(vetoCalled, true);
101
assert.strictEqual(finalVetoCalled, false);
102
});
103
104
test('onBeforeShutdown - veto with error is treated as veto', async function () {
105
disposables.add(lifecycleService.onBeforeShutdown(e => {
106
e.veto(new Promise<boolean>((resolve, reject) => {
107
reject(new Error('Fail'));
108
}), 'test');
109
}));
110
111
const veto = await lifecycleService.testHandleBeforeShutdown(ShutdownReason.QUIT);
112
113
assert.strictEqual(veto, true);
114
});
115
116
test('onBeforeShutdown - final veto with error is treated as veto', async function () {
117
disposables.add(lifecycleService.onBeforeShutdown(e => {
118
e.finalVeto(() => new Promise<boolean>((resolve, reject) => {
119
reject(new Error('Fail'));
120
}), 'test');
121
}));
122
123
const veto = await lifecycleService.testHandleBeforeShutdown(ShutdownReason.QUIT);
124
125
assert.strictEqual(veto, true);
126
});
127
128
test('onWillShutdown - join', async function () {
129
let joinCalled = false;
130
131
disposables.add(lifecycleService.onWillShutdown(e => {
132
e.join(new Promise(resolve => {
133
joinCalled = true;
134
135
resolve();
136
}), { id: 'test', label: 'test' });
137
}));
138
139
await lifecycleService.testHandleWillShutdown(ShutdownReason.QUIT);
140
141
assert.strictEqual(joinCalled, true);
142
});
143
144
test('onWillShutdown - join with error is handled', async function () {
145
let joinCalled = false;
146
147
disposables.add(lifecycleService.onWillShutdown(e => {
148
e.join(new Promise((resolve, reject) => {
149
joinCalled = true;
150
151
reject(new Error('Fail'));
152
}), { id: 'test', label: 'test' });
153
}));
154
155
await lifecycleService.testHandleWillShutdown(ShutdownReason.QUIT);
156
157
assert.strictEqual(joinCalled, true);
158
});
159
160
test('onWillShutdown - join order', async function () {
161
return runWithFakedTimers({ useFakeTimers: true }, async () => {
162
const order: string[] = [];
163
164
disposables.add(lifecycleService.onWillShutdown(e => {
165
e.join(async () => {
166
order.push('disconnect start');
167
await timeout(1);
168
order.push('disconnect end');
169
}, { id: 'test', label: 'test', order: WillShutdownJoinerOrder.Last });
170
171
e.join((async () => {
172
order.push('default start');
173
await timeout(1);
174
order.push('default end');
175
})(), { id: 'test', label: 'test', order: WillShutdownJoinerOrder.Default });
176
}));
177
178
await lifecycleService.testHandleWillShutdown(ShutdownReason.QUIT);
179
180
assert.deepStrictEqual(order, [
181
'default start',
182
'default end',
183
'disconnect start',
184
'disconnect end'
185
]);
186
});
187
});
188
189
test('willShutdown is set when shutting down', async function () {
190
let willShutdownSet = false;
191
192
disposables.add(lifecycleService.onWillShutdown(e => {
193
e.join(new Promise(resolve => {
194
if (lifecycleService.willShutdown) {
195
willShutdownSet = true;
196
resolve();
197
}
198
}), { id: 'test', label: 'test' });
199
}));
200
201
await lifecycleService.testHandleWillShutdown(ShutdownReason.QUIT);
202
203
assert.strictEqual(willShutdownSet, true);
204
});
205
206
ensureNoDisposablesAreLeakedInTestSuite();
207
});
208
209