mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-01 11:22:21 -06:00
ExternalProject: add INACTIVITY_TIMEOUT argument
In order to abort transfers on slow connections the ExternalProject command support passing the INACTIVITY_TIMEOUT argument. Fixes: #20992
This commit is contained in:
committed by
Brad King
parent
f24e34975a
commit
116b06870d
@@ -105,7 +105,8 @@ set(retry_number 5)
|
||||
|
||||
message(STATUS "Downloading...
|
||||
dst='@LOCAL@'
|
||||
timeout='@TIMEOUT_MSG@'"
|
||||
timeout='@TIMEOUT_MSG@'
|
||||
inactivity timeout='@INACTIVITY_TIMEOUT_MSG@'"
|
||||
)
|
||||
set(download_retry_codes 7 6 8 15)
|
||||
set(skip_url_list)
|
||||
@@ -128,6 +129,7 @@ foreach(i RANGE ${retry_number})
|
||||
"${url}" "@LOCAL@"
|
||||
@SHOW_PROGRESS@
|
||||
@TIMEOUT_ARGS@
|
||||
@INACTIVITY_TIMEOUT_ARGS@
|
||||
STATUS status
|
||||
LOG log
|
||||
@USERPWD_ARGS@
|
||||
|
||||
@@ -179,6 +179,9 @@ External Project Definition
|
||||
``TIMEOUT <seconds>``
|
||||
Maximum time allowed for file download operations.
|
||||
|
||||
``INACTIVITY_TIMEOUT <seconds>``
|
||||
Terminate the operation after a period of inactivity.
|
||||
|
||||
``HTTP_USERNAME <username>``
|
||||
Username for the download operation if authentication is required.
|
||||
|
||||
@@ -1300,7 +1303,7 @@ function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_r
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_progress hash tls_verify tls_cainfo userpwd http_headers netrc netrc_file)
|
||||
function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout inactivity_timeout no_progress hash tls_verify tls_cainfo userpwd http_headers netrc netrc_file)
|
||||
if(timeout)
|
||||
set(TIMEOUT_ARGS TIMEOUT ${timeout})
|
||||
set(TIMEOUT_MSG "${timeout} seconds")
|
||||
@@ -1308,6 +1311,14 @@ function(_ep_write_downloadfile_script script_filename REMOTE LOCAL timeout no_p
|
||||
set(TIMEOUT_ARGS "# no TIMEOUT")
|
||||
set(TIMEOUT_MSG "none")
|
||||
endif()
|
||||
if(inactivity_timeout)
|
||||
set(INACTIVITY_TIMEOUT_ARGS INACTIVITY_TIMEOUT ${inactivity_timeout})
|
||||
set(INACTIVITY_TIMEOUT_MSG "${inactivity_timeout} seconds")
|
||||
else()
|
||||
set(INACTIVITY_TIMEOUT_ARGS "# no INACTIVITY_TIMEOUT")
|
||||
set(INACTIVITY_TIMEOUT_MSG "none")
|
||||
endif()
|
||||
|
||||
|
||||
if(no_progress)
|
||||
set(SHOW_PROGRESS "")
|
||||
@@ -2512,6 +2523,7 @@ function(_ep_add_download_command name)
|
||||
string(REPLACE ";" "-" fname "${fname}")
|
||||
set(file ${download_dir}/${fname})
|
||||
get_property(timeout TARGET ${name} PROPERTY _EP_TIMEOUT)
|
||||
get_property(inactivity_timeout TARGET ${name} PROPERTY _EP_INACTIVITY_TIMEOUT)
|
||||
get_property(no_progress TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS)
|
||||
get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY)
|
||||
get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO)
|
||||
@@ -2521,7 +2533,7 @@ function(_ep_add_download_command name)
|
||||
get_property(http_password TARGET ${name} PROPERTY _EP_HTTP_PASSWORD)
|
||||
get_property(http_headers TARGET ${name} PROPERTY _EP_HTTP_HEADER)
|
||||
set(download_script "${stamp_dir}/download-${name}.cmake")
|
||||
_ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}" "${http_username}:${http_password}" "${http_headers}" "${netrc}" "${netrc_file}")
|
||||
_ep_write_downloadfile_script("${download_script}" "${url}" "${file}" "${timeout}" "${inactivity_timeout}" "${no_progress}" "${hash}" "${tls_verify}" "${tls_cainfo}" "${http_username}:${http_password}" "${http_headers}" "${netrc}" "${netrc_file}")
|
||||
set(cmd ${CMAKE_COMMAND} -P "${download_script}"
|
||||
COMMAND)
|
||||
if (no_extract)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(MyProj URL ${SERVER_URL} INACTIVITY_TIMEOUT 2 DOWNLOAD_NO_EXTRACT TRUE
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
@@ -0,0 +1 @@
|
||||
(Timeout was reached)?
|
||||
@@ -0,0 +1,5 @@
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(MyProj URL ${SERVER_URL} INACTIVITY_TIMEOUT 2 DOWNLOAD_NO_EXTRACT TRUE
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
42
Tests/RunCMake/ExternalProject/DownloadServer.py
Normal file
42
Tests/RunCMake/ExternalProject/DownloadServer.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
import argparse
|
||||
import time
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
args = None
|
||||
outerthread = None
|
||||
|
||||
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
data = b'D'
|
||||
|
||||
if args.speed_limit:
|
||||
slow_deadline = time.time()+args.limit_duration
|
||||
|
||||
while time.time() < slow_deadline:
|
||||
self.wfile.write(data)
|
||||
if args.speed_limit:
|
||||
time.sleep(1.1)
|
||||
|
||||
data = data * 100
|
||||
self.wfile.write(data)
|
||||
self.close_connection = True
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--speed_limit', help='transfer rate limitation', action='store_true',default=False)
|
||||
parser.add_argument('--limit_duration', help='duration of the transfer rate limitation',default=1, type=float)
|
||||
parser.add_argument('--file', help='file to write the url to connect to')
|
||||
parser.add_argument('--subprocess', action='store_true')
|
||||
args = parser.parse_args()
|
||||
if not args.subprocess:
|
||||
subprocess.Popen([sys.executable]+sys.argv+['--subprocess'],stdin=subprocess.DEVNULL, stderr=subprocess.DEVNULL,stdout=subprocess.DEVNULL)
|
||||
else:
|
||||
httpd = HTTPServer(('localhost', 0), SimpleHTTPRequestHandler)
|
||||
with open(args.file,"w") as f:
|
||||
f.write('http://localhost:{}/test'.format(httpd.socket.getsockname()[1]))
|
||||
httpd.handle_request()
|
||||
os.remove(args.file)
|
||||
@@ -1,5 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
include(RunCMake)
|
||||
|
||||
# We do not contact any remote URLs, but may use a local one.
|
||||
# Remove any proxy configuration that may change behavior.
|
||||
unset(ENV{http_proxy})
|
||||
unset(ENV{https_proxy})
|
||||
|
||||
run_cmake(IncludeScope-Add)
|
||||
run_cmake(IncludeScope-Add_Step)
|
||||
run_cmake(NoOptions)
|
||||
@@ -27,6 +33,50 @@ function(__ep_test_with_build testName)
|
||||
run_cmake_command(${testName}-build ${CMAKE_COMMAND} --build .)
|
||||
endfunction()
|
||||
|
||||
find_package(Python3)
|
||||
function(__ep_test_with_build_with_server testName)
|
||||
if(NOT Python3_EXECUTABLE)
|
||||
return()
|
||||
endif()
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${testName}-build)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
set(RunCMake_TEST_TIMEOUT 20)
|
||||
set(RunCMake_TEST_OUTPUT_MERGE TRUE)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
set(URL_FILE ${RunCMake_BINARY_DIR}/${testName}.url)
|
||||
if(EXISTS "${URL_FILE}")
|
||||
file(REMOVE "${URL_FILE}")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/DownloadServer.py --file "${URL_FILE}" ${ARGN}
|
||||
OUTPUT_FILE ${RunCMake_BINARY_DIR}/${testName}-python.txt
|
||||
ERROR_FILE ${RunCMake_BINARY_DIR}/${testName}-python.txt
|
||||
RESULT_VARIABLE result
|
||||
TIMEOUT 30
|
||||
)
|
||||
if(NOT result EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to start download server:\n ${result}")
|
||||
endif()
|
||||
|
||||
foreach(i RANGE 1 8)
|
||||
if(EXISTS ${URL_FILE})
|
||||
break()
|
||||
endif()
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${i})
|
||||
endforeach()
|
||||
|
||||
if(NOT EXISTS ${URL_FILE})
|
||||
message(FATAL_ERROR "Failed to load download server URL from:\n ${URL_FILE}")
|
||||
endif()
|
||||
|
||||
file(READ ${URL_FILE} SERVER_URL)
|
||||
message(STATUS "URL : ${URL_FILE} - ${SERVER_URL}")
|
||||
run_cmake_with_options(${testName} ${CMAKE_COMMAND} -DSERVER_URL=${SERVER_URL} )
|
||||
run_cmake_command(${testName}-clean ${CMAKE_COMMAND} --build . --target clean)
|
||||
run_cmake_command(${testName}-build ${CMAKE_COMMAND} --build .)
|
||||
endfunction()
|
||||
|
||||
__ep_test_with_build(MultiCommand)
|
||||
|
||||
set(RunCMake_TEST_OUTPUT_MERGE 1)
|
||||
@@ -39,6 +89,8 @@ if(NOT RunCMake_GENERATOR MATCHES "Visual Studio")
|
||||
__ep_test_with_build(LogOutputOnFailure)
|
||||
__ep_test_with_build(LogOutputOnFailureMerged)
|
||||
__ep_test_with_build(DownloadTimeout)
|
||||
__ep_test_with_build_with_server(DownloadInactivityTimeout --speed_limit --limit_duration 40)
|
||||
__ep_test_with_build_with_server(DownloadInactivityResume --speed_limit --limit_duration 1)
|
||||
endif()
|
||||
|
||||
# We can't test the substitution when using the old MSYS due to
|
||||
|
||||
Reference in New Issue
Block a user