@@ -20,6 +20,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
2020import { PodmanConnection } from './podmanConnection' ;
2121import type {
2222 ContainerProviderConnection ,
23+ Extension ,
2324 ProviderConnectionStatus ,
2425 ProviderContainerConnection ,
2526 ProviderEvent ,
@@ -29,10 +30,11 @@ import type {
2930 UpdateContainerConnectionEvent ,
3031 Webview ,
3132} from '@podman-desktop/api' ;
32- import { containerEngine , process , provider , EventEmitter , env } from '@podman-desktop/api' ;
33+ import { containerEngine , extensions , process , provider , EventEmitter , env } from '@podman-desktop/api' ;
3334import { VMType } from '@shared/src/models/IPodman' ;
3435import { Messages } from '@shared/Messages' ;
3536import type { ModelInfo } from '@shared/src/models/IModelInfo' ;
37+ import { getPodmanCli , getPodmanMachineName } from '../utils/podman' ;
3638
3739const webviewMock = {
3840 postMessage : vi . fn ( ) ,
@@ -51,6 +53,9 @@ vi.mock('@podman-desktop/api', async () => {
5153 process : {
5254 exec : vi . fn ( ) ,
5355 } ,
56+ extensions : {
57+ getExtension : vi . fn ( ) ,
58+ } ,
5459 containerEngine : {
5560 listInfos : vi . fn ( ) ,
5661 } ,
@@ -64,6 +69,7 @@ vi.mock('@podman-desktop/api', async () => {
6469vi . mock ( '../utils/podman' , ( ) => {
6570 return {
6671 getPodmanCli : vi . fn ( ) ,
72+ getPodmanMachineName : vi . fn ( ) ,
6773 MIN_CPUS_VALUE : 4 ,
6874 } ;
6975} ) ;
@@ -73,6 +79,8 @@ beforeEach(() => {
7379
7480 vi . mocked ( webviewMock . postMessage ) . mockResolvedValue ( true ) ;
7581 vi . mocked ( provider . getContainerConnections ) . mockReturnValue ( [ ] ) ;
82+ vi . mocked ( getPodmanCli ) . mockReturnValue ( 'podman-executable' ) ;
83+ vi . mocked ( getPodmanMachineName ) . mockImplementation ( connection => connection . name ) ;
7684
7785 const listeners : ( ( value : unknown ) => void ) [ ] = [ ] ;
7886
@@ -86,6 +94,151 @@ beforeEach(() => {
8694 } as unknown as EventEmitter < unknown > ) ;
8795} ) ;
8896
97+ const providerContainerConnectionMock : ProviderContainerConnection = {
98+ connection : {
99+ type : 'podman' ,
100+ status : ( ) => 'started' ,
101+ name : 'Podman Machine' ,
102+ endpoint : {
103+ socketPath : './socket-path' ,
104+ } ,
105+ } ,
106+ providerId : 'podman' ,
107+ } ;
108+
109+ describe ( 'execute' , ( ) => {
110+ test ( 'execute should get the podman extension from api' , async ( ) => {
111+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( undefined ) ;
112+ const manager = new PodmanConnection ( webviewMock ) ;
113+ await manager . execute ( providerContainerConnectionMock . connection , [ 'ls' ] ) ;
114+ expect ( extensions . getExtension ) . toHaveBeenCalledWith ( 'podman-desktop.podman' ) ;
115+ } ) ;
116+
117+ test ( 'execute should call getPodmanCli if extension not available' , async ( ) => {
118+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( undefined ) ;
119+ const manager = new PodmanConnection ( webviewMock ) ;
120+ await manager . execute ( providerContainerConnectionMock . connection , [ 'ls' ] ) ;
121+
122+ expect ( getPodmanCli ) . toHaveBeenCalledOnce ( ) ;
123+ expect ( process . exec ) . toHaveBeenCalledWith ( 'podman-executable' , [ 'ls' ] , undefined ) ;
124+ } ) ;
125+
126+ test ( 'options should be propagated to process execution when provided' , async ( ) => {
127+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( undefined ) ;
128+ const manager = new PodmanConnection ( webviewMock ) ;
129+ await manager . execute ( providerContainerConnectionMock . connection , [ 'ls' ] , {
130+ isAdmin : true ,
131+ } ) ;
132+
133+ expect ( getPodmanCli ) . toHaveBeenCalledOnce ( ) ;
134+ expect ( process . exec ) . toHaveBeenCalledWith ( 'podman-executable' , [ 'ls' ] , {
135+ isAdmin : true ,
136+ } ) ;
137+ } ) ;
138+
139+ test ( 'execute should use extension exec if available' , async ( ) => {
140+ vi . mocked ( provider . getContainerConnections ) . mockReturnValue ( [ providerContainerConnectionMock ] ) ;
141+ const podmanAPI = {
142+ exec : vi . fn ( ) ,
143+ } ;
144+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( { exports : podmanAPI } as unknown as Extension < unknown > ) ;
145+ const manager = new PodmanConnection ( webviewMock ) ;
146+ await manager . execute ( providerContainerConnectionMock . connection , [ 'ls' ] ) ;
147+
148+ expect ( getPodmanCli ) . not . toHaveBeenCalledOnce ( ) ;
149+ expect ( podmanAPI . exec ) . toHaveBeenCalledWith ( [ 'ls' ] , {
150+ connection : providerContainerConnectionMock ,
151+ } ) ;
152+ } ) ;
153+
154+ test ( 'an error should be throw if the provided container connection do not exists' , async ( ) => {
155+ vi . mocked ( provider . getContainerConnections ) . mockReturnValue ( [ ] ) ;
156+ const podmanAPI = {
157+ exec : vi . fn ( ) ,
158+ } ;
159+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( { exports : podmanAPI } as unknown as Extension < unknown > ) ;
160+ const manager = new PodmanConnection ( webviewMock ) ;
161+
162+ await expect ( async ( ) => {
163+ await manager . execute ( providerContainerConnectionMock . connection , [ 'ls' ] , {
164+ isAdmin : true ,
165+ } ) ;
166+ } ) . rejects . toThrowError ( 'cannot find podman provider with connection name Podman Machine' ) ;
167+ } ) ;
168+
169+ test ( 'execute should propagate options to extension exec if available' , async ( ) => {
170+ vi . mocked ( provider . getContainerConnections ) . mockReturnValue ( [ providerContainerConnectionMock ] ) ;
171+ const podmanAPI = {
172+ exec : vi . fn ( ) ,
173+ } ;
174+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( { exports : podmanAPI } as unknown as Extension < unknown > ) ;
175+ const manager = new PodmanConnection ( webviewMock ) ;
176+ await manager . execute ( providerContainerConnectionMock . connection , [ 'ls' ] , {
177+ isAdmin : true ,
178+ } ) ;
179+
180+ expect ( getPodmanCli ) . not . toHaveBeenCalledOnce ( ) ;
181+ expect ( podmanAPI . exec ) . toHaveBeenCalledWith ( [ 'ls' ] , {
182+ isAdmin : true ,
183+ connection : providerContainerConnectionMock ,
184+ } ) ;
185+ } ) ;
186+ } ) ;
187+
188+ describe ( 'executeSSH' , ( ) => {
189+ test ( 'executeSSH should call getPodmanCli if extension not available' , async ( ) => {
190+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( undefined ) ;
191+ const manager = new PodmanConnection ( webviewMock ) ;
192+ await manager . executeSSH ( providerContainerConnectionMock . connection , [ 'ls' ] ) ;
193+
194+ expect ( getPodmanCli ) . toHaveBeenCalledOnce ( ) ;
195+ expect ( process . exec ) . toHaveBeenCalledWith (
196+ 'podman-executable' ,
197+ [ 'machine' , 'ssh' , providerContainerConnectionMock . connection . name , 'ls' ] ,
198+ undefined ,
199+ ) ;
200+ } ) ;
201+
202+ test ( 'executeSSH should use extension exec if available' , async ( ) => {
203+ vi . mocked ( provider . getContainerConnections ) . mockReturnValue ( [ providerContainerConnectionMock ] ) ;
204+ const podmanAPI = {
205+ exec : vi . fn ( ) ,
206+ } ;
207+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( { exports : podmanAPI } as unknown as Extension < unknown > ) ;
208+ const manager = new PodmanConnection ( webviewMock ) ;
209+ await manager . executeSSH ( providerContainerConnectionMock . connection , [ 'ls' ] ) ;
210+
211+ expect ( getPodmanCli ) . not . toHaveBeenCalledOnce ( ) ;
212+ expect ( podmanAPI . exec ) . toHaveBeenCalledWith (
213+ [ 'machine' , 'ssh' , providerContainerConnectionMock . connection . name , 'ls' ] ,
214+ {
215+ connection : providerContainerConnectionMock ,
216+ } ,
217+ ) ;
218+ } ) ;
219+
220+ test ( 'executeSSH should propagate options to extension exec if available' , async ( ) => {
221+ vi . mocked ( provider . getContainerConnections ) . mockReturnValue ( [ providerContainerConnectionMock ] ) ;
222+ const podmanAPI = {
223+ exec : vi . fn ( ) ,
224+ } ;
225+ vi . mocked ( extensions . getExtension ) . mockReturnValue ( { exports : podmanAPI } as unknown as Extension < unknown > ) ;
226+ const manager = new PodmanConnection ( webviewMock ) ;
227+ await manager . executeSSH ( providerContainerConnectionMock . connection , [ 'ls' ] , {
228+ isAdmin : true ,
229+ } ) ;
230+
231+ expect ( getPodmanCli ) . not . toHaveBeenCalledOnce ( ) ;
232+ expect ( podmanAPI . exec ) . toHaveBeenCalledWith (
233+ [ 'machine' , 'ssh' , providerContainerConnectionMock . connection . name , 'ls' ] ,
234+ {
235+ isAdmin : true ,
236+ connection : providerContainerConnectionMock ,
237+ } ,
238+ ) ;
239+ } ) ;
240+ } ) ;
241+
89242describe ( 'podman connection initialization' , ( ) => {
90243 test ( 'init should notify publisher' , ( ) => {
91244 const manager = new PodmanConnection ( webviewMock ) ;
0 commit comments