Skip to content

Commit f5621db

Browse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
fix: flaky compiler test
- The gRPC core client provider requires an initialized config service when processing the error message received during the `InitRequest` - Additional logging in the config service. - The tests log into the console. Signed-off-by: Akos Kitta <[email protected]>
1 parent 658f117 commit f5621db

File tree

3 files changed

+125
-10
lines changed

3 files changed

+125
-10
lines changed

Diff for: arduino-ide-extension/src/node/config-service-impl.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,10 @@ export class ConfigServiceImpl
136136
}
137137

138138
private async initConfig(): Promise<void> {
139+
this.logger.info('>>> Initializing CLI configuration...');
139140
try {
140141
const cliConfig = await this.loadCliConfig();
142+
this.logger.info('Loaded the CLI configuration.');
141143
this.cliConfig = cliConfig;
142144
const [config] = await Promise.all([
143145
this.mapCliConfigToAppConfig(this.cliConfig),
@@ -153,10 +155,16 @@ export class ConfigServiceImpl
153155
}),
154156
]);
155157
this.config.config = config;
158+
this.logger.info(
159+
`Mapped the CLI configuration: ${JSON.stringify(this.config.config)}`
160+
);
161+
this.logger.info('Validating the CLI configuration...');
156162
await this.validateCliConfig(this.cliConfig);
157163
delete this.config.messages;
164+
this.logger.info('The CLI config is valid.');
158165
if (config) {
159166
this.ready.resolve();
167+
this.logger.info('<<< Initialized the CLI configuration.');
160168
return;
161169
}
162170
} catch (err: unknown) {
@@ -173,18 +181,35 @@ export class ConfigServiceImpl
173181
): Promise<DefaultCliConfig> {
174182
const cliConfigFileUri = await this.getCliConfigFileUri();
175183
const cliConfigPath = FileUri.fsPath(cliConfigFileUri);
184+
this.logger.info(`Loading CLI configuration from ${cliConfigPath}...`);
176185
try {
177186
const content = await fs.readFile(cliConfigPath, {
178187
encoding: 'utf8',
179188
});
180189
const model = (yaml.safeLoad(content) || {}) as DefaultCliConfig;
190+
this.logger.info(`Loaded CLI configuration: ${JSON.stringify(model)}`);
181191
if (model.directories.data && model.directories.user) {
192+
this.logger.info(
193+
"'directories.data' and 'directories.user' are set in the CLI configuration model."
194+
);
182195
return model;
183196
}
184197
// The CLI can run with partial (missing `port`, `directories`), the IDE2 cannot.
185198
// We merge the default CLI config with the partial user's config.
199+
this.logger.info(
200+
"Loading fallback CLI configuration to get 'directories.data' and 'directories.user'"
201+
);
186202
const fallbackModel = await this.getFallbackCliConfig();
187-
return deepmerge(fallbackModel, model) as DefaultCliConfig;
203+
this.logger.info(
204+
`Loaded fallback CLI configuration: ${JSON.stringify(fallbackModel)}`
205+
);
206+
const mergedModel = deepmerge(fallbackModel, model) as DefaultCliConfig;
207+
this.logger.info(
208+
`Merged CLI configuration with the fallback: ${JSON.stringify(
209+
mergedModel
210+
)}`
211+
);
212+
return mergedModel;
188213
} catch (error) {
189214
if (ErrnoException.isENOENT(error)) {
190215
if (initializeIfAbsent) {

Diff for: arduino-ide-extension/src/node/core-client-provider.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ export class CoreClientProvider {
254254
}
255255
})
256256
.on('error', reject)
257-
.on('end', () => {
258-
const error = this.evaluateErrorStatus(errors);
257+
.on('end', async () => {
258+
const error = await this.evaluateErrorStatus(errors);
259259
if (error) {
260260
reject(error);
261261
return;
@@ -265,7 +265,10 @@ export class CoreClientProvider {
265265
});
266266
}
267267

268-
private evaluateErrorStatus(status: RpcStatus[]): Error | undefined {
268+
private async evaluateErrorStatus(
269+
status: RpcStatus[]
270+
): Promise<Error | undefined> {
271+
await this.configService.getConfiguration(); // to ensure the CLI config service has been initialized.
269272
const { cliConfiguration } = this.configService;
270273
if (!cliConfiguration) {
271274
// If the CLI config is not available, do not even try to guess what went wrong.

Diff for: arduino-ide-extension/src/test/node/core-service-impl.slow-test.ts

+93-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
import { bindContributionProvider } from '@theia/core/lib/common/contribution-provider';
88
import { Disposable } from '@theia/core/lib/common/disposable';
99
import { EnvVariablesServer as TheiaEnvVariablesServer } from '@theia/core/lib/common/env-variables';
10-
import { ILogger } from '@theia/core/lib/common/logger';
10+
import { ILogger, Loggable } from '@theia/core/lib/common/logger';
11+
import { LogLevel } from '@theia/core/lib/common/logger-protocol';
1112
import { isWindows } from '@theia/core/lib/common/os';
1213
import { waitForEvent } from '@theia/core/lib/common/promise-util';
1314
import { MockLogger } from '@theia/core/lib/common/test/mock-logger';
@@ -66,7 +67,7 @@ describe('core-service-impl', () => {
6667
let toDispose: Disposable[];
6768

6869
before(() => {
69-
BackendApplicationConfigProvider.set({ configDirName: 'testArduinoIDE' });
70+
BackendApplicationConfigProvider.set({ configDirName: '.testArduinoIDE' });
7071
});
7172

7273
beforeEach(async function () {
@@ -175,10 +176,11 @@ function createContainer(): Container {
175176
);
176177
bind(EnvVariablesServer).toSelf().inSingletonScope();
177178
bind(TheiaEnvVariablesServer).toService(EnvVariablesServer);
178-
bind(ArduinoDaemonImpl).toSelf().inSingletonScope();
179-
bind(ArduinoDaemon).toService(ArduinoDaemonImpl);
180-
bind(MockLogger).toSelf().inSingletonScope();
181-
bind(ILogger).toService(MockLogger);
179+
bind(SilentArduinoDaemon).toSelf().inSingletonScope();
180+
bind(ArduinoDaemon).toService(SilentArduinoDaemon);
181+
bind(ArduinoDaemonImpl).toService(SilentArduinoDaemon);
182+
bind(ConsoleLogger).toSelf().inSingletonScope();
183+
bind(ILogger).toService(ConsoleLogger);
182184
bind(TestNotificationServiceServer).toSelf().inSingletonScope();
183185
bind(NotificationServiceServer).toService(TestNotificationServiceServer);
184186
bind(ConfigServiceImpl).toSelf().inSingletonScope();
@@ -312,3 +314,88 @@ class TestCommandRegistry extends CommandRegistry {
312314
return undefined;
313315
}
314316
}
317+
318+
@injectable()
319+
class ConsoleLogger extends MockLogger {
320+
override log(
321+
logLevel: number,
322+
arg2: string | Loggable | Error,
323+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
324+
...params: any[]
325+
): Promise<void> {
326+
if (arg2 instanceof Error) {
327+
return this.error(String(arg2), params);
328+
}
329+
switch (logLevel) {
330+
case LogLevel.INFO:
331+
return this.info(arg2, params);
332+
case LogLevel.WARN:
333+
return this.warn(arg2, params);
334+
case LogLevel.TRACE:
335+
return this.trace(arg2, params);
336+
case LogLevel.ERROR:
337+
return this.error(arg2, params);
338+
case LogLevel.FATAL:
339+
return this.fatal(arg2, params);
340+
default:
341+
return this.info(arg2, params);
342+
}
343+
}
344+
345+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
346+
override async info(arg: string | Loggable, ...params: any[]): Promise<void> {
347+
if (params.length) {
348+
console.info(arg, ...params);
349+
} else {
350+
console.info(arg);
351+
}
352+
}
353+
354+
override async trace(
355+
arg: string | Loggable,
356+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
357+
...params: any[]
358+
): Promise<void> {
359+
if (params.length) {
360+
console.trace(arg, ...params);
361+
} else {
362+
console.trace(arg);
363+
}
364+
}
365+
366+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
367+
override async warn(arg: string | Loggable, ...params: any[]): Promise<void> {
368+
if (params.length) {
369+
console.warn(arg, ...params);
370+
} else {
371+
console.warn(arg);
372+
}
373+
}
374+
375+
override async error(
376+
arg: string | Loggable,
377+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
378+
...params: any[]
379+
): Promise<void> {
380+
if (params.length) {
381+
console.error(arg, ...params);
382+
} else {
383+
console.error(arg);
384+
}
385+
}
386+
387+
override async fatal(
388+
arg: string | Loggable,
389+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
390+
...params: any[]
391+
): Promise<void> {
392+
return this.error(arg, params);
393+
}
394+
}
395+
396+
@injectable()
397+
class SilentArduinoDaemon extends ArduinoDaemonImpl {
398+
protected override onData(): void {
399+
// NOOP
400+
}
401+
}

0 commit comments

Comments
 (0)