Skip to content

Commit 06c21b6

Browse files
feature: handle new frontend deployment for frontend (#204)
Summary: The frontend url (lab.core.strateos.com/haven/wctest) is not the same that the url to the frontend node. This would be confusing to user to have to use different one. The exec method will request the frontend server for the IP of the frontend node, and then make the request to it. ``` $ transcriptic preview Read | transcriptic exec --api http://lab.core.strateos.com/haven/wctest Sending request to 13.52.223.111:9000 Success. View http://lab.core.strateos.com/haven/wctest/dashboard to see the scheduling outcome. ```
1 parent 39cfcf7 commit 06c21b6

3 files changed

Lines changed: 66 additions & 20 deletions

File tree

test/commands/exec_test.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,16 @@ def queue_test_success_res(sessionId="testSessionId"):
1313
return {"success": True, "sessionId": sessionId}
1414

1515

16+
def app_config_res():
17+
return {"hostManifest": {"lab": {"workcell": "something.bar.foo"}}}
18+
19+
1620
def mock_api_endpoint():
17-
return "foo.bar.baz"
21+
return "foo.bar.baz/lab/workcell"
22+
23+
24+
def mockget(*args, **kwargs):
25+
return MockResponse(0, app_config_res(), json.dumps(app_config_res()))
1826

1927

2028
@pytest.fixture
@@ -39,12 +47,13 @@ def mockpost(*args, **kwargs):
3947
)
4048

4149
monkeypatch.setattr(requests, "post", mockpost)
50+
monkeypatch.setattr(requests, "get", mockget)
4251
result = cli_test_runner.invoke(
4352
cli, ["exec", str(ap_file), "-a", mock_api_endpoint()]
4453
)
4554
assert result.exit_code == 0
4655
assert (
47-
f"Success. View {mock_api_endpoint()}/dashboard?sessionId=testSessionId to see the scheduling outcome."
56+
f"Success. View http://{mock_api_endpoint()}/dashboard to see the scheduling outcome."
4857
in result.output
4958
)
5059

@@ -81,6 +90,7 @@ def mockpost(*args, **kwargs):
8190
return MockResponse(0, "not-json", "not-json")
8291

8392
monkeypatch.setattr(requests, "post", mockpost)
93+
monkeypatch.setattr(requests, "get", mockget)
8494
result = cli_test_runner.invoke(
8595
cli, ["exec", str(ap_file), "-a", mock_api_endpoint()]
8696
)
@@ -95,22 +105,23 @@ def mockpost(*args, **kwargs):
95105
)
96106

97107
monkeypatch.setattr(requests, "post", mockpost)
108+
monkeypatch.setattr(requests, "get", mockget)
98109
result = cli_test_runner.invoke(
99110
cli, ["exec", str(ap_file), "-a", mock_api_endpoint(), "-w", "wc3"]
100111
)
101112
assert result.exit_code == 0
102113
assert (
103-
f"Success. View {mock_api_endpoint()}/dashboard?sessionId=testSessionId to see the scheduling outcome."
114+
f"Success. View http://{mock_api_endpoint()}/dashboard to see the scheduling outcome."
104115
in result.output
105116
)
106117

107118

108-
def test_bad_workcell(cli_test_runner, ap_file):
119+
def test_bad_workcell(cli_test_runner, monkeypatch, ap_file):
109120
result = cli_test_runner.invoke(
110-
cli, ["exec", str(ap_file), "-a", mock_api_endpoint(), "-w", "bad-workcell-id"]
121+
cli, ["exec", str(ap_file), "-a", mock_api_endpoint(), "-w", "hello.world"]
111122
)
112123
assert result.exit_code != 0
113-
assert "Workcell id must be like wcN but was bad-workcell-id" in result.stderr
124+
assert "Error: " in result.stderr
114125

115126

116127
def test_session_id(cli_test_runner, monkeypatch, ap_file):
@@ -124,6 +135,7 @@ def mockpost(*args, **kwargs):
124135
)
125136

