@@ -2,8 +2,8 @@ import { CoreV1Api, CustomObjectsApi } from '@kubernetes/client-node';
22import Metalk8sLocalVolumeProvider , {
33 VolumeType ,
44} from './Metalk8sLocalVolumeProvider' ;
5- import { Metalk8sV1alpha1VolumeClient } from './Metalk8sVolumeClient.generated' ;
65import { updateApiServerConfig } from './api' ;
6+ import { Metalk8sV1alpha1VolumeClient } from './Metalk8sVolumeClient.generated' ;
77
88jest . mock ( '../k8s/api' , ( ) => ( {
99 updateApiServerConfig : jest . fn ( ) ,
@@ -18,13 +18,18 @@ describe('Metalk8sLocalVolumeProvider', () => {
1818 listClusterCustomObject : jest . fn ( ) ,
1919 } as unknown as CustomObjectsApi ;
2020
21- const mockVolumeClient = new Metalk8sV1alpha1VolumeClient (
22- mockCustomObjectsApi ,
23- ) ;
21+ const mockVolumeClient = {
22+ deleteMetalk8sV1alpha1Volume : jest . fn ( ) . mockResolvedValue ( { body : { } } ) ,
23+ getMetalk8sV1alpha1VolumeList : jest . fn ( ) ,
24+ getMetalk8sV1alpha1Volume : jest . fn ( ) ,
25+ createMetalk8sV1alpha1Volume : jest . fn ( ) ,
26+ patchMetalk8sV1alpha1Volume : jest . fn ( ) ,
27+ } as unknown as Metalk8sV1alpha1VolumeClient ;
2428
2529 const mockCoreV1Api = {
2630 listNode : jest . fn ( ) ,
2731 listPersistentVolume : jest . fn ( ) ,
32+ deletePersistentVolume : jest . fn ( ) ,
2833 } as unknown as CoreV1Api ;
2934
3035 beforeEach ( ( ) => {
@@ -68,7 +73,7 @@ describe('Metalk8sLocalVolumeProvider', () => {
6873 } ) ;
6974
7075 (
71- mockCustomObjectsApi . listClusterCustomObject as jest . Mock
76+ mockVolumeClient . getMetalk8sV1alpha1VolumeList as jest . Mock
7277 ) . mockResolvedValue ( {
7378 body : {
7479 items : [
@@ -150,12 +155,122 @@ describe('Metalk8sLocalVolumeProvider', () => {
150155 } ) ;
151156
152157 (
153- mockCustomObjectsApi . listClusterCustomObject as jest . Mock
158+ mockVolumeClient . getMetalk8sV1alpha1VolumeList as jest . Mock
154159 ) . mockRejectedValue ( new Error ( 'Failed to fetch volumes' ) ) ;
155160
156161 await expect (
157162 provider . listLocalPersistentVolumes ( 'test-node' ) ,
158- ) . rejects . toThrow ( 'Failed to fetch metalk8s volumes' ) ;
163+ ) . rejects . toThrow (
164+ 'Failed to fetch local persistent volumes: Failed to fetch volumes' ,
165+ ) ;
166+ } ) ;
167+ } ) ;
168+
169+ describe ( 'detachVolumes' , ( ) => {
170+ it ( 'should detach hardware volumes and virtual volumes' , async ( ) => {
171+ //S
172+ (
173+ mockVolumeClient . deleteMetalk8sV1alpha1Volume as jest . Mock
174+ ) . mockResolvedValue ( {
175+ body : { } ,
176+ } ) ;
177+ ( mockCoreV1Api . deletePersistentVolume as jest . Mock ) . mockResolvedValue ( {
178+ body : { } ,
179+ } ) ;
180+ (
181+ mockVolumeClient . getMetalk8sV1alpha1VolumeList as jest . Mock
182+ ) . mockResolvedValue ( {
183+ body : {
184+ items : [
185+ {
186+ metadata : { name : 'test-volume' } ,
187+ spec : {
188+ nodeName : 'test-node' ,
189+ rawBlockDevice : { devicePath : '/dev/sda' } ,
190+ } ,
191+ } ,
192+ {
193+ metadata : { name : 'test-lvm' } ,
194+ spec : {
195+ nodeName : 'test-node' ,
196+ lvmLogicalVolume : { vgName : 'test-lvm' , size : '10Gi' } ,
197+ } ,
198+ } ,
199+ ] ,
200+ } ,
201+ } ) ;
202+
203+ //E
204+ await provider . detachVolumes ( [
205+ {
206+ IP : '192.168.1.100' ,
207+ devicePath : '/dev/sda' ,
208+ volumeType : VolumeType . Hardware ,
209+ nodeName : 'test-node' ,
210+ } ,
211+ {
212+ IP : '192.168.1.100' ,
213+ devicePath : 'test-lvm' ,
214+ volumeType : VolumeType . Virtual ,
215+ nodeName : 'test-node' ,
216+ } ,
217+ ] ) ;
218+ //V
219+ expect ( mockCoreV1Api . deletePersistentVolume ) . toHaveBeenCalledWith (
220+ 'test-volume' ,
221+ ) ;
222+ expect (
223+ mockVolumeClient . deleteMetalk8sV1alpha1Volume ,
224+ ) . toHaveBeenCalledWith ( 'test-volume' ) ;
225+ expect ( mockCoreV1Api . deletePersistentVolume ) . toHaveBeenCalledWith (
226+ 'test-lvm' ,
227+ ) ;
228+ expect (
229+ mockVolumeClient . deleteMetalk8sV1alpha1Volume ,
230+ ) . toHaveBeenCalledWith ( 'test-lvm' ) ;
231+ } ) ;
232+
233+ it ( 'should raise an error if pv deletion fails' , async ( ) => {
234+ //S
235+ ( mockCoreV1Api . deletePersistentVolume as jest . Mock ) . mockRejectedValue (
236+ new Error ( 'Failed to delete volume' ) ,
237+ ) ;
238+ //E+V
239+ await expect (
240+ provider . detachVolumes ( [
241+ {
242+ IP : '192.168.1.100' ,
243+ devicePath : '/dev/sda' ,
244+ volumeType : VolumeType . Hardware ,
245+ nodeName : 'test-node' ,
246+ } ,
247+ ] ) ,
248+ ) . rejects . toThrow (
249+ 'Failed to delete PV test-volume: Failed to delete volume' ,
250+ ) ;
251+ } ) ;
252+
253+ it ( 'should raise an error if metalk8s volume deletion fails' , async ( ) => {
254+ //S
255+ ( mockCoreV1Api . deletePersistentVolume as jest . Mock ) . mockResolvedValue ( {
256+ body : { } ,
257+ } ) ;
258+ (
259+ mockVolumeClient . deleteMetalk8sV1alpha1Volume as jest . Mock
260+ ) . mockRejectedValue ( new Error ( 'Failed to delete metalk8s volume' ) ) ;
261+ //E+V
262+ await expect (
263+ provider . detachVolumes ( [
264+ {
265+ IP : '192.168.1.100' ,
266+ devicePath : '/dev/sda' ,
267+ volumeType : VolumeType . Hardware ,
268+ nodeName : 'test-node' ,
269+ } ,
270+ ] ) ,
271+ ) . rejects . toThrow (
272+ 'Failed to delete Metalk8s volume test-volume: Failed to delete metalk8s volume' ,
273+ ) ;
159274 } ) ;
160275 } ) ;
161276} ) ;
0 commit comments