39
39
V1Work ,
40
40
)
41
41
42
- from lightning_app import _PROJECT_ROOT , LightningApp , LightningWork
42
+ from lightning_app import _PROJECT_ROOT , BuildConfig , LightningApp , LightningWork
43
43
from lightning_app .runners import backends , cloud , CloudRuntime
44
+ from lightning_app .runners .cloud import _validate_build_spec_and_compute
44
45
from lightning_app .storage import Drive , Mount
45
46
from lightning_app .testing .helpers import EmptyFlow
46
47
from lightning_app .utilities .cloud import _get_project
@@ -54,17 +55,17 @@ def run(self):
54
55
55
56
56
57
class WorkWithSingleDrive (LightningWork ):
57
- def __init__ (self ):
58
- super ().__init__ ()
58
+ def __init__ (self , * args , ** kwargs ):
59
+ super ().__init__ (* args , ** kwargs )
59
60
self .drive = None
60
61
61
62
def run (self ):
62
63
pass
63
64
64
65
65
66
class WorkWithTwoDrives (LightningWork ):
66
- def __init__ (self ):
67
- super ().__init__ ()
67
+ def __init__ (self , * args , ** kwargs ):
68
+ super ().__init__ (* args , ** kwargs )
68
69
self .lit_drive_1 = None
69
70
self .lit_drive_2 = None
70
71
@@ -403,13 +404,13 @@ def test_call_with_work_app(self, lightningapps, start_with_flow, monkeypatch, t
403
404
monkeypatch .setattr (cloud , "_prepare_lightning_wheels_and_requirements" , mock .MagicMock ())
404
405
app = mock .MagicMock ()
405
406
406
- work = MyWork (start_with_flow = start_with_flow )
407
- monkeypatch . setattr ( work , " _name" , "test-work" )
408
- monkeypatch . setattr ( work ._cloud_build_config , " build_commands" , lambda : ["echo 'start'" ])
409
- monkeypatch . setattr ( work ._cloud_build_config , " requirements" , ["torch==1.0.0" , "numpy==1.0.0" ])
410
- monkeypatch . setattr ( work ._cloud_build_config , " image" , "random_base_public_image" )
411
- monkeypatch . setattr ( work ._cloud_compute , " disk_size" , 0 )
412
- monkeypatch . setattr ( work , " _port" , 8080 )
407
+ work = MyWork (start_with_flow = start_with_flow , cloud_compute = CloudCompute ( "custom" ) )
408
+ work . _name = "test-work"
409
+ work ._cloud_build_config . build_commands = lambda : ["echo 'start'" ]
410
+ work ._cloud_build_config . requirements = ["torch==1.0.0" , "numpy==1.0.0" ]
411
+ work ._cloud_build_config . image = "random_base_public_image"
412
+ work ._cloud_compute . disk_size = 0
413
+ work . _port = 8080
413
414
414
415
app .works = [work ]
415
416
cloud_runtime = cloud .CloudRuntime (app = app , entrypoint_file = (source_code_root_dir / "entrypoint.py" ))
@@ -450,7 +451,7 @@ def test_call_with_work_app(self, lightningapps, start_with_flow, monkeypatch, t
450
451
),
451
452
drives = [],
452
453
user_requested_compute_config = V1UserRequestedComputeConfig (
453
- name = "default " ,
454
+ name = "custom " ,
454
455
count = 1 ,
455
456
disk_size = 0 ,
456
457
shm_size = 0 ,
@@ -585,7 +586,7 @@ def test_call_with_work_app_and_attached_drives(self, lightningapps, monkeypatch
585
586
# should be the results of the deepcopy operation (an instance of the original class)
586
587
mocked_drive .__deepcopy__ .return_value = copy (mocked_drive )
587
588
588
- work = WorkWithSingleDrive ()
589
+ work = WorkWithSingleDrive (cloud_compute = CloudCompute ( "custom" ) )
589
590
monkeypatch .setattr (work , "drive" , mocked_drive )
590
591
monkeypatch .setattr (work , "_state" , {"_port" , "drive" })
591
592
monkeypatch .setattr (work , "_name" , "test-work" )
@@ -646,7 +647,7 @@ def test_call_with_work_app_and_attached_drives(self, lightningapps, monkeypatch
646
647
),
647
648
],
648
649
user_requested_compute_config = V1UserRequestedComputeConfig (
649
- name = "default " ,
650
+ name = "custom " ,
650
651
count = 1 ,
651
652
disk_size = 0 ,
652
653
shm_size = 0 ,
@@ -709,14 +710,14 @@ def test_call_with_work_app_and_app_comment_command_execution_set(self, lightnin
709
710
monkeypatch .setattr (cloud , "_prepare_lightning_wheels_and_requirements" , mock .MagicMock ())
710
711
app = mock .MagicMock ()
711
712
712
- work = MyWork ()
713
- monkeypatch . setattr ( work , " _state" , {"_port" })
714
- monkeypatch . setattr ( work , " _name" , "test-work" )
715
- monkeypatch . setattr ( work ._cloud_build_config , " build_commands" , lambda : ["echo 'start'" ])
716
- monkeypatch . setattr ( work ._cloud_build_config , " requirements" , ["torch==1.0.0" , "numpy==1.0.0" ])
717
- monkeypatch . setattr ( work ._cloud_build_config , " image" , "random_base_public_image" )
718
- monkeypatch . setattr ( work ._cloud_compute , " disk_size" , 0 )
719
- monkeypatch . setattr ( work , " _port" , 8080 )
713
+ work = MyWork (cloud_compute = CloudCompute ( "custom" ) )
714
+ work . _state = {"_port" }
715
+ work . _name = "test-work"
716
+ work ._cloud_build_config . build_commands = lambda : ["echo 'start'" ]
717
+ work ._cloud_build_config . requirements = ["torch==1.0.0" , "numpy==1.0.0" ]
718
+ work ._cloud_build_config . image = "random_base_public_image"
719
+ work ._cloud_compute . disk_size = 0
720
+ work . _port = 8080
720
721
721
722
app .works = [work ]
722
723
cloud_runtime = cloud .CloudRuntime (app = app , entrypoint_file = (source_code_root_dir / "entrypoint.py" ))
@@ -755,7 +756,7 @@ def test_call_with_work_app_and_app_comment_command_execution_set(self, lightnin
755
756
),
756
757
drives = [],
757
758
user_requested_compute_config = V1UserRequestedComputeConfig (
758
- name = "default " , count = 1 , disk_size = 0 , shm_size = 0 , preemptible = mock .ANY
759
+ name = "custom " , count = 1 , disk_size = 0 , shm_size = 0 , preemptible = mock .ANY
759
760
),
760
761
network_config = [V1NetworkConfig (name = mock .ANY , host = None , port = 8080 )],
761
762
cluster_id = mock .ANY ,
@@ -835,16 +836,16 @@ def test_call_with_work_app_and_multiple_attached_drives(self, lightningapps, mo
835
836
# should be the results of the deepcopy operation (an instance of the original class)
836
837
mocked_lit_drive .__deepcopy__ .return_value = copy (mocked_lit_drive )
837
838
838
- work = WorkWithTwoDrives ()
839
- monkeypatch . setattr ( work , " lit_drive_1" , mocked_lit_drive )
840
- monkeypatch . setattr ( work , " lit_drive_2" , mocked_lit_drive )
841
- monkeypatch . setattr ( work , " _state" , {"_port" , "_name" , "lit_drive_1" , "lit_drive_2" })
842
- monkeypatch . setattr ( work , " _name" , "test-work" )
843
- monkeypatch . setattr ( work ._cloud_build_config , " build_commands" , lambda : ["echo 'start'" ])
844
- monkeypatch . setattr ( work ._cloud_build_config , " requirements" , ["torch==1.0.0" , "numpy==1.0.0" ])
845
- monkeypatch . setattr ( work ._cloud_build_config , " image" , "random_base_public_image" )
846
- monkeypatch . setattr ( work ._cloud_compute , " disk_size" , 0 )
847
- monkeypatch . setattr ( work , " _port" , 8080 )
839
+ work = WorkWithTwoDrives (cloud_compute = CloudCompute ( "custom" ) )
840
+ work . lit_drive_1 = mocked_lit_drive
841
+ work . lit_drive_2 = mocked_lit_drive
842
+ work . _state = {"_port" , "_name" , "lit_drive_1" , "lit_drive_2" }
843
+ work . _name = "test-work"
844
+ work ._cloud_build_config . build_commands = lambda : ["echo 'start'" ]
845
+ work ._cloud_build_config . requirements = ["torch==1.0.0" , "numpy==1.0.0" ]
846
+ work ._cloud_build_config . image = "random_base_public_image"
847
+ work ._cloud_compute . disk_size = 0
848
+ work . _port = 8080
848
849
849
850
app .works = [work ]
850
851
cloud_runtime = cloud .CloudRuntime (app = app , entrypoint_file = (source_code_root_dir / "entrypoint.py" ))
@@ -914,7 +915,7 @@ def test_call_with_work_app_and_multiple_attached_drives(self, lightningapps, mo
914
915
),
915
916
drives = [lit_drive_2_spec , lit_drive_1_spec ],
916
917
user_requested_compute_config = V1UserRequestedComputeConfig (
917
- name = "default " ,
918
+ name = "custom " ,
918
919
count = 1 ,
919
920
disk_size = 0 ,
920
921
shm_size = 0 ,
@@ -953,7 +954,7 @@ def test_call_with_work_app_and_multiple_attached_drives(self, lightningapps, mo
953
954
),
954
955
drives = [lit_drive_1_spec , lit_drive_2_spec ],
955
956
user_requested_compute_config = V1UserRequestedComputeConfig (
956
- name = "default " ,
957
+ name = "custom " ,
957
958
count = 1 ,
958
959
disk_size = 0 ,
959
960
shm_size = 0 ,
@@ -1043,7 +1044,7 @@ def test_call_with_work_app_and_attached_mount_and_drive(self, lightningapps, mo
1043
1044
setattr (mocked_mount , "mount_path" , "/content/foo" )
1044
1045
setattr (mocked_mount , "protocol" , "s3://" )
1045
1046
1046
- work = WorkWithSingleDrive ()
1047
+ work = WorkWithSingleDrive (cloud_compute = CloudCompute ( "custom" ) )
1047
1048
monkeypatch .setattr (work , "drive" , mocked_drive )
1048
1049
monkeypatch .setattr (work , "_state" , {"_port" , "drive" })
1049
1050
monkeypatch .setattr (work , "_name" , "test-work" )
@@ -1119,7 +1120,7 @@ def test_call_with_work_app_and_attached_mount_and_drive(self, lightningapps, mo
1119
1120
),
1120
1121
],
1121
1122
user_requested_compute_config = V1UserRequestedComputeConfig (
1122
- name = "default " ,
1123
+ name = "custom " ,
1123
1124
count = 1 ,
1124
1125
disk_size = 0 ,
1125
1126
shm_size = 0 ,
@@ -1227,3 +1228,23 @@ def test_load_app_from_file_module_error():
1227
1228
empty_app = CloudRuntime .load_app_from_file (os .path .join (_PROJECT_ROOT , "examples" , "app_v0" , "app.py" ))
1228
1229
assert isinstance (empty_app , LightningApp )
1229
1230
assert isinstance (empty_app .root , EmptyFlow )
1231
+
1232
+
1233
+ def test_incompatible_cloud_compute_and_build_config ():
1234
+ """Test that an exception is raised when a build config has a custom image defined, but the cloud compute is
1235
+ the default.
1236
+
1237
+ This combination is not supported by the platform.
1238
+ """
1239
+
1240
+ class Work (LightningWork ):
1241
+ def __init__ (self ):
1242
+ super ().__init__ ()
1243
+ self .cloud_compute = CloudCompute (name = "default" )
1244
+ self .cloud_build_config = BuildConfig (image = "custom" )
1245
+
1246
+ def run (self ):
1247
+ pass
1248
+
1249
+ with pytest .raises (ValueError , match = "You requested a custom base image for the Work with name" ):
1250
+ _validate_build_spec_and_compute (Work ())
0 commit comments