@@ -2195,3 +2195,161 @@ def test_ctrl_c_during_build_streaming_shows_cancelled(
21952195
21962196 assert "🟡" in result .output
21972197 assert "Cancelled." in result .output
2198+
2199+
2200+ def _create_file (path : Path , size_bytes : int ) -> None :
2201+ """Create a file of the given size."""
2202+ path .parent .mkdir (parents = True , exist_ok = True )
2203+ with open (path , "wb" ) as f :
2204+ if size_bytes > 0 :
2205+ f .seek (size_bytes - 1 )
2206+ f .write (b"\0 " )
2207+
2208+
2209+ @pytest .mark .respx
2210+ def test_large_file_threshold_warning (
2211+ logged_in_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
2212+ ) -> None :
2213+ app_data = _get_random_app ()
2214+ app_id = app_data ["id" ]
2215+ team_id = "some-team-id"
2216+ deployment_data = _get_random_deployment (app_id = app_id )
2217+
2218+ _setup_deployment_mocks (respx_mock , app_id , team_id , deployment_data , tmp_path )
2219+ respx_mock .get (f"/apps/{ app_id } /deployments/{ deployment_data ['id' ]} " ).mock (
2220+ return_value = Response (200 , json = {** deployment_data , "status" : "success" })
2221+ )
2222+
2223+ _create_file (tmp_path / "model.bin" , 12 * 1024 * 1024 ) # 12 MB
2224+ _create_file (tmp_path / "data.csv" , 10 * 1024 * 1024 + 1 ) # 10+ MB
2225+
2226+ with changing_dir (tmp_path ):
2227+ result = runner .invoke (app , ["deploy" ])
2228+
2229+ assert result .exit_code == 0
2230+ assert "Some uploaded files are larger than 10 MB" in result .output
2231+ assert "model.bin" in result .output
2232+ assert "12 MB" in result .output
2233+ assert "data.csv" in result .output
2234+ assert "10 MB" in result .output
2235+
2236+
2237+ @pytest .mark .respx
2238+ def test_large_file_threshold_only_top_three_files_with_more_indicator (
2239+ logged_in_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
2240+ ) -> None :
2241+ app_data = _get_random_app ()
2242+ app_id = app_data ["id" ]
2243+ team_id = "some-team-id"
2244+ deployment_data = _get_random_deployment (app_id = app_id )
2245+
2246+ _setup_deployment_mocks (respx_mock , app_id , team_id , deployment_data , tmp_path )
2247+ respx_mock .get (f"/apps/{ app_id } /deployments/{ deployment_data ['id' ]} " ).mock (
2248+ return_value = Response (200 , json = {** deployment_data , "status" : "success" })
2249+ )
2250+
2251+ _create_file (tmp_path / "huge.bin" , 50 * 1024 * 1024 )
2252+ _create_file (tmp_path / "big.bin" , 40 * 1024 * 1024 )
2253+ _create_file (tmp_path / "medium.bin" , 30 * 1024 * 1024 )
2254+ _create_file (tmp_path / "smaller.bin" , 20 * 1024 * 1024 )
2255+ _create_file (tmp_path / "smallest.bin" , 15 * 1024 * 1024 )
2256+
2257+ with changing_dir (tmp_path ):
2258+ result = runner .invoke (app , ["deploy" ])
2259+
2260+ assert result .exit_code == 0
2261+ assert "huge.bin" in result .output
2262+ assert "big.bin" in result .output
2263+ assert "medium.bin" in result .output
2264+ assert "smaller.bin" not in result .output
2265+ assert "smallest.bin" not in result .output
2266+ assert "...and 2 more" in result .output
2267+
2268+
2269+ @pytest .mark .respx
2270+ def test_large_file_threshold_does_not_warn_when_no_large_files (
2271+ logged_in_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
2272+ ) -> None :
2273+ app_data = _get_random_app ()
2274+ app_id = app_data ["id" ]
2275+ team_id = "some-team-id"
2276+ deployment_data = _get_random_deployment (app_id = app_id )
2277+
2278+ _setup_deployment_mocks (respx_mock , app_id , team_id , deployment_data , tmp_path )
2279+ respx_mock .get (f"/apps/{ app_id } /deployments/{ deployment_data ['id' ]} " ).mock (
2280+ return_value = Response (200 , json = {** deployment_data , "status" : "success" })
2281+ )
2282+
2283+ # Files are less or equal to 10 MB (default threshold), so no warning should be shown
2284+ _create_file (tmp_path / "data.bin" , 5 * 1024 * 1024 )
2285+ _create_file (tmp_path / "data.bin" , 10 * 1024 * 1024 )
2286+
2287+ with changing_dir (tmp_path ):
2288+ result = runner .invoke (app , ["deploy" ])
2289+
2290+ assert result .exit_code == 0
2291+ assert "Some uploaded files are larger than" not in result .output
2292+ assert "data.bin" not in result .output
2293+
2294+
2295+ @pytest .mark .respx
2296+ def test_large_file_threshold_custom_threshold (
2297+ logged_in_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
2298+ ) -> None :
2299+ app_data = _get_random_app ()
2300+ app_id = app_data ["id" ]
2301+ team_id = "some-team-id"
2302+ deployment_data = _get_random_deployment (app_id = app_id )
2303+
2304+ _setup_deployment_mocks (respx_mock , app_id , team_id , deployment_data , tmp_path )
2305+ respx_mock .get (f"/apps/{ app_id } /deployments/{ deployment_data ['id' ]} " ).mock (
2306+ return_value = Response (200 , json = {** deployment_data , "status" : "success" })
2307+ )
2308+
2309+ # 5 MB file: above a 1 MB threshold, below the default 10 MB threshold
2310+ _create_file (tmp_path / "data.bin" , 5 * 1024 * 1024 )
2311+
2312+ with changing_dir (tmp_path ):
2313+ result = runner .invoke (app , ["deploy" , "--large-file-threshold" , "1" ])
2314+
2315+ assert result .exit_code == 0
2316+ assert "Some uploaded files are larger than 1 MB" in result .output
2317+ assert "data.bin" in result .output
2318+
2319+
2320+ @pytest .mark .respx
2321+ def test_large_file_threshold_custom_threshold_envvar (
2322+ logged_in_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
2323+ ) -> None :
2324+ app_data = _get_random_app ()
2325+ app_id = app_data ["id" ]
2326+ team_id = "some-team-id"
2327+ deployment_data = _get_random_deployment (app_id = app_id )
2328+
2329+ _setup_deployment_mocks (respx_mock , app_id , team_id , deployment_data , tmp_path )
2330+ respx_mock .get (f"/apps/{ app_id } /deployments/{ deployment_data ['id' ]} " ).mock (
2331+ return_value = Response (200 , json = {** deployment_data , "status" : "success" })
2332+ )
2333+
2334+ # 5 MB file: above a 1 MB threshold, below the default 10 MB threshold
2335+ _create_file (tmp_path / "data.bin" , 5 * 1024 * 1024 )
2336+
2337+ with changing_dir (tmp_path ):
2338+ result = runner .invoke (
2339+ app , ["deploy" ], env = {"FASTAPI_CLOUD_LARGE_FILE_THRESHOLD" : "1" }
2340+ )
2341+
2342+ assert result .exit_code == 0
2343+ assert "Some uploaded files are larger than 1 MB" in result .output
2344+ assert "data.bin" in result .output
2345+
2346+
2347+ @pytest .mark .respx
2348+ def test_invalid_large_file_threshold (
2349+ logged_in_cli : None , tmp_path : Path , respx_mock : respx .MockRouter
2350+ ) -> None :
2351+ with changing_dir (tmp_path ):
2352+ result = runner .invoke (app , ["deploy" , "--large-file-threshold" , "0" ])
2353+
2354+ assert result .exit_code == 2
2355+ assert "Invalid value for '--large-file-threshold'" in result .output
0 commit comments