@@ -716,3 +716,275 @@ def test_subset_with_same_bin_file(self):
716716 ],
717717 ]],
718718 )
719+
720+ @responses .activate
721+ @mock .patch .dict (os .environ , {"SMART_TESTS_TOKEN" : CliTestCase .smart_tests_token })
722+ def test_subset_id_file_not_set (self ):
723+ pipe = "test_1.py\n test_2.py\n "
724+ mock_json_response = {
725+ "testPaths" : [
726+ [{"type" : "file" , "name" : "test_1.py" }],
727+ [{"type" : "file" , "name" : "test_2.py" }],
728+ ],
729+ "testRunner" : "file" ,
730+ "rest" : [],
731+ "subsettingId" : self .subsetting_id ,
732+ "summary" : {
733+ "subset" : {"duration" : 10 , "candidates" : 2 , "rate" : 100 },
734+ "rest" : {"duration" : 0 , "candidates" : 0 , "rate" : 0 },
735+ },
736+ "isObservation" : False ,
737+ }
738+ responses .replace (
739+ responses .POST ,
740+ f"{ get_base_url ()} /intake/organizations/{ self .organization } /workspaces/{ self .workspace } /subset" ,
741+ json = mock_json_response ,
742+ status = 200 ,
743+ )
744+
745+ sentinel = tempfile .NamedTemporaryFile (delete = False )
746+ sentinel_path = sentinel .name
747+ sentinel .close ()
748+ os .unlink (sentinel_path )
749+
750+ result = self .cli (
751+ "subset" , "file" ,
752+ "--session" , self .session ,
753+ mix_stderr = False ,
754+ input = pipe ,
755+ )
756+ self .assert_success (result )
757+ self .assertEqual (result .stdout , "test_1.py\n test_2.py\n " )
758+ self .assertFalse (os .path .exists (sentinel_path ))
759+
760+ @responses .activate
761+ @mock .patch .dict (os .environ , {"SMART_TESTS_TOKEN" : CliTestCase .smart_tests_token })
762+ def test_subset_id_file_written (self ):
763+ pipe = "test_1.py\n test_2.py\n "
764+ mock_json_response = {
765+ "testPaths" : [
766+ [{"type" : "file" , "name" : "test_1.py" }],
767+ [{"type" : "file" , "name" : "test_2.py" }],
768+ ],
769+ "testRunner" : "file" ,
770+ "rest" : [],
771+ "subsettingId" : self .subsetting_id ,
772+ "summary" : {
773+ "subset" : {"duration" : 10 , "candidates" : 2 , "rate" : 100 },
774+ "rest" : {"duration" : 0 , "candidates" : 0 , "rate" : 0 },
775+ },
776+ "isObservation" : False ,
777+ }
778+ responses .replace (
779+ responses .POST ,
780+ f"{ get_base_url ()} /intake/organizations/{ self .organization } /workspaces/{ self .workspace } /subset" ,
781+ json = mock_json_response ,
782+ status = 200 ,
783+ )
784+
785+ with tempfile .NamedTemporaryFile (delete = False ) as id_file :
786+ id_file_path = id_file .name
787+
788+ try :
789+ result = self .cli (
790+ "subset" , "file" ,
791+ "--session" , self .session ,
792+ "--subset-id-file" , id_file_path ,
793+ mix_stderr = False ,
794+ input = pipe ,
795+ )
796+ self .assert_success (result )
797+ self .assertEqual (result .stdout , "test_1.py\n test_2.py\n " )
798+ with open (id_file_path ) as f :
799+ self .assertEqual (f .read (), f"{ self .subsetting_id } \n " )
800+ finally :
801+ os .unlink (id_file_path )
802+
803+ @responses .activate
804+ @mock .patch .dict (os .environ , {"SMART_TESTS_TOKEN" : CliTestCase .smart_tests_token })
805+ def test_subset_id_file_with_target (self ):
806+ pipe = "test_1.py\n test_2.py\n test_3.py\n "
807+ mock_json_response = {
808+ "testPaths" : [
809+ [{"type" : "file" , "name" : "test_1.py" }],
810+ ],
811+ "testRunner" : "file" ,
812+ "rest" : [
813+ [{"type" : "file" , "name" : "test_2.py" }],
814+ [{"type" : "file" , "name" : "test_3.py" }],
815+ ],
816+ "subsettingId" : self .subsetting_id ,
817+ "summary" : {
818+ "subset" : {"duration" : 5 , "candidates" : 1 , "rate" : 33 },
819+ "rest" : {"duration" : 10 , "candidates" : 2 , "rate" : 67 },
820+ },
821+ "isObservation" : False ,
822+ }
823+ responses .replace (
824+ responses .POST ,
825+ f"{ get_base_url ()} /intake/organizations/{ self .organization } /workspaces/{ self .workspace } /subset" ,
826+ json = mock_json_response ,
827+ status = 200 ,
828+ )
829+
830+ with tempfile .NamedTemporaryFile (delete = False ) as id_file :
831+ id_file_path = id_file .name
832+
833+ try :
834+ result = self .cli (
835+ "subset" , "file" ,
836+ "--session" , self .session ,
837+ "--target" , "30%" ,
838+ "--subset-id-file" , id_file_path ,
839+ mix_stderr = False ,
840+ input = pipe ,
841+ )
842+ self .assert_success (result )
843+ self .assertEqual (result .stdout , "test_1.py\n " )
844+ with open (id_file_path ) as f :
845+ self .assertEqual (f .read (), f"{ self .subsetting_id } \n " )
846+ finally :
847+ os .unlink (id_file_path )
848+
849+ @responses .activate
850+ @mock .patch .dict (os .environ , {"SMART_TESTS_TOKEN" : CliTestCase .smart_tests_token })
851+ def test_subset_id_file_with_rest (self ):
852+ pipe = "test_1.py\n test_2.py\n "
853+ mock_json_response = {
854+ "testPaths" : [
855+ [{"type" : "file" , "name" : "test_1.py" }],
856+ ],
857+ "testRunner" : "file" ,
858+ "rest" : [
859+ [{"type" : "file" , "name" : "test_2.py" }],
860+ ],
861+ "subsettingId" : self .subsetting_id ,
862+ "summary" : {
863+ "subset" : {"duration" : 5 , "candidates" : 1 , "rate" : 50 },
864+ "rest" : {"duration" : 5 , "candidates" : 1 , "rate" : 50 },
865+ },
866+ "isObservation" : False ,
867+ }
868+ responses .replace (
869+ responses .POST ,
870+ f"{ get_base_url ()} /intake/organizations/{ self .organization } /workspaces/{ self .workspace } /subset" ,
871+ json = mock_json_response ,
872+ status = 200 ,
873+ )
874+
875+ with tempfile .NamedTemporaryFile (delete = False ) as id_file , \
876+ tempfile .NamedTemporaryFile (delete = False ) as rest_file :
877+ id_file_path = id_file .name
878+ rest_file_path = rest_file .name
879+
880+ try :
881+ result = self .cli (
882+ "subset" , "file" ,
883+ "--session" , self .session ,
884+ "--rest" , rest_file_path ,
885+ "--subset-id-file" , id_file_path ,
886+ mix_stderr = False ,
887+ input = pipe ,
888+ )
889+ self .assert_success (result )
890+ self .assertEqual (result .stdout , "test_1.py\n " )
891+ with open (id_file_path ) as f :
892+ self .assertEqual (f .read (), f"{ self .subsetting_id } \n " )
893+ with open (rest_file_path ) as f :
894+ self .assertIn ("test_2.py" , f .read ())
895+ finally :
896+ os .unlink (id_file_path )
897+ os .unlink (rest_file_path )
898+
899+ @responses .activate
900+ @mock .patch .dict (os .environ , {"SMART_TESTS_TOKEN" : CliTestCase .smart_tests_token })
901+ def test_subset_id_file_no_id_returned (self ):
902+ pipe = "test_1.py\n "
903+ mock_json_response = {
904+ "testPaths" : [
905+ [{"type" : "file" , "name" : "test_1.py" }],
906+ ],
907+ "testRunner" : "file" ,
908+ "rest" : [],
909+ "subsettingId" : "" ,
910+ "summary" : {
911+ "subset" : {"duration" : 5 , "candidates" : 1 , "rate" : 100 },
912+ "rest" : {"duration" : 0 , "candidates" : 0 , "rate" : 0 },
913+ },
914+ "isObservation" : False ,
915+ }
916+ responses .replace (
917+ responses .POST ,
918+ f"{ get_base_url ()} /intake/organizations/{ self .organization } /workspaces/{ self .workspace } /subset" ,
919+ json = mock_json_response ,
920+ status = 200 ,
921+ )
922+
923+ with tempfile .NamedTemporaryFile (delete = False ) as id_file :
924+ id_file_path = id_file .name
925+
926+ try :
927+ result = self .cli (
928+ "subset" , "file" ,
929+ "--session" , self .session ,
930+ "--subset-id-file" , id_file_path ,
931+ mix_stderr = False ,
932+ input = pipe ,
933+ )
934+ self .assert_exit_code (result , 1 )
935+ self .assertIn ("Subset request did not return a subset ID" , result .stderr )
936+ finally :
937+ if os .path .exists (id_file_path ):
938+ os .unlink (id_file_path )
939+
940+ @responses .activate
941+ @mock .patch .dict (os .environ , {"SMART_TESTS_TOKEN" : CliTestCase .smart_tests_token })
942+ def test_subset_id_file_round_trip (self ):
943+ pipe = "test_1.py\n test_2.py\n "
944+ mock_json_response = {
945+ "testPaths" : [
946+ [{"type" : "file" , "name" : "test_1.py" }],
947+ [{"type" : "file" , "name" : "test_2.py" }],
948+ ],
949+ "testRunner" : "file" ,
950+ "rest" : [],
951+ "subsettingId" : self .subsetting_id ,
952+ "summary" : {
953+ "subset" : {"duration" : 10 , "candidates" : 2 , "rate" : 100 },
954+ "rest" : {"duration" : 0 , "candidates" : 0 , "rate" : 0 },
955+ },
956+ "isObservation" : False ,
957+ }
958+ responses .replace (
959+ responses .POST ,
960+ f"{ get_base_url ()} /intake/organizations/{ self .organization } /workspaces/{ self .workspace } /subset" ,
961+ json = mock_json_response ,
962+ status = 200 ,
963+ )
964+
965+ with tempfile .NamedTemporaryFile (delete = False ) as id_file :
966+ id_file_path = id_file .name
967+
968+ try :
969+ # Step 1: capture the subset ID into a file
970+ result = self .cli (
971+ "subset" , "file" ,
972+ "--session" , self .session ,
973+ "--subset-id-file" , id_file_path ,
974+ mix_stderr = False ,
975+ input = pipe ,
976+ )
977+ self .assert_success (result )
978+
979+ # Step 2: feed the file back via --input-snapshot-id @file
980+ result2 = self .cli (
981+ "subset" , "file" ,
982+ "--session" , self .session ,
983+ "--input-snapshot-id" , f"@{ id_file_path } " ,
984+ mix_stderr = False ,
985+ )
986+ self .assert_success (result2 )
987+ payload = self .decode_request_body (self .find_request ('/subset' , n = 1 ).request .body )
988+ self .assertEqual (payload .get ('subsettingId' ), self .subsetting_id )
989+ finally :
990+ os .unlink (id_file_path )
0 commit comments