Skip to content
Draft
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
6 changes: 5 additions & 1 deletion libos/test/ltp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ EXTRA_CFLAGS = -Wno-implicit-function-declaration
clean-extra += clean-build

.PHONY: all
all: $(INSTALLDIR)/INSTALL_SUCCESS manifests etc/nsswitch.conf etc/passwd
all: $(INSTALLDIR)/INSTALL_SUCCESS testltp manifests etc/nsswitch.conf etc/passwd

testltp: testltp.o
testltp.o: testltp.c

$(SRCDIR)/Makefile:
$(error "$(SRCDIR) is empty. Please run `git submodule update --init $(SRCDIR)` or download the LTP source code (https://github.com/linux-test-project/ltp) into $(SRCDIR).")
Expand Down Expand Up @@ -68,6 +71,7 @@ clean:
$(RM) -r \
$(BUILDDIR) \
$(INSTALLDIR) \
testltp testltp.o \
ltp*.xml \
etc/ \
.pytest_cache \
Expand Down
4 changes: 3 additions & 1 deletion libos/test/ltp/test_ltp.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ def test_ltp(cmd, section):

loader = 'gramine-sgx' if HAS_SGX else 'gramine-direct'
timeout = int(section.getfloat('timeout') * LTP_TIMEOUT_FACTOR)
full_cmd = [loader, *cmd]
env = os.getenv("LTP_ENV", None)
full_cmd = list(filter(None, [loader, env, *cmd]))

logging.info('command: %s', full_cmd)
logging.info('must_pass: %s', list(must_pass) if must_pass else 'all')
Expand Down Expand Up @@ -238,6 +239,7 @@ def pytest_generate_tests(metafunc):

def main():
if sys.argv[1:] == ['--list']:
print("testltp") # let 'gramine-test build' generate testltp.manifest
seen = set()
for _tag, cmd, section in list_tests():
executable = cmd[0]
Expand Down
32 changes: 32 additions & 0 deletions libos/test/ltp/testltp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */

/*
* The program is introduced to allow later versions of LTP (version after 20220527) can be
* tested via command: gramine-{direct|sgx} testltp <TEST_BINARY>
*/

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
if (argc < 2) {
errx(1, "Usage - testltp <ltp testcase(s)>");
}

for (int i=1; i < argc; i++) {
pid_t pid = fork();
if (pid < 0) {
err(1, "fork");
} else if (pid == 0) {
execl(argv[i], argv[i], NULL);
err(1, "execl failed");
} else {
waitpid(pid, NULL, 0);
}
}
return 0;
}
68 changes: 68 additions & 0 deletions libos/test/ltp/testltp.manifest.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (C) 2023 Gramine contributors
# SPDX-License-Identifier: BSD-3-Clause

libos.entrypoint = "/testltp"

loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/lib:/usr/lib64"
loader.env.PATH = "/bin:/usr/bin:."
loader.env.LD_PRELOAD = "{{ coreutils_libdir }}/libstdbuf.so"
loader.env._STDBUF_O = "L"
loader.insecure__use_cmdline_argv = true

fs.root.uri = "file:{{ binary_dir }}"

fs.mounts = [
{ path = "/testltp", uri = "file:testltp" },
{ path = "/etc", uri = "file:/etc" },
{ path = "/lib", uri = "file:{{ gramine.runtimedir() }}" },
{ path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" },
{ path = "/usr", uri = "file:/usr" },
{ path = "/tmp", uri = "file:/tmp" },

# many LTP multi-process tests rely on shared-memory IPC via `mmap(MAP_SHARED, </dev/shm fd>)`
{ type = "untrusted_shm", path = "/dev/shm", uri = "dev:/dev/shm" },
]

# for flock tests
sys.experimental__enable_flock = true

sys.brk.max_size = "32M"
sys.stack.size = "4M"
sgx.debug = true
sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}

# for tests that require SIGSEGV handling (e.g., setrlimit01, mmap03)
sgx.use_exinfo = true

sgx.allowed_files = [
"file:/etc",
"file:/tmp",
"file:/usr",

"dev:/dev/shm/", # for tests that rely on shared-memory IPC, see note above

"file:install/testcases/bin/execl01_child", # for execl01 test
"file:install/testcases/bin/execlp01_child", # for execlp01 test
"file:install/testcases/bin/execv01_child", # for execv01 test
"file:install/testcases/bin/execvp01_child", # for execvp01 test
]

sgx.trusted_files = [
"file:testltp",
"file:{{ gramine.runtimedir() }}/",
"file:{{ coreutils_libdir }}/libstdbuf.so",
"file:{{ binary_dir }}/",
]

# below IOCTL is for socket ioctl tests (e.g. `sockioctl01`); note that there is no additional
# sanitization of these IOCTLs but this is only for testing anyway
sys.ioctl_structs.ifconf = [
# When ifc_req is NULL, direction of ifc_len is out. Otherwise, direction is in.
{ size = 4, direction = "inout", name = "ifc_len" }, # ifc_len
{ size = 4, direction = "none" }, # padding
{ ptr = [ { size = "ifc_len", direction = "in" } ] }, # ifc_req
]

sys.allowed_ioctls = [
{ request_code = 0x8912, struct = "ifconf" }, # SIOCGIFCONF
]