LIT(1)
π lit β LLVM Integrated Tester
Bestie, welcome to LIT(1) β the manual for lit, the LLVM Integrated Tester. She's the cutest little test runner in the whole toolchain and she's about to tell you everything. Sit down, grab a matcha, let's go π
β¨ SYNOPSIS β¨
lit [options] [tests]
π DESCRIPTION π
Okay so first things first: lit is a portable tool for executing LLVM and Clang style test suites, summarizing their results, and giving you a heads-up when things fail. That's literally her whole job. She's designed to be a lightweight testing tool with a user interface that's as simple as possible β no bloat, no drama, no cap. π
You should run lit with one or more tests specified right there on the command line. Those tests can be either individual test files or directories that she'll search for tests (peep TEST DISCOVERY for the deets). π΅οΈββοΈ
Each test you specify gets executed (potentially concurrently, because she multitasks π
) and once all of them have run, lit prints summary info on how many tests passed or failed (that's TEST STATUS RESULTS, iykyk). And heads up: lit will exit with a non-zero exit code if any tests fail. So if your CI is red, that's why bestie. π
By default lit uses a succinct progress display and only prints summary information for test failures. If you wanna control the progress display and output, that's all in OUTPUT OPTIONS. ποΈ
She also ships with a bunch of options for controlling how tests are executed β though ngl, specific features may depend on the particular test format you're using. See EXECUTION OPTIONS for more. π₯
Finally, lit supports additional options for only running a subset of the tests specified on the command line. That's SELECTION OPTIONS, and it's giving "main character energy" for real. β¨
π‘ Important pipeline tea:litparses options from the environment variableLIT_OPTSafter parsing options from the command line.LIT_OPTSis primarily useful for supplementing or overriding the command-line options supplied tolitby check targets defined by a project's build system.
She can also read options from response files, which you specify as inputs using the @path/to/file.rsp syntax. Arguments read from a file must be one per line, and they're treated as if they were in the exact same place as the original file-referencing argument on the command line. And yes β a response file can reference other response files. It's response files all the way down, bestie. πͺ
If you're the kind of girlie who's interested in the lit architecture or designing a lit testing implementation, go look at LIT INFRASTRUCTURE. That's your lane. π§
πΈ GENERAL OPTIONS πΈ
-h,--helpβ Show thelithelp message and exit. The classic "hello, what do you do" move. π«Ά--versionβ Showlit's version number and exit. Gotta know which era of lit you're in. β-j N,--workers Nβ RunNtests in parallel. By default this is automatically chosen to match the number of detected available CPUs β she'll figure out your whole vibe on her own. π--config-prefix NAMEβ Search forNAME.cfgandNAME.site.cfgwhen searching for test suites, instead oflit.cfgandlit.site.cfg. Custom naming, custom queen. π-D NAME[=VALUE],--param NAME[=VALUE]β Add a user defined parameterNAMEwith the givenVALUE(or the empty string if not given). What these parameters actually mean and how they get used is totally test suite dependent, so ask your config, not me. π
π¦ OUTPUT OPTIONS π¦
-q,--quietβ Suppress any output except for test failures. Silence is golden, unless something breaks, then it's loud. π-s,--succinctβ Show less output β for example, don't show information on tests that pass. Also shows a progress bar, unless--no-progress-baris specified. Subtle. Understated. Iconic. β¨-v,--verboseβ Show more information on test failures, for example the entire test output instead of just the test result.
Each command is printed before it is executed. This can be valuable for debugging test failures, since the last printed command is the one that failed. Moreover, lit inserts 'RUN: at line N' after each command pipeline in the output to help you locate the source line of the failed command. It's giving detective energy. π
-vv,--echo-all-commandsβ Deprecated alias for-v. She's still here, but she's deprecated bestie, we don't use her anymore. π₯²-a,--show-allβ Enable-v, but for all tests, not just failed ones. All the receipts, all the time. π§Ύ-o PATH,--output PATHβ Write test results to the provided path. File her away. π--no-progress-barβ Do not use the curses based progress bar. No curses today, thank you. π«--min-output-interval INTERVALβ Only output updates to the progress bar and status line at most once perINTERVALseconds. Has no effect if the curses based progress bar is not used. Rate limiting for your eyeballs. ποΈ--show-excludedβ Show excluded tests. Let the exes be seen. π--show-skippedβ Show skipped tests. π¦--show-unsupportedβ Show unsupported tests. π§--show-passβ Show passed tests. Celebrate the wins!! π--show-flakypassβ Show passed with retry tests. She passed, but she made us nervous first. π--show-xfailβ Show expectedly failed tests. Failing on purpose is still failing, but make it fashion. π
π₯ EXECUTION OPTIONS π₯
--gtest-shardingβ Enable sharding for GoogleTest format. π°--no-gtest-shardingβ Disable sharding for GoogleTest format. π«π°--path PATHβ Specify an additionalPATHto use when searching for executables in tests. Extend her search radius. π§--vgβ Run individual tests under valgrind (using thememchecktool). The--error-exitcodeargument for valgrind is used so that valgrind failures will cause the program to exit with a non-zero status.
When this option is enabled, lit will also automatically provide a "valgrind" feature that can be used to conditionally disable (or expect failure in) certain tests. Valgrind said "let me check her" and honestly she did. π¬
--vg-leakβ When--vgis used, enable memory leak checks. When this option is enabled,litwill also automatically provide a"vg_leak"feature that can be used to conditionally disable (or expect failure in) certain tests. Drip check, but for memory. π§--vg-arg ARGβ When--vgis used, specify an additional argument to pass to valgrind itself. Give valgrind a little extra something. π--no-executeβ Don't execute any tests (assume that they pass). Manifesting a green run, no cap. π--xunit-xml-output XUNIT_XML_OUTPUTβ Write XUnit-compatible XML test reports to the specified file. π--report-failures-onlyβ Only include failures (see TEST STATUS RESULTS) in the report. We don't talk about the passes. π--resultdb-output RESULTDB_OUTPUTβ Write LuCI ResultDB compatible JSON to the specified file. π§Ύ--time-trace-output TIME_TRACE_OUTPUTβ Write Chrome tracing compatible JSON to the specified file. Chrome girlies rise. π--timeout MAXINDIVIDUALTESTTIMEβ Maximum time to spend running a single test (in seconds).0means no time limit. [Default: 0] β°--timeout Nβ Spend at mostNseconds (approximately) running each individual test.0means no time limit, and0is the default. Note that this is not an alias for--max-timeβ the two are different kinds of maximums. Don't confuse your queens. β οΈ--max-failures MAX_FAILURESβ Stop execution after the given number of failures. Set your limit, protect your peace. π--max-retries-per-test Nβ Retry running failed tests at mostNtimes. Out of the following options to rerun failed tests, the--max-retries-per-testis the only one that doesn't require a change in the test scripts or the test config:--max-retries-per-testlit optionconfig.test_retry_attemptstest suite optionALLOW_RETRIES:annotation in test script
Any option in the list above overrules its predecessor. Ranked list, top wins, periodt. π
--allow-empty-runsβ Do not fail the run if all tests are filtered out. Sometimes the vibe check filters everyone out and that's okay. π«Ά--per-test-coverageβ Emit the necessary test coverage data, divided per test case (involves setting a unique value toLLVM_PROFILE_FILEfor eachRUN). The coverage data files will be emitted in the directory specified byconfig.test_exec_root. Coverage queen behaviour fr fr. π--ignore-failβ Exit with status zero even if some tests fail. Delulu is the solulu. π--skip-test-time-recordingβ Do not track elapsed wall time for each test. β±οΈ--time-tests[=N|all]β Track the wall time individual tests take to execute and include the results in the summary output. This is useful for determining which tests in a test suite take the most time to execute. When enabled,litprints a slowest-test list and a histogram over all timed tests. The slowest-test list defaults to the 20 slowest tests, but can be limited with=Nor expanded to every timed test with=all. The headings report how many tests are listed, for exampleSlowest Tests (N of M):andTest Times (M):. Name and shame the slow ones. ππ₯
π SELECTION OPTIONS π
Okay bestie, so out of the box lit is smart about this: it runs the failing tests first, then does the rest in descending execution-time order so the concurrency gets optimized. But you can absolutely change the execution order with --order if you want to be a different kind of main character.
The timing data lives in test_exec_root in a file named .lit_test_times.txt. If that file isn't there, lit checks test_source_root for it, so clean builds can optionally get a little speed boost. No cap, that's the whole vibe.
--max-tests Nβ Run at mostNtests and then bail. That's it, that's the whole thing. π--max-time Nβ Spend at mostNseconds (approximately) running tests and then terminate. And real talk: this is not an alias for--timeoutβ those are two completely different kinds of maximums, don't get it twisted. π«Ά--order {lexical,random,smart}β Define the order in which tests are run. The supported values are:lexicalβ tests get run in lexical order according to the test file path. This option is useful when predictable test order is desired (iykyk, sometimes you just want to know exactly what's coming next).randomβ tests get run in random order. Chaos, but make it deliberate. π²smartβ tests that failed previously get run first, then the remaining tests, all in descending execution-time order. This is the default, because it optimizes concurrency. Iconic behavior honestly. π
--shuffleβ Run the tests in a random order, not failing/slowest first. Deprecated, use--orderinstead. We're retiring her, she served her time. π-i,--incrementalβ Run failed tests first. (DEPRECATED: use--order=smartβ same energy, newer packaging).--filter REGEXPβ Run only those tests whose name matches the regular expression specified in REGEXP. The environment variableLIT_FILTERcan also be used in place of this option, which is especially useful in environments where the call tolitis issued indirectly (like, when something else is doing the dialing and you can't pass flags). β¨--filter-out REGEXPβ Filter out those tests whose name matches the regular expression specified in REGEXP. The environment variableLIT_FILTER_OUTcan also be used in place of this option, which is especially useful in environments where the call tolitis issued indirectly. Bye bestie, not you. π¦--filter-failedβ Run only those tests that previously failed. Tests that have been newly added but not yet run are not included. Only the certified ex-failures get a callback. π--xfail LISTβ Treat those tests whose name is in the semicolon separated list LIST as XFAIL. This can be helpful when one does not want to modify the test suite. The environment variableLIT_XFAILcan also be used in place of this option, which is especially useful in environments where the call tolitis issued indirectly.
A test name can be specified as a file name relative to the test suite directory. For example:
LIT_XFAIL="affinity/kmp-hw-subset.c;offloading/memory_manager.cpp"
In this case, all of the following tests are treated as XFAIL:
libomp :: affinity/kmp-hw-subset.c
libomptarget :: nvptx64-nvidia-cuda :: offloading/memory_manager.cpp
libomptarget :: x86_64-pc-linux-gnu :: offloading/memory_manager.cpp
Alternatively, a test name can be specified as the full test name reported in LIT output. For example, we can adjust the previous example not to treat the nvptx64-nvidia-cuda version of offloading/memory_manager.cpp as XFAIL:
LIT_XFAIL="affinity/kmp-hw-subset.c;libomptarget :: x86_64-pc-linux-gnu :: offloading/memory_manager.cpp"
See, you can be surgical about it. Bougie. π
--xfail-not LISTβ Do not treat the specified tests as XFAIL. The environment variableLIT_XFAIL_NOTcan also be used in place of this option. The syntax is the same as for--xfailandLIT_XFAIL. And listen:--xfail-notandLIT_XFAIL_NOTalways override all other XFAIL specifications, including an--xfailappearing later on the command line. The primary purpose is to suppress anXPASSresult without modifying a test case that uses theXFAILdirective. She has final say, periodt. π--unsupported LISTβ Treat those tests whose name is in the semicolon separated list LIST as UNSUPPORTED. This can be helpful when one does not want to modify the test suite. The environment variableLIT_UNSUPPORTEDcan also be used in place of this option, which is especially useful in environments where the call tolitis issued indirectly.
The syntax for specifying test names is the same as for --xfail and LIT_XFAIL. A test name can be specified as a file name relative to the test suite directory or as the full test name reported in LIT output.
--unsupported-not LISTβ Do not treat the specified tests as UNSUPPORTED. The environment variableLIT_UNSUPPORTED_NOTcan also be used in place of this option. The syntax is the same as for--unsupportedandLIT_UNSUPPORTED. And same deal as before:--unsupported-notandLIT_UNSUPPORTED_NOTalways override all other UNSUPPORTED specifications, including an--unsupportedappearing later on the command line. π--exclude-xfailβ XFAIL tests won't be run, unless they are listed in the--xfail-not(orLIT_XFAIL_NOT) lists. Simple as that, bestie.--num-shards Mβ Divide the set of selected tests intoMequal-sized subsets or "shards", and run only one of them. Must be used with the--run-shard=Noption, which selects the shard to run. The environment variableLIT_NUM_SHARDScan also be used in place of this option. These two options provide a coarse mechanism for partitioning large testsuites, for parallel execution on separate machines (say, in a large testing farm β very farm-core, very distributed slay). π--run-shard Nβ Select which shard to run, assuming the--num-shards=Moption was provided. The two options must be used together, and the value ofNmust be in the range1..M. The environment variableLIT_RUN_SHARDcan also be used in place of this option. Teamwork makes the dream work. π«Ά
π οΈ ADDITIONAL OPTIONS π οΈ
--debugβ Runlitin debug mode, for debugging configuration issues andlititself. Turning the camera on herself, honestly. πΈ--show-suitesβ List the discovered test suites and exit. Show and tell, but make it infrastructure.--show-testsβ List all of the discovered tests and exit. Every single one, no crumbs left behind. β¨--show-used-featuresβ Show all features used in the test suite (inXFAIL,UNSUPPORTEDandREQUIRES) and exit. Receipts, basically.--update-testsβ Pass failing tests to functions in thelit_config.test_updaterslist to check whether any of them know how to update the test to make it pass. Let the updaters try to fix her up, bestie. π
πͺ EXIT STATUS πͺ
lit will exit with an exit code of 1 if there are any failures (see TEST STATUS RESULTS) and --ignore-fail has not been passed. Otherwise, it will exit with the status 0. Other exit codes are used for non-test related failures (for example, a user error or an internal program error). So like β 1 means the tests said no, 0 means we're chilling, and anything else means something else went sideways. π
π TEST DISCOVERY π
The inputs passed to lit can be either individual tests, or entire directories or hierarchies of tests to run. When lit starts up, the first thing it does is convert the inputs into a complete list of tests to run as part of test discovery. Like making a guest list before the party, except everyone's invited by default. π
In the lit model, every test must exist inside some test suite. lit resolves the inputs specified on the command line to test suites by searching upwards from the input path until it finds a lit.cfg or lit.site.cfg file. These files serve as both a marker of test suites and as configuration files which lit loads in order to understand how to find and run the tests inside the test suite. Two jobs, one outfit. π
Once lit has mapped the inputs into test suites it traverses the list of inputs, adding tests for individual files and recursively searching for tests in directories. Very thorough, very main character.
This behavior makes it easy to specify a subset of tests to run, while still allowing the test suite configuration to control exactly how tests are interpreted. In addition, lit always identifies tests by the test suite they are in, and their relative path inside the test suite. For appropriately configured projects, this allows lit to provide convenient and flexible support for out-of-tree builds. We love a flexible icon. πΈ
π TEST STATUS RESULTS π
Each test ultimately produces one of the following eight results. Eight! A whole little zodiac of outcomes:
PASSβ The test succeeded. The moment. The slay. β¨FLAKYPASSβ The test succeeded after being re-run more than once. This only applies to tests containing anALLOW_RETRIES:annotation. She's a little inconsistent but she got there in the end. πXFAILβ The test failed, but that is expected. This is used for test formats which allow specifying that a test does not currently work, but wish to leave it in the test suite. It's giving "known issue, on purpose." πXPASSβ The test succeeded, but it was expected to fail. This is used for tests which were specified as expected to fail, but are now succeeding (generally because the feature they test was broken and has been fixed). Plot twist: the failure was the imposter. πFAILβ The test failed. No notes. πUNRESOLVEDβ The test result could not be determined. For example, this occurs when the test could not be run, the test itself is invalid, or the test was interrupted. The mystery of it all. π΅οΈUNSUPPORTEDβ The test is not supported in this environment. This is used by test formats which can report unsupported tests. Not her era, not this machine's era. π¦TIMEOUTβ The test was run, but it timed out before it was able to complete. It simply ran out of time, bestie. β°
Unresolved (UNRESOLVED), timed out (TIMEOUT), failed (FAIL) and unexpectedly passed (XPASS) tests are considered failures. Yep, even the XPASS β because it was supposed to fail, and now it doesn't, and that's a whole thing.
Depending on the test format, tests may produce additional information about their status (generally only for failures). See the OUTPUT OPTIONS section for more information. π«Ά
ποΈ LIT INFRASTRUCTURE ποΈ
This section describes the lit testing architecture for users interested in creating a new lit testing implementation, or extending an existing one. So like, if you want to build your own, this is your blueprint. π§
lit proper is primarily an infrastructure for discovering and running arbitrary tests, and to expose a single convenient interface to these tests. lit itself doesn't know how to run tests β rather, this logic is defined by test suites. She's the manager, not the performer. π€
π TEST SUITES π
As described in TEST DISCOVERY, tests are always located inside a test suite. Test suites serve to define the format of the tests they contain, the logic for finding those tests, and any additional information to run the tests.
lit identifies test suites as directories containing lit.cfg or lit.site.cfg files (see also --config-prefix). Test suites are initially discovered by recursively searching up the directory hierarchy for all the input files passed on the command line. You can use --show-suites to display the discovered test suites at startup.
Once a test suite is discovered, its config file is loaded. Config files themselves are Python modules which will be executed. When the config file is executed, two important global variables are predefined. (Well β here's where this part picks up, and lit_config is the one we're meeting right now:)
lit_config
The global lit configuration object (a LitConfig instance), which defines the builtin test formats, global configuration parameters, and other helper routines for implementing test configurations. She's the one holding everything together, fr fr. π
π config π
Okay so this one is the config object β it's a TestingConfig instance for the whole test suite, and the config file is literally expected to fill it in. Obsessed. π
On top of that, these variables also live on the config object: some of them have to be set by the config, and the rest are either optional or already predefined for you. No cap:
name[required] β the name of the test suite, bestie. It shows up in reports and diagnostics, so likeβ¦ make it good? πtest_format[required] β the test format object that lit will use to discover and run the tests in this suite. Generally this is gonna be a builtin test format you can grab from thelit.formatsmodule. π§test_source_rootβ the filesystem path to the test suite root. For out-of-dir builds, this is the directory that gets scanned for tests. π¦test_exec_rootβ for out-of-dir builds, the path to the test suite root inside the object directory. This is where tests actually get run and where temporary output files get dropped. πΈenvironmentβ a dictionary representing the environment to use when executing tests in the suite. β¨standalone_testsβ when true, mark a directory with tests that are expected to be run standalone. Test discovery is disabled for that directory. And heads up:lit.suffixesandlit.excludesmust be empty when this variable is true. Fr fr, it's a rule.suffixesβ for lit test formats that scan directories for tests, this is a list of suffixes used to identify test files. Used by:ShTest. πsubstitutionsβ for lit test formats that substitute variables into a test script, this is the list of substitutions to perform. Used by:ShTest. πunsupportedβ marks a directory as unsupported, and all the tests inside it get reported as unsupported. Used by:ShTest. πparentβ the parent configuration, i.e. the config object for the directory containing the test suite, orNone. πrootβ the root configuration. This is the top-most lit configuration in the project. Main character energy honestly. πpipefailβ normally a test using a shell pipe fails if any of the commands on the pipe fail. If that's not what you want, set this variable to false and the test will fail only if the last command in the pipe fails. π«Άavailable_featuresβ a set of features you can use inXFAIL,REQUIRES, andUNSUPPORTEDdirectives. π
β¨ TEST DISCOVERY β¨
So once the test suites are located, lit goes full detective mode and recursively traverses the source directory (following test_source_root) looking for tests. π
When lit enters a sub-directory, the first thing it does is check whether a nested test suite is defined in that directory. If there is one β slay β it loads that test suite recursively. If not, it instantiates a local test config for that directory instead (peep LOCAL CONFIGURATION FILES below π).
Tests are identified by the test suite they're contained within plus the relative path inside that suite. And ngl this part is kinda important: that relative path might not refer to an actual file on disk. Some test formats (looking at you, GoogleTest) define "virtual tests" whose path contains both the path to the actual test file and a subpath identifying the virtual test. Iconic behavior, honestly. π¦
π LOCAL CONFIGURATION FILES π
When lit loads a subdirectory in a test suite, it instantiates a local test configuration by cloning the configuration for the parent directory β and the root of this configuration chain will always be a test suite. Periodt.
Once the test configuration is cloned, lit checks for a lit.local.cfg file in the subdirectory. If it's there, that file gets loaded and you can use it to specialize the configuration for each individual directory. π
So what's this facility even for? Two big ones:
- defining subdirectories of optional tests π
- changing other configuration parameters β for example, changing the test format, or changing the suffixes that identify test files β¨
π SUBSTITUTIONS π
okay so this is where it gets fun β lit lets you substitute patterns right inside your RUN commands, and it also hands you a whole starter pack of base substitutions, all defined in TestRunner.py. bestie, these are your little magic words β¨
Here's the full roster, no skips:
%sβ source path (the path to the file that's currently being run)%Sβ source dir (the directory of the file currently being run)%pβ same as%S%{pathsep}β path separator%{fs-src-root}β the root component of file system paths that point to the LLVM checkout%{fs-tmp-root}β the root component of file system paths that point to the test's temporary directory%{fs-sep}β file system path separator%tβ a path unique to the test (which may be used to make files or directories) π«Ά%basename_tβ the last path component of%tbut without the.tmpextension (deprecated, use%{t:stem}instead) β οΈ%%β literally just%%/sβ%sbut\is replaced by/%/Sβ%Sbut\is replaced by/%/pβ%pbut\is replaced by/%/tβ%tbut\is replaced by/%{s:basename}β the last path component of%s%{s:stem}β the last path component of%sbut with the last extension removed%{t:stem}β the last path component of%tbut without the.tmpextension (an alias for%basename_t)%{s:real}β%safter expanding all symbolic links and substitute drives%{S:real}β%Safter expanding all symbolic links and substitute drives%{p:real}β%pafter expanding all symbolic links and substitute drives%{t:real}β%tafter expanding all symbolic links and substitute drives%{/s:real}β%/safter expanding all symbolic links and substitute drives%{/S:real}β%/Safter expanding all symbolic links and substitute drives%{/p:real}β%/pafter expanding all symbolic links and substitute drives%{/t:real}β%/tafter expanding all symbolic links and substitute drives%{/s:regex_replacement}β%/sbut escaped for use in the replacement of as@@@command insed%{/S:regex_replacement}β%/Sbut escaped for use in the replacement of as@@@command insed%{/p:regex_replacement}β%/pbut escaped for use in the replacement of as@@@command insed%{/t:regex_replacement}β%/tbut escaped for use in the replacement of as@@@command insed%:sβ on Windows,%/sbut a:is removed if it's the second character. Otherwise,%s%:Sβ on Windows it's%/Sbut with a:yeeted off if it happens to be the second character πͺ otherwise it's%Swith one single leading/removed%:pβ on Windows,%/pwith a:removed if it's the second character; otherwise%pbut with a single leading/removed%:tβ on Windows,%/twith a:removed if it's the second character; otherwise%tbut with a single leading/removed%{readfile:<filename>}β literally just reads the file you point it at π
Other substitutions exist too, and they're all little variations on this base set, and ngl each test module can define even more substitution patterns on top of that. Peep the modules LOCAL CONFIGURATION FILES section for that tea π«
Want the full lore on substitutions? It lives in the LLVM Testing Infrastructure Guide <>.
π¦ TEST RUN OUTPUT FORMAT π¦
Okay bestie, the lit output for a test run follows this schema β and it's the same in both short and verbose modes (tho in short mode you won't see any PASS lines at all, so don't come for me when they're missing π). This schema was picked so a machine can reliably parse it (think buildbot log scraping, iykyk) and so other tools can generate it too. It's giving machine-readable and we love that for us β¨
Every test result is expected to show up on a line that matches:
<result code>: <test name> (<progress info>)
where <result-code> is a standard test result like PASS, FAIL, XFAIL, XPASS, UNRESOLVED, or UNSUPPORTED. And yes, the performance result codes IMPROVED and REGRESSED are allowed too π
The <test name> field can be literally any arbitrary string as long as it has no newline in it.
The <progress info> field is there to report progress info like (1/300), or it can just be empty β but even when it's empty the parentheses are required, so do not skip them, I'm begging π
Now, if a test is allowed retries (that's the ALLOW_RETRIES: annotation, go read it) and it needed more than one attempt to succeed, then <progress info> gets extended with this:
, <num_attempts_made> of <max_allowed_attempts> attempts
Each test result can also include extra (multiline) log info, formatted like this:
<log delineator> TEST '(<test name>)' <trailing delineator>
... log message ...
<log delineator>
where <test name> should be the name of a test that was reported earlier, <log delineator> is a string of * characters at least four characters long (the recommended length is 20), and <trailing delineator> is an arbitrary string that doesn't get parsed at all π
Here's an example test run output with four tests β A, B, C, and D β plus a log message for the failing test C:
PASS: A (1 of 4)
PASS: B (2 of 4)
FAIL: C (3 of 4)
******************** TEST 'C' FAILED ********************
Test 'C' failed as a result of exit code 1.
********************
PASS: D (4 of 4)
πΈ DEFAULT FEATURES πΈ
For convenience (because lit is a considerate icon), lit automatically adds available_features for a bunch of common use cases π
lit adds a feature based on the operating system it's being built on, for example: system-darwin, system-linux, etc. It also automatically adds a feature based on the current architecture, for example target-x86_64, target-aarch64, etc. π₯οΈ
And when you're building with sanitizers enabled, lit automatically adds the short name of the sanitizer, for example: asan, tsan, etc.
Wanna see the full list of features that can be added? Go look at llvm/utils/lit/lit/llvm/config.py β it's all in there fr fr.
π§ LIT EXAMPLE TESTS π§
The lit distribution ships with several example implementations of test suites chilling in the ExampleTests directory. Perfect for when you're like "how does any of this work" π β go read them, they ate π
π SEE ALSO π
π Author π
Maintained by the LLVM Team (https://llvm.org/).
π Copyright π
2003-2026, LLVM Project
That's the whole page bestie, you made it to the end π«Ά this was LIT(1), dated 2026-10-20 β now go write some tests, slay, and remember: no cap, the schema is there for a reason πβ¨
π¦ where this page comes from
- arch rolling: llvm 23.1.4-1 Β· Apache-2.0 WITH LLVM-exception
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms