Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/desktop/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import { CsolutionService } from '../json-rpc/csolution-rpc-client';
import { BuildStopCommand } from '../tasks/build/build-stop-command';
import { ComponentsPacksWebviewMain } from '../views/manage-components-packs/components-packs-webview-main';
import { SolutionConverterImpl } from '../solutions/solution-converter';
import { SolutionProblemsImpl } from '../solutions/solution-problems';
import { EnvironmentManager } from './env-manager';
import { ExtensionApiWrapper } from '../vscode-api/extension-api-wrapper';
import { SerialMonitorApi, Version } from '@microsoft/vscode-serial-monitor-api';
Expand Down Expand Up @@ -178,6 +179,7 @@ export const activate = async (context: ExtensionContext): Promise<CsolutionExte
cmsisToolboxManager,
compileCommandsGenerator,
);
const solutionProblems = new SolutionProblemsImpl(solutionManager, eventHub);

const themeProvider = new ThemeProviderImpl();
const statusBar = new StatusBar(solutionManager, cmsisToolboxManager, themeProvider);
Expand Down Expand Up @@ -263,6 +265,7 @@ export const activate = async (context: ExtensionContext): Promise<CsolutionExte
runGeneratorCommand.activate(context),
convertMdkToCsolution.activate(context),
solutionConverterImpl.activate(context),
solutionProblems.activate(context),
clangdManager.activate(context),
componentsManager.activate(context),
createSolution.activate(context),
Expand Down
9 changes: 1 addition & 8 deletions src/solutions/csolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { ContextDescriptor, contextDescriptorFromString } from './descriptors/de
import { CmsisSettingsJsonFile } from '../global/cmsis-settings-json-file';
import { CSolutionYamlFile } from './files/csolution-yaml-file';
import { CProjectYamlFile } from './files/cproject-yaml-file';
import { VariablesConfiguration, LogMessages } from '../json-rpc/csolution-rpc-client';
import { VariablesConfiguration } from '../json-rpc/csolution-rpc-client';
import { CbuildPackFile } from './files/cbuild-pack-file';

