From af1e43d2ede83d6d961421454cdcdbf7d0cd41e1 Mon Sep 17 00:00:00 2001 From: Paran Lee Date: Sun, 10 Dec 2023 13:11:10 +0900 Subject: [PATCH] tests: Add Rust basic testcase Add Rust-lang abc test for rust uftrace supports. Signed-off-by: Paran Lee Co-authored-by: Michelle Jin Reviewed-by: Gichoel Choi --- tests/r001_basic.py | 56 ++++++++++++++++++++++++++++++++++++ tests/runtest.py | 70 +++++++++++++++++++++++++++++++++++++++++++++ tests/s-abc.rs | 17 +++++++++++ 3 files changed, 143 insertions(+) create mode 100644 tests/r001_basic.py create mode 100644 tests/s-abc.rs diff --git a/tests/r001_basic.py b/tests/r001_basic.py new file mode 100644 index 000000000..006972f98 --- /dev/null +++ b/tests/r001_basic.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python + +from runtest import RustTestBase + +class TestCase(RustTestBase): + def __init__(self): + RustTestBase.__init__(self, 'abc', """ +# DURATION TID FUNCTION + 1.852 us [1008471] | getauxval(); + 0.204 us [1008471] | getauxval(); + 0.203 us [1008471] | getauxval(); + [1008471] | std::rt::lang_start() { + 14.260 us [1008471] | poll(); + 5.056 us [1008471] | signal(); + 2.759 us [1008471] | sigaction(); + 2.426 us [1008471] | sigaction(); + 2.537 us [1008471] | sigaction(); + 2.722 us [1008471] | sigaltstack(); + 0.408 us [1008471] | sysconf(); + 13.907 us [1008471] | mmap64(); + 0.260 us [1008471] | sysconf(); + 26.444 us [1008471] | mprotect(); + 0.296 us [1008471] | sysconf(); + 2.019 us [1008471] | sigaltstack(); + 0.185 us [1008471] | sysconf(); + 0.278 us [1008471] | pthread_self(); + 618.405 us [1008471] | pthread_getattr_np(); + 0.389 us [1008471] | pthread_attr_getstack(); + 0.371 us [1008471] | pthread_attr_destroy(); + 0.166 us [1008471] | malloc(); + 0.389 us [1008471] | malloc(); + 4.241 us [1008471] | __cxa_thread_atexit_impl(); + [1008471] | std::rt::lang_start::_{{closure}}() { + [1008471] | std::sys_common::backtrace::__rust_begin_short_backtrace() { + [1008471] | core::ops::function::FnOnce::call_once() { + [1008471] | s_abc::main() { + [1008471] | s_abc::a() { + [1008471] | s_abc::b() { + [1008471] | s_abc::c() { + 2.389 us [1008471] | getpid(); + 4.630 us [1008471] | } /* s_abc::c */ + 5.148 us [1008471] | } /* s_abc::b */ + 5.500 us [1008471] | } /* s_abc::a */ + 5.889 us [1008471] | } /* s_abc::main */ + 6.426 us [1008471] | } /* core::ops::function::FnOnce::call_once */ + 6.908 us [1008471] | } /* std::sys_common::backtrace::__rust_begin_short_backtrace */ + 0.111 us [1008471] | _<()>::report(); + 8.037 us [1008471] | } /* std::rt::lang_start::_{{closure}} */ + 2.408 us [1008471] | sigaltstack(); + 0.259 us [1008471] | sysconf(); + 0.167 us [1008471] | sysconf(); + 41.648 us [1008471] | munmap(); + 780.960 us [1008471] | } /* std::rt::lang_start */ + 0.259 us [1008471] | free(); + 0.166 us [1008471] | free(); +""") diff --git a/tests/runtest.py b/tests/runtest.py index 6460fc9df..1dbb780d7 100755 --- a/tests/runtest.py +++ b/tests/runtest.py @@ -69,6 +69,8 @@ class TestBase: supported_lang = { 'C': { 'cc': 'gcc', 'flags': 'CFLAGS', 'ext': '.c' }, 'C++': { 'cc': 'g++', 'flags': 'CXXFLAGS', 'ext': '.cpp' }, + # https://github.com/emosenkis/esp-rs/issues/10 + 'Rust': { 'cc': 'rustc', 'flags': "+nightly -Z instrument-mcount -C passes=ee-instrument ", 'ext': '.rs' }, } TEST_SUCCESS = 0 @@ -714,6 +716,22 @@ def __init__(self, name, result, lang='Python', cflags='', ldflags='', sort='sim if orig_path != "": os.environ["PYTHONPATH"] += ':' + orig_path +class RustTestBase(TestBase): + def __init__(self, name, result, lang='Rust', cflags='', ldflags='', sort='simple', serial=False): + TestBase.__init__(self, name, result, lang, cflags, ldflags, sort, serial) + + def build(self, name, rflags='', ldflags=''): + + lang = TestBase.supported_lang[self.lang] + prog = 't-' + name + src = 's-' + name + ".rs" + rflags = self.supported_lang['Rust']['flags'] + + build_cmd = '%s %s -o %s %s' % (lang['cc'], rflags, prog, src) + + self.pr_debug("build command: %s" % build_cmd) + return self.build_it(build_cmd) + RED = '\033[1;31m' GREEN = '\033[1;32m' YELLOW = '\033[1;33m' @@ -780,6 +798,18 @@ def run_python_case(T, case, timeout): ret = tc.postrun(ret) return (ret, dif) +def run_rust_case(T, case, timeout): + tc = T.TestCase() + tc.set_debug(arg.debug) + tc.set_keep(arg.keep) + ret = tc.build(tc.name, "") + ret = tc.prerun(timeout) + dif = '' + if ret == TestBase.TEST_SUCCESS: + ret, dif = tc.run(case, "", arg.diff, timeout) + ret = tc.postrun(ret) + return (ret, dif) + def run_single_case(case, flags, opts, arg, compilers): result = [] timeout = int(arg.timeout) @@ -795,6 +825,11 @@ def run_single_case(case, flags, opts, arg, compilers): result.append((ret, dif)) continue + if compiler == 'rustc': + ret, dif = run_rust_case(T, case, timeout) + result.append((ret, dif)) + continue + for flag in flags: for opt in opts: tc = T.TestCase() @@ -910,6 +945,30 @@ def print_python_test_header(ftests): ftests.write(header2 + '\n') ftests.flush() +def print_rust_test_header(flags, ftests, compilers): + header1 = '%-24s ' % 'Compiler' + header2 = '%-24s ' % 'Runtime test case' + header3 = '-' * 24 + ':' + empty = ' ' * 100 + + for i, compiler in enumerate(compilers): + if i != 0: + header1 += ' ' + header2 += ' ' + header3 += ' ' + for flag in flags: + # align with optimization flags + header2 += ' ' + flag + header1 += ' ' + compiler + + print("") + print(header1) + print(header2) + print(header3) + ftests.write(header1 + '\n') + ftests.write(header2 + '\n') + ftests.write(header3 + '\n') + ftests.flush() def print_test_report(color, shared): success = shared.stats[TestBase.TEST_SUCCESS] + shared.stats[TestBase.TEST_SUCCESS_FIXED] @@ -962,6 +1021,8 @@ def parse_argument(): help="Hide normal results and print only abnormal results.") parser.add_argument("-P", "--python", dest='python', action='store_true', help="Run python test cases instead") + parser.add_argument("-R", "--rust", dest='rust', action='store_true', + help="Run rust test cases instead") return parser.parse_args() @@ -976,6 +1037,8 @@ def parse_argument(): if arg.cases == 'all': if arg.python: testcases = glob.glob('p???_*.py') + elif arg.rust: + testcases = glob.glob('r???_*.py') else: testcases = glob.glob('t???_*.py') else: @@ -984,6 +1047,8 @@ def parse_argument(): for case in cases: if arg.python: testcases.extend(glob.glob('p*' + case + '*.py')) + elif arg.rust: + testcases.extend(glob.glob('r*' + case + '*.py')) else: testcases.extend(glob.glob('t*' + case + '*.py')) arg.worker = min(arg.worker, len(testcases)) @@ -1029,6 +1094,9 @@ def has_compiler(compiler): compilers = [] if arg.python: compilers.append('python') + elif arg.rust: + if has_compiler('rustc') and os.system('rustup default nightly > /dev/null') == 0: + compilers.append('rustc') elif arg.compiler == 'all': for compiler in ['gcc', 'clang']: if has_compiler(compiler): @@ -1083,6 +1151,8 @@ class dotdict(dict): if arg.python: print_python_test_header(ftests) + elif arg.rust: + print_rust_test_header(flags, ftests, ['rustc']) else: print_test_header(opts, flags, ftests, compilers) diff --git a/tests/s-abc.rs b/tests/s-abc.rs new file mode 100644 index 000000000..68826e6d6 --- /dev/null +++ b/tests/s-abc.rs @@ -0,0 +1,17 @@ +use std::process; + +fn a() -> u32 { + return b(); +} + +fn b() -> u32 { + return c(); +} + +fn c() -> u32 { + return process::id(); +} + +fn main() { + a(); +}