@@ -528,13 +528,13 @@ class TestExperimentsCreateMultiNode(object):
528528 "--datasetName" , "some dataset name" ,
529529 "--datasetAwsAccessKeyId" , "none" ,
530530 "--datasetAwsSecretAccessKey" , "none" ,
531- "--datasetVersionId" , "none " ,
531+ "--datasetVersionId" , "version1 " ,
532532 "--datasetEtag" , "some etag" ,
533533 "--datasetUri" , "s3://some.other.dataset/uri" ,
534534 "--datasetName" , "none" ,
535535 "--datasetAwsAccessKeyId" , "some_other_key_id" ,
536536 "--datasetAwsSecretAccessKey" , "some_other_secret" ,
537- "--datasetVersionId" , "none " ,
537+ "--datasetVersionId" , "version2 " ,
538538 "--datasetEtag" , "some other etag" ,
539539 "--datasetVolumeKind" , "dynamic" ,
540540 "--datasetVolumeSize" , "10Gi" ,
@@ -594,6 +594,7 @@ class TestExperimentsCreateMultiNode(object):
594594 "uri" : "s3://some.dataset/uri" ,
595595 "name" : "some dataset name" ,
596596 "etag" : "some etag" ,
597+ "versionId" : "version1" ,
597598 "volumeOptions" : {
598599 "kind" : "dynamic" ,
599600 "size" : "10Gi" ,
@@ -604,6 +605,7 @@ class TestExperimentsCreateMultiNode(object):
604605 "awsAccessKeyId" : "some_other_key_id" ,
605606 "awsSecretAccessKey" : "some_other_secret" ,
606607 "etag" : "some other etag" ,
608+ "versionId" : "version2" ,
607609 },
608610 ]
609611 }
@@ -668,31 +670,6 @@ def test_should_send_proper_data_and_print_message_when_create_experiment_was_ru
668670 def test_should_use_tensorboard_handler_with_true_value_when_tensorboard_option_was_used_without_value (
669671 self , post_patched , tensorboard_handler_class ):
670672 post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
671- command = self .FULL_OPTIONS_COMMAND [:] + ["--tensorboard=some_tensorboard_id" ]
672- tensorboard_handler = mock .MagicMock ()
673- tensorboard_handler_class .return_value = tensorboard_handler
674-
675- runner = CliRunner ()
676- result = runner .invoke (cli .cli , command )
677-
678- assert self .EXPECTED_STDOUT in result .output , result .exc_info
679- post_patched .assert_called_once_with (self .URL_V2 ,
680- headers = EXPECTED_HEADERS_WITH_CHANGED_API_KEY ,
681- json = self .FULL_OPTIONS_REQUEST ,
682- params = None ,
683- files = None ,
684- data = None )
685- assert result .exit_code == 0
686- assert EXPECTED_HEADERS_WITH_CHANGED_API_KEY ["X-API-Key" ] == "some_key"
687-
688- tensorboard_handler_class .assert_called_once_with ("some_key" )
689- tensorboard_handler .maybe_add_to_tensorboard .assert_called_once_with ("some_tensorboard_id" , "sadkfhlskdjh" )
690-
691- @mock .patch ("gradient.commands.experiments.TensorboardHandler" )
692- @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
693- def test_should_use_tensorboard_handler_with_tb_id_when_tensorboard_option_was_used_with_tb_id (
694- self , post_patched , tensorboard_handler_class ):
695- post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
696673 command = self .FULL_OPTIONS_COMMAND [:] + ["--tensorboard" ]
697674 tensorboard_handler = mock .MagicMock ()
698675 tensorboard_handler_class .return_value = tensorboard_handler
@@ -715,219 +692,7 @@ def test_should_use_tensorboard_handler_with_tb_id_when_tensorboard_option_was_u
715692
716693 @mock .patch ("gradient.commands.experiments.TensorboardHandler" )
717694 @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
718- def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_full_options (
719- self , post_patched , tensorboard_handler_class ):
720- post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
721- command = self .FULL_OPTIONS_COMMAND [:] + ["--tensorboard" ]
722- tensorboard_handler = mock .MagicMock ()
723- tensorboard_handler_class .return_value = tensorboard_handler
724-
725- runner = CliRunner ()
726- result = runner .invoke (cli .cli , command )
727-
728- assert self .EXPECTED_STDOUT in result .output , result .exc_info
729- post_patched .assert_called_once_with (self .URL_V2 ,
730- headers = EXPECTED_HEADERS_WITH_CHANGED_API_KEY ,
731- json = self .FULL_OPTIONS_REQUEST ,
732- params = None ,
733- files = None ,
734- data = None )
735- assert result .exit_code == 0
736- assert EXPECTED_HEADERS_WITH_CHANGED_API_KEY ["X-API-Key" ] == "some_key"
737-
738- tensorboard_handler_class .assert_called_once_with ("some_key" )
739- tensorboard_handler .maybe_add_to_tensorboard .assert_called_once_with (True , "sadkfhlskdjh" )
740-
741-
742- class TestExperimentsCreateMultiNode (object ):
743- URL = "https://services.paperspace.io/experiments/v1/experiments/"
744- URL_V2 = "https://services.paperspace.io/experiments/v2/experiments/"
745- BASIC_OPTIONS_COMMAND = [
746- "experiments" , "create" , "multinode" ,
747- "--projectId" , "prq70zy79" ,
748- "--experimentType" , "GRPC" ,
749- "--workerContainer" , "wcon" ,
750- "--workerMachineType" , "mty" ,
751- "--workerCommand" , "wcom" ,
752- "--workerCount" , 2 ,
753- "--parameterServerContainer" , "pscon" ,
754- "--parameterServerMachineType" , "psmtype" ,
755- "--parameterServerCommand" , "ls" ,
756- "--parameterServerCount" , 2 ,
757- "--workerContainerUser" , "usr" ,
758- "--workspace" , "https://github.com/Paperspace/gradient-cli.git" ,
759- ]
760- FULL_OPTIONS_COMMAND = [
761- "experiments" , "create" , "multinode" ,
762- "--name" , "multinode_mpi" ,
763- "--ports" , 3456 ,
764- "--workspace" , "s3://some-workspace" ,
765- "--workspaceRef" , "some_branch_name" ,
766- "--workspaceUsername" , "username" ,
767- "--workspacePassword" , "password" ,
768- "--workingDirectory" , "/dir" ,
769- "--artifactDirectory" , "/artdir" ,
770- "--clusterId" , '2a' ,
771- "--experimentEnv" , '{"key":"val"}' ,
772- "--projectId" , "prq70zy79" ,
773- "--experimentType" , "MPI" ,
774- "--workerContainer" , "wcon" ,
775- "--workerMachineType" , "mty" ,
776- "--workerCommand" , "wcom" ,
777- "--workerCount" , 2 ,
778- "--masterContainer" , "pscon" ,
779- "--masterMachineType" , "psmtype" ,
780- "--masterCommand" , "ls" ,
781- "--masterCount" , 2 ,
782- "--workerContainerUser" , "usr" ,
783- "--workerRegistryUsername" , "rusr" ,
784- "--workerRegistryPassword" , "rpass" ,
785- "--workerRegistryUrl" , "rurl" ,
786- "--masterContainerUser" , "pscuser" ,
787- "--masterRegistryUsername" , "psrcus" ,
788- "--masterRegistryPassword" , "psrpass" ,
789- "--masterRegistryUrl" , "psrurl" ,
790- "--apiKey" , "some_key" ,
791- "--modelPath" , "some-model-path" ,
792- "--modelType" , "some-model-type" ,
793- "--ignoreFiles" , "file1,file2" ,
794- "--isPreemptible" ,
795- "--datasetUri" , "s3://some.dataset/uri" ,
796- "--datasetName" , "some dataset name" ,
797- "--datasetAwsAccessKeyId" , "none" ,
798- "--datasetAwsSecretAccessKey" , "none" ,
799- "--datasetVersionId" , "none" ,
800- "--datasetEtag" , "some etag" ,
801- "--datasetUri" , "s3://some.other.dataset/uri" ,
802- "--datasetName" , "none" ,
803- "--datasetAwsAccessKeyId" , "some_other_key_id" ,
804- "--datasetAwsSecretAccessKey" , "some_other_secret" ,
805- "--datasetVersionId" , "none" ,
806- "--datasetEtag" , "some other etag" ,
807- ]
808- FULL_OPTIONS_COMMAND_WITH_OPTIONS_FILE = [
809- "experiments" , "create" , "multinode" ,
810- "--optionsFile" , # path added in test,
811- ]
812- BASIC_OPTIONS_REQUEST = {
813- u"projectHandle" : u"prq70zy79" ,
814- u"experimentTypeId" : 2 ,
815- u"workerContainer" : u"wcon" ,
816- u"workerMachineType" : u"mty" ,
817- u"workerCommand" : u"d2NvbQ==" ,
818- u"workerCount" : 2 ,
819- u"parameterServerContainer" : u"pscon" ,
820- u"parameterServerMachineType" : u"psmtype" ,
821- u"parameterServerCommand" : u"bHM=" ,
822- u"parameterServerCount" : 2 ,
823- u"workerContainerUser" : u"usr" ,
824- u"workspaceUrl" : u"https://github.com/Paperspace/gradient-cli.git" ,
825- }
826- FULL_OPTIONS_REQUEST = {
827- "name" : u"multinode_mpi" ,
828- "ports" : "3456" ,
829- "workspaceUrl" : u"s3://some-workspace" ,
830- "workspaceRef" : "some_branch_name" ,
831- "workspaceUsername" : u"username" ,
832- "workspacePassword" : u"password" ,
833- "workingDirectory" : u"/dir" ,
834- "artifactDirectory" : u"/artdir" ,
835- "clusterId" : '2a' ,
836- "experimentEnv" : {"key" : "val" },
837- "projectHandle" : "prq70zy79" ,
838- "experimentTypeId" : 3 ,
839- "workerContainer" : u"wcon" ,
840- "workerMachineType" : u"mty" ,
841- "workerCommand" : u"d2NvbQ==" ,
842- "workerCount" : 2 ,
843- "masterContainer" : u"pscon" ,
844- "masterMachineType" : u"psmtype" ,
845- "masterCommand" : u"bHM=" ,
846- "masterCount" : 2 ,
847- "workerContainerUser" : u"usr" ,
848- "workerRegistryUsername" : u"rusr" ,
849- "workerRegistryPassword" : u"rpass" ,
850- "workerRegistryUrl" : u"rurl" ,
851- "masterContainerUser" : u"pscuser" ,
852- "masterRegistryUsername" : u"psrcus" ,
853- "masterRegistryPassword" : u"psrpass" ,
854- "masterRegistryUrl" : u"psrurl" ,
855- "isPreemptible" : True ,
856- "modelPath" : "some-model-path" ,
857- "modelType" : "some-model-type" ,
858- "datasets" : [
859- {
860- "uri" : "s3://some.dataset/uri" ,
861- "name" : "some dataset name" ,
862- "etag" : "some etag" ,
863- },
864- {
865- "uri" : "s3://some.other.dataset/uri" ,
866- "awsAccessKeyId" : "some_other_key_id" ,
867- "awsSecretAccessKey" : "some_other_secret" ,
868- "etag" : "some other etag" ,
869- },
870- ]
871- }
872- RESPONSE_JSON_200 = {"handle" : "sadkfhlskdjh" , "message" : "success" }
873- RESPONSE_CONTENT_200 = b'{"handle":"sadkfhlskdjh","message":"success"}\n '
874- EXPECTED_STDOUT = "New experiment created with ID: sadkfhlskdjh\n "
875-
876- @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
877- def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_basic_options (self ,
878- post_patched ):
879- post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
880-
881- runner = CliRunner ()
882- result = runner .invoke (cli .cli , self .BASIC_OPTIONS_COMMAND )
883-
884- assert self .EXPECTED_STDOUT in result .output , result .exc_info
885- post_patched .assert_called_once_with (self .URL ,
886- headers = EXPECTED_HEADERS ,
887- json = self .BASIC_OPTIONS_REQUEST ,
888- params = None ,
889- files = None ,
890- data = None )
891- assert result .exit_code == 0
892-
893- @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
894- def test_should_read_options_from_config_file (
895- self , post_patched , create_multi_node_experiment_config_path ):
896- post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
897- command = self .FULL_OPTIONS_COMMAND_WITH_OPTIONS_FILE [:] + [create_multi_node_experiment_config_path ]
898-
899- runner = CliRunner ()
900- result = runner .invoke (cli .cli , command )
901-
902- assert self .EXPECTED_STDOUT in result .output , result .exc_info
903- post_patched .assert_called_once_with (self .URL_V2 ,
904- headers = EXPECTED_HEADERS_WITH_CHANGED_API_KEY ,
905- json = self .FULL_OPTIONS_REQUEST ,
906- params = None ,
907- files = None ,
908- data = None )
909- assert result .exit_code == 0
910-
911- @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
912- def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_full_options (self ,
913- post_patched ):
914- post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
915-
916- runner = CliRunner ()
917- result = runner .invoke (cli .cli , self .FULL_OPTIONS_COMMAND )
918-
919- post_patched .assert_called_once_with (self .URL_V2 ,
920- headers = EXPECTED_HEADERS_WITH_CHANGED_API_KEY ,
921- json = self .FULL_OPTIONS_REQUEST ,
922- params = None ,
923- files = None ,
924- data = None )
925- assert self .EXPECTED_STDOUT in result .output
926- assert result .exit_code == 0
927-
928- @mock .patch ("gradient.commands.experiments.TensorboardHandler" )
929- @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
930- def test_should_use_tensorboard_handler_with_true_value_when_tensorboard_option_was_used_without_value (
695+ def test_should_use_tensorboard_handler_with_tb_id_when_tensorboard_option_was_used_with_tb_id (
931696 self , post_patched , tensorboard_handler_class ):
932697 post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
933698 command = self .FULL_OPTIONS_COMMAND [:] + ["--tensorboard=some_tensorboard_id" ]
@@ -950,9 +715,10 @@ def test_should_use_tensorboard_handler_with_true_value_when_tensorboard_option_
950715 tensorboard_handler_class .assert_called_once_with ("some_key" )
951716 tensorboard_handler .maybe_add_to_tensorboard .assert_called_once_with ("some_tensorboard_id" , "sadkfhlskdjh" )
952717
718+
953719 @mock .patch ("gradient.commands.experiments.TensorboardHandler" )
954720 @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
955- def test_should_use_tensorboard_handler_with_tb_id_when_tensorboard_option_was_used_with_tb_id (
721+ def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_full_options (
956722 self , post_patched , tensorboard_handler_class ):
957723 post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
958724 command = self .FULL_OPTIONS_COMMAND [:] + ["--tensorboard" ]
@@ -975,14 +741,11 @@ def test_should_use_tensorboard_handler_with_tb_id_when_tensorboard_option_was_u
975741 tensorboard_handler_class .assert_called_once_with ("some_key" )
976742 tensorboard_handler .maybe_add_to_tensorboard .assert_called_once_with (True , "sadkfhlskdjh" )
977743
978- @mock .patch ("gradient.commands.experiments.TensorboardHandler" )
979744 @mock .patch ("gradient.api_sdk.clients.http_client.requests.post" )
980- def test_should_send_proper_data_and_print_message_when_create_experiment_was_run_with_full_options (
981- self , post_patched , tensorboard_handler_class ):
745+ def test_should_read_options_from_config_file_with_dataset_defined_as_list_of_objects (
746+ self , post_patched , create_multi_node_experiment_ds_objects_config_path ):
982747 post_patched .return_value = MockResponse (self .RESPONSE_JSON_200 )
983- command = self .FULL_OPTIONS_COMMAND [:] + ["--tensorboard" ]
984- tensorboard_handler = mock .MagicMock ()
985- tensorboard_handler_class .return_value = tensorboard_handler
748+ command = self .FULL_OPTIONS_COMMAND_WITH_OPTIONS_FILE [:] + [create_multi_node_experiment_ds_objects_config_path ]
986749
987750 runner = CliRunner ()
988751 result = runner .invoke (cli .cli , command )
@@ -995,10 +758,6 @@ def test_should_send_proper_data_and_print_message_when_create_experiment_was_ru
995758 files = None ,
996759 data = None )
997760 assert result .exit_code == 0
998- assert EXPECTED_HEADERS_WITH_CHANGED_API_KEY ["X-API-Key" ] == "some_key"
999-
1000- tensorboard_handler_class .assert_called_once_with ("some_key" )
1001- tensorboard_handler .maybe_add_to_tensorboard .assert_called_once_with (True , "sadkfhlskdjh" )
1002761
1003762
1004763class TestExperimentsCreateAndStartSingleNode (TestExperimentsCreateSingleNode ):
@@ -1121,13 +880,13 @@ class TestExperimentsCreateAndStartMultiNode(TestExperimentsCreateMultiNode):
1121880 "--datasetName" , "some dataset name" ,
1122881 "--datasetAwsAccessKeyId" , "none" ,
1123882 "--datasetAwsSecretAccessKey" , "none" ,
1124- "--datasetVersionId" , "none " ,
883+ "--datasetVersionId" , "version1 " ,
1125884 "--datasetEtag" , "some etag" ,
1126885 "--datasetUri" , "s3://some.other.dataset/uri" ,
1127886 "--datasetName" , "none" ,
1128887 "--datasetAwsAccessKeyId" , "some_other_key_id" ,
1129888 "--datasetAwsSecretAccessKey" , "some_other_secret" ,
1130- "--datasetVersionId" , "none " ,
889+ "--datasetVersionId" , "version2 " ,
1131890 "--datasetEtag" , "some other etag" ,
1132891 "--datasetVolumeKind" , "dynamic" ,
1133892 "--datasetVolumeSize" , "10Gi" ,
0 commit comments