export const targetTypeSchema = new Schema({
Expand Down Expand Up @@ -81,9 +81,6 @@ export class CSolution {
// layer configurations
variablesConfigurations?: VariablesConfiguration[] = undefined;

// log messages
logMessages?: LogMessages = undefined;

public get projects() {
return this.csolutionYml.projects;
}
Expand Down Expand Up @@ -488,10 +485,6 @@ export class CSolution {
public setVariablesConfigurations(variablesConfigurations: VariablesConfiguration[] | undefined) {
this.variablesConfigurations = variablesConfigurations;
}

public setLogMessages(logMessages: LogMessages | undefined) {
this.logMessages = logMessages;
}
};

export function expandPath(path: string, csolution?: CSolution, targetType?: string,): string {
Expand Down
58 changes: 25 additions & 33 deletions src/solutions/solution-converter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { expect, it, describe } from '@jest/globals';
import * as path from 'path';
import * as manifest from '../manifest';
import { ExtensionContext } from 'vscode';
import * as vscode from 'vscode';
import { SolutionConverterImpl } from './solution-converter';
import { MockOutputChannelProvider, outputChannelProviderFactory } from '../vscode-api/output-channel-provider.factories';
import { MockConfigurationProvider, configurationProviderFactory } from '../vscode-api/configuration-provider.factories';
Expand All @@ -39,6 +38,7 @@ import { getWorkspaceFolder } from '../utils/vscode-utils';
import * as fsUtils from '../utils/fs-utils';
import { ConvertRequestData, SolutionEventHub } from './solution-event-hub';
import { waitTimeout } from '../__test__/test-waits';
import { SolutionProblemsImpl } from './solution-problems';

jest.mock('which', () => jest.fn((cmd) => Promise.resolve(path.join('path', 'to', cmd))));

Expand Down Expand Up @@ -72,6 +72,7 @@ describe('SolutionConverter', () => {
let mockCsolutionService: jest.Mocked<ReturnType<typeof csolutionServiceFactory>>;
let convertRequestData: ConvertRequestData;
let completedListener: jest.Mock;
let solutionProblems: SolutionProblemsImpl;

/**
* Helper to wait for N completion events from EventHub
Expand Down Expand Up @@ -143,9 +144,11 @@ describe('SolutionConverter', () => {
cmsisToolboxManager,
compileCommandsGenerator,
);
solutionProblems = new SolutionProblemsImpl(solutionManager, eventHub);

initUtils(mockConfigurationProvider, solutionManager);
converter.activate({ subscriptions: [] } as unknown as ExtensionContext);
await solutionProblems.activate({ subscriptions: [] } as unknown as ExtensionContext);

mockCsolutionService.listMissingPacks.mockResolvedValue({ success: true });
mockCsolutionService.convertSolution.mockResolvedValue({ success: true });
Expand Down Expand Up @@ -304,9 +307,6 @@ describe('SolutionConverter', () => {
});

it('get log messages and set diagnostics accordingly', async () => {
const mockDiagnosticsCollectionSet = jest.spyOn(vscode.languages.createDiagnosticCollection(), 'set');
const mockDiagnosticsCollectionClear = jest.spyOn(vscode.languages.createDiagnosticCollection(), 'clear');

mockCsolutionService.convertSolution.mockResolvedValue({ success: false });
mockCsolutionService.getLogMessages.mockResolvedValue({
success: true,
Expand All @@ -316,13 +316,10 @@ describe('SolutionConverter', () => {
});
await fireAndWaitForConversion();

expect(mockDiagnosticsCollectionClear).toHaveBeenCalled();
expect(mockDiagnosticsCollectionSet).toHaveBeenCalledTimes(3);
expect(completedListener).toHaveBeenCalledTimes(1);
});

it('get cbuild west output and set diagnostics accordingly', async () => {
const mockDiagnosticsCollectionSet = jest.spyOn(vscode.languages.createDiagnosticCollection(), 'set');
mockCsolutionService.convertSolution.mockResolvedValue({ success: true });
mockCsolutionService.getLogMessages.mockResolvedValue({ success: true });
let mockRunCbuildSetup = jest.spyOn(compileCommandsGenerator, 'runCbuildSetup').mockResolvedValue([true, [
Expand All @@ -336,15 +333,23 @@ describe('SolutionConverter', () => {
jest.spyOn(vscodeUtils, 'getWorkspaceFolder').mockReturnValue('workspace/folder');

await fireAndWaitForConversion();
await waitTimeout();
expect(mockRunCbuildSetup).toHaveBeenCalledTimes(1);
expect(mockDiagnosticsCollectionSet).toHaveBeenCalledTimes(2);
expect(completedListener).toHaveBeenCalledTimes(1);
expect(completedListener).toHaveBeenLastCalledWith(
expect.objectContaining({
severity: 'error',
toolsOutputMessages: expect.arrayContaining([
'warning cbuild: missing ZEPHYR_BASE environment variable',
'error cbuild: exec: "west": executable file not found in $PATH',
]),
}),
);

// Remove settings.json
completedListener.mockClear();
const settings = path.join(getWorkspaceFolder(), '.vscode', 'settings.json');
mockRunCbuildSetup.mockClear();
mockDiagnosticsCollectionSet.mockClear();
fsUtils.deleteFileIfExists(settings);
await fireAndWaitForConversion();
expect(mockRunCbuildSetup).toHaveBeenCalledTimes(1);
Expand All @@ -354,7 +359,6 @@ describe('SolutionConverter', () => {
completedListener.mockClear();
mockRunCbuildSetup = jest.spyOn(compileCommandsGenerator, 'runCbuildSetup').mockResolvedValue([true, []]);
mockRunCbuildSetup.mockClear();
mockDiagnosticsCollectionSet.mockClear();
await fireAndWaitForConversion();
expect(mockRunCbuildSetup).toHaveBeenCalledTimes(1);
expect(completedListener).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -425,11 +429,7 @@ describe('SolutionConverter', () => {
});
});

it('creates diagnostic when cpackget fails to download a pack', async () => {
const diagnosticCollection = vscode.languages.createDiagnosticCollection();
const mockDiagnosticsCollectionSet = jest.spyOn(diagnosticCollection, 'set') as unknown as jest.MockedFunction<
(uri: vscode.Uri, diagnostics: readonly vscode.Diagnostic[] | undefined) => void
>;
it('reports error severity when cpackget fails to download a pack', async () => {
jest.spyOn(cmsisToolboxManager, 'runCmsisTool').mockImplementation(async (_t, _a, onOutput) => {
onOutput('W: retry failed');
onOutput('E: network timeout');
Expand All @@ -440,24 +440,16 @@ describe('SolutionConverter', () => {

await fireAndWaitForConversion();

expect(mockDiagnosticsCollectionSet).toHaveBeenCalledTimes(1);
const [[, diagnostics]] = mockDiagnosticsCollectionSet.mock.calls;
expect(diagnostics?.[0]?.message).toContain('network timeout');
expect(diagnostics?.[0]?.message).toContain('retry failed');
expect(completedListener).toHaveBeenCalledWith(
expect.objectContaining({
severity: 'error',
toolsOutputMessages: expect.arrayContaining([
expect.stringContaining("error cpackget: downloading pack 'VendorA::PackA@1.0.0' failed"),
expect.stringContaining('network timeout'),
expect.stringContaining('retry failed'),
]),
})
);
});

it('extracts warnings from cbuild2cmake and csolution tool output', async () => {
const mockDiagnosticsCollectionSet = jest.spyOn(vscode.languages.createDiagnosticCollection(), 'set');
mockCsolutionService.convertSolution.mockResolvedValue({ success: true });
mockCsolutionService.getLogMessages.mockResolvedValue({ success: true });
jest.spyOn(compileCommandsGenerator, 'runCbuildSetup').mockResolvedValue([true, [
'warning cbuild2cmake: some warning',
'error csolution: some error',
]]);

await fireAndWaitForConversion();

// Expect two calls: one for cbuild2cmake warning, one for csolution error
expect(mockDiagnosticsCollectionSet).toHaveBeenCalledTimes(2);
});
});
Loading
Loading