remoteRF-server 1.0.3__tar.gz → 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/PKG-INFO +1 -1
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/pyproject.toml +1 -1
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/schema.py +2 -2
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/device_manager.py +6 -1
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/grpc_server.py +13 -5
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/serverrf_cli.py +14 -18
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/PKG-INFO +1 -1
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_cert_provider.py +24 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_dynamic_v2.py +68 -2
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_pluto_compat.py +15 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/README.md +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/setup.cfg +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/grpc_host_pb2.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/grpc_pb2.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/v2_codec.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/device_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/pluto_mimo_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/pluto_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/v2.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/ansi_codes.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/api_token.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/db_connection.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/db_location.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/list_string.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/process_arg.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/adalm_pluto/pluto_mimo_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/adalm_pluto/pluto_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/usrp/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/usrp/policy.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/usrp/uhd_manifest.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/usrp/usrp_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/host/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/host/host_auth_token.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/host/host_directory_store.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/host/host_tunnel_server.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/acc_perms.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/cert_provider.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/dynamic_v2.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/reservation.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/rpc_manager.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/user_group_cli.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/user_group_handler.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/v2_errors.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/tools/__init__.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/tools/gen_certs.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/tools/gist_status.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/tools/gist_status_testing.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/tools/introspect_uhd.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/SOURCES.txt +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/dependency_links.txt +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/entry_points.txt +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/requires.txt +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/top_level.txt +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_default_usrp_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_idl_schema.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_process_arg.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_reservation_timestamps.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_rpc_manager_calln.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_usrp_client_server_hardware.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_usrp_client_server_localhost.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_usrp_remoterf_rx_hardware.py +0 -0
- {remoterf_server-1.0.3 → remoterf_server-1.0.4}/tests/test_usrp_uhd410_hardware.py +0 -0
|
@@ -6,7 +6,7 @@ Admin writes one .py per device TYPE, drops it in ~/.config/remoterf/drivers/,
|
|
|
6
6
|
and the server auto-discovers it on startup via load_drivers().
|
|
7
7
|
|
|
8
8
|
~/.config/remoterf/
|
|
9
|
-
devices.
|
|
9
|
+
devices.yml ← "I have 3 devices at these serials"
|
|
10
10
|
drivers/
|
|
11
11
|
pluto_schema.py ← "here's what a pluto IS"
|
|
12
12
|
hackrf_schema.py
|
|
@@ -531,7 +531,7 @@ class DeviceSchema:
|
|
|
531
531
|
Base for all device schemas. Admin subclasses this once per device type.
|
|
532
532
|
|
|
533
533
|
Class attributes (admin sets these):
|
|
534
|
-
device_type str — must match
|
|
534
|
+
device_type str — must match device_type in devices.yml
|
|
535
535
|
driver_version str — semver
|
|
536
536
|
|
|
537
537
|
Admin implements:
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/device_manager.py
RENAMED
|
@@ -314,6 +314,11 @@ def _load_device_records() -> Dict[int, Dict[str, str]]:
|
|
|
314
314
|
def _connect_from_record(rec: Dict[str, Any]):
|
|
315
315
|
"""Returns (schema_instance_or_None, ident, dtype)."""
|
|
316
316
|
dtype = (rec.get("TYPE") or "").strip().lower()
|
|
317
|
+
# Older serverrf builds serialized the --pluto shorthand as "pluto",
|
|
318
|
+
# while the packaged schema has always registered as "adalm_pluto".
|
|
319
|
+
# Keep those inventories usable while all new writes use the canonical type.
|
|
320
|
+
if dtype == "pluto":
|
|
321
|
+
dtype = "adalm_pluto"
|
|
317
322
|
ident = (rec.get("IDENT") or "").strip()
|
|
318
323
|
init_kwargs = rec.get("INIT") or {}
|
|
319
324
|
|
|
@@ -873,7 +878,7 @@ def acquire_device(api_token: str) -> Iterator[Tuple[int, object]]:
|
|
|
873
878
|
|
|
874
879
|
def reload_devices() -> None:
|
|
875
880
|
"""
|
|
876
|
-
Reload devices.
|
|
881
|
+
Reload devices.yml and reconnect local devices.
|
|
877
882
|
Preserves existing salt/hash for devices that remain (same gid),
|
|
878
883
|
and preserves host virtual devices + their auth state.
|
|
879
884
|
"""
|
|
@@ -214,6 +214,18 @@ def _load_server_credentials(cert_dir: Path):
|
|
|
214
214
|
)
|
|
215
215
|
|
|
216
216
|
|
|
217
|
+
def _print_tls_credentials_error(cert_dir: Path, error: Exception) -> None:
|
|
218
|
+
messages = (
|
|
219
|
+
"TLS certs/keys not found or unreadable.",
|
|
220
|
+
f"Expected in: {cert_dir}",
|
|
221
|
+
f"Fix: run serverrf --gen-certs {local_ip} --force",
|
|
222
|
+
"Or set REMOTERF_CERT_DIR to your cert folder.",
|
|
223
|
+
f"Details: {error}",
|
|
224
|
+
)
|
|
225
|
+
for message in messages:
|
|
226
|
+
printf(message, Sty.MAGENTA)
|
|
227
|
+
|
|
228
|
+
|
|
217
229
|
def start_server_runtime(
|
|
218
230
|
*,
|
|
219
231
|
bind_host: str | None = None,
|
|
@@ -258,11 +270,7 @@ def start_server_runtime(
|
|
|
258
270
|
try:
|
|
259
271
|
server_credentials = _load_server_credentials(cert_dir)
|
|
260
272
|
except Exception as e:
|
|
261
|
-
|
|
262
|
-
printf("Expected in: ", Sty.DEFAULT, f"{cert_dir}", Sty.MAGENTA)
|
|
263
|
-
printf("Fix: run ", Sty.DEFAULT, "RRRFcerts --ip ", Sty.GREEN, f"{local_ip}", Sty.MAGENTA, " --force", Sty.DEFAULT)
|
|
264
|
-
printf("Or set REMOTERF_CERT_DIR to your cert folder.", Sty.GRAY)
|
|
265
|
-
print(f"\nDetails: {e}\n", file=sys.stderr)
|
|
273
|
+
_print_tls_credentials_error(cert_dir, e)
|
|
266
274
|
raise SystemExit(2)
|
|
267
275
|
|
|
268
276
|
if include_host_tunnel:
|
|
@@ -135,7 +135,7 @@ def _server_env_path() -> Path:
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
def _devices_env_path() -> Path:
|
|
138
|
-
#
|
|
138
|
+
# Read-only migration source for pre-YAML installations.
|
|
139
139
|
return _cfg_dir() / "devices.env"
|
|
140
140
|
|
|
141
141
|
|
|
@@ -156,11 +156,11 @@ def _gen_certs_path() -> Path:
|
|
|
156
156
|
return (_repo_root() / "tools" / "gen_certs.py").resolve()
|
|
157
157
|
|
|
158
158
|
def _gist_env_path() -> Path:
|
|
159
|
-
# Stored alongside server.env/devices.
|
|
159
|
+
# Stored alongside server.env/devices.yml under ~/.config/remoterf by default
|
|
160
160
|
return _cfg_dir() / "gist.env"
|
|
161
161
|
|
|
162
162
|
def _tos_ack_path() -> Path:
|
|
163
|
-
# Stored alongside server.env/devices.
|
|
163
|
+
# Stored alongside server.env/devices.yml under ~/.config/remoterf by default
|
|
164
164
|
return _cfg_dir() / "tos.env"
|
|
165
165
|
|
|
166
166
|
|
|
@@ -262,6 +262,7 @@ def print_help() -> None:
|
|
|
262
262
|
"\n"
|
|
263
263
|
"Devices:\n"
|
|
264
264
|
" serverrf -d | --device [options]\n"
|
|
265
|
+
" Inventory: ~/.config/remoterf/devices.yml (canonical YAML)\n"
|
|
265
266
|
"\n"
|
|
266
267
|
"Device options:\n"
|
|
267
268
|
" --add --pluto <id:name:iio_serial> Add an ADALM-Pluto\n"
|
|
@@ -811,7 +812,11 @@ def _read_device_records() -> Dict[int, Dict[str, Any]]:
|
|
|
811
812
|
recs[gid] = {
|
|
812
813
|
"TYPE": dtype,
|
|
813
814
|
"NAME": str(item.get("name") or f"device-{gid}").strip(),
|
|
814
|
-
"IDENT_KIND":
|
|
815
|
+
"IDENT_KIND": (
|
|
816
|
+
"iio_serial"
|
|
817
|
+
if dtype in {"pluto", "adalm_pluto"}
|
|
818
|
+
else "serial"
|
|
819
|
+
),
|
|
815
820
|
"IDENT": ident,
|
|
816
821
|
"INIT": dict(init),
|
|
817
822
|
}
|
|
@@ -833,7 +838,6 @@ def _read_device_records() -> Dict[int, Dict[str, Any]]:
|
|
|
833
838
|
|
|
834
839
|
def _write_device_records(recs: Dict[int, Dict[str, Any]]) -> None:
|
|
835
840
|
devices: List[Dict[str, Any]] = []
|
|
836
|
-
out: Dict[str, str] = {}
|
|
837
841
|
for gid in sorted(recs.keys()):
|
|
838
842
|
fields = recs[gid]
|
|
839
843
|
dtype = str(fields.get("TYPE") or "").strip().lower()
|
|
@@ -852,22 +856,14 @@ def _write_device_records(recs: Dict[int, Dict[str, Any]]) -> None:
|
|
|
852
856
|
"init": init,
|
|
853
857
|
}
|
|
854
858
|
)
|
|
855
|
-
order = ["TYPE", "NAME", "IDENT_KIND", "IDENT"]
|
|
856
|
-
for f in order:
|
|
857
|
-
if f in fields and fields[f] != "":
|
|
858
|
-
out[f"DEVICE_{gid}_{f}"] = str(fields[f])
|
|
859
|
-
for f in sorted(fields.keys()):
|
|
860
|
-
if f in order or f == "INIT":
|
|
861
|
-
continue
|
|
862
|
-
if fields[f] != "":
|
|
863
|
-
out[f"DEVICE_{gid}_{f}"] = str(fields[f])
|
|
864
859
|
_cfg_dir().mkdir(parents=True, exist_ok=True)
|
|
865
860
|
_devices_yaml_path().write_text(
|
|
866
861
|
yaml.safe_dump({"devices": devices}, sort_keys=False),
|
|
867
862
|
encoding="utf-8",
|
|
868
863
|
)
|
|
869
|
-
#
|
|
870
|
-
|
|
864
|
+
# Once a legacy inventory has been migrated successfully, remove it so
|
|
865
|
+
# there is exactly one authoritative device manifest.
|
|
866
|
+
_devices_env_path().unlink(missing_ok=True)
|
|
871
867
|
|
|
872
868
|
|
|
873
869
|
def _device_add_pluto(spec: str) -> int:
|
|
@@ -894,14 +890,14 @@ def _device_add_pluto(spec: str) -> int:
|
|
|
894
890
|
return 2
|
|
895
891
|
|
|
896
892
|
recs[gid] = {
|
|
897
|
-
"TYPE": "
|
|
893
|
+
"TYPE": "adalm_pluto",
|
|
898
894
|
"NAME": name,
|
|
899
895
|
"IDENT_KIND": "iio_serial",
|
|
900
896
|
"IDENT": iio_serial,
|
|
901
897
|
}
|
|
902
898
|
_write_device_records(recs)
|
|
903
899
|
|
|
904
|
-
print(f"Added device: {gid} type=
|
|
900
|
+
print(f"Added device: {gid} type=adalm_pluto name={name} iio_serial={iio_serial}")
|
|
905
901
|
return 0
|
|
906
902
|
|
|
907
903
|
|
|
@@ -59,6 +59,30 @@ class CertificateProviderTests(unittest.TestCase):
|
|
|
59
59
|
self.assertEqual(served, ca_pem)
|
|
60
60
|
self.assertNotEqual(served, leaf_pem)
|
|
61
61
|
|
|
62
|
+
def test_missing_tls_guidance_is_visible_and_uses_serverrf(self):
|
|
63
|
+
from remoteRF_server.server import grpc_server
|
|
64
|
+
|
|
65
|
+
cert_dir = Path("/tmp/remoterf-test-certs")
|
|
66
|
+
error = FileNotFoundError("missing server.key")
|
|
67
|
+
with patch.object(grpc_server, "printf") as mock_printf:
|
|
68
|
+
grpc_server._print_tls_credentials_error(cert_dir, error)
|
|
69
|
+
|
|
70
|
+
rendered = [call.args for call in mock_printf.call_args_list]
|
|
71
|
+
self.assertEqual(
|
|
72
|
+
[message for message, _style in rendered],
|
|
73
|
+
[
|
|
74
|
+
"TLS certs/keys not found or unreadable.",
|
|
75
|
+
f"Expected in: {cert_dir}",
|
|
76
|
+
f"Fix: run serverrf --gen-certs {grpc_server.local_ip} --force",
|
|
77
|
+
"Or set REMOTERF_CERT_DIR to your cert folder.",
|
|
78
|
+
"Details: missing server.key",
|
|
79
|
+
],
|
|
80
|
+
)
|
|
81
|
+
self.assertTrue(
|
|
82
|
+
all(style is grpc_server.Sty.MAGENTA for _message, style in rendered)
|
|
83
|
+
)
|
|
84
|
+
self.assertNotIn("RRRFcerts", "\n".join(message for message, _style in rendered))
|
|
85
|
+
|
|
62
86
|
|
|
63
87
|
if __name__ == "__main__":
|
|
64
88
|
unittest.main()
|
|
@@ -7,6 +7,7 @@ from pathlib import Path
|
|
|
7
7
|
from unittest.mock import patch
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
|
+
import yaml
|
|
10
11
|
|
|
11
12
|
from remoteRF_server import serverrf_cli
|
|
12
13
|
from remoteRF_server.common.grpc import grpc_pb2
|
|
@@ -875,7 +876,7 @@ class DynamicV2ServerTests(unittest.TestCase):
|
|
|
875
876
|
entry.active_operation = ""
|
|
876
877
|
manager.close_all()
|
|
877
878
|
|
|
878
|
-
def
|
|
879
|
+
def test_usrp_cli_writes_only_canonical_yaml_inventory(self):
|
|
879
880
|
with tempfile.TemporaryDirectory() as tmp:
|
|
880
881
|
with patch.dict(
|
|
881
882
|
os.environ,
|
|
@@ -894,7 +895,72 @@ class DynamicV2ServerTests(unittest.TestCase):
|
|
|
894
895
|
records = serverrf_cli._read_device_records()
|
|
895
896
|
self.assertEqual(records[7]["TYPE"], "usrp")
|
|
896
897
|
self.assertEqual(records[7]["IDENT"], "31A2B3C")
|
|
897
|
-
self.
|
|
898
|
+
self.assertFalse(Path(tmp, "devices.env").exists())
|
|
899
|
+
|
|
900
|
+
def test_pluto_cli_uses_registered_adalm_pluto_device_type(self):
|
|
901
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
902
|
+
with patch.dict(
|
|
903
|
+
os.environ,
|
|
904
|
+
{"REMOTERF_CONFIG_DIR": tmp},
|
|
905
|
+
clear=False,
|
|
906
|
+
):
|
|
907
|
+
self.assertEqual(
|
|
908
|
+
serverrf_cli._device_add_pluto("1:Pluto A:104473f6"),
|
|
909
|
+
0,
|
|
910
|
+
)
|
|
911
|
+
inventory = Path(tmp, "devices.yml")
|
|
912
|
+
text = inventory.read_text(encoding="utf-8")
|
|
913
|
+
self.assertIn("device_type: adalm_pluto", text)
|
|
914
|
+
self.assertIn("serial: 104473f6", text)
|
|
915
|
+
records = serverrf_cli._read_device_records()
|
|
916
|
+
self.assertEqual(records[1]["TYPE"], "adalm_pluto")
|
|
917
|
+
self.assertEqual(records[1]["IDENT"], "104473f6")
|
|
918
|
+
self.assertEqual(records[1]["IDENT_KIND"], "iio_serial")
|
|
919
|
+
self.assertFalse(Path(tmp, "devices.env").exists())
|
|
920
|
+
|
|
921
|
+
def test_device_cli_migrates_legacy_env_inventory_to_yaml(self):
|
|
922
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
923
|
+
with patch.dict(
|
|
924
|
+
os.environ,
|
|
925
|
+
{"REMOTERF_CONFIG_DIR": tmp},
|
|
926
|
+
clear=False,
|
|
927
|
+
):
|
|
928
|
+
Path(tmp, "devices.env").write_text(
|
|
929
|
+
"DEVICE_1_TYPE=adalm_pluto\n"
|
|
930
|
+
"DEVICE_1_NAME=Pluto A\n"
|
|
931
|
+
"DEVICE_1_IDENT_KIND=iio_serial\n"
|
|
932
|
+
"DEVICE_1_IDENT=104473f6\n",
|
|
933
|
+
encoding="utf-8",
|
|
934
|
+
)
|
|
935
|
+
|
|
936
|
+
self.assertEqual(
|
|
937
|
+
serverrf_cli._device_add_usrp("7:lab_usrp:31A2B3C"),
|
|
938
|
+
0,
|
|
939
|
+
)
|
|
940
|
+
|
|
941
|
+
inventory = yaml.safe_load(
|
|
942
|
+
Path(tmp, "devices.yml").read_text(encoding="utf-8")
|
|
943
|
+
)
|
|
944
|
+
self.assertEqual(
|
|
945
|
+
inventory,
|
|
946
|
+
{
|
|
947
|
+
"devices": [
|
|
948
|
+
{
|
|
949
|
+
"device_id": 1,
|
|
950
|
+
"device_type": "adalm_pluto",
|
|
951
|
+
"name": "Pluto A",
|
|
952
|
+
"init": {"serial": "104473f6"},
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
"device_id": 7,
|
|
956
|
+
"device_type": "usrp",
|
|
957
|
+
"name": "lab_usrp",
|
|
958
|
+
"init": {"serial": "31A2B3C"},
|
|
959
|
+
},
|
|
960
|
+
]
|
|
961
|
+
},
|
|
962
|
+
)
|
|
963
|
+
self.assertFalse(Path(tmp, "devices.env").exists())
|
|
898
964
|
|
|
899
965
|
def test_server_cli_exposes_headless_runtime(self):
|
|
900
966
|
with (
|
|
@@ -12,6 +12,7 @@ sys.modules.setdefault("adi", types.ModuleType("adi"))
|
|
|
12
12
|
from remoteRF_server.common.idl.pluto_schema import PlutoSchema
|
|
13
13
|
from remoteRF_server.common.utils import map_arg, unmap_arg
|
|
14
14
|
from remoteRF_server.drivers.adalm_pluto.pluto_remote_server import PlutoServer
|
|
15
|
+
from remoteRF_server.server import device_manager
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class FakePluto:
|
|
@@ -79,6 +80,20 @@ class PlutoCompatTests(unittest.TestCase):
|
|
|
79
80
|
self.assertIsNone(schema.dispatch("call_tx", {"value": samples}))
|
|
80
81
|
np.testing.assert_allclose(self.device.tx_samples, samples)
|
|
81
82
|
|
|
83
|
+
def test_legacy_pluto_inventory_type_resolves_to_packaged_schema(self) -> None:
|
|
84
|
+
with patch.object(PlutoSchema, "make_device", return_value=self.device):
|
|
85
|
+
schema, ident, dtype = device_manager._connect_from_record(
|
|
86
|
+
{
|
|
87
|
+
"TYPE": "pluto",
|
|
88
|
+
"IDENT": "104473f6",
|
|
89
|
+
"INIT": {"serial": "104473f6"},
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
self.assertIsInstance(schema, PlutoSchema)
|
|
94
|
+
self.assertEqual(ident, "104473f6")
|
|
95
|
+
self.assertEqual(dtype, "adalm_pluto")
|
|
96
|
+
|
|
82
97
|
|
|
83
98
|
if __name__ == "__main__":
|
|
84
99
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/grpc_host_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/device_schema.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/pluto_mimo_schema.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/idl/pluto_schema.py
RENAMED
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/__init__.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/ansi_codes.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/api_token.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/db_connection.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/db_location.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/list_string.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/common/utils/process_arg.py
RENAMED
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/adalm_pluto/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/usrp/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/usrp/uhd_manifest.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/drivers/usrp/usrp_schema.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/host/host_directory_store.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/host/host_tunnel_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/user_group_cli.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/server/user_group_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server/tools/gist_status_testing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{remoterf_server-1.0.3 → remoterf_server-1.0.4}/src/remoteRF_server.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|