@@ -2,8 +2,10 @@ 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' ;
7+
8+ const HARDWARE_DEVICEPATH = '/dev/sda' ;
79
810jest . mock ( '../k8s/api' , ( ) => ( {
911 updateApiServerConfig : jest . fn ( ) ,
@@ -18,13 +20,18 @@ describe('Metalk8sLocalVolumeProvider', () => {
1820 listClusterCustomObject : jest . fn ( ) ,
1921 } as unknown as CustomObjectsApi ;
2022
21- const mockVolumeClient = new Metalk8sV1alpha1VolumeClient (
22- mockCustomObjectsApi ,
23- ) ;
23+ const mockVolumeClient = {
24+ deleteMetalk8sV1alpha1Volume : jest . fn ( ) . mockResolvedValue ( { body : { } } ) ,
25+ getMetalk8sV1alpha1VolumeList : jest . fn ( ) ,
26+ getMetalk8sV1alpha1Volume : jest . fn ( ) ,
27+ createMetalk8sV1alpha1Volume : jest . fn ( ) ,
28+ patchMetalk8sV1alpha1Volume : jest . fn ( ) ,
29+ } as unknown as Metalk8sV1alpha1VolumeClient ;
2430
2531 const mockCoreV1Api = {
2632 listNode : jest . fn ( ) ,
2733 listPersistentVolume : jest . fn ( ) ,
34+ deletePersistentVolume : jest . fn ( ) ,
2835 } as unknown as CoreV1Api ;
2936
3037 beforeEach ( ( ) => {
@@ -68,7 +75,7 @@ describe('Metalk8sLocalVolumeProvider', () => {
6875 } ) ;
6976
7077 (
71- mockCustomObjectsApi . listClusterCustomObject as jest . Mock
78+ mockVolumeClient . getMetalk8sV1alpha1VolumeList as jest . Mock
7279 ) . mockResolvedValue ( {
7380 body : {
7481 items : [
@@ -150,12 +157,103 @@ describe('Metalk8sLocalVolumeProvider', () => {
150157 } ) ;
151158
152159 (
153- mockCustomObjectsApi . listClusterCustomObject as jest . Mock
160+ mockVolumeClient . getMetalk8sV1alpha1VolumeList as jest . Mock
154161 ) . mockRejectedValue ( new Error ( 'Failed to fetch volumes' ) ) ;
155162
156163 await expect (
157164 provider . listLocalPersistentVolumes ( 'test-node' ) ,
158- ) . rejects . toThrow ( 'Failed to fetch metalk8s volumes' ) ;
165+ ) . rejects . toThrow (
166+ 'Failed to fetch local persistent volumes: Failed to fetch volumes' ,
167+ ) ;
168+ } ) ;
169+ } ) ;
170+
171+ describe ( 'detachVolumes' , ( ) => {
172+ it ( 'should detach volumes' , async ( ) => {
173+ //S
174+ (
175+ mockVolumeClient . deleteMetalk8sV1alpha1Volume as jest . Mock
176+ ) . mockResolvedValue ( {
177+ body : { } ,
178+ } ) ;
179+ ( mockCoreV1Api . deletePersistentVolume as jest . Mock ) . mockResolvedValue ( {
180+ body : { } ,
181+ } ) ;
182+ (
183+ mockVolumeClient . getMetalk8sV1alpha1VolumeList as jest . Mock
184+ ) . mockResolvedValue ( {
185+ body : {
186+ items : [
187+ {
188+ metadata : { name : 'test-volume' } ,
189+ spec : {
190+ nodeName : 'test-node' ,
191+ rawBlockDevice : { devicePath : HARDWARE_DEVICEPATH } ,
192+ } ,
193+ } ,
194+ ] ,
195+ } ,
196+ } ) ;
197+
198+ //E
199+ await provider . detachVolumes ( [
200+ {
201+ IP : '192.168.1.100' ,
202+ devicePath : HARDWARE_DEVICEPATH ,
203+ volumeType : VolumeType . Hardware ,
204+ nodeName : 'test-node' ,
205+ } ,
206+ ] ) ;
207+ //V
208+ expect ( mockCoreV1Api . deletePersistentVolume ) . toHaveBeenCalledWith (
209+ 'test-volume' ,
210+ ) ;
211+ expect (
212+ mockVolumeClient . deleteMetalk8sV1alpha1Volume ,
213+ ) . toHaveBeenCalledWith ( 'test-volume' ) ;
214+ } ) ;
215+
216+ it ( 'should raise an error if pv deletion fails' , async ( ) => {
217+ //S
218+ ( mockCoreV1Api . deletePersistentVolume as jest . Mock ) . mockRejectedValue (
219+ new Error ( 'Failed to delete volume' ) ,
220+ ) ;
221+ //E+V
222+ await expect (
223+ provider . detachVolumes ( [
224+ {
225+ IP : '192.168.1.100' ,
226+ devicePath : HARDWARE_DEVICEPATH ,
227+ volumeType : VolumeType . Hardware ,
228+ nodeName : 'test-node' ,
229+ } ,
230+ ] ) ,
231+ ) . rejects . toThrow (
232+ 'Failed to delete PV test-volume: Failed to delete volume' ,
233+ ) ;
234+ } ) ;
235+
236+ it ( 'should raise an error if metalk8s volume deletion fails' , async ( ) => {
237+ //S
238+ ( mockCoreV1Api . deletePersistentVolume as jest . Mock ) . mockResolvedValue ( {
239+ body : { } ,
240+ } ) ;
241+ (
242+ mockVolumeClient . deleteMetalk8sV1alpha1Volume as jest . Mock
243+ ) . mockRejectedValue ( new Error ( 'Failed to delete metalk8s volume' ) ) ;
244+ //E+V
245+ await expect (
246+ provider . detachVolumes ( [
247+ {
248+ IP : '192.168.1.100' ,
249+ devicePath : HARDWARE_DEVICEPATH ,
250+ volumeType : VolumeType . Hardware ,
251+ nodeName : 'test-node' ,
252+ } ,
253+ ] ) ,
254+ ) . rejects . toThrow (
255+ 'Failed to delete Metalk8s volume test-volume: Failed to delete metalk8s volume' ,
256+ ) ;
159257 } ) ;
160258 } ) ;
161259} ) ;
0 commit comments