Skip to content

Commit 6bb33d3

Browse files
authored
fix: report stderr outpunt to the log in case of error (#134)
Signed-off-by: Denis Golovin <[email protected]>
1 parent 64cace8 commit 6bb33d3

File tree

3 files changed

+339
-77
lines changed

3 files changed

+339
-77
lines changed

src/extension.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,12 @@ async function signIntoRedHatDeveloperAccount(
8585

8686
const REGISTRY_REDHAT_IO = 'registry.redhat.io';
8787

88-
async function createRegistry(username: string, secret: string, alias: string, serverUrl: string = REGISTRY_REDHAT_IO): Promise<void> {
88+
async function createRegistry(
89+
username: string,
90+
secret: string,
91+
alias: string,
92+
serverUrl: string = REGISTRY_REDHAT_IO,
93+
): Promise<void> {
8994
extensionApi.registry.registerRegistry({
9095
serverUrl,
9196
username,
@@ -150,7 +155,11 @@ async function createOrReuseRegistryServiceAccount(): Promise<void> {
150155
});
151156
}
152157

153-
createRegistry(selectedServiceAccount!.credentials!.username!, selectedServiceAccount!.credentials!.password!, currentSession.account.label);
158+
createRegistry(
159+
selectedServiceAccount!.credentials!.username!,
160+
selectedServiceAccount!.credentials!.password!,
161+
currentSession.account.label,
162+
);
154163
}
155164

156165
async function createOrReuseActivationKey() {

src/podman-cli.spec.ts

+238
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/**********************************************************************
2+
* Copyright (C) 2024 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import { ProgressLocation, TelemetryLogger, commands, process as podmanProcess } from '@podman-desktop/api';
20+
import { beforeEach, expect, suite, test, vi } from 'vitest';
21+
import {
22+
PODMAN_COMMANDS,
23+
getPodmanCli,
24+
runCreateFactsFile,
25+
runRpmInstallSubscriptionManager,
26+
runStartPodmanMachine,
27+
runStopPodmanMachine,
28+
runSubscriptionManager,
29+
runSubscriptionManagerActivationStatus,
30+
runSubscriptionManagerRegister,
31+
} from './podman-cli';
32+
import { ExtensionTelemetryLogger } from './telemetry';
33+
34+
vi.mock('@podman-desktop/api', async () => {
35+
return {
36+
env: {
37+
createTelemetryLogger: vi.fn().mockImplementation(
38+
() =>
39+
({
40+
logUsage: vi.fn(),
41+
logError: vi.fn(),
42+
}) as unknown as TelemetryLogger,
43+
),
44+
},
45+
ProgressLocation: {
46+
TASK_WIDGET: 2,
47+
},
48+
process: {
49+
exec: vi.fn(),
50+
},
51+
configuration: {
52+
getConfiguration: () => {
53+
return {
54+
get: vi.fn(),
55+
};
56+
},
57+
},
58+
};
59+
});
60+
61+
const runResult = { command: 'command line', stdout: 'stdout output', stderr: 'stderr output' };
62+
const runError = { exitCode: 1, stdout: 'stdout output', stderr: 'stderr output', toString: () => 'error message' };
63+
64+
beforeEach(() => {
65+
vi.resetAllMocks();
66+
});
67+
68+
test('runSubscriptionManager returns 0 when it is installed', async () => {
69+
vi.mocked(podmanProcess.exec).mockResolvedValue(runResult);
70+
const result = await runSubscriptionManager();
71+
expect(result).toBe(0);
72+
});
73+
74+
test('runSubscriptionManager returns 1 when it is not installed', async () => {
75+
vi.mocked(podmanProcess.exec).mockRejectedValue({
76+
exitCode: 1,
77+
stdout: 'stdout output',
78+
stderr: 'stderr output',
79+
toString: () => 'error message',
80+
});
81+
const result = await runSubscriptionManager();
82+
expect(result).toBe(1);
83+
});
84+
85+
test('runRpmInstallSubscription manager returns 0 when successful', async () => {
86+
vi.mocked(podmanProcess.exec).mockResolvedValue(runResult);
87+
const result = await runRpmInstallSubscriptionManager();
88+
expect(result).toBe(runResult);
89+
expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.RPM_INSTALL_SM());
90+
});
91+
92+
test('runRpmInstallSubscription manager returns none 0 error code when failed and send telemetry', async () => {
93+
vi.mocked(podmanProcess.exec).mockRejectedValue(runError);
94+
const logErrorSpy = vi.spyOn(ExtensionTelemetryLogger, 'logError').mockImplementation(() => {
95+
return;
96+
});
97+
const consoleError = vi.spyOn(console, 'error');
98+
let error: Error | undefined;
99+
const result = await runRpmInstallSubscriptionManager().catch(err => {
100+
error = err;
101+
});
102+
expect(String(error)).toBe(String(runError));
103+
expect(logErrorSpy).toBeCalledWith('subscriptionManagerInstallationError', { error: 'error message' });
104+
expect(consoleError).toBeCalledWith(
105+
'Subscription manager installation failed.',
106+
runError.toString(),
107+
`stdout: ${runError.stdout}`,
108+
`stderr: ${runError.stderr}`,
109+
);
110+
});
111+
112+
test('runSubscriptionManagerActivationStatus returns 0 when it has subscription activated', async () => {
113+
vi.mocked(podmanProcess.exec).mockResolvedValue(runResult);
114+
const result = await runSubscriptionManagerActivationStatus();
115+
expect(result).toBe(0);
116+
});
117+
118+
test('runSubscriptionManagerActivationStatus returns 1 when it has no active subscription', async () => {
119+
vi.mocked(podmanProcess.exec).mockRejectedValue({
120+
exitCode: 1,
121+
stdout: 'stdout output',
122+
stderr: 'stderr output',
123+
toString: () => 'error message',
124+
});
125+
const result = await runSubscriptionManagerActivationStatus();
126+
expect(result).toBe(1);
127+
});
128+
129+
test('runSubscriptionManagerRegister returns 0 when successful', async () => {
130+
vi.mocked(podmanProcess.exec).mockResolvedValue(runResult);
131+
const result = await runSubscriptionManagerRegister('activation-key-name', 'orgId');
132+
expect(result).toBe(runResult);
133+
expect(podmanProcess.exec).toBeCalledWith(
134+
getPodmanCli(),
135+
PODMAN_COMMANDS.SM_ACTIVATE_SUBS('activation-key-name', 'orgId'),
136+
);
137+
});
138+
139+
test('runSubscriptionManagerRegister manager returns none 0 error code when failed and send telemetry', async () => {
140+
vi.mocked(podmanProcess.exec).mockRejectedValue(runError);
141+
const logErrorSpy = vi.spyOn(ExtensionTelemetryLogger, 'logError').mockImplementation(() => {
142+
return;
143+
});
144+
const consoleError = vi.spyOn(console, 'error');
145+
let error: Error | undefined;
146+
const result = await runSubscriptionManagerRegister('activation-key-name', 'orgId').catch(err => {
147+
error = err;
148+
});
149+
expect(String(error)).toBe(String(runError));
150+
expect(logErrorSpy).toBeCalledWith('subscriptionManagerRegisterError', { error: 'error message' });
151+
expect(consoleError).toBeCalledWith(
152+
'Subscription manager registration failed.',
153+
runError.toString(),
154+
`stdout: ${runError.stdout}`,
155+
`stderr: ${runError.stderr}`,
156+
);
157+
});
158+
159+
test('runCreateFactsFile returns 0 when successful', async () => {
160+
vi.mocked(podmanProcess.exec).mockResolvedValue(runResult);
161+
const result = await runCreateFactsFile('{"field":"value"}');
162+
expect(result).toBe(runResult);
163+
expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.CREATE_FACTS_FILE('{"field":"value"}'));
164+
});
165+
166+
test('runCreateFactsFile manager returns none 0 error code when failed and send telemetry', async () => {
167+
vi.mocked(podmanProcess.exec).mockRejectedValue(runError);
168+
const logErrorSpy = vi.spyOn(ExtensionTelemetryLogger, 'logError').mockImplementation(() => {
169+
return;
170+
});
171+
const consoleError = vi.spyOn(console, 'error');
172+
let error: Error | undefined;
173+
const result = await runCreateFactsFile('{"field":"value"}').catch(err => {
174+
error = err;
175+
});
176+
expect(String(error)).toBe(String(runError));
177+
expect(logErrorSpy).toBeCalledWith('subscriptionManagerCreateFactsFileError', { error: 'error message' });
178+
expect(consoleError).toBeCalledWith(
179+
'Writing /etc/rhsm/facts/podman-desktop-redhat-account-ext.facts failed.',
180+
runError.toString(),
181+
`stdout: ${runError.stdout}`,
182+
`stderr: ${runError.stderr}`,
183+
);
184+
});
185+
186+
test('runStopPodmanMachine returns 0 when successful', async () => {
187+
vi.mocked(podmanProcess.exec).mockResolvedValue(runResult);
188+
const result = await runStopPodmanMachine();
189+
expect(result).toBe(runResult);
190+
expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.MACHINE_STOP());
191+
});
192+
193+
test('runStopPodmanMachine manager returns none 0 error code when failed and send telemetry', async () => {
194+
vi.mocked(podmanProcess.exec).mockRejectedValue(runError);
195+
const logErrorSpy = vi.spyOn(ExtensionTelemetryLogger, 'logError').mockImplementation(() => {
196+
return;
197+
});
198+
const consoleError = vi.spyOn(console, 'error');
199+
let error: Error | undefined;
200+
const result = await runStopPodmanMachine().catch(err => {
201+
error = err;
202+
});
203+
expect(String(error)).toBe(String(runError));
204+
expect(logErrorSpy).toBeCalledWith('stopPodmanMachineError', { error: 'error message' });
205+
expect(consoleError).toBeCalledWith(
206+
'Podman machine stop failed.',
207+
runError.toString(),
208+
`stdout: ${runError.stdout}`,
209+
`stderr: ${runError.stderr}`,
210+
);
211+
});
212+
213+
test('runStartPodmanMachine returns 0 when successful', async () => {
214+
vi.mocked(podmanProcess.exec).mockResolvedValue(runResult);
215+
const result = await runStartPodmanMachine();
216+
expect(result).toBe(runResult);
217+
expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.MACHINE_START());
218+
});
219+
220+
test('runStartPodmanMachine manager returns none 0 error code when failed and send telemetry', async () => {
221+
vi.mocked(podmanProcess.exec).mockRejectedValue(runError);
222+
const logErrorSpy = vi.spyOn(ExtensionTelemetryLogger, 'logError').mockImplementation(() => {
223+
return;
224+
});
225+
const consoleError = vi.spyOn(console, 'error');
226+
let error: Error | undefined;
227+
const result = await runStartPodmanMachine().catch(err => {
228+
error = err;
229+
});
230+
expect(String(error)).toBe(String(runError));
231+
expect(logErrorSpy).toBeCalledWith('startPodmanMachineError', { error: 'error message' });
232+
expect(consoleError).toBeCalledWith(
233+
'Podman machine start failed.',
234+
runError.toString(),
235+
`stdout: ${runError.stdout}`,
236+
`stderr: ${runError.stderr}`,
237+
);
238+
});

0 commit comments

Comments
 (0)