Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 42 additions & 17 deletions scripts/start_ursim.sh
Original file line number Diff line number Diff line change
Expand Up @@ -404,27 +404,46 @@ post_setup_polyscopex()
curl -L -o "$urcapx_file" "$URCAPX_DOWNLOAD_URL"
fi

# Prefer a published host mapping for HTTP (needed on Docker Desktop / NAT where the
# container IP is unreachable). Fall back to the container IP when nothing is published.
local forwarded_endpoint http_host
if forwarded_endpoint=$(get_forwarded_access_endpoint 80); then
http_host="$forwarded_endpoint"
else
http_host="$IP_ADDRESS"
# UrService is reachable on the container IP from another container on ursim_net
# (CI). A published host port is required on Docker Desktop, where that IP is
# not routed. Probe both, and install the URCap through whichever answers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR title needs grammar fixes

Low Severity

The PR title is missing articles and uses urcap instead of URCap. A clearer wording is Probe the container IP and forwarded IP for the URCap endpoint.

Fix in Cursor Fix in Web

Triggered by team rule: PR title

Reviewed by Cursor Bugbot for commit e144383. Configure here.

local forwarded_endpoint=""
forwarded_endpoint=$(get_forwarded_access_endpoint 80) || forwarded_endpoint=""
local -a base_urls=("http://${IP_ADDRESS}")
if [[ -n "$forwarded_endpoint" ]]; then
base_urls+=("http://${forwarded_endpoint}")
fi
local base_url="http://${http_host}"
local urcaps_url="${base_url}/universal-robots/urservice/api/v1/urcaps"
local urcaps_path="/universal-robots/urservice/api/v1/urcaps"
# Overall wait for UrService. Override with URSIM_URSERVICE_TIMEOUT (seconds).
local urservice_timeout="${URSIM_URSERVICE_TIMEOUT:-300}"
local urcaps_url=""
local base status_code
local deadline=$((SECONDS + urservice_timeout))

echo -ne "Starting URSim. Waiting for UrService to be up..."
status_code=$(curl --retry-connrefused -f --write-out "%{http_code}" --silent --output /dev/null "$urcaps_url")

until [ "$status_code" == "200" ]
do
sleep 1
echo -ne "."
status_code=$(curl --retry-connrefused -f --write-out "%{http_code}" --silent --output /dev/null "$urcaps_url")
while [[ -z "$urcaps_url" && "$SECONDS" -lt "$deadline" ]]; do
for base in "${base_urls[@]}"; do
status_code=$(
curl --connect-timeout 2 --max-time 5 --silent --output /dev/null \
--write-out "%{http_code}" "${base}${urcaps_path}" || true
)
if [[ "$status_code" == "200" ]]; then
urcaps_url="${base}${urcaps_path}"
break
fi
done
if [[ -z "$urcaps_url" ]]; then
sleep 1
echo -ne "."
fi
done

if [[ -z "$urcaps_url" ]]; then
echo ""
echo "Timed out after ${urservice_timeout}s waiting for UrService. Tried: ${base_urls[*]}"
return 1
fi

echo ""; echo "UrService is up"

echo "Installing URCapX $urcapx_file"
Expand Down Expand Up @@ -666,7 +685,13 @@ main() {
trap "$TRAP_CMD" SIGINT SIGTERM


eval "post_setup_${ROBOT_SERIES}"
if ! "post_setup_${ROBOT_SERIES}"; then
if [ "$DETACHED" = false ]; then
docker container kill "$CONTAINER_NAME" > /dev/null 2>&1 || true
docker container wait "$CONTAINER_NAME" > /dev/null 2>&1 || true
fi
exit 1
fi

if [ "$DETACHED" = false ]; then
echo "To exit, press CTRL+C"
Expand Down
62 changes: 60 additions & 2 deletions tests/test_start_ursim.bats
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ stub_docker_port() {
[[ "$output" != *"Access PolyScope X: http://192."* ]]
}

@test "post_setup_polyscopex uses forwarded endpoint for http calls" {
@test "post_setup_polyscopex uses container IP for http calls when it responds" {
IP_ADDRESS="192.168.56.101"
CONTAINER_NAME="ursim"
DOCKER_PORT_MAP='80=127.0.0.1:8000'
Expand All @@ -1000,15 +1000,73 @@ stub_docker_port() {
touch "$URCAP_STORAGE/external-control-0.0.0.urcapx"
URSIM_VERSION="10.8.0"

run post_setup_polyscopex
echo "$output"
echo "curl log:"; cat "$CURL_LOG"
[ "$status" -eq 0 ]
grep -F "http://192.168.56.101/universal-robots/urservice/api/v1/urcaps" "$CURL_LOG"
! grep -F "http://127.0.0.1:8000/universal-robots/urservice/api/v1/urcaps" "$CURL_LOG"
rm -f "$CURL_LOG"
}

@test "post_setup_polyscopex uses forwarded endpoint when container IP is unreachable" {
IP_ADDRESS="192.168.56.101"
CONTAINER_NAME="ursim"
DOCKER_PORT_MAP='80=127.0.0.1:8000'
stub_docker_port
get_download_url_urcapx() { URCAPX_VERSION="0.0.0"; URCAPX_DOWNLOAD_URL=""; }
CURL_LOG=$(mktemp)
curl() {
printf '%s\n' "$*" >> "$CURL_LOG"
if [[ "$*" == *"--form"* ]]; then
return 0
fi
if [[ "$*" == *"http://192.168.56.101/universal-robots/urservice/api/v1/urcaps"* ]]; then
echo "000"
return 7
fi
echo "200"
}
URCAP_STORAGE=/tmp/ursim-test-urcaps-post-setup
mkdir -p "$URCAP_STORAGE"
touch "$URCAP_STORAGE/external-control-0.0.0.urcapx"
URSIM_VERSION="10.8.0"

run post_setup_polyscopex
echo "$output"
echo "curl log:"; cat "$CURL_LOG"
[ "$status" -eq 0 ]
grep -F "http://127.0.0.1:8000/universal-robots/urservice/api/v1/urcaps" "$CURL_LOG"
! grep -F "http://192.168.56.101/universal-robots/urservice/api/v1/urcaps" "$CURL_LOG"
rm -f "$CURL_LOG"
}

@test "post_setup_polyscopex times out when UrService does not respond" {
IP_ADDRESS="192.168.56.101"
CONTAINER_NAME="ursim"
DOCKER_PORT_MAP='80=127.0.0.1:8000'
stub_docker_port
get_download_url_urcapx() { URCAPX_VERSION="0.0.0"; URCAPX_DOWNLOAD_URL=""; }
curl() {
if [[ "$*" == *"--form"* ]]; then
return 0
fi
echo "000"
return 7
}
URCAP_STORAGE=/tmp/ursim-test-urcaps-post-setup
mkdir -p "$URCAP_STORAGE"
touch "$URCAP_STORAGE/external-control-0.0.0.urcapx"
URSIM_VERSION="10.8.0"
URSIM_URSERVICE_TIMEOUT=1

run post_setup_polyscopex
echo "$output"
[ "$status" -ne 0 ]
[[ "$output" == *"Timed out after 1s waiting for UrService."* ]]
[[ "$output" == *"http://192.168.56.101"* ]]
[[ "$output" == *"http://127.0.0.1:8000"* ]]
}

@test "post_setup_polyscopex falls back to IP_ADDRESS for http calls when unpublished" {
IP_ADDRESS="192.168.56.101"
CONTAINER_NAME="ursim"
Expand Down
Loading