126137
monkeypatch.setattr(requests, "post", mockpost)
138+
monkeypatch.setattr(requests, "get", mockget)
127139
result = cli_test_runner.invoke(
128140
cli,
129141
[
@@ -137,7 +149,7 @@ def mockpost(*args, **kwargs):
137149
)
138150
assert result.exit_code == 0
139151
assert (
140-
f"Success. View {mock_api_endpoint()}/dashboard?sessionId={sessionId} to see the scheduling outcome."
152+
f"Success. View http://{mock_api_endpoint()}/dashboard to see the scheduling outcome."
141153
in result.output
142154
)
143155

transcriptic/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ def format_cmd(manifest):
641641
@click.option(
642642
"--workcell-id",
643643
"-w",
644-
help="The workcell id to use for the device set. This is not permitted along with the `device-set` or `session-id` option.",
644+
help="The workcell id to use for the device set (wc4-mcx1, tst-01-mcx-01, etc.). This is not permitted along with the `device-set` or `session-id` option.",
645645
)
646646
@click.option(
647647
"--device-set",

transcriptic/commands.py

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,30 @@ def execute(
14891489
partition_horizon,
14901490
partitioning_swap_device_id,
14911491
):
1492+
# Clean api end point
1493+
if api.startswith("http://"):
1494+
clean_api = api[7:]
1495+
elif api.startswith("https://"):
1496+
click.echo("HTTPS endpoint is not supported, falling back to HTTP.")
1497+
clean_api = api[8:]
1498+
else:
1499+
clean_api = api
1500+
if clean_api[-1] == "/":
1501+
clean_api = clean_api[0:-1] # remove trailing slash
1502+
1503+
# Validate api
1504+
path_tokens = clean_api.split("/")
1505+
if len(path_tokens) != 3:
1506+
click.echo(
1507+
f"Invalid api target, expects http://base/facility/workcell.", err=True
1508+
)
1509+
return
1510+
1511+
clean_api = f"http://{clean_api}"
1512+
path_base = f"http://{path_tokens[0]}"
1513+
path_lab = path_tokens[1]
1514+
path_workcell = path_tokens[2]
1515+
14921516
# Define the initial payload
14931517
payload = {"timeLimit": f"{time_limit}:second"}
14941518

@@ -1527,9 +1551,9 @@ def execute(
15271551
in_use.append("--device-set")
15281552

15291553
if workcell_id:
1530-
if not re.search("^wc[a-z,0-9]+$", workcell_id):
1531-
raise BadParameter(f"Workcell id must be like wcN but was {workcell_id}")
1532-
payload["workcellIdForDeviceSet"] = f"{workcell_id}-mcx1"
1554+
if "." in workcell_id:
1555+
raise BadParameter(f"Workcell id can't have '.' but was {workcell_id}")
1556+
payload["workcellIdForDeviceSet"] = workcell_id
15331557
in_use.append("--workcell-id")
15341558

15351559
if session_id is not None:
@@ -1553,27 +1577,37 @@ def execute(
15531577
if partitioning_swap_device_id is not None:
15541578
payload["partitioningSwapDeviceId"] = partitioning_swap_device_id
15551579

1556-
# Clean api end point
1557-
if api[-1] == "/":
1558-
clean_api = api[0:-1] # remove trailing slash
1559-
else:
1560-
clean_api = api
1580+
res = requests.get(f"{path_base}/app-config")
1581+
try:
1582+
res_json = json.loads(res.text)
1583+
if (
1584+
res_json["hostManifest"]
1585+
and res_json["hostManifest"][path_lab]
1586+
and res_json["hostManifest"][path_lab][path_workcell]
1587+
):
1588+
frontend_node_address = res_json["hostManifest"][path_lab][path_workcell]
1589+
else:
1590+
click.echo(f"Error when get frontend node address: {res_json}", err=True)
1591+
return
1592+
except json.decoder.JSONDecodeError:
1593+
click.echo(f"Error when get frontend node address: {res.text}", err=True)
1594+
return
15611595

15621596
# POST to workcell
1563-
test_run_endpoint = f"{clean_api}/testRun"
1564-
click.echo("Sending request...")
1597+
test_run_endpoint = f"http://{frontend_node_address}/testRun"
1598+
click.echo(f"Sending request to {frontend_node_address}")
15651599
res = requests.post(test_run_endpoint, json=payload)
15661600
try:
15671601
res_json = json.loads(res.text)
15681602
if res_json["success"]:
15691603
click.echo(
1570-
f"Success. View {clean_api}/dashboard?sessionId={res_json['sessionId']} to see the scheduling outcome."
1604+
f"Success. View {clean_api}/dashboard to see the scheduling outcome."
15711605
)
15721606
else:
15731607
click.echo(f"Error: {res_json['message']}", err=True)
15741608
if "sessionId" in res_json:
15751609
click.echo(
1576-
f"Dashboard can be seen at: {clean_api}/dashboard?sessionId={res_json['sessionId']}",
1610+
f"Dashboard can be seen at: {clean_api}/dashboard",
15771611
err=True,
15781612
)
15791613
except json.decoder.JSONDecodeError:

0 commit comments

Comments
 (0)