77from dstack ._internal .core .models .backends .base import BackendType
88from dstack ._internal .core .models .volumes import VolumeStatus
99from dstack ._internal .server .background .tasks .process_idle_volumes import (
10- _get_volume_idle_duration ,
11- _should_delete_idle_volume ,
10+ _get_idle_time ,
11+ _should_delete_volume ,
1212 process_idle_volumes ,
1313)
1414from dstack ._internal .server .models import VolumeAttachmentModel
2525@pytest .mark .asyncio
2626@pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
2727class TestProcessIdleVolumes :
28- async def test_no_idle_duration_configured (self , test_db , session : AsyncSession ):
28+ async def test_no_idle_duration (self , test_db , session : AsyncSession ):
2929 project = await create_project (session = session )
3030 user = await create_user (session = session )
3131
@@ -39,106 +39,82 @@ async def test_no_idle_duration_configured(self, test_db, session: AsyncSession)
3939 volume_provisioning_data = get_volume_provisioning_data (),
4040 )
4141
42- should_delete = _should_delete_idle_volume (volume )
43- assert not should_delete
42+ assert not _should_delete_volume (volume )
4443
4544 async def test_idle_duration_disabled (self , test_db , session : AsyncSession ):
4645 project = await create_project (session = session )
4746 user = await create_user (session = session )
4847
49- volume_config = get_volume_configuration (name = "test-volume" )
50- volume_config .idle_duration = - 1
48+ config = get_volume_configuration (name = "test-volume" )
49+ config .idle_duration = - 1
5150
5251 volume = await create_volume (
5352 session = session ,
5453 project = project ,
5554 user = user ,
5655 status = VolumeStatus .ACTIVE ,
5756 backend = BackendType .AWS ,
58- configuration = volume_config ,
57+ configuration = config ,
5958 volume_provisioning_data = get_volume_provisioning_data (),
6059 )
6160
62- should_delete = _should_delete_idle_volume (volume )
63- assert not should_delete
61+ assert not _should_delete_volume (volume )
6462
65- async def test_volume_still_attached (self , test_db , session : AsyncSession ):
63+ async def test_volume_attached (self , test_db , session : AsyncSession ):
6664 project = await create_project (session = session )
6765 user = await create_user (session = session )
6866
69- volume_config = get_volume_configuration (name = "test-volume" )
70- volume_config .idle_duration = "1h"
67+ config = get_volume_configuration (name = "test-volume" )
68+ config .idle_duration = "1h"
7169
7270 volume = await create_volume (
7371 session = session ,
7472 project = project ,
7573 user = user ,
7674 status = VolumeStatus .ACTIVE ,
7775 backend = BackendType .AWS ,
78- configuration = volume_config ,
76+ configuration = config ,
7977 volume_provisioning_data = get_volume_provisioning_data (),
8078 )
8179
8280 instance = await create_instance (session = session , project = project )
83- attachment = VolumeAttachmentModel (
84- volume_id = volume .id ,
85- instance_id = instance .id ,
81+ volume .attachments .append (
82+ VolumeAttachmentModel (volume_id = volume .id , instance_id = instance .id )
8683 )
87- volume .attachments .append (attachment )
8884 await session .commit ()
8985
90- should_delete = _should_delete_idle_volume (volume )
91- assert not should_delete
86+ assert not _should_delete_volume (volume )
9287
93- async def test_idle_duration_not_exceeded (self , test_db , session : AsyncSession ):
88+ async def test_idle_duration_threshold (self , test_db , session : AsyncSession ):
9489 project = await create_project (session = session )
9590 user = await create_user (session = session )
9691
97- volume_config = get_volume_configuration (name = "test-volume" )
98- volume_config .idle_duration = "1h"
92+ config = get_volume_configuration (name = "test-volume" )
93+ config .idle_duration = "1h"
9994
10095 volume = await create_volume (
10196 session = session ,
10297 project = project ,
10398 user = user ,
10499 status = VolumeStatus .ACTIVE ,
105100 backend = BackendType .AWS ,
106- configuration = volume_config ,
101+ configuration = config ,
107102 volume_provisioning_data = get_volume_provisioning_data (),
108103 )
109104
105+ # Not exceeded - 30 minutes ago
110106 volume .last_job_processed_at = (
111107 datetime .datetime .now (datetime .timezone .utc ) - datetime .timedelta (minutes = 30 )
112108 ).replace (tzinfo = None )
109+ assert not _should_delete_volume (volume )
113110
114- should_delete = _should_delete_idle_volume (volume )
115- assert not should_delete
116-
117- async def test_idle_duration_exceeded (self , test_db , session : AsyncSession ):
118- project = await create_project (session = session )
119- user = await create_user (session = session )
120-
121- volume_config = get_volume_configuration (name = "test-volume" )
122- volume_config .idle_duration = "1h"
123-
124- volume = await create_volume (
125- session = session ,
126- project = project ,
127- user = user ,
128- status = VolumeStatus .ACTIVE ,
129- backend = BackendType .AWS ,
130- configuration = volume_config ,
131- volume_provisioning_data = get_volume_provisioning_data (),
132- )
133-
111+ # Exceeded - 2 hours ago
134112 volume .last_job_processed_at = (
135113 datetime .datetime .now (datetime .timezone .utc ) - datetime .timedelta (hours = 2 )
136114 ).replace (tzinfo = None )
115+ assert _should_delete_volume (volume )
137116
138- should_delete = _should_delete_idle_volume (volume )
139- assert should_delete
140-
141- async def test_volume_never_used_by_job (self , test_db , session : AsyncSession ):
117+ async def test_never_used_volume (self , test_db , session : AsyncSession ):
142118 project = await create_project (session = session )
143119 user = await create_user (session = session )
144120
@@ -154,38 +130,34 @@ async def test_volume_never_used_by_job(self, test_db, session: AsyncSession):
154130 )
155131
156132 volume .last_job_processed_at = None
133+ idle_time = _get_idle_time (volume )
134+ assert idle_time .total_seconds () >= 7000
157135
158- idle_duration = _get_volume_idle_duration (volume )
159- assert idle_duration .total_seconds () >= 7000
160-
161- async def test_process_idle_volumes_integration (self , test_db , session : AsyncSession ):
136+ async def test_integration (self , test_db , session : AsyncSession ):
162137 project = await create_project (session = session )
163138 user = await create_user (session = session )
164139
165- volume_config = get_volume_configuration (name = "test-volume" )
166- volume_config .idle_duration = "1h"
140+ config = get_volume_configuration (name = "test-volume" )
141+ config .idle_duration = "1h"
167142
168143 volume = await create_volume (
169144 session = session ,
170145 project = project ,
171146 user = user ,
172147 status = VolumeStatus .ACTIVE ,
173148 backend = BackendType .AWS ,
174- configuration = volume_config ,
149+ configuration = config ,
175150 volume_provisioning_data = get_volume_provisioning_data (),
176151 )
177152
178153 volume .last_job_processed_at = (
179154 datetime .datetime .now (datetime .timezone .utc ) - datetime .timedelta (hours = 2 )
180155 ).replace (tzinfo = None )
181-
182156 await session .commit ()
183157
184158 with patch (
185159 "dstack._internal.server.background.tasks.process_idle_volumes.delete_volumes"
186- ) as mock_delete :
160+ ) as mock :
187161 await process_idle_volumes ()
188-
189- mock_delete .assert_called_once ()
190- call_args = mock_delete .call_args
191- assert call_args [0 ][2 ] == ["test-volume" ]
162+ mock .assert_called_once ()
163+ assert mock .call_args [0 ][2 ] == ["test-volume" ]
0 commit comments