summaryrefslogtreecommitdiff
path: root/lib9p
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-01-09 23:29:30 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-01-11 23:33:26 -0700
commitf6b4897e86ee68836794caa641cf0d4a93131c0f (patch)
tree34f0bb918db3506c88d2034b6b4bf73b7f9d1db8 /lib9p
parent1dcc029b2d25dc2d337de00262dfedecb7aa7fd1 (diff)
mv cmd/srv9p lib9p/tests/test_server # and supporting changes
Diffstat (limited to 'lib9p')
-rw-r--r--lib9p/CMakeLists.txt6
-rw-r--r--lib9p/tests/test_server/CMakeLists.txt42
-rw-r--r--lib9p/tests/test_server/config/config.h60
-rw-r--r--lib9p/tests/test_server/main.c129
-rw-r--r--lib9p/tests/test_server/static/Documentation/x1
-rw-r--r--lib9p/tests/test_server/static/README.md1
6 files changed, 238 insertions, 1 deletions
diff --git a/lib9p/CMakeLists.txt b/lib9p/CMakeLists.txt
index 488cff9..86fde39 100644
--- a/lib9p/CMakeLists.txt
+++ b/lib9p/CMakeLists.txt
@@ -1,6 +1,6 @@
# lib9p/CMakeLists.txt - TODO
#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
add_library(lib9p INTERFACE)
@@ -15,3 +15,7 @@ target_link_libraries(lib9p INTERFACE
libmisc
libhw
)
+
+if (ENABLE_TESTS)
+ add_subdirectory(tests/test_server)
+endif()
diff --git a/lib9p/tests/test_server/CMakeLists.txt b/lib9p/tests/test_server/CMakeLists.txt
new file mode 100644
index 0000000..a107b75
--- /dev/null
+++ b/lib9p/tests/test_server/CMakeLists.txt
@@ -0,0 +1,42 @@
+# lib9p/tests/test_server/CMakeLists.txt - Build script for test_server executable
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+if (PICO_PLATFORM STREQUAL "host")
+
+# Compile ######################################################################
+
+add_library(test_server_objs OBJECT
+ main.c
+)
+target_include_directories(test_server_objs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config)
+target_include_directories(test_server_objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(test_server_objs
+ libcr
+ libcr_ipc
+ libmisc
+ lib9p
+ lib9p_util
+)
+
+# Analyze the stack ############################################################
+
+add_stack_analysis(test_server_stack.c test_server_objs)
+
+# Link #########################################################################
+
+add_executable(test_server)
+target_sources(test_server PRIVATE
+ test_server_stack.c
+ "$<TARGET_OBJECTS:test_server_objs>"
+)
+
+# Embed ########################################################################
+
+target_embed_sources(test_server_objs test_server static.h
+ static/README.md
+ static/Documentation/x
+)
+
+endif()
diff --git a/lib9p/tests/test_server/config/config.h b/lib9p/tests/test_server/config/config.h
new file mode 100644
index 0000000..4f8384e
--- /dev/null
+++ b/lib9p/tests/test_server/config/config.h
@@ -0,0 +1,60 @@
+/* config.h - Compile-time configuration for srv9p
+ *
+ * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+#define CONFIG_SRV9P_NUM_CONNS 8
+
+/* 9P *************************************************************************/
+
+#define CONFIG_9P_PORT 564
+/**
+ * This max-msg-size is sized so that a Twrite message can return
+ * 8KiB of data.
+ *
+ * This is the same as the default in Plan 9 4e's lib9p; it has the
+ * comment that "24" is "ample room for Twrite/Rread header
+ * (iounit)". In fact, the Twrite header is only 23 bytes
+ * ("size[4] Twrite[1] tag[2] fid[4] offset[8] count[4]") and the
+ * Rread header is even shorter at 11 bytes ("size[4] Rread[1]
+ * tag[2] count[4]"), so "24" appears to be the size of the Twrite
+ * header rounded up to a nice round number.
+ *
+ * In older versions of 9P ("9P1"), the max message size was
+ * defined as part of the protocol specification rather than
+ * negotiated. In Plan 9 1e it was (8*1024)+128, and was bumped to
+ * (8*1024)+160 in 2e and 3e.
+ */
+#define CONFIG_9P_MAX_MSG_SIZE ((4*1024)+24)
+/**
+ * Maximum host-data-structure size. A message may be larger in
+ * unmarshaled-host-structures than marshaled-net-bytes due to (1)
+ * struct padding, (2) nul-terminator byes for strings.
+ */
+#define CONFIG_9P_MAX_HOSTMSG_SIZE CONFIG_9P_MAX_MSG_SIZE+16
+#define CONFIG_9P_MAX_FIDS 16
+#define CONFIG_9P_MAX_REQS 2
+#define CONFIG_9P_MAX_ERR_SIZE 128 /* 128 is what Plan 9 4e uses */
+#define CONFIG_9P_ENABLE_9P2000 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */
+#define CONFIG_9P_ENABLE_9P2000_e 0 /* bool */
+
+/* COROUTINE ******************************************************************/
+
+#define CONFIG_COROUTINE_DEFAULT_STACK_SIZE (32*1024)
+#define CONFIG_COROUTINE_NAME_LEN 16
+#define CONFIG_COROUTINE_MEASURE_STACK 1 /* bool */
+#define CONFIG_COROUTINE_PROTECT_STACK 1 /* bool */
+#define CONFIG_COROUTINE_DEBUG 0 /* bool */
+#define CONFIG_COROUTINE_VALGRIND 1 /* bool */
+#define CONFIG_COROUTINE_GDB 1 /* bool */
+#define CONFIG_COROUTINE_NUM (1 /* usb_common */ +\
+ 1 /* usb_keyboard */ +\
+ CONFIG_SRV9P_NUM_CONNS /* accept+read */ +\
+ (CONFIG_9P_MAX_REQS*CONFIG_SRV9P_NUM_CONNS) /* work+write */ )
+
+#endif /* _CONFIG_H_ */
diff --git a/lib9p/tests/test_server/main.c b/lib9p/tests/test_server/main.c
new file mode 100644
index 0000000..adeba38
--- /dev/null
+++ b/lib9p/tests/test_server/main.c
@@ -0,0 +1,129 @@
+/* lib9p/tests/test_server/main.c - Main entry point for test 9P server
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <error.h>
+
+#include <lib9p/srv.h>
+#include <libcr/coroutine.h>
+#include <libhw/generic/net.h>
+#include <libhw/generic/alarmclock.h>
+#include <libhw/host_net.h>
+#include <libmisc/macro.h>
+#include <util9p/static.h>
+
+#include "static.h"
+
+/* configuration **************************************************************/
+
+#include "config.h"
+
+#ifndef CONFIG_SRV9P_NUM_CONNS
+ #error config.h must define CONFIG_SRV9P_NUM_CONNS
+#endif
+
+/* implementation *************************************************************/
+
+/* file tree ******************************************************************/
+
+#define FILE_COMMON(NAME) { \
+ .vtable = &util9p_static_file_vtable, \
+ \
+ .u_name = "root", .u_num = 0, /* owner user */ \
+ .g_name = "root", .g_num = 0, /* owner group */ \
+ .m_name = "root", .m_num = 0, /* last-modified-by user */ \
+ \
+ .pathnum = __COUNTER__, \
+ .name = NAME, \
+ .perm = 0444, \
+ .atime = 1728337905, \
+ .mtime = 1728337904, \
+ }
+
+#define DIR_COMMON(NAME) { \
+ .vtable = &util9p_static_dir_vtable, \
+ \
+ .u_name = "root", .u_num = 0, /* owner user */ \
+ .g_name = "root", .g_num = 0, /* owner group */ \
+ .m_name = "root", .m_num = 0, /* last-modified-by user */ \
+ \
+ .pathnum = __COUNTER__, \
+ .name = NAME, \
+ .perm = 0555, \
+ .atime = 1728337905, \
+ .mtime = 1728337904, \
+ }
+
+#define STATIC_FILE(STRNAME, SYMNAME) \
+ &((static struct util9p_static_file){ \
+ ._util9p_static_common = FILE_COMMON(STRNAME), \
+ .data_start = _binary_static_##SYMNAME##_start, \
+ .data_end = _binary_static_##SYMNAME##_end, \
+ })
+
+static struct util9p_static_dir root = {
+ ._util9p_static_common = DIR_COMMON(""),
+ .members = {
+ &((static struct util9p_static_dir){
+ ._util9p_static_common = DIR_COMMON("Documentation"),
+ .members = {
+ STATIC_FILE("x", Documentation_x),
+ NULL
+ },
+ }),
+ STATIC_FILE("README.md", README_md),
+ NULL,
+ },
+};
+
+static implements_lib9p_srv_file *get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), char *LM_UNUSED(treename)) {
+ return &root;
+}
+
+/* main ***********************************************************************/
+
+static COROUTINE read_cr(void *_srv) {
+ struct lib9p_srv *srv = _srv;
+ assert(srv);
+
+ cr_begin();
+
+ struct hostnet_tcp_listener listener;
+ hostnet_tcp_listener_init(&listener, 9000);
+
+ lib9p_srv_read_cr(srv, &listener);
+
+ cr_end();
+}
+
+const char *hexdig = "0123456789abcdef";
+
+struct lib9p_srv srv = {
+ .rootdir = get_root,
+};
+
+static COROUTINE init_cr(void *) {
+ cr_begin();
+
+ for (int i = 0; i < CONFIG_SRV9P_NUM_CONNS; i++) {
+ char name[] = {'r', 'e', 'a', 'd', '-', hexdig[i], '\0'};
+ if (!coroutine_add(name, read_cr, &srv))
+ error(1, 0, "coroutine_add(read_cr, &srv)");
+ sleep_for_s(1);
+ }
+ for (int i = 0; i < 2*CONFIG_SRV9P_NUM_CONNS; i++) {
+ char name[] = {'w', 'r', 'i', 't', 'e', '-', hexdig[i], '\0'};
+ if (!coroutine_add(name, lib9p_srv_write_cr, &srv))
+ error(1, 0, "coroutine_add(lib9p_srv_write_cr, &srv)");
+ sleep_for_s(1);
+ }
+
+ cr_exit();
+}
+
+int main() {
+ coroutine_add("init", init_cr, NULL);
+ coroutine_main();
+}
diff --git a/lib9p/tests/test_server/static/Documentation/x b/lib9p/tests/test_server/static/Documentation/x
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/lib9p/tests/test_server/static/Documentation/x
@@ -0,0 +1 @@
+foo
diff --git a/lib9p/tests/test_server/static/README.md b/lib9p/tests/test_server/static/README.md
new file mode 100644
index 0000000..af5626b
--- /dev/null
+++ b/lib9p/tests/test_server/static/README.md
@@ -0,0 +1 @@
+Hello, world!