pw_system: Add RPC test runner to demo
Registers the unit test handler in the pw_system demo application, and
links in a couple tests to demonstrate running unit tests.
Change-Id: I0ed92f71cfdf17b7edf8cb15e4293eaea3de712d
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/95362
Reviewed-by: Anthony DiGirolamo <tonymd@google.com>
Pigweed-Auto-Submit: Armando Montanez <amontanez@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_system/BUILD.gn b/pw_system/BUILD.gn
index fd5cb5a..5d422bc 100644
--- a/pw_system/BUILD.gn
+++ b/pw_system/BUILD.gn
@@ -107,6 +107,7 @@
public_configs = [ ":public_include_path" ]
public_deps = [
":config",
+ "$dir_pw_rpc:server",
"$dir_pw_thread:thread_core",
]
}
@@ -217,6 +218,11 @@
":pw_system",
"$dir_pw_log",
"$dir_pw_thread:sleep",
+ "$dir_pw_unit_test:rpc_service",
+
+ # Adds a test that the test server can run.
+ "$dir_pw_status:status_test.lib",
+ "$dir_pw_string:string_builder_test.lib",
]
}
diff --git a/pw_system/example_user_app_init.cc b/pw_system/example_user_app_init.cc
index 93c8415..4289f8b 100644
--- a/pw_system/example_user_app_init.cc
+++ b/pw_system/example_user_app_init.cc
@@ -13,11 +13,19 @@
// the License.
#include "pw_log/log.h"
+#include "pw_system/rpc_server.h"
#include "pw_thread/sleep.h"
+#include "pw_unit_test/unit_test_service.h"
+
namespace pw::system {
+pw::unit_test::UnitTestService unit_test_service;
+
// This will run once after pw::system::Init() completes. This callback must
// return or it will block the work queue.
-void UserAppInit() { PW_LOG_INFO("Pigweed is fun!"); }
+void UserAppInit() {
+ PW_LOG_INFO("Pigweed is fun!");
+ GetRpcServer().RegisterService(unit_test_service);
+}
} // namespace pw::system
diff --git a/pw_system/public/pw_system/rpc_server.h b/pw_system/public/pw_system/rpc_server.h
index 3918ded..bf05fcc 100644
--- a/pw_system/public/pw_system/rpc_server.h
+++ b/pw_system/public/pw_system/rpc_server.h
@@ -16,6 +16,7 @@
#include <cstdint>
+#include "pw_rpc/server.h"
#include "pw_system/config.h"
#include "pw_thread/thread_core.h"
diff --git a/pw_system/py/BUILD.gn b/pw_system/py/BUILD.gn
index 53ee336..8e31836 100644
--- a/pw_system/py/BUILD.gn
+++ b/pw_system/py/BUILD.gn
@@ -35,6 +35,8 @@
"$dir_pw_protobuf_compiler/py",
"$dir_pw_rpc/py",
"$dir_pw_tokenizer/py",
+ "$dir_pw_unit_test:unit_test_proto.python",
+ "$dir_pw_unit_test/py",
]
inputs = []
diff --git a/pw_system/py/pw_system/console.py b/pw_system/py/pw_system/console.py
index f38b569..56d71e0 100644
--- a/pw_system/py/pw_system/console.py
+++ b/pw_system/py/pw_system/console.py
@@ -62,6 +62,7 @@
from pw_rpc.console_tools.console import flattened_rpc_completions
from pw_system.device import Device
from pw_tokenizer.detokenize import AutoUpdatingDetokenizer
+from pw_unit_test_proto import unit_test_pb2
_LOG = logging.getLogger('tools')
_DEVICE_LOG = logging.getLogger('rpc_device')
@@ -171,7 +172,6 @@
help_text=__doc__,
config_file_path=config_file_path,
)
- interactive_console.hide_windows('Host Logs')
interactive_console.add_sentence_completer(completions)
if serial_debug:
interactive_console.add_bottom_toolbar(BandwidthToolbar())
@@ -250,6 +250,7 @@
# provided, and shadowing errors due to ordering when the default global
# search path is used.
compiled_protos.append(log_pb2)
+ compiled_protos.append(unit_test_pb2)
protos.extend(compiled_protos)
if not protos:
diff --git a/pw_system/py/pw_system/device.py b/pw_system/py/pw_system/device.py
index 1288f68..5a99bfc 100644
--- a/pw_system/py/pw_system/device.py
+++ b/pw_system/py/pw_system/device.py
@@ -21,12 +21,12 @@
from pw_hdlc.rpc import HdlcRpcClient, default_channels
import pw_log_tokenized
-
from pw_log.proto import log_pb2
from pw_rpc import callback_client, console_tools
from pw_status import Status
from pw_tokenizer.detokenize import Detokenizer
from pw_tokenizer.proto import decode_optionally_tokenized
+import pw_unit_test.rpc
# Internal log for troubleshooting this tool (the console).
_LOG = logging.getLogger('tools')
@@ -79,6 +79,10 @@
"""Returns an object for accessing services on the specified channel."""
return next(iter(self.client.client.channels())).rpcs
+ def run_tests(self, timeout_s: Optional[float] = 5) -> bool:
+ """Runs the unit tests on this device."""
+ return pw_unit_test.rpc.run_tests(self.rpcs, timeout_s=timeout_s)
+
def listen_to_log_stream(self):
"""Opens a log RPC for the device's unrequested log stream.
diff --git a/targets/host_device_simulator/target_docs.rst b/targets/host_device_simulator/target_docs.rst
index 494a4b9..43bf9bd 100644
--- a/targets/host_device_simulator/target_docs.rst
+++ b/targets/host_device_simulator/target_docs.rst
@@ -39,3 +39,19 @@
To communicate with the launched process, use
``pw-system-console -s localhost:33000 --proto-globs pw_rpc/echo.proto``.
+
+In the bottom-most pane labeled ``Python Repl``, you'll now be able to send RPC
+commands to the simulated device process. For example, you can send an RPC
+message that will be echoed back:
+
+.. code:: sh
+
+ >>> device.rpcs.pw.rpc.EchoService.Echo(msg='Hello, world!')
+ (Status.OK, pw.rpc.EchoMessage(msg='Hello, world!'))
+
+Or run unit tests included on the simulated device:
+
+.. code:: sh
+
+ >>> device.run_tests()
+ True