diff --git a/content/docs/languages/_index.md b/content/docs/languages/_index.md new file mode 100644 index 00000000..6a66558f --- /dev/null +++ b/content/docs/languages/_index.md @@ -0,0 +1,15 @@ +--- +weight: 3 +bookFlatSection: true +title: "Languages" +--- + +# Languages + +This section presents language-specific tools. For each programming language we cover topics such as: + +- Advanced unit testing +- Static analysis +- Dynamic analysis + +{{< section >}} diff --git a/content/docs/languages/rust/00-unit-testing.md b/content/docs/languages/rust/00-unit-testing.md new file mode 100644 index 00000000..cbc3b451 --- /dev/null +++ b/content/docs/languages/rust/00-unit-testing.md @@ -0,0 +1,493 @@ +--- +title: "Unit testing" +slug: rust-unit-testing +summary: "This section describes tricks for Rust unit testing" +weight: 1 +--- + + +# Unit testing + +This is the most basic type of testing that every project should have. +Unit tests are easy to execute, low-effort to implement, and catch a lot of simple mistakes. + +## Installation and first steps + +The standard and ultimate tool for executing unit and integration tests for Rust codebases is `cargo test`. +The basic setup and usage of `cargo test` is well-known, so we will skip the introduction. + +You can also try [`cargo-nextest`](https://nexte.st/index.html) - a new test runner. + + +```rust +#[cfg(test)] +mod tests { + #[test] + fn true_dilemma() { + assert_ne!(true, false); + } +} +``` + + +Please note that [`docs tests` don't work in binary targets](https://github.com/rust-lang/rust/issues/50784). + +Once you have your tests written and all of them pass, let's improve. + +## Improvements + +### Randomization + +First let's make sure that tests do not depend on a global state and that there are no unwanted dependencies between them. + +For that you can run tests multiple times, taking advantage of the enabled-by-default parallel execution. However, this approach is not optimal. That is because tests are executed in basically alphabetical order, even when multi-threaded. + +Better to run tests in a random order without parallel execution. + +```sh +cargo test -- -Z unstable-options --test-threads 1 --shuffle +``` + +Execute command above multiple times. If any run reports a failed test, use the displayed "shuffle seed" to reliably repeat the error: + +```sh +cargo test -- -Z unstable-options --test-threads 1 --shuffle-seed 7331 +``` + +{{< details "Example to try" >}} + +Tests below fail randomly when run with `cargo test`. To get reproducible failure run: + +```sh +cargo test -- -Z unstable-options --test-threads 1 --shuffle-seed 1337 +``` + +```rust +fn main() { println!("Hello, world!"); } + +static mut glob_var: i32 = 2; + +unsafe fn global_var_set(arg: i32) { + glob_var = arg; +} + +#[cfg(test)] +mod tests { + use crate::{glob_var, global_var_set}; + + #[test] + fn a_true_dilemma() { + unsafe { assert_eq!(glob_var, 2); } + unsafe { global_var_set(5); } + unsafe { assert_eq!(glob_var, 5); } + assert_ne!(true, false); + } + + #[test] + fn not_true_dilemma() { + unsafe { assert_eq!(glob_var, 2); } + assert_ne!(true, false); + } +} +``` + +{{< /details >}} + +When you are happy with the results, randomize features using [`cargo hack`](https://github.com/taiki-e/cargo-hack). Start with testing your code against all the features taken separately, then combine multiple features in one run: + +```sh +cargo +stable install cargo-hack --locked +cargo hack test -Z avoid-dev-deps --each-feature +cargo hack test -Z avoid-dev-deps --feature-powerset --depth 2 +``` + +{{< details "Example to try" >}} + +The test below passes when run with `cargo test`. Also passes with `cargo hack test --each-feature`. To find the code path that makes the test fail run: + +```sh +cargo hack test --feature-powerset --depth 2 +``` + +```rust +fn main() { println!("Hello, world!"); } + +fn feauture_one() -> i32 { + #[cfg(all(feature = "fone", feature = "fthree", not(feature = "ftwo")))] + { + return 3; + } + #[cfg(feature = "fone")] { + return 1; + } + #[cfg(feature = "ftwo")] { + return 2; + } + return 0; +} + + +#[cfg(test)] +mod tests { + use crate::{feauture_one}; + + #[test] + fn feature_test1() { + let z = feauture_one(); + assert!(z < 3); + } +} +``` + +{{< /details >}} + +### Integer overflows + +While some integer overflows are detected with [the `overflow-checks` flag](https://doc.rust-lang.org/rustc/codegen-options/index.html#overflow-checks), overflows in explicit casts are not. To make our tests detect overflows in `expr as T` expressions we must use [`cast_checks`](https://github.com/trailofbits/cast_checks). + +Add relevant dependency to `Cargo.toml`: + +```toml +[dependencies] +cast_checks = "0.1.4" +``` + +Now mark functions where you expect overflows with `#[cast_checks::enable]` and run tests as always. + +Alternatively, enable `inner atributes` feature with `#![feature(custom_inner_attributes, proc_macro_hygiene)]` and put `#![cast_checks::enable]` attribute in relevant modules. When doing so add `RUSTFLAGS='--cfg procmacro2_semver_exempt'` to cargo commands. + +{{< details "Example to try" >}} + +The `int_overflow_simple` test always passes, as arithmetic overflows are detected with standard `overflow-checks`. However, to detect overflow in the `int_overflow_in_cast` we must use `cast_checks`. + +```rust +#![feature(custom_inner_attributes, proc_macro_hygiene)] + +fn main() { println!("Hello, world!"); } + +mod lib { + #![cast_checks::enable] + + pub(crate) fn do_overflow(a: i32) -> i32 { + return a * 8; + } + + pub(crate) fn as_u16(z: i32) -> u16 { + z as u16 + } +} + +#[cfg(test)] +mod tests { + use crate::{lib::as_u16, lib::do_overflow}; + + #[should_panic] + #[test] + fn int_overflow_simple() { + let y_str = "2147483647"; + let y = y_str.parse::().unwrap(); + let x = do_overflow(y); + } + + #[should_panic] + #[test] + fn int_overflow_in_cast() { + let y_str = "2147483647"; + let y = y_str.parse::().unwrap(); + println!("{}", y); + let a = as_u16(y); + } +} +``` + +{{< /details >}} + +### Sanitizers + +While Rust is memory-safe, one may open a gate to the `unsafe` world and introduce all the well known vulnerabilities like use-after-free or reading of uninitialized memory. Moreover, Rust compiler does not prevent memory leaks and data races. + +To find deep bugs we can enhance our tests with [various sanitizers](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html): + +* AddressSanitizer +* LeakSanitizer +* MemorySanitizer +* ThreadSanitizer + +To enable them: + +```sh +RUSTFLAGS='-Z sanitizer=address' cargo test +RUSTFLAGS='-Z sanitizer=leak' cargo test --target x86_64-unknown-linux-gnu +RUSTFLAGS='-Z sanitizer=memory' cargo test --target aarch64-unknown-linux-gnu +RUSTFLAGS='-Z sanitizer=thread' cargo test +``` + +Not all targets are created equal, so check which are supported by the given sanitizer. + +{{< details "Example to try" >}} + +The test below passes. But the AddressSanitizer can help us find the bug. + +```sh +RUSTFLAGS='-Z sanitizer=address' cargo test +``` + +```rust +fn main() { println!("Hello, world!"); } + +#[cfg(test)] +mod tests { + #[test] + fn uaf() { + let a = vec![7, 3, 3, 1]; + let b = a.as_ptr(); + drop(a); + let z = unsafe { *b }; + } +} +``` + +{{< /details >}} + +### Miri + +[Miri](https://github.com/rust-lang/miri) is an interpreter for Rust "mid-level intermediate representation ". You can run your tests through Miri with: + +``` +rustup +nightly component add miri +cargo miri test +``` + +Miri helps to detect: +* undefined behavior +* memory corruption bugs +* memory leaks +* uses of uninitialized data +* memory alignment issues +* issues with aliasing for reference types +* data races + +## Property testing with Proptest + +Normal unit tests are great for testing a single scenario - you test code by providing a single, specific +value and checking if the code behaves as expected. + +But instead of using a single value, you can generate a set of inputs and execute the unit test multiple times +to check if it works correctly for every input. + +Lets use [Proptest](https://github.com/proptest-rs/proptest) tool for that task. It is a tool inspired by the famous [QuickCheck](https://hackage.haskell.org/package/QuickCheck). + +### Installation + +Simply add the dev dependency to your project. Nothing more needed. + +```toml +[dev-dependencies] +proptest = "1.0.0" +``` + +### Usage + +To use Proptest you must write unit tests. But instead of hard-coding values that are used for testing, +you define *generators* for values (called "strategies" in proptest's docs). +Proptest will execute the unit test dozen of times with randomly generated values. + +Proptest ships with a dozen of [configurable strategies](https://docs.rs/proptest/latest/proptest/): +* range-like generator for `integers` +* regex generator for `strings` +* simple generators for `bits`, `bools`, `chars` +* random-size generators for `std:collections` +* generators for `Option` and `Result` + +The generators [can be combined together](https://proptest-rs.github.io/proptest/proptest/tutorial/macro-prop-compose.html). You can also use macros to do further combine and restric generation: +* do mapping with `prop_map` +* do filtering with `prop_filter` +* create enums with `prop_oneof` +* do recursion with `prop_recursive` + +Lets see an example code: + +```rust +fn simple_thingy_dingy(a: u64, b: &str) -> u64 { + return a + match b.parse::() { + Ok(x) => x, + Err(_) => b.len() as u64, + }; +} + +#[cfg(test)] +mod tests { + use crate::simple_thingy_dingy; + use proptest::prelude::*; + + proptest! { + #![proptest_config(ProptestConfig::with_cases(100))] + #[test] + fn test_simple_thingy_dingy(a in 1337..7331u64, b in "[0-9]{1,3}") { + println!("{a} | {b}"); + let sum = simple_thingy_dingy(a, &b); + assert!(sum >= a); + assert!(sum > 1337); + } + } +} +``` + +The `simple_thingy_dingy` is function we want to unit-test. For that we need to wrap a normal `#[test]` with `proptest!` helper. +Then we use two generators for `a` and `b` values: range-like for integers and regex for strings. + +Now we just need to run `cargo test` and wait for the Proptest to finish. Running `cargo test -- --show-output` +will enable us to observe what values were generated. + +By default Proptest executes an unit test 256 times, but we can change that with `ProptestConfig::with_cases`. + +If the Proptest finds an input failing the unit test, it writes the input to the `proptest-regressions` directory. + +As can be seen, we have to write a strategy for every single value we use. However, we could instead create [a strategy for a type](https://proptest-rs.github.io/proptest/proptest/tutorial/arbitrary.html) using the `Arbitrary` trait. + +{{< hint info >}} +**You can combine Proptest with other improvements** + +Using Proptest with improvements [listed above](/docs/languages/rust/unit-tests/#improvements) +can enhance your testing even further. + +To use with Proptest with Miri you have to disable persistence (the `proptest-regressions` directory): + +```sh +PROPTEST_DISABLE_FAILURE_PERSISTENCE=true \ +MIRIFLAGS='-Zmiri-env-forward=PROPTEST_DISABLE_FAILURE_PERSISTENCE' \ +cargo miri test +``` +{{< /hint >}} + + +## Coverage + +It is critically important to know how much coverage your tests have. Coverage gathering consists of three steps: + +* compile-time instrumentation +* execution of tests, producing "raw" data +* convertion of "raw" data to an usable format + +There are three common instrumentation backends (engines): + +* GCC's `gcov` + * produces `gcno` (during compilation) and `gcda` (during execution) raw data +* LLVM's `SanitizerCoverage` + * produces `profraw` raw data + * can produce `gcno`&`gcda` raw data - not supported in the tooling below +* `ptrace`-based + * produces `profraw` raw data + +There are three popular tools wrapping the above engines for easier consumption in Rust projects. +Instead of them you can directly use [the tools described in the fuzzing chapter](#) (TODO: link). + +| Feature \ Tool | [`cargo-llvm-cov`](https://github.com/taiki-e/cargo-llvm-cov) | [`cargo-tarpaulin`](https://github.com/xd009642/tarpaulin) | [`grcov`](https://github.com/mozilla/grcov) +| ----------- | ----------- | ----------- | ----------- | +| Backends | LLVM | LLVM, ptrace | LLVM, gcov | +| Coverage | Lines, functions, regions | Lines | Lines, functions, branches | +| Output format | Text, lcov, JSON, HTML, cobertura, codecov | Text, lcov, JSON, HTML, xml | Lcov, JSON, HTML, cobertura, coveralls+, markdown, ade | +| Exclude files | [`--ignore-filename-regex`](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#exclude-file-from-coverage) | `--exclude-files` | `--ignore` | +| Exclude functions | [With attributes](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#exclude-function-from-coverage) | [With attributes](https://github.com/xd009642/tarpaulin?tab=readme-ov-file#ignoring-code-in-files) | With in-code markers & regexes | +| Exclude tests' coverage | [With external module](https://github.com/taiki-e/coverage-helper/tree/v0.2.0) | `--ignore-tests` | No | +| Coverage for C/C++ | [`--include-ffi`](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#get-coverage-of-cc-code-linked-to-rust-librarybinary) | `--follow-exec` | ? | +| Merge data from multiple runs | [Yes](https://github.com/taiki-e/cargo-llvm-cov?tab=readme-ov-file#merge-coverages-generated-under-different-test-conditions) | [Yes/No](https://github.com/xd009642/tarpaulin?tab=readme-ov-file#command-line) (only shows delta) | No | + +While checking coverage statistics from a command line and using one of many coverage-visualizers, +HTML report is often what you need. + +| HTML output \ Tool | `cargo-llvm-cov` | `cargo-tarpaulin` | `grcov` | +| ----------- | ----------- | ----------- | ----------- | +| Examples | [Open `llvm-cov`](/samples_rust_coverage/llvm_cov/index.html?:), [open `llvm-cov-pretty`](/samples_rust_coverage/llvm_cov_pretty/index.html?:) | [Open `tarpaulin`](/samples_rust_coverage/tarpaulin-report.html?:) | [Open `grcov`](/samples_rust_coverage/grcov/index.html?:), [open `grcov` with `lcov`](/samples_rust_coverage/grcov_lcov/index.html?:) | +| Handles Rust's constructions | Yes | Yes | Yes | +| Expands Rust's generics | `--show-instantiations` | No | No | +| Number of hits | Yes | No | Yes | +| Multi-file output | Yes | No | Yes | + +For post-processing (generating HTML reports, like merging files from multiple runs, and excluding selected files, ..) +of `lcov` outputs you can use: +* [The `lcov` tool's `genhtml` utility](https://github.com/linux-test-project/lcov) +* [`llvm-cov-pretty`](https://github.com/dnaka91/llvm-cov-pretty) + +Our recommendations are: +* Use `cargo-llvm-cov` (with `llvm-cov-pretty`) for rapid testing: easiest to run, can resolve generics +* Use either `cargo-llvm-cov` or `grcov` for complex projects: both are decent, unique, and produce multi-file HTML output +* Use `cargo-tarpaulin` when other tools works incorrectly. [Authors claim](https://github.com/xd009642/tarpaulin?tab=readme-ov-file#nuances-with-llvm-coverage) that these can happen when: + * the code panic unexpecteadly + * there are race conditions + * the code forks + +{{< details title="Example to try" open=true >}} +Go to the [Testing Handbook's repository `samples/rust_coverage`](https://github.com/trailofbits/testing-handbook/tree/main/samples/rust_coverage/) folder. + +There you will find Dockerfile generating HTML reports using the described tools. +{{< /details >}} + + +## Validation of tests + +Who tests tests? What if your critical test has a bug that makes it to pass incorrectly? + +To find issues in your tests [use `necessist`](https://github.com/trailofbits/necessist). + +```sh +cargo install necessist +necessist +``` + +Necessist works by mutating tests - removing certain instructions from them - and executing them. +A mutated test that passed with an instruction removed is shown as: + +``` +filename:line-line `removed code` passed +``` + +It requires manual investigation if a finding really revealed a bug in a testcase (or in the code being tested). + +The tool produces a `necessist.db` file that can be used to resume an interrupted run. + +{{< details "Example to try" >}} + +Necessist should report that the `parser_detects_errors` test passes even if one line is removed from it. +It indicates that either magic number in the example or in the `validate_data` is incorrect, preventing the "real" +bug from being tested properly. + +```rust +fn validate_data(data: &Data) -> Result<(), ()> { + if !data.magic.eq(&[0x13, 0x37]) { return Err(()) } + if data.len as usize != data.content.len() { return Err(()) } + return Ok(()); +} + +struct Data { + magic: [u8; 2], + len: u8, + content: String +} + +#[cfg(test)] +mod tests { + use crate::{Data, validate_data}; + + #[test] + fn parser_detects_errors() { + let mut blob = Data{ + magic: [0x73, 0x31], + len: 2, + content: "AB".parse().unwrap(), + }; + blob.content = blob.content + "Y"; + let result = validate_data(&blob); + assert!(result.is_err()); + } +} +``` + +{{< /details >}} + +Necessist is slow and sometimes produces false positives. We recommend running it manually from time to time, instead of in a CI pipeline. The database should be kept between runs to accellerate new tests. Please report any false-positives on GitHub. + +## Resources + +* ["The Rust Programming Language", chapter 11. Testing](https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/second-edition/ch11-00-testing.html): the basics of unit and integration testing in Rust +* [Ed Page's "Iterating on Testing in Rust"](https://epage.github.io/blog/2023/06/iterating-on-test/): lists potential issues with `cargo test` and introduces `cargo-nextest` diff --git a/content/docs/languages/rust/10-static-analysis.md b/content/docs/languages/rust/10-static-analysis.md new file mode 100644 index 00000000..c62e4ea9 --- /dev/null +++ b/content/docs/languages/rust/10-static-analysis.md @@ -0,0 +1,65 @@ +--- +title: "Static analysis" +slug: rust-static-analysis +summary: "This section provides overview of static analysis tooling for Rust" +weight: 10 +--- + +# Static Analysis + +Analyze source code without executing it. + +## Clippy + +Clippy is the basic linter. Just use it. + +```sh +cargo clippy +``` + +Being pedantic won't hurt. +```sh +cargo clippy -- -W clippy::pedantic +``` + +A nice list of lints can be found at [rust-lang.github.io](https://rust-lang.github.io/rust-clippy/master/index.html). + +## Dylint + +Clippy is nice, but [creating custom lints](https://doc.rust-lang.org/nightly/clippy/development/adding_lints.html) is [a bit of a pain](https://blog.trailofbits.com/2021/11/09/write-rust-lints-without-forking-clippy/). + +To write your own lints and to take adventage of not-standarized lints of others people [use `dylint`](https://github.com/trailofbits/dylint/) - dynamic linter. + +### Quick start + +Add the following to `Cargo.toml`: + +```toml +[workspace.metadata.dylint] +libraries = [ + { git = "https://github.com/trailofbits/dylint", pattern = "examples/general/*" }, + { git = "https://github.com/trailofbits/dylint", pattern = "examples/supplementary/*" }, +] +``` + +And run: + +```sh +cargo install cargo-dylint dylint-link +cargo dylint --all --workspace +``` + +### Writing your own lints + +TODO! + +```sh +cargo dylint --new +``` + +Now implement the `LateLintPass` trait and accommodate the symbols asking to be filled in. + + +## Semgrep + +Semgrep has a beta support for Rust language. Check the [semgrep page](/docs/static-analysis/semgrep/) for more information. diff --git a/content/docs/languages/rust/20-model-checking.md b/content/docs/languages/rust/20-model-checking.md new file mode 100644 index 00000000..91dc6cc8 --- /dev/null +++ b/content/docs/languages/rust/20-model-checking.md @@ -0,0 +1,226 @@ +--- +title: "Model checking" +slug: rust-model-checking +summary: "This section lists advanced testing tools for Rust" +weight: 20 +--- + +# Model checking + +Model checking is about verification that a program works correctly for all possible inputs. + +Instead of testing with a single value (like with unit testing) or with a set of values (like with property testing) +we check all possible values - and hope that smart algorithms will make it possible to finish testing in a reasonable time. + +tldr; these tools are overkill and you don't need them. If you do, then this handbook is far too less to get you started. +But read on for a nice overview. + +## Prusti + +[Prusti](https://github.com/viperproject/prusti-dev) is based on [Viper](https://www.pm.inf.ethz.ch/research/viper.html) - a framework for building verification tools. +It uses symbolic execution and [Z3 Theorem Prover](https://github.com/Z3Prover/z3). + +### Installation + +Authors recommend using [Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=viper-admin.prusti-assistant). Command-line tools can be [downloaded from GitHub's Releases](https://github.com/viperproject/prusti-dev/releases) + + +### Usage + +You can simply run Prusti on your code and it will look for: +* absence of reachable panics +* absence of reachable, failing assertions +* absence of integer overflows + +Prusti detects all functions in a project (even unreachable ones) and checks them "independently". +It simply assumes that functions arguments can take any value - are bounded only by their types. + +Please note that Prusti [does not check testing code](https://viperproject.github.io/prusti-dev/user-guide/tour/testing.html). + +To restrict values, and to define more code's properties for verification, we have to +create specifications for functions. + +#### Function specifications + +The main power of Prusti lays in its ability to specify and validate functions' contracts (or specifications). +A function's specification consists of pre- and post-conditions. + +* Pre-conditions + * are checked *before* calls + * Prust verifies that all calls to the function are done with arguments meeting the pre-conditions + * Pre-condition limits set of possible values for post-condition checks +* Post-conditions + * are checked *after* function returns + * Prust verifies that post-conditions are meet at all exit-points of the function + +In the example below, conditions are implemented with Rust attributes: +`requires` (pre-) and `ensures` (post-). + +Prusti will check if all calls to `prusti_check` pass the argument that is less or equal to 20. + +Then it will check if possible return values from the `prusti_check` function are below 10 - assuming +the input is less or equal to 20. + +```rust +use prusti_contracts::*; +fn main() { + prusti_check(20); + prusti_check(11); +} + +#[requires(x <= 20)] +#[ensures(x < 10)] +fn prusti_check(x: u32) -> u32 { + if x >= 10 { + return x / 100; + } + return x; +} +``` + +If values violating conditions are found, Prusti retruns an error and can produce [an example set of values that demonstrate the problem](https://viperproject.github.io/prusti-dev/user-guide/verify/counterexample.html). + +{{< hint danger >}} +**Prusti does not support loops automatically** + +You have to specify [`body_invariant`s](https://viperproject.github.io/prusti-dev/user-guide/tour/loop_invariants.html) to enable code verification. +{{< /hint >}} + + +## Kani + +[Kani](https://github.com/model-checking/kani) is a frontend for [CBMC](https://www.cprover.org/cbmc/) (Bounded Model Checker for C and C++). + +### Installation + +You can [simply use cargo for installation](https://model-checking.github.io/kani/install-guide.html). + +```sh +cargo install --locked kani-verifier +cargo kani setup +``` + +### Basic usage + +Kani reasembles normal unit tests writing. You have to write a test and run + +```sh +cargo kani +``` + +However, instead of using concrete values, use `kani::any()` to create a "symbolic" (or unbounded or nondeterministic) variable. +Such variable can take any value (of its type). + +Runnig the test, Kani will verify absence of the following conditions for all poosible values +of the symbolic variables: +* failing assertions +* panics +* memory safety issues +* integer overflows + +If the code to test is too complex, Kani may take long time to finish or even not terminate at all. +To overcome this, we can use three features: + +* [`kani::assume`](https://model-checking.github.io/kani/tutorial-first-steps.html#assertions-assumptions-and-harnesses) - for restricting (bounding) symbolic values. It is a bit similar to [Prusti's pre-conditions](/docs/languages/rust/rust-advanced-testing/#function-specifications) +* [`kani::unwind`](https://model-checking.github.io/kani/tutorial-loop-unwinding.html) - for controlling bounds for loops. Kani will assume that loops can loop only the configured +amount of times. Greater the amount, slower the execution. But configuring the amount to be too small, Kani will fail too early. This is the mechanism that overcomes [Prusti's limitation with the `body_invariant`](http://localhost:1313/docs/languages/rust/rust-advanced-testing/#usage). +* [`kani::Arbitrary`](https://model-checking.github.io/kani/tutorial-nondeterministic-variables.html#custom-nondeterministic-types) - for defining per-type limitations for symbolic values + + +Lets see an example: + +```rust +pub struct Book { + title: String, + pages: u16 +} + +fn read_book(r: Book) -> u16 { + return if r.title == "The Black Book" { + 0 + } else { + let mut letters = 0; + for page in 0..r.pages { + if page == 13 { + panic!("Bad luck"); + } + letters += page; + } + letters + } +} + +#[cfg(kani)] +mod verification { + use crate::{Book, read_book}; + + impl kani::Arbitrary for Book { + fn any() -> Self { + let titles = vec!["The Black Book", "Lord of the ToB", + "The White Book"]; + let title_id: usize = kani::any(); + kani::assume(title_id < titles.len()); + Book { title: titles[title_id].to_string(), pages: kani::any() } + } + } + + #[kani::proof] + #[kani::unwind(18)] + fn verify_book() { + let book: Book = kani::any(); + kani::assume(book.pages < 4096); + let y = read_book(book); + assert!(y < 100); + } +} +``` + +Here we have a simple structure and a function that panics for some inputs. + +We define a new `verification` module under `cfg(kani)` attribute - this lets us disable Kani-specific code when +not needed. Then we implement `kani::Arbitrary` trait to tell Kani how to generate symbolic `Book`s: +by limiting set of `title`s to three possible values and using unbounded number the `pages` field. + +Then we use the `#[kani::proof]` attribute and write a test similar to normal unit tests. With three main differences: +* generating symbolic `book` variable (using our `kani::Arbitrary` implementation) +* restricting `book.pages` to be less than 4096 +* limiting amount of loops to 20 with `#[kani::unwind(20)]` + +[Kani documenatation recommends](https://model-checking.github.io/kani/tutorial-loop-unwinding.html) to set the `kani::unwind` experimentaly: +* start with a number a bit larger than the maximum of the expected numbers of all loops' repetitions +* if Kali takes too much time to finish - lower the `unwind` number +* if Kali errors out with `FAILURE: unwinding assertion loop X` - increase the `unwind` number + +If Kali found a `FAILURE`, then we can generate example values that will trigger the failure with one of two mthods: +* generating a normal unit test with `cargo kani --concrete-playback print -Z concrete-playback` +* generating a HTML report with `cargo kani --visualize --enable-unstable` + +{{< hint danger >}} +**Kali does not scale well for:** + +* strings with unbounded content (i.e., long strings with arbitrary data) +* structures of symbolic sizes that involves heap allocations +{{< /hint >}} + + +## Other model checkers + +#### [Creusot](https://github.com/xldenis/creusot) +- based on [Why3](https://why3.lri.fr/) +- allows to provide and verify functions specifications + +#### [Crux](https://github.com/GaloisInc/crucible/blob/master/crux-mir/README.md) +- symbolic analysis +- enables writing "symbolized" unit tests + +#### [Flux](https://github.com/flux-rs/flux) +- refinement type checker +- allows you to annotate functions with complex conditions + +#### [MIRAI](https://github.com/facebookexperimental/MIRAI) +- implements abstract interpretation, taint analysis, and constant time analysis + +#### [Stateright](https://www.stateright.rs/title-page.html) +- TLA+ for rust +- lets you model state machine of a system and test properties on it + diff --git a/content/docs/languages/rust/30-concurrency-testing.md b/content/docs/languages/rust/30-concurrency-testing.md new file mode 100644 index 00000000..813be514 --- /dev/null +++ b/content/docs/languages/rust/30-concurrency-testing.md @@ -0,0 +1,18 @@ +--- +title: "Concurrency testing" +slug: rust-concurrency-testing +summary: "This section lists advanced testing tools for Rust" +weight: 30 +--- + +## Concurrency testing + +#### [`Shuttle`](https://github.com/awslabs/shuttle) +- is un-sound, but is scalable +- does random testing, analogously to the property testing + +#### [`Loom`](https://docs.rs/loom/latest/loom/) +- is sound, but slow +- works analogously to model checkers + +https://github.com/BurtonQin/lockbud diff --git a/content/docs/languages/rust/40-supply-chain-analysis.md b/content/docs/languages/rust/40-supply-chain-analysis.md new file mode 100644 index 00000000..e3dfb96a --- /dev/null +++ b/content/docs/languages/rust/40-supply-chain-analysis.md @@ -0,0 +1,87 @@ +--- +title: "Supply chain analysis" +slug: rust-supply-chain-analysis +summary: "This section describes tricks for Rust unit testing" +weight: 40 +--- + +# Supply chain analysis + +## Vetting + +The tools in this section are more for "understanding" than "checking." E.g., running them does not produce "bug reports", but can help you assess maturity and security of dependencies. Tools below are rather "quantitative" than "qualitative" - you will need to do manuall, in-depth review of the outputs to extract any solid evidences about the maturity. + +This reveals who you are implicitly trusting when you rely on a dependency (e.g., you want that set to be small): +```bash +cargo-supply-chain +``` + +This checks if dependencies were audited by a "trusted party": +```bash +cargo-vet +``` + +* rust-crate-audits - collection of Google's audits + +This is a distrubuted core-review platform: +```bash +cargo-crev +``` + +Cargo plugin for linting your dependencies: +```bash +cargo-deny +``` + + + +## Looking for vulnerabilities + +The ultimate tool for detection of vulnerabilities is [`cargo-audit`]() - you should just use it. +The tool compares dependencies against a database with known vulnerabilities: + +```bash +cargo audit +``` + +### Old versions + +Even if a dependency doesn't have vulns, it's still worth knowing if it can be updated. + +For that task, you [use `cargo-outdated` tool](https://github.com/kbknapp/cargo-outdated), which lists dependencies that have newer versions available: + +```bash +cargo outdated --workspace +``` + +{{< hint info >}} +"Removed" label in the output means that the dependency would be removed from the dependency tree if its parent was updated. +{{< /hint >}} + +Another way to detect crates with newer versions available [is to use `cargo-edit`](https://github.com/killercup/cargo-edit?tab=readme-ov-file#cargo-upgrade): +```bash +cargo upgrade --incompatible --dry-run +``` + +### Divergent versions + +It may happen that your project depends on multiple different versions of the same dependency. +While that's not necessarily a security problem, it's better to limit number of divergent versions of a crate. + +To detect dependencies with multiple versions [use the `cargo-deny`](https://github.com/EmbarkStudios/cargo-deny): + +```bash +cargo deny check bans --exclude-dev +``` + +{{< hint info >}} +Look for `warning[duplicate]` outputs. +{{< /hint >}} + + +Similarly, a dependency that is obtained from multiple sources (e.g., `crates.io` and `github.com`) may indicate some issues. +To report such offending dependencies, use [cargo-vendor](https://doc.rust-lang.org/cargo/commands/cargo-vendor.html): + +```bash +cargo vendor --locked ./tmp_path +``` diff --git a/content/docs/languages/rust/_index.md b/content/docs/languages/rust/_index.md new file mode 100644 index 00000000..5a3e2c56 --- /dev/null +++ b/content/docs/languages/rust/_index.md @@ -0,0 +1,16 @@ +--- +title: "Rust" +weight: 3 +summary: "Rust is a multi-paradigm, general-purpose, memory-safe programming language." +# draft: true +# bookFlatSection: false +# bookToc: true +# bookHidden: false +bookCollapseSection: true +# bookComments: false +# bookSearchExclude: false +--- + +## Rust + +Rust is a multi-paradigm, general-purpose, memory-safe programming language. diff --git a/samples/rust_coverage/Cargo.toml b/samples/rust_coverage/Cargo.toml new file mode 100644 index 00000000..ef8459ea --- /dev/null +++ b/samples/rust_coverage/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "tmp" +version = "0.1.0" +edition = "2021" diff --git a/samples/rust_coverage/Dockerfile b/samples/rust_coverage/Dockerfile new file mode 100644 index 00000000..19a75781 --- /dev/null +++ b/samples/rust_coverage/Dockerfile @@ -0,0 +1,20 @@ +FROM rust:1.74.0-slim-bullseye + +RUN apt update +RUN apt install -y pkg-config libssl-dev lcov +RUN cargo install cargo-tarpaulin +RUN cargo install cargo-llvm-cov --locked +RUN cargo install llvm-cov-pretty +RUN rustup component add llvm-tools-preview +RUN cargo install grcov + +WORKDIR /home/test + +COPY ./Cargo.toml /home/test/ +COPY ./src /home/test/src +COPY ./get_coverage.sh /home/test/ +RUN mkdir /home/test/outputs + +RUN /bin/bash ./get_coverage.sh + +CMD /bin/bash \ No newline at end of file diff --git a/samples/rust_coverage/README.md b/samples/rust_coverage/README.md new file mode 100644 index 00000000..d46862d2 --- /dev/null +++ b/samples/rust_coverage/README.md @@ -0,0 +1,19 @@ +# Rust coverage + +A simple Rust project and a script for generating HTML coverage reports using various tools. + +Build and run docker container: +```sh +docker build -t tob_cov_test . +docker run -it --name tob_cov_test tob_cov_test bash +``` + +Copy content from the container: +```sh +docker cp tob_cov_test:/home/test/outputs . +``` + +Review results opening relevant HTML files: +```sh +find . -name 'index.html' -or -name tarpaulin-report.html +``` diff --git a/samples/rust_coverage/get_coverage.sh b/samples/rust_coverage/get_coverage.sh new file mode 100644 index 00000000..789ae3a0 --- /dev/null +++ b/samples/rust_coverage/get_coverage.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# gather coverage + +# llvm-cov +cargo llvm-cov --html --show-instantiations && \ +mv ./target/llvm-cov/html ./outputs/llvm_cov && \ +cargo clean + +cargo llvm-cov --json | llvm-cov-pretty --output-dir ./outputs/llvm_cov_pretty && \ +cargo clean + +# tarpaulin +cargo tarpaulin --ignore-tests --count --engine llvm --out html --force-clean && \ +mv tarpaulin-report.html ./outputs && \ +cargo clean + +# MUST RUN MANUALLY with insecure docker settings: +# docker run -it --security-opt seccomp=unconfined tob_cov_test bash +# cargo tarpaulin --ignore-tests --count --engine ptrace --out html --force-clean && \ +# mv tarpaulin-report.html ./outputs && \ +# cargo clean + +# grcov llvm +export RUSTFLAGS="-Cinstrument-coverage" && \ +cargo build && \ +export LLVM_PROFILE_FILE="tob_test-%p-%m.profraw" && \ +cargo test && \ +grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing -o ./outputs/grcov_llvm && \ +mkdir ./outputs/grcov_llvm_lcov && \ +grcov . -s . --binary-path ./target/debug/ -t lcov --branch --ignore-not-existing -o ./outputs/grcov_llvm_lcov && \ +genhtml -o ./outputs/grcov_llvm_lcov --show-details --highlight --ignore-errors source --legend ./outputs/grcov_llvm_lcov/lcov && \ +cargo clean && \ +find . -name '*.profraw' -exec rm '{}' \; && \ +unset LLVM_PROFILE_FILE RUSTFLAGS + +# grcov +export RUSTC_BOOTSTRAP=1 +export CARGO_INCREMENTAL=0 +export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" +export RUSTDOCFLAGS="-Cpanic=abort" +cargo build && \ +cargo test && \ +grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing -o ./outputs/grcov +mkdir ./outputs/grcov_lcov && \ +grcov . -s . --binary-path ./target/debug/ -t lcov --branch --ignore-not-existing -o ./outputs/grcov_lcov && \ +genhtml -o ./outputs/grcov_lcov --show-details --highlight --ignore-errors source --legend ./outputs/grcov_lcov/lcov \ No newline at end of file diff --git a/samples/rust_coverage/src/main.rs b/samples/rust_coverage/src/main.rs new file mode 100644 index 00000000..9ec9f3eb --- /dev/null +++ b/samples/rust_coverage/src/main.rs @@ -0,0 +1,107 @@ +mod second; + +fn main() { println!("Hello, world!"); } + +fn validate_data_simple(data: &Data) -> Result<(), ()> { + if !data.magic.eq(&[0x13, 0x37]) { return Err(()) } + if data.len as usize != data.content.len() { return Err(()) } + return Ok(()); +} + +fn validate_data_match(data: &Data) -> i32 { + let x: u32 = match data.content.parse::() { + Ok(_x) => { + let y = 2 * _x; + if y < 6 { + y + } else { + y * 2 + } + } + Err(_) => 0 + }; + if x == 0 { + -1 + } else { + (x as i32) + 1 + } +} + +// https://doc.rust-lang.org/book/ch10-01-syntax.html +fn largest(list: &[T]) -> &T { + let mut largest = &list[0]; + for item in list { + if item > largest { + largest = item; + } + } + largest +} + +fn validate_data_generics(data: &Data) { + let number_list = vec![34, 50, 25, 100, 65]; + + let result = largest(&number_list); + println!("The largest number is {}", result); + + let char_list = vec!['y', 'm', 'a', 'q']; + + let result = largest(&char_list); + println!("The largest char is {}", result); + + let result = largest(data.content.as_bytes()); + println!("The largest content char is {}", result); +} + +struct Data { + magic: [u8; 2], + len: u8, + content: String +} + +#[cfg(test)] +mod tests { + use crate::second::validate_data_panic; + use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple}; + + #[test] + fn parser_detects_errors() { + let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() }; + blob.content = blob.content + "Y"; + let result = validate_data_simple(&blob); + assert!(result.is_err()); + } + + #[test] + fn check_match() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() }; + let x = validate_data_match(&blob); + assert_eq!(x, -1); + } + + #[test] + fn check_match2() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() }; + let x = validate_data_match(&blob); + assert_eq!(x, 161); + } + + #[test] + fn check_generic() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() }; + validate_data_generics(&blob); + } + + #[test] + #[should_panic] + fn check_panic() { + let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() }; + validate_data_panic(&blob); + } + + #[test] + fn check_not_panic() { + let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() }; + validate_data_panic(&blob); + } +} \ No newline at end of file diff --git a/samples/rust_coverage/src/second.rs b/samples/rust_coverage/src/second.rs new file mode 100644 index 00000000..0f11a808 --- /dev/null +++ b/samples/rust_coverage/src/second.rs @@ -0,0 +1,7 @@ +use crate::Data; + +pub(crate) fn validate_data_panic(data: &Data) { + if data.len == 0 { + panic!("panic") + } +} \ No newline at end of file diff --git a/samples/rust_tests/Cargo.lock b/samples/rust_tests/Cargo.lock new file mode 100644 index 00000000..48bc4c54 --- /dev/null +++ b/samples/rust_tests/Cargo.lock @@ -0,0 +1,427 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast_checks" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a972b2e7af7903f86a571f50d30d4646fb750ccb294d2a79c3646b1814e503e0" +dependencies = [ + "cast_checks_convert", + "cast_checks_macro", +] + +[[package]] +name = "cast_checks_convert" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2794a887efab1c03c774eb442a710bd37a605a65fb0a608472b93a0be2ba539b" + +[[package]] +name = "cast_checks_macro" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e4ff263730893dde55b2baa124850725411705dc55e79133e6a94e1dca24cc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.166" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rust_tests" +version = "0.1.0" +dependencies = [ + "cast_checks", + "proptest", +] + +[[package]] +name = "rustix" +version = "0.38.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/samples/rust_tests/Cargo.toml b/samples/rust_tests/Cargo.toml new file mode 100644 index 00000000..542ddaf3 --- /dev/null +++ b/samples/rust_tests/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "rust_tests" +version = "0.1.0" +edition = "2021" + +[dev-dependencies] +proptest = "1.5.0" +cast_checks = "0.1.5" + +[features] +fone = [] +ftwo = [] +fthree = [] \ No newline at end of file diff --git a/samples/rust_tests/fuzz/Cargo.lock b/samples/rust_tests/fuzz/Cargo.lock new file mode 100644 index 00000000..305d93ae --- /dev/null +++ b/samples/rust_tests/fuzz/Cargo.lock @@ -0,0 +1,385 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "cc" +version = "1.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rstest" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2c585be59b6b5dd66a9d2084aa1d8bd52fbdb806eafdeffb52791147862035" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825ea780781b15345a146be27eaefb05085e337e869bff01b4306a4fd4a9ad5a" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + +[[package]] +name = "rust_tests" +version = "0.1.0" + +[[package]] +name = "rust_tests-fuzz" +version = "0.0.0" +dependencies = [ + "libfuzzer-sys", + "rstest", + "rust_tests", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "syn" +version = "2.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] diff --git a/samples/rust_tests/fuzz/Cargo.toml b/samples/rust_tests/fuzz/Cargo.toml new file mode 100644 index 00000000..f8b66d35 --- /dev/null +++ b/samples/rust_tests/fuzz/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "rust_tests-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" +rstest = "0.23.0" + +[dependencies.rust_tests] +path = ".." + +[[bin]] +name = "fuzz_target_1" +path = "fuzz_targets/fuzz_target_1.rs" +test = false +doc = false +bench = false + +[[bin]] +name = "fuzz_target_2" +path = "fuzz_targets/fuzz_target_2.rs" +test = false +doc = false +bench = false diff --git a/samples/rust_tests/fuzz/fuzz_targets/fuzz_target_1.rs b/samples/rust_tests/fuzz/fuzz_targets/fuzz_target_1.rs new file mode 100644 index 00000000..90a8f9ad --- /dev/null +++ b/samples/rust_tests/fuzz/fuzz_targets/fuzz_target_1.rs @@ -0,0 +1,29 @@ +#![cfg_attr(not(any(miri, test)), no_main)] + +use libfuzzer_sys::fuzz_target; +use rust_tests::check_buf; +fn harness(data: &[u8]) { + check_buf(data); +} + +fuzz_target!(|data: &[u8]| { + harness(data); +}); + +#[cfg(test)] +#[cfg(miri)] +mod tests { + use { + crate::{harness}, + rstest::rstest, + std::{fs::File, io::Read, path::PathBuf}, + }; + + #[rstest] + fn miri(#[files("corpus/fuzz_target_1/*")] path: PathBuf) { + let mut input = File::open(path).unwrap(); + let mut buf = Vec::new(); + input.read_to_end(&mut buf).unwrap(); + harness(&buf); + } +} \ No newline at end of file diff --git a/samples/rust_tests/src/lib.rs b/samples/rust_tests/src/lib.rs new file mode 100644 index 00000000..e2b14bae --- /dev/null +++ b/samples/rust_tests/src/lib.rs @@ -0,0 +1,11 @@ +use std::process; + +pub fn check_buf(buf: &[u8]) { + if buf.len() > 0 && buf[0] == b'a' { + if buf.len() > 1 && buf[1] == b'b' { + if buf.len() > 2 && buf[2] == b'c' { + process::abort(); + } + } + } +} \ No newline at end of file diff --git a/samples/rust_tests/src/main.rs b/samples/rust_tests/src/main.rs new file mode 100644 index 00000000..0022bd29 --- /dev/null +++ b/samples/rust_tests/src/main.rs @@ -0,0 +1,68 @@ +#![feature(custom_inner_attributes, proc_macro_hygiene)] + +use rust_tests::check_buf; + +mod unit_tests; + +fn main() { + println!("Hello, world!"); + let buffer: &[u8] = b"123"; + check_buf(buffer); +} + +/* Unit Testing */ +static mut GLOB_VAR: i32 = 2; + +unsafe fn global_var_set(arg: i32) { + GLOB_VAR = arg; +} + +#[allow(unreachable_code)] +fn feature_one() -> i32 { + #[cfg(all(feature = "fone", feature = "fthree", not(feature = "ftwo")))] + { + return 3; + } + #[cfg(feature = "fone")] { + return 1; + } + #[cfg(feature = "ftwo")] { + return 2; + } + return 0; +} + +mod overflow_lib { + // #![cast_checks::enable] + + pub(crate) fn do_overflow(a: i32) -> i32 { + return a * 8; + } + + pub(crate) fn as_u16(z: i32) -> u16 { + z as u16 + } +} + +fn simple_thingy_dingy(a: u64, b: &str) -> u64 { + return a + match b.parse::() { + Ok(x) => x, + Err(_) => b.len() as u64, + }; +} + +fn validate_data(data: &Data) -> Result<(), ()> { + if !data.magic.eq(&[0x13, 0x37]) { return Err(()) } + if data.len as usize != data.content.len() { return Err(()) } + return Ok(()); +} + +struct Data { + magic: [u8; 2], + len: u8, + content: String +} + +/* END Unit Testing */ + + diff --git a/samples/rust_tests/src/unit_tests.rs b/samples/rust_tests/src/unit_tests.rs new file mode 100644 index 00000000..e14c1e63 --- /dev/null +++ b/samples/rust_tests/src/unit_tests.rs @@ -0,0 +1,134 @@ +#[cfg(test)] +mod unit_tests { + #[test] + fn true_dilemma() { + assert_ne!(true, false); + } + + /* Randomization */ + #[cfg(test)] + mod tests2 { + use crate::{GLOB_VAR, global_var_set}; + + #[test] + fn a_true_dilemma() { + unsafe { assert_eq!(GLOB_VAR, 2); } + unsafe { global_var_set(5); } + unsafe { assert_eq!(GLOB_VAR, 5); } + assert_ne!(true, false); + } + + #[test] + fn not_true_dilemma() { + unsafe { assert_eq!(GLOB_VAR, 2); } + assert_ne!(true, false); + } + } + + #[cfg(test)] + mod tests3 { + use crate::{feature_one}; + + #[test] + fn feature_test1() { + let z = feature_one(); + assert!(z < 3); + } + } + /* END Randomization */ + + /* Integer overflows */ + #[cfg(test)] + #[allow(unused_variables)] + mod tests4 { + use crate::{overflow_lib::as_u16, overflow_lib::do_overflow}; + + #[should_panic] + #[test] + fn int_overflow_simple() { + let y_str = "2147483647"; + let y = y_str.parse::().unwrap(); + let x = do_overflow(y); + } + + #[should_panic] + #[test] + fn int_overflow_in_cast() { + let y_str = "2147483647"; + let y = y_str.parse::().unwrap(); + println!("{}", y); + let a = as_u16(y); + } + } + /* END Integer overflows */ + + /* Sanitizers */ + #[cfg(test)] + #[allow(unused_variables)] + mod tests5 { + #[test] + fn uaf() { + let a = vec![7, 3, 3, 1]; + let b = a.as_ptr(); + drop(a); + let z = unsafe { *b }; + } + } + /* END Sanitizers */ + + /* Miri */ + #[cfg(test)] + mod tests_miri { + fn x() {} + + #[test] + fn miri_example() { + let f = x as *const usize; + let y = unsafe { + *f.map_addr(|a| a + 8) + }; + assert_eq!(y, 0x841f0f); + } + } + /* END Miri */ + + /* Proptest */ + #[cfg(test)] + mod tests6 { + use crate::simple_thingy_dingy; + use proptest::prelude::*; + + proptest! { + #![proptest_config(ProptestConfig::with_cases(100))] + #[test] + fn test_simple_thingy_dingy(a in 1337..7331u64, b in "[0-9]{1,3}") { + println!("{a} | {b}"); + let sum = simple_thingy_dingy(a, &b); + assert!(sum >= a); + assert!(sum > 1337); + } + } + } + /* END Proptest */ + + /* Necessist */ + #[cfg(test)] + mod tests7 { + use crate::{Data, validate_data}; + + #[test] + fn parser_detects_errors() { + let mut blob = Data{ + magic: [0x73, 0x31], + len: 2, + content: "AB".parse().unwrap(), + }; + blob.content = blob.content + "Y"; + let result = validate_data(&blob); + assert!(result.is_err()); + } + } + /* END Necessist */ +} + + diff --git a/static/samples_rust_coverage/grcov/badges/flat.svg b/static/samples_rust_coverage/grcov/badges/flat.svg new file mode 100644 index 00000000..03e135bf --- /dev/null +++ b/static/samples_rust_coverage/grcov/badges/flat.svg @@ -0,0 +1,23 @@ + + coverage: 94% + + + + + + + + + + + + + + + coverage + + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov/badges/flat_square.svg b/static/samples_rust_coverage/grcov/badges/flat_square.svg new file mode 100644 index 00000000..b7a4567a --- /dev/null +++ b/static/samples_rust_coverage/grcov/badges/flat_square.svg @@ -0,0 +1,13 @@ + + coverage: 94% + + + + + + coverage + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov/badges/for_the_badge.svg b/static/samples_rust_coverage/grcov/badges/for_the_badge.svg new file mode 100644 index 00000000..70b55d30 --- /dev/null +++ b/static/samples_rust_coverage/grcov/badges/for_the_badge.svg @@ -0,0 +1,13 @@ + + COVERAGE: 94% + + + + + + COVERAGE + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov/badges/plastic.svg b/static/samples_rust_coverage/grcov/badges/plastic.svg new file mode 100644 index 00000000..c84a8cee --- /dev/null +++ b/static/samples_rust_coverage/grcov/badges/plastic.svg @@ -0,0 +1,25 @@ + + coverage: 94% + + + + + + + + + + + + + + + + + coverage + + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov/badges/social.svg b/static/samples_rust_coverage/grcov/badges/social.svg new file mode 100644 index 00000000..da39da47 --- /dev/null +++ b/static/samples_rust_coverage/grcov/badges/social.svg @@ -0,0 +1,27 @@ + + Coverage: 94% + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov/coverage.json b/static/samples_rust_coverage/grcov/coverage.json new file mode 100644 index 00000000..c0a27736 --- /dev/null +++ b/static/samples_rust_coverage/grcov/coverage.json @@ -0,0 +1 @@ +{"schemaVersion":1,"label":"coverage","message":"94.03%","color":"green"} \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov/index.html b/static/samples_rust_coverage/grcov/index.html new file mode 100644 index 00000000..19571c04 --- /dev/null +++ b/static/samples_rust_coverage/grcov/index.html @@ -0,0 +1,88 @@ + + + + + Grcov report - top_level + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectoryLine CoverageFunctionsBranches
src + + 94.03% + + + 94.03% + + 63 / 67 + 68.97%20 / 29 67.5%27 / 40
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov/src/index.html b/static/samples_rust_coverage/grcov/src/index.html new file mode 100644 index 00000000..9b2c6a1f --- /dev/null +++ b/static/samples_rust_coverage/grcov/src/index.html @@ -0,0 +1,115 @@ + + + + + Grcov report - src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctionsBranches
main.rs + + 93.75% + + + 93.75% + + 60 / 64 + 70.37%19 / 27 65.79%25 / 38
second.rs + + 100% + + + 100% + + 3 / 3 + 50%1 / 2 100%2 / 2
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov/src/main.rs.html b/static/samples_rust_coverage/grcov/src/main.rs.html new file mode 100644 index 00000000..59773bc9 --- /dev/null +++ b/static/samples_rust_coverage/grcov/src/main.rs.html @@ -0,0 +1,1762 @@ + + + + + Grcov report - main.rs + + +
+ + + +
+
+ 1 +
+
+ 8 +
+
+
mod second;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
fn main() { println!("Hello, world!"); }
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ 1 +
+
+
fn validate_data_simple(data: &Data) -> Result<(), ()> {
+
+
+
+ 6 +
+
+ 1 +
+
+
    if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
+
+
+
+ 7 +
+
+ +
+
+
    if data.len as usize != data.content.len() { return Err(()) }
+
+
+
+ 8 +
+
+ +
+
+
    return Ok(());
+
+
+
+ 9 +
+
+ 1 +
+
+
}
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ 2 +
+
+
fn validate_data_match(data: &Data) -> i32 {
+
+
+
+ 12 +
+
+ 2 +
+
+
    let x: u32 = match data.content.parse::<u32>() {
+
+
+
+ 13 +
+
+ 1 +
+
+
        Ok(_x) => {
+
+
+
+ 14 +
+
+ 1 +
+
+
            let y = 2 * _x;
+
+
+
+ 15 +
+
+ 1 +
+
+
            if y < 6 {
+
+
+
+ 16 +
+
+ +
+
+
                y
+
+
+
+ 17 +
+
+ +
+
+
            } else {
+
+
+
+ 18 +
+
+ 1 +
+
+
                y * 2
+
+
+
+ 19 +
+
+ +
+
+
            }
+
+
+
+ 20 +
+
+ +
+
+
        }
+
+
+
+ 21 +
+
+ 1 +
+
+
        Err(_) => 0
+
+
+
+ 22 +
+
+ +
+
+
    };
+
+
+
+ 23 +
+
+ 2 +
+
+
    if x == 0 {
+
+
+
+ 24 +
+
+ 1 +
+
+
        -1
+
+
+
+ 25 +
+
+ +
+
+
    } else {
+
+
+
+ 26 +
+
+ 1 +
+
+
        (x as i32) + 1
+
+
+
+ 27 +
+
+ +
+
+
    }
+
+
+
+ 28 +
+
+ 2 +
+
+
}
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
// https://doc.rust-lang.org/book/ch10-01-syntax.html
+
+
+
+ 31 +
+
+ 3 +
+
+
fn largest<T: PartialOrd>(list: &[T]) -> &T {
+
+
+
+ 32 +
+
+ 3 +
+
+
    let mut largest = &list[0];
+
+
+
+ 33 +
+
+ 15 +
+
+
    for item in list {
+
+
+
+ 34 +
+
+ 12 +
+
+
        if item > largest {
+
+
+
+ 35 +
+
+ 3 +
+
+
            largest = item;
+
+
+
+ 36 +
+
+ +
+
+
        }
+
+
+
+ 37 +
+
+ +
+
+
    }
+
+
+
+ 38 +
+
+ 3 +
+
+
    largest
+
+
+
+ 39 +
+
+ 3 +
+
+
}
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ 1 +
+
+
fn validate_data_generics(data: &Data) {
+
+
+
+ 42 +
+
+ 1 +
+
+
    let number_list = vec![34, 50, 25, 100, 65];
+
+
+
+ 43 +
+
+ +
+
+

+            
+
+
+ 44 +
+
+ 1 +
+
+
    let result = largest(&number_list);
+
+
+
+ 45 +
+
+ 1 +
+
+
    println!("The largest number is {}", result);
+
+
+
+ 46 +
+
+ +
+
+

+            
+
+
+ 47 +
+
+ 1 +
+
+
    let char_list = vec!['y', 'm', 'a', 'q'];
+
+
+
+ 48 +
+
+ +
+
+

+            
+
+
+ 49 +
+
+ 1 +
+
+
    let result = largest(&char_list);
+
+
+
+ 50 +
+
+ 1 +
+
+
    println!("The largest char is {}", result);
+
+
+
+ 51 +
+
+ +
+
+

+            
+
+
+ 52 +
+
+ 1 +
+
+
    let result = largest(data.content.as_bytes());
+
+
+
+ 53 +
+
+ 1 +
+
+
    println!("The largest content char is {}", result);
+
+
+
+ 54 +
+
+ 1 +
+
+
}
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
struct Data {
+
+
+
+ 57 +
+
+ +
+
+
    magic: [u8; 2],
+
+
+
+ 58 +
+
+ +
+
+
    len: u8,
+
+
+
+ 59 +
+
+ +
+
+
    content: String
+
+
+
+ 60 +
+
+ +
+
+
}
+
+
+
+ 61 +
+
+ +
+
+

+            
+
+
+ 62 +
+
+ +
+
+
#[cfg(test)]
+
+
+
+ 63 +
+
+ +
+
+
mod tests {
+
+
+
+ 64 +
+
+ +
+
+
    use crate::second::validate_data_panic;
+
+
+
+ 65 +
+
+ +
+
+
    use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
+
+
+
+ 66 +
+
+ +
+
+

+            
+
+
+ 67 +
+
+ +
+
+
    #[test]
+
+
+
+ 68 +
+
+ 2 +
+
+
    fn parser_detects_errors() {
+
+
+
+ 69 +
+
+ 1 +
+
+
        let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
+
+
+
+ 70 +
+
+ 1 +
+
+
        blob.content = blob.content + "Y";
+
+
+
+ 71 +
+
+ 1 +
+
+
        let result = validate_data_simple(&blob);
+
+
+
+ 72 +
+
+ 1 +
+
+
        assert!(result.is_err());
+
+
+
+ 73 +
+
+ 2 +
+
+
    }
+
+
+
+ 74 +
+
+ +
+
+

+            
+
+
+ 75 +
+
+ +
+
+
    #[test]
+
+
+
+ 76 +
+
+ 2 +
+
+
    fn check_match() {
+
+
+
+ 77 +
+
+ 1 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
+
+
+
+ 78 +
+
+ 1 +
+
+
        let x = validate_data_match(&blob);
+
+
+
+ 79 +
+
+ 1 +
+
+
        assert_eq!(x, -1);
+
+
+
+ 80 +
+
+ 2 +
+
+
    }
+
+
+
+ 81 +
+
+ +
+
+

+            
+
+
+ 82 +
+
+ +
+
+
    #[test]
+
+
+
+ 83 +
+
+ 2 +
+
+
    fn check_match2() {
+
+
+
+ 84 +
+
+ 1 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
+
+
+
+ 85 +
+
+ 1 +
+
+
        let x = validate_data_match(&blob);
+
+
+
+ 86 +
+
+ 1 +
+
+
        assert_eq!(x, 161);
+
+
+
+ 87 +
+
+ 2 +
+
+
    }
+
+
+
+ 88 +
+
+ +
+
+

+            
+
+
+ 89 +
+
+ +
+
+
    #[test]
+
+
+
+ 90 +
+
+ 2 +
+
+
    fn check_generic() {
+
+
+
+ 91 +
+
+ 1 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
+
+
+
+ 92 +
+
+ 1 +
+
+
        validate_data_generics(&blob);
+
+
+
+ 93 +
+
+ 2 +
+
+
    }
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ +
+
+
    #[test]
+
+
+
+ 96 +
+
+ +
+
+
    #[should_panic]
+
+
+
+ 97 +
+
+ 2 +
+
+
    fn check_panic() {
+
+
+
+ 98 +
+
+ 1 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
+
+
+
+ 99 +
+
+ 1 +
+
+
        validate_data_panic(&blob);
+
+
+
+ 100 +
+
+ 2 +
+
+
    }
+
+
+
+ 101 +
+
+ +
+
+

+            
+
+
+ 102 +
+
+ +
+
+
    #[test]
+
+
+
+ 103 +
+
+ 2 +
+
+
    fn check_not_panic() {
+
+
+
+ 104 +
+
+ 1 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
+
+
+
+ 105 +
+
+ 1 +
+
+
        validate_data_panic(&blob);
+
+
+
+ 106 +
+
+ 2 +
+
+
    }
+
+
+
+ 107 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov/src/second.rs.html b/static/samples_rust_coverage/grcov/src/second.rs.html new file mode 100644 index 00000000..aa02939b --- /dev/null +++ b/static/samples_rust_coverage/grcov/src/second.rs.html @@ -0,0 +1,162 @@ + + + + + Grcov report - second.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use crate::Data;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ 2 +
+
+
pub(crate) fn validate_data_panic(data: &Data) {
+
+
+
+ 4 +
+
+ 2 +
+
+
    if data.len == 0 {
+
+
+
+ 5 +
+
+ 1 +
+
+
        panic!("panic")
+
+
+
+ 6 +
+
+ +
+
+
    }
+
+
+
+ 7 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov_lcov/amber.png b/static/samples_rust_coverage/grcov_lcov/amber.png new file mode 100644 index 00000000..2cab170d Binary files /dev/null and b/static/samples_rust_coverage/grcov_lcov/amber.png differ diff --git a/static/samples_rust_coverage/grcov_lcov/emerald.png b/static/samples_rust_coverage/grcov_lcov/emerald.png new file mode 100644 index 00000000..38ad4f40 Binary files /dev/null and b/static/samples_rust_coverage/grcov_lcov/emerald.png differ diff --git a/static/samples_rust_coverage/grcov_lcov/gcov.css b/static/samples_rust_coverage/grcov_lcov/gcov.css new file mode 100644 index 00000000..bfd0a83e --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/gcov.css @@ -0,0 +1,519 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #FFFFFF; +} + +/* All views: standard link format*/ +a:link +{ + color: #284FA8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00CB40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #FF0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #DAE7FE; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #A7FC9D; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FFEA20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FF0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688D4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #FFFFFF; + background-color: #6688D4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #FFFFFF; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #DAE7FE; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #EFE383; +} + +/* Source code view: format for lines which were executed */ +td.lineCov, +span.lineCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #CAD7FE; +} + +/* Source code view: format for lines which were not executed */ +td.lineNoCov, +span.lineNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #FF6230; +} + +/* Source code view (function table): standard link - visited format */ +td.lineNoCov > a:visited, +td.lineCov > a:visited +{ + color: black; + text-decoration: underline; +} + +/* Source code view: format for lines which were executed only in a + previous version */ +span.lineDiffCov +{ + background-color: #B5F7AF; +} + +/* Source code view: format for branches which were executed + * and taken */ +span.branchCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for branches which were executed + * but not taken */ +span.branchNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for branches which were not executed */ +span.branchNoExec +{ + background-color: #FF6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #FF0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #FFEA20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #A7FC9D; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FF0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FFEA20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #A7FC9D; +} diff --git a/static/samples_rust_coverage/grcov_lcov/glass.png b/static/samples_rust_coverage/grcov_lcov/glass.png new file mode 100644 index 00000000..e1abc006 Binary files /dev/null and b/static/samples_rust_coverage/grcov_lcov/glass.png differ diff --git a/static/samples_rust_coverage/grcov_lcov/index-sort-f.html b/static/samples_rust_coverage/grcov_lcov/index-sort-f.html new file mode 100644 index 00000000..4d6ce7e3 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/index-sort-f.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
94.0%94.0%
+
94.0 %63 / 67100.0 %18 / 18
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/index-sort-l.html b/static/samples_rust_coverage/grcov_lcov/index-sort-l.html new file mode 100644 index 00000000..9e74ae27 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/index-sort-l.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
94.0%94.0%
+
94.0 %63 / 67100.0 %18 / 18
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/index.html b/static/samples_rust_coverage/grcov_lcov/index.html new file mode 100644 index 00000000..b01ea368 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/index.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
94.0%94.0%
+
94.0 %63 / 67100.0 %18 / 18
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/lcov b/static/samples_rust_coverage/grcov_lcov/lcov new file mode 100644 index 00000000..c5aee163 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/lcov @@ -0,0 +1,182 @@ +TN: +SF:src/main.rs +FN:11,tmp::validate_data_match +FN:76,tmp::tests::check_match +FN:76,tmp::tests::check_match::{{closure}} +FN:31,tmp::largest +FN:31,tmp::largest +FN:41,tmp::validate_data_generics +FN:3,tmp::main +FN:41,tmp::validate_data_generics +FN:103,tmp::tests::check_not_panic::{{closure}} +FN:31,tmp::largest +FN:31,tmp::largest +FN:68,tmp::tests::parser_detects_errors +FN:90,tmp::tests::check_generic::{{closure}} +FN:11,tmp::validate_data_match +FN:97,tmp::tests::check_panic::{{closure}} +FN:103,tmp::tests::check_not_panic +FN:1,tmp::main +FN:83,tmp::tests::check_match2 +FN:31,tmp::largest +FN:5,tmp::validate_data_simple +FN:5,tmp::validate_data_simple +FN:3,tmp::main +FN:31,tmp::largest +FN:97,tmp::tests::check_panic +FN:90,tmp::tests::check_generic +FN:83,tmp::tests::check_match2::{{closure}} +FN:68,tmp::tests::parser_detects_errors::{{closure}} +FNDA:0,tmp::validate_data_match +FNDA:1,tmp::tests::check_match +FNDA:1,tmp::tests::check_match::{{closure}} +FNDA:0,tmp::largest +FNDA:1,tmp::largest +FNDA:0,tmp::validate_data_generics +FNDA:0,tmp::main +FNDA:1,tmp::validate_data_generics +FNDA:1,tmp::tests::check_not_panic::{{closure}} +FNDA:1,tmp::largest +FNDA:0,tmp::largest +FNDA:1,tmp::tests::parser_detects_errors +FNDA:1,tmp::tests::check_generic::{{closure}} +FNDA:1,tmp::validate_data_match +FNDA:1,tmp::tests::check_panic::{{closure}} +FNDA:1,tmp::tests::check_not_panic +FNDA:1,tmp::main +FNDA:1,tmp::tests::check_match2 +FNDA:1,tmp::largest +FNDA:0,tmp::validate_data_simple +FNDA:1,tmp::validate_data_simple +FNDA:0,tmp::main +FNDA:0,tmp::largest +FNDA:1,tmp::tests::check_panic +FNDA:1,tmp::tests::check_generic +FNDA:1,tmp::tests::check_match2::{{closure}} +FNDA:1,tmp::tests::parser_detects_errors::{{closure}} +FNF:27 +FNH:19 +BRDA:6,0,0,1 +BRDA:6,0,1,- +BRDA:7,0,0,- +BRDA:7,0,1,- +BRDA:12,0,0,1 +BRDA:12,0,1,1 +BRDA:15,0,0,1 +BRDA:15,0,1,- +BRDA:23,0,0,1 +BRDA:23,0,1,1 +BRDA:32,0,0,1 +BRDA:32,0,1,- +BRDA:32,0,2,1 +BRDA:32,0,3,- +BRDA:32,0,4,1 +BRDA:32,0,5,- +BRDA:33,0,0,1 +BRDA:33,0,1,1 +BRDA:33,0,2,1 +BRDA:33,0,3,1 +BRDA:33,0,4,1 +BRDA:33,0,5,1 +BRDA:34,0,0,1 +BRDA:34,0,1,- +BRDA:34,0,2,1 +BRDA:34,0,3,1 +BRDA:34,0,4,1 +BRDA:34,0,5,1 +BRDA:42,0,0,1 +BRDA:42,0,1,- +BRDA:47,0,0,1 +BRDA:47,0,1,- +BRDA:72,0,0,- +BRDA:72,0,1,1 +BRDA:79,0,0,- +BRDA:79,0,1,1 +BRDA:86,0,0,- +BRDA:86,0,1,1 +BRF:38 +BRH:25 +DA:1,8 +DA:3,0 +DA:5,1 +DA:6,1 +DA:7,0 +DA:8,0 +DA:9,1 +DA:11,2 +DA:12,2 +DA:13,1 +DA:14,1 +DA:15,1 +DA:16,0 +DA:18,1 +DA:21,1 +DA:23,2 +DA:24,1 +DA:26,1 +DA:28,2 +DA:31,3 +DA:32,3 +DA:33,15 +DA:34,12 +DA:35,3 +DA:38,3 +DA:39,3 +DA:41,1 +DA:42,1 +DA:44,1 +DA:45,1 +DA:47,1 +DA:49,1 +DA:50,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:68,2 +DA:69,1 +DA:70,1 +DA:71,1 +DA:72,1 +DA:73,2 +DA:76,2 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,2 +DA:83,2 +DA:84,1 +DA:85,1 +DA:86,1 +DA:87,2 +DA:90,2 +DA:91,1 +DA:92,1 +DA:93,2 +DA:97,2 +DA:98,1 +DA:99,1 +DA:100,2 +DA:103,2 +DA:104,1 +DA:105,1 +DA:106,2 +LF:64 +LH:60 +end_of_record +SF:src/second.rs +FN:3,tmp::second::validate_data_panic +FN:3,tmp::second::validate_data_panic +FNDA:0,tmp::second::validate_data_panic +FNDA:1,tmp::second::validate_data_panic +FNF:2 +FNH:1 +BRDA:4,0,0,1 +BRDA:4,0,1,1 +BRF:2 +BRH:2 +DA:3,2 +DA:4,2 +DA:5,1 +LF:3 +LH:3 +end_of_record diff --git a/static/samples_rust_coverage/grcov_lcov/ruby.png b/static/samples_rust_coverage/grcov_lcov/ruby.png new file mode 100644 index 00000000..991b6d4e Binary files /dev/null and b/static/samples_rust_coverage/grcov_lcov/ruby.png differ diff --git a/static/samples_rust_coverage/grcov_lcov/snow.png b/static/samples_rust_coverage/grcov_lcov/snow.png new file mode 100644 index 00000000..2cdae107 Binary files /dev/null and b/static/samples_rust_coverage/grcov_lcov/snow.png differ diff --git a/static/samples_rust_coverage/grcov_lcov/src/index-detail-sort-f.html b/static/samples_rust_coverage/grcov_lcov/src/index-detail-sort-f.html new file mode 100644 index 00000000..4eaa6b6b --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/index-detail-sort-f.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( hide details ) Sort by line coverageFunctions Sort by function coverage
second.rs +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
<unnamed>100.0 %3 / 3100.0 %1 / 1
main.rs +
93.8%93.8%
+
93.8 %60 / 64100.0 %17 / 17
<unnamed>93.8 %60 / 64100.0 %17 / 17
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/index-detail-sort-l.html b/static/samples_rust_coverage/grcov_lcov/src/index-detail-sort-l.html new file mode 100644 index 00000000..d60b3dc4 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/index-detail-sort-l.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( hide details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
93.8%93.8%
+
93.8 %60 / 64100.0 %17 / 17
<unnamed>93.8 %60 / 64100.0 %17 / 17
second.rs +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
<unnamed>100.0 %3 / 3100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/index-detail.html b/static/samples_rust_coverage/grcov_lcov/src/index-detail.html new file mode 100644 index 00000000..f1629cb2 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/index-detail.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( hide details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
93.8%93.8%
+
93.8 %60 / 64100.0 %17 / 17
<unnamed>93.8 %60 / 64100.0 %17 / 17
second.rs +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
<unnamed>100.0 %3 / 3100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/index-sort-f.html b/static/samples_rust_coverage/grcov_lcov/src/index-sort-f.html new file mode 100644 index 00000000..7cb1bf00 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/index-sort-f.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( show details ) Sort by line coverageFunctions Sort by function coverage
second.rs +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
main.rs +
93.8%93.8%
+
93.8 %60 / 64100.0 %17 / 17
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/index-sort-l.html b/static/samples_rust_coverage/grcov_lcov/src/index-sort-l.html new file mode 100644 index 00000000..d659e9e6 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/index-sort-l.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( show details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
93.8%93.8%
+
93.8 %60 / 64100.0 %17 / 17
second.rs +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/index.html b/static/samples_rust_coverage/grcov_lcov/src/index.html new file mode 100644 index 00000000..2f58aed9 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/index.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:636794.0 %
Date:2024-01-12 19:04:52Functions:1818100.0 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( show details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
93.8%93.8%
+
93.8 %60 / 64100.0 %17 / 17
second.rs +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/main.rs.func-sort-c.html b/static/samples_rust_coverage/grcov_lcov/src/main.rs.func-sort-c.html new file mode 100644 index 00000000..abdc9280 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/main.rs.func-sort-c.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - lcov - src/main.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)HitTotalCoverage
Test:lcovLines:606493.8 %
Date:2024-01-12 19:04:52Functions:1717100.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::main1
tmp::tests::check_generic1
tmp::tests::check_generic::{{closure}}1
tmp::tests::check_match1
tmp::tests::check_match21
tmp::tests::check_match2::{{closure}}1
tmp::tests::check_match::{{closure}}1
tmp::tests::check_not_panic1
tmp::tests::check_not_panic::{{closure}}1
tmp::tests::check_panic1
tmp::tests::check_panic::{{closure}}1
tmp::tests::parser_detects_errors1
tmp::tests::parser_detects_errors::{{closure}}1
tmp::validate_data_generics1
tmp::validate_data_match1
tmp::validate_data_simple1
tmp::largest3
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/main.rs.func.html b/static/samples_rust_coverage/grcov_lcov/src/main.rs.func.html new file mode 100644 index 00000000..ace030f9 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/main.rs.func.html @@ -0,0 +1,148 @@ + + + + + + + LCOV - lcov - src/main.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)HitTotalCoverage
Test:lcovLines:606493.8 %
Date:2024-01-12 19:04:52Functions:1717100.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::largest3
tmp::main1
tmp::tests::check_generic1
tmp::tests::check_generic::{{closure}}1
tmp::tests::check_match1
tmp::tests::check_match21
tmp::tests::check_match2::{{closure}}1
tmp::tests::check_match::{{closure}}1
tmp::tests::check_not_panic1
tmp::tests::check_not_panic::{{closure}}1
tmp::tests::check_panic1
tmp::tests::check_panic::{{closure}}1
tmp::tests::parser_detects_errors1
tmp::tests::parser_detects_errors::{{closure}}1
tmp::validate_data_generics1
tmp::validate_data_match1
tmp::validate_data_simple1
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/main.rs.gcov.html b/static/samples_rust_coverage/grcov_lcov/src/main.rs.gcov.html new file mode 100644 index 00000000..50fbfa4a --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/main.rs.gcov.html @@ -0,0 +1,191 @@ + + + + + + + LCOV - lcov - src/main.rs + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)HitTotalCoverage
Test:lcovLines:606493.8 %
Date:2024-01-12 19:04:52Functions:1717100.0 %
Legend: Lines: + hit + not hit +
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1           8 : mod second;
+       2             : 
+       3           0 : fn main() { println!("Hello, world!"); }
+       4             : 
+       5           1 : fn validate_data_simple(data: &Data) -> Result<(), ()> {
+       6           1 :     if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
+       7           0 :     if data.len as usize != data.content.len() { return Err(()) }
+       8           0 :     return Ok(());
+       9           1 : }
+      10             : 
+      11           2 : fn validate_data_match(data: &Data) -> i32 {
+      12           2 :     let x: u32 = match data.content.parse::<u32>() {
+      13           1 :         Ok(_x) => {
+      14           1 :             let y = 2 * _x;
+      15           1 :             if y < 6 {
+      16           0 :                 y
+      17             :             } else {
+      18           1 :                 y * 2
+      19             :             }
+      20             :         }
+      21           1 :         Err(_) => 0
+      22             :     };
+      23           2 :     if x == 0 {
+      24           1 :         -1
+      25             :     } else {
+      26           1 :         (x as i32) + 1
+      27             :     }
+      28           2 : }
+      29             : 
+      30             : // https://doc.rust-lang.org/book/ch10-01-syntax.html
+      31           3 : fn largest<T: PartialOrd>(list: &[T]) -> &T {
+      32           3 :     let mut largest = &list[0];
+      33          15 :     for item in list {
+      34          12 :         if item > largest {
+      35           3 :             largest = item;
+      36             :         }
+      37             :     }
+      38           3 :     largest
+      39           3 : }
+      40             : 
+      41           1 : fn validate_data_generics(data: &Data) {
+      42           1 :     let number_list = vec![34, 50, 25, 100, 65];
+      43             : 
+      44           1 :     let result = largest(&number_list);
+      45           1 :     println!("The largest number is {}", result);
+      46             : 
+      47           1 :     let char_list = vec!['y', 'm', 'a', 'q'];
+      48             : 
+      49           1 :     let result = largest(&char_list);
+      50           1 :     println!("The largest char is {}", result);
+      51             : 
+      52           1 :     let result = largest(data.content.as_bytes());
+      53           1 :     println!("The largest content char is {}", result);
+      54           1 : }
+      55             : 
+      56             : struct Data {
+      57             :     magic: [u8; 2],
+      58             :     len: u8,
+      59             :     content: String
+      60             : }
+      61             : 
+      62             : #[cfg(test)]
+      63             : mod tests {
+      64             :     use crate::second::validate_data_panic;
+      65             :     use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
+      66             : 
+      67             :     #[test]
+      68           2 :     fn parser_detects_errors() {
+      69           1 :         let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
+      70           1 :         blob.content = blob.content + "Y";
+      71           1 :         let result = validate_data_simple(&blob);
+      72           1 :         assert!(result.is_err());
+      73           2 :     }
+      74             : 
+      75             :     #[test]
+      76           2 :     fn check_match() {
+      77           1 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
+      78           1 :         let x = validate_data_match(&blob);
+      79           1 :         assert_eq!(x, -1);
+      80           2 :     }
+      81             : 
+      82             :     #[test]
+      83           2 :     fn check_match2() {
+      84           1 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
+      85           1 :         let x = validate_data_match(&blob);
+      86           1 :         assert_eq!(x, 161);
+      87           2 :     }
+      88             : 
+      89             :     #[test]
+      90           2 :     fn check_generic() {
+      91           1 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
+      92           1 :         validate_data_generics(&blob);
+      93           2 :     }
+      94             : 
+      95             :     #[test]
+      96             :     #[should_panic]
+      97           2 :     fn check_panic() {
+      98           1 :         let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
+      99           1 :         validate_data_panic(&blob);
+     100           2 :     }
+     101             : 
+     102             :     #[test]
+     103           2 :     fn check_not_panic() {
+     104           1 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
+     105           1 :         validate_data_panic(&blob);
+     106           2 :     }
+     107             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/second.rs.func-sort-c.html b/static/samples_rust_coverage/grcov_lcov/src/second.rs.func-sort-c.html new file mode 100644 index 00000000..aa01274d --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/second.rs.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov - src/second.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)HitTotalCoverage
Test:lcovLines:33100.0 %
Date:2024-01-12 19:04:52Functions:11100.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::second::validate_data_panic1
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/second.rs.func.html b/static/samples_rust_coverage/grcov_lcov/src/second.rs.func.html new file mode 100644 index 00000000..a1c3f0d4 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/second.rs.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov - src/second.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)HitTotalCoverage
Test:lcovLines:33100.0 %
Date:2024-01-12 19:04:52Functions:11100.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::second::validate_data_panic1
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/src/second.rs.gcov.html b/static/samples_rust_coverage/grcov_lcov/src/second.rs.gcov.html new file mode 100644 index 00000000..59d584f0 --- /dev/null +++ b/static/samples_rust_coverage/grcov_lcov/src/second.rs.gcov.html @@ -0,0 +1,91 @@ + + + + + + + LCOV - lcov - src/second.rs + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)HitTotalCoverage
Test:lcovLines:33100.0 %
Date:2024-01-12 19:04:52Functions:11100.0 %
Legend: Lines: + hit + not hit +
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : use crate::Data;
+       2             : 
+       3           2 : pub(crate) fn validate_data_panic(data: &Data) {
+       4           2 :     if data.len == 0 {
+       5           1 :         panic!("panic")
+       6             :     }
+       7             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_lcov/updown.png b/static/samples_rust_coverage/grcov_lcov/updown.png new file mode 100644 index 00000000..aa56a238 Binary files /dev/null and b/static/samples_rust_coverage/grcov_lcov/updown.png differ diff --git a/static/samples_rust_coverage/grcov_llvm/badges/flat.svg b/static/samples_rust_coverage/grcov_llvm/badges/flat.svg new file mode 100644 index 00000000..03e135bf --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/badges/flat.svg @@ -0,0 +1,23 @@ + + coverage: 94% + + + + + + + + + + + + + + + coverage + + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov_llvm/badges/flat_square.svg b/static/samples_rust_coverage/grcov_llvm/badges/flat_square.svg new file mode 100644 index 00000000..b7a4567a --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/badges/flat_square.svg @@ -0,0 +1,13 @@ + + coverage: 94% + + + + + + coverage + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov_llvm/badges/for_the_badge.svg b/static/samples_rust_coverage/grcov_llvm/badges/for_the_badge.svg new file mode 100644 index 00000000..70b55d30 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/badges/for_the_badge.svg @@ -0,0 +1,13 @@ + + COVERAGE: 94% + + + + + + COVERAGE + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov_llvm/badges/plastic.svg b/static/samples_rust_coverage/grcov_llvm/badges/plastic.svg new file mode 100644 index 00000000..c84a8cee --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/badges/plastic.svg @@ -0,0 +1,25 @@ + + coverage: 94% + + + + + + + + + + + + + + + + + coverage + + 94% + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov_llvm/badges/social.svg b/static/samples_rust_coverage/grcov_llvm/badges/social.svg new file mode 100644 index 00000000..da39da47 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/badges/social.svg @@ -0,0 +1,27 @@ + + Coverage: 94% + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov_llvm/coverage.json b/static/samples_rust_coverage/grcov_llvm/coverage.json new file mode 100644 index 00000000..4d62a96b --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/coverage.json @@ -0,0 +1 @@ +{"schemaVersion":1,"label":"coverage","message":"94.94%","color":"green"} \ No newline at end of file diff --git a/static/samples_rust_coverage/grcov_llvm/index.html b/static/samples_rust_coverage/grcov_llvm/index.html new file mode 100644 index 00000000..9d59da38 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/index.html @@ -0,0 +1,88 @@ + + + + + Grcov report - top_level + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectoryLine CoverageFunctionsBranches
src + + 94.94% + + + 94.94% + + 75 / 79 + 73.08%19 / 26 100%0 / 0
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov_llvm/src/index.html b/static/samples_rust_coverage/grcov_llvm/src/index.html new file mode 100644 index 00000000..6ebdea76 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/src/index.html @@ -0,0 +1,115 @@ + + + + + Grcov report - src + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileLine CoverageFunctionsBranches
main.rs + + 94.59% + + + 94.59% + + 70 / 74 + 75%18 / 24 100%0 / 0
second.rs + + 100% + + + 100% + + 5 / 5 + 50%1 / 2 100%0 / 0
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov_llvm/src/main.rs.html b/static/samples_rust_coverage/grcov_llvm/src/main.rs.html new file mode 100644 index 00000000..f7698c96 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/src/main.rs.html @@ -0,0 +1,1762 @@ + + + + + Grcov report - main.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
mod second;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ +
+
+
fn main() { println!("Hello, world!"); }
+
+
+
+ 4 +
+
+ +
+
+

+            
+
+
+ 5 +
+
+ 2 +
+
+
fn validate_data_simple(data: &Data) -> Result<(), ()> {
+
+
+
+ 6 +
+
+ 2 +
+
+
    if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
+
+
+
+ 7 +
+
+ +
+
+
    if data.len as usize != data.content.len() { return Err(()) }
+
+
+
+ 8 +
+
+ +
+
+
    return Ok(());
+
+
+
+ 9 +
+
+ 2 +
+
+
}
+
+
+
+ 10 +
+
+ +
+
+

+            
+
+
+ 11 +
+
+ 4 +
+
+
fn validate_data_match(data: &Data) -> i32 {
+
+
+
+ 12 +
+
+ 4 +
+
+
    let x: u32 = match data.content.parse::<u32>() {
+
+
+
+ 13 +
+
+ 2 +
+
+
        Ok(_x) => {
+
+
+
+ 14 +
+
+ 2 +
+
+
            let y = 2 * _x;
+
+
+
+ 15 +
+
+ 2 +
+
+
            if y < 6 {
+
+
+
+ 16 +
+
+ +
+
+
                y
+
+
+
+ 17 +
+
+ +
+
+
            } else {
+
+
+
+ 18 +
+
+ 2 +
+
+
                y * 2
+
+
+
+ 19 +
+
+ +
+
+
            }
+
+
+
+ 20 +
+
+ +
+
+
        }
+
+
+
+ 21 +
+
+ 2 +
+
+
        Err(_) => 0
+
+
+
+ 22 +
+
+ +
+
+
    };
+
+
+
+ 23 +
+
+ 4 +
+
+
    if x == 0 {
+
+
+
+ 24 +
+
+ 2 +
+
+
        -1
+
+
+
+ 25 +
+
+ +
+
+
    } else {
+
+
+
+ 26 +
+
+ 2 +
+
+
        (x as i32) + 1
+
+
+
+ 27 +
+
+ +
+
+
    }
+
+
+
+ 28 +
+
+ 4 +
+
+
}
+
+
+
+ 29 +
+
+ +
+
+

+            
+
+
+ 30 +
+
+ +
+
+
// https://doc.rust-lang.org/book/ch10-01-syntax.html
+
+
+
+ 31 +
+
+ 6 +
+
+
fn largest<T: PartialOrd>(list: &[T]) -> &T {
+
+
+
+ 32 +
+
+ 6 +
+
+
    let mut largest = &list[0];
+
+
+
+ 33 +
+
+ 30 +
+
+
    for item in list {
+
+
+
+ 34 +
+
+ 24 +
+
+
        if item > largest {
+
+
+
+ 35 +
+
+ 6 +
+
+
            largest = item;
+
+
+
+ 36 +
+
+ 18 +
+
+
        }
+
+
+
+ 37 +
+
+ +
+
+
    }
+
+
+
+ 38 +
+
+ 6 +
+
+
    largest
+
+
+
+ 39 +
+
+ 6 +
+
+
}
+
+
+
+ 40 +
+
+ +
+
+

+            
+
+
+ 41 +
+
+ 2 +
+
+
fn validate_data_generics(data: &Data) {
+
+
+
+ 42 +
+
+ 2 +
+
+
    let number_list = vec![34, 50, 25, 100, 65];
+
+
+
+ 43 +
+
+ 2 +
+
+

+            
+
+
+ 44 +
+
+ 2 +
+
+
    let result = largest(&number_list);
+
+
+
+ 45 +
+
+ 2 +
+
+
    println!("The largest number is {}", result);
+
+
+
+ 46 +
+
+ 2 +
+
+

+            
+
+
+ 47 +
+
+ 2 +
+
+
    let char_list = vec!['y', 'm', 'a', 'q'];
+
+
+
+ 48 +
+
+ 2 +
+
+

+            
+
+
+ 49 +
+
+ 2 +
+
+
    let result = largest(&char_list);
+
+
+
+ 50 +
+
+ 2 +
+
+
    println!("The largest char is {}", result);
+
+
+
+ 51 +
+
+ 2 +
+
+

+            
+
+
+ 52 +
+
+ 2 +
+
+
    let result = largest(data.content.as_bytes());
+
+
+
+ 53 +
+
+ 2 +
+
+
    println!("The largest content char is {}", result);
+
+
+
+ 54 +
+
+ 2 +
+
+
}
+
+
+
+ 55 +
+
+ +
+
+

+            
+
+
+ 56 +
+
+ +
+
+
struct Data {
+
+
+
+ 57 +
+
+ +
+
+
    magic: [u8; 2],
+
+
+
+ 58 +
+
+ +
+
+
    len: u8,
+
+
+
+ 59 +
+
+ +
+
+
    content: String
+
+
+
+ 60 +
+
+ +
+
+
}
+
+
+
+ 61 +
+
+ +
+
+

+            
+
+
+ 62 +
+
+ +
+
+
#[cfg(test)]
+
+
+
+ 63 +
+
+ +
+
+
mod tests {
+
+
+
+ 64 +
+
+ +
+
+
    use crate::second::validate_data_panic;
+
+
+
+ 65 +
+
+ +
+
+
    use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
+
+
+
+ 66 +
+
+ +
+
+

+            
+
+
+ 67 +
+
+ 2 +
+
+
    #[test]
+
+
+
+ 68 +
+
+ 2 +
+
+
    fn parser_detects_errors() {
+
+
+
+ 69 +
+
+ 2 +
+
+
        let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
+
+
+
+ 70 +
+
+ 2 +
+
+
        blob.content = blob.content + "Y";
+
+
+
+ 71 +
+
+ 2 +
+
+
        let result = validate_data_simple(&blob);
+
+
+
+ 72 +
+
+ 2 +
+
+
        assert!(result.is_err());
+
+
+
+ 73 +
+
+ 2 +
+
+
    }
+
+
+
+ 74 +
+
+ +
+
+

+            
+
+
+ 75 +
+
+ 2 +
+
+
    #[test]
+
+
+
+ 76 +
+
+ 2 +
+
+
    fn check_match() {
+
+
+
+ 77 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
+
+
+
+ 78 +
+
+ 2 +
+
+
        let x = validate_data_match(&blob);
+
+
+
+ 79 +
+
+ 2 +
+
+
        assert_eq!(x, -1);
+
+
+
+ 80 +
+
+ 2 +
+
+
    }
+
+
+
+ 81 +
+
+ +
+
+

+            
+
+
+ 82 +
+
+ 2 +
+
+
    #[test]
+
+
+
+ 83 +
+
+ 2 +
+
+
    fn check_match2() {
+
+
+
+ 84 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
+
+
+
+ 85 +
+
+ 2 +
+
+
        let x = validate_data_match(&blob);
+
+
+
+ 86 +
+
+ 2 +
+
+
        assert_eq!(x, 161);
+
+
+
+ 87 +
+
+ 2 +
+
+
    }
+
+
+
+ 88 +
+
+ +
+
+

+            
+
+
+ 89 +
+
+ 2 +
+
+
    #[test]
+
+
+
+ 90 +
+
+ 2 +
+
+
    fn check_generic() {
+
+
+
+ 91 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
+
+
+
+ 92 +
+
+ 2 +
+
+
        validate_data_generics(&blob);
+
+
+
+ 93 +
+
+ 2 +
+
+
    }
+
+
+
+ 94 +
+
+ +
+
+

+            
+
+
+ 95 +
+
+ 2 +
+
+
    #[test]
+
+
+
+ 96 +
+
+ +
+
+
    #[should_panic]
+
+
+
+ 97 +
+
+ 2 +
+
+
    fn check_panic() {
+
+
+
+ 98 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
+
+
+
+ 99 +
+
+ 2 +
+
+
        validate_data_panic(&blob);
+
+
+
+ 100 +
+
+ 2 +
+
+
    }
+
+
+
+ 101 +
+
+ +
+
+

+            
+
+
+ 102 +
+
+ 2 +
+
+
    #[test]
+
+
+
+ 103 +
+
+ 2 +
+
+
    fn check_not_panic() {
+
+
+
+ 104 +
+
+ 2 +
+
+
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
+
+
+
+ 105 +
+
+ 2 +
+
+
        validate_data_panic(&blob);
+
+
+
+ 106 +
+
+ 2 +
+
+
    }
+
+
+
+ 107 +
+
+ +
+
+
}
+
+
+
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov_llvm/src/second.rs.html b/static/samples_rust_coverage/grcov_llvm/src/second.rs.html new file mode 100644 index 00000000..069c1be5 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm/src/second.rs.html @@ -0,0 +1,162 @@ + + + + + Grcov report - second.rs + + +
+ + + +
+
+ 1 +
+
+ +
+
+
use crate::Data;
+
+
+
+ 2 +
+
+ +
+
+

+            
+
+
+ 3 +
+
+ 4 +
+
+
pub(crate) fn validate_data_panic(data: &Data) {
+
+
+
+ 4 +
+
+ 4 +
+
+
    if data.len == 0 {
+
+
+
+ 5 +
+
+ 2 +
+
+
        panic!("panic")
+
+
+
+ 6 +
+
+ 2 +
+
+
    }
+
+
+
+ 7 +
+
+ 2 +
+
+
}
+
+
+
+
+
+

Date: 2024-01-12 19:04

+
+
+ + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/amber.png b/static/samples_rust_coverage/grcov_llvm_lcov/amber.png new file mode 100644 index 00000000..2cab170d Binary files /dev/null and b/static/samples_rust_coverage/grcov_llvm_lcov/amber.png differ diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/emerald.png b/static/samples_rust_coverage/grcov_llvm_lcov/emerald.png new file mode 100644 index 00000000..38ad4f40 Binary files /dev/null and b/static/samples_rust_coverage/grcov_llvm_lcov/emerald.png differ diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/gcov.css b/static/samples_rust_coverage/grcov_llvm_lcov/gcov.css new file mode 100644 index 00000000..bfd0a83e --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/gcov.css @@ -0,0 +1,519 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #FFFFFF; +} + +/* All views: standard link format*/ +a:link +{ + color: #284FA8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00CB40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #FF0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #DAE7FE; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #A7FC9D; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FFEA20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FF0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688D4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #FFFFFF; + background-color: #6688D4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #FFFFFF; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #DAE7FE; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #EFE383; +} + +/* Source code view: format for lines which were executed */ +td.lineCov, +span.lineCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #CAD7FE; +} + +/* Source code view: format for lines which were not executed */ +td.lineNoCov, +span.lineNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #FF6230; +} + +/* Source code view (function table): standard link - visited format */ +td.lineNoCov > a:visited, +td.lineCov > a:visited +{ + color: black; + text-decoration: underline; +} + +/* Source code view: format for lines which were executed only in a + previous version */ +span.lineDiffCov +{ + background-color: #B5F7AF; +} + +/* Source code view: format for branches which were executed + * and taken */ +span.branchCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for branches which were executed + * but not taken */ +span.branchNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for branches which were not executed */ +span.branchNoExec +{ + background-color: #FF6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #FF0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #FFEA20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #A7FC9D; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FF0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FFEA20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #A7FC9D; +} diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/glass.png b/static/samples_rust_coverage/grcov_llvm_lcov/glass.png new file mode 100644 index 00000000..e1abc006 Binary files /dev/null and b/static/samples_rust_coverage/grcov_llvm_lcov/glass.png differ diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/index-sort-f.html b/static/samples_rust_coverage/grcov_llvm_lcov/index-sort-f.html new file mode 100644 index 00000000..8f62c510 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/index-sort-f.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
94.9%94.9%
+
94.9 %75 / 7990.5 %19 / 21
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/index-sort-l.html b/static/samples_rust_coverage/grcov_llvm_lcov/index-sort-l.html new file mode 100644 index 00000000..4f2d38cc --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/index-sort-l.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
94.9%94.9%
+
94.9 %75 / 7990.5 %19 / 21
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/index.html b/static/samples_rust_coverage/grcov_llvm_lcov/index.html new file mode 100644 index 00000000..f486b10b --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/index.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
94.9%94.9%
+
94.9 %75 / 7990.5 %19 / 21
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/lcov b/static/samples_rust_coverage/grcov_llvm_lcov/lcov new file mode 100644 index 00000000..8bcf8213 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/lcov @@ -0,0 +1,148 @@ +TN: +SF:src/main.rs +FN:31,tmp::largest:: +FN:67,tmp::tests::parser_detects_errors::{closure#0} +FN:75,tmp::tests::check_match::{closure#0} +FN:90,tmp::tests::check_generic +FN:102,tmp::tests::check_not_panic::{closure#0} +FN:5,tmp::validate_data_simple +FN:3,tmp::main +FN:11,tmp::validate_data_match +FN:31,tmp::largest:: +FN:83,tmp::tests::check_match2 +FN:76,tmp::tests::check_match +FN:68,tmp::tests::parser_detects_errors +FN:3,tmp::main +FN:31,tmp::largest:: +FN:41,tmp::validate_data_generics +FN:31,tmp::largest::<_> +FN:103,tmp::tests::check_not_panic +FN:41,tmp::validate_data_generics +FN:89,tmp::tests::check_generic::{closure#0} +FN:97,tmp::tests::check_panic +FN:11,tmp::validate_data_match +FN:82,tmp::tests::check_match2::{closure#0} +FN:5,tmp::validate_data_simple +FN:95,tmp::tests::check_panic::{closure#0} +FNDA:1,tmp::largest:: +FNDA:1,tmp::tests::parser_detects_errors::{closure#0} +FNDA:1,tmp::tests::check_match::{closure#0} +FNDA:1,tmp::tests::check_generic +FNDA:1,tmp::tests::check_not_panic::{closure#0} +FNDA:0,tmp::validate_data_simple +FNDA:0,tmp::main +FNDA:0,tmp::validate_data_match +FNDA:1,tmp::largest:: +FNDA:1,tmp::tests::check_match2 +FNDA:1,tmp::tests::check_match +FNDA:1,tmp::tests::parser_detects_errors +FNDA:0,tmp::main +FNDA:1,tmp::largest:: +FNDA:0,tmp::validate_data_generics +FNDA:0,tmp::largest::<_> +FNDA:1,tmp::tests::check_not_panic +FNDA:1,tmp::validate_data_generics +FNDA:1,tmp::tests::check_generic::{closure#0} +FNDA:1,tmp::tests::check_panic +FNDA:1,tmp::validate_data_match +FNDA:1,tmp::tests::check_match2::{closure#0} +FNDA:1,tmp::validate_data_simple +FNDA:1,tmp::tests::check_panic::{closure#0} +FNF:24 +FNH:18 +BRF:0 +BRH:0 +DA:3,0 +DA:5,2 +DA:6,2 +DA:7,0 +DA:8,0 +DA:9,2 +DA:11,4 +DA:12,4 +DA:13,2 +DA:14,2 +DA:15,2 +DA:16,0 +DA:18,2 +DA:21,2 +DA:23,4 +DA:24,2 +DA:26,2 +DA:28,4 +DA:31,6 +DA:32,6 +DA:33,30 +DA:34,24 +DA:35,6 +DA:36,18 +DA:38,6 +DA:39,6 +DA:41,2 +DA:42,2 +DA:43,2 +DA:44,2 +DA:45,2 +DA:46,2 +DA:47,2 +DA:48,2 +DA:49,2 +DA:50,2 +DA:51,2 +DA:52,2 +DA:53,2 +DA:54,2 +DA:67,2 +DA:68,2 +DA:69,2 +DA:70,2 +DA:71,2 +DA:72,2 +DA:73,2 +DA:75,2 +DA:76,2 +DA:77,2 +DA:78,2 +DA:79,2 +DA:80,2 +DA:82,2 +DA:83,2 +DA:84,2 +DA:85,2 +DA:86,2 +DA:87,2 +DA:89,2 +DA:90,2 +DA:91,2 +DA:92,2 +DA:93,2 +DA:95,2 +DA:97,2 +DA:98,2 +DA:99,2 +DA:100,2 +DA:102,2 +DA:103,2 +DA:104,2 +DA:105,2 +DA:106,2 +LF:74 +LH:70 +end_of_record +SF:src/second.rs +FN:3,tmp::second::validate_data_panic +FN:3,tmp::second::validate_data_panic +FNDA:1,tmp::second::validate_data_panic +FNDA:0,tmp::second::validate_data_panic +FNF:2 +FNH:1 +BRF:0 +BRH:0 +DA:3,4 +DA:4,4 +DA:5,2 +DA:6,2 +DA:7,2 +LF:5 +LH:5 +end_of_record diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/ruby.png b/static/samples_rust_coverage/grcov_llvm_lcov/ruby.png new file mode 100644 index 00000000..991b6d4e Binary files /dev/null and b/static/samples_rust_coverage/grcov_llvm_lcov/ruby.png differ diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/snow.png b/static/samples_rust_coverage/grcov_llvm_lcov/snow.png new file mode 100644 index 00000000..2cdae107 Binary files /dev/null and b/static/samples_rust_coverage/grcov_llvm_lcov/snow.png differ diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail-sort-f.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail-sort-f.html new file mode 100644 index 00000000..4c8e2e57 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail-sort-f.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( hide details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
94.6%94.6%
+
94.6 %70 / 7490.0 %18 / 20
<unnamed>94.6 %70 / 7490.0 %18 / 20
second.rs +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
<unnamed>100.0 %5 / 5100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail-sort-l.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail-sort-l.html new file mode 100644 index 00000000..a70098c8 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail-sort-l.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( hide details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
94.6%94.6%
+
94.6 %70 / 7490.0 %18 / 20
<unnamed>94.6 %70 / 7490.0 %18 / 20
second.rs +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
<unnamed>100.0 %5 / 5100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail.html new file mode 100644 index 00000000..057dbcf8 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-detail.html @@ -0,0 +1,128 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( hide details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
94.6%94.6%
+
94.6 %70 / 7490.0 %18 / 20
<unnamed>94.6 %70 / 7490.0 %18 / 20
second.rs +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
<unnamed>100.0 %5 / 5100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/index-sort-f.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-sort-f.html new file mode 100644 index 00000000..261c980d --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-sort-f.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( show details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
94.6%94.6%
+
94.6 %70 / 7490.0 %18 / 20
second.rs +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/index-sort-l.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-sort-l.html new file mode 100644 index 00000000..4f65d7fa --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/index-sort-l.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( show details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
94.6%94.6%
+
94.6 %70 / 7490.0 %18 / 20
second.rs +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/index.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/index.html new file mode 100644 index 00000000..23b3224e --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/index.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcovLines:757994.9 %
Date:2024-01-12 19:04:51Functions:192190.5 %
Legend: Rating: + low: < 75 % + medium: >= 75 % + high: >= 90 % +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage ( show details ) Sort by line coverageFunctions Sort by function coverage
main.rs +
94.6%94.6%
+
94.6 %70 / 7490.0 %18 / 20
second.rs +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.func-sort-c.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.func-sort-c.html new file mode 100644 index 00000000..dea706e2 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.func-sort-c.html @@ -0,0 +1,160 @@ + + + + + + + LCOV - lcov - src/main.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)HitTotalCoverage
Test:lcovLines:707494.6 %
Date:2024-01-12 19:04:51Functions:182090.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::largest::<_>0
tmp::main0
tmp::largest::<char>1
tmp::largest::<i32>1
tmp::largest::<u8>1
tmp::tests::check_generic1
tmp::tests::check_generic::{closure#0}1
tmp::tests::check_match1
tmp::tests::check_match21
tmp::tests::check_match2::{closure#0}1
tmp::tests::check_match::{closure#0}1
tmp::tests::check_not_panic1
tmp::tests::check_not_panic::{closure#0}1
tmp::tests::check_panic1
tmp::tests::check_panic::{closure#0}1
tmp::tests::parser_detects_errors1
tmp::tests::parser_detects_errors::{closure#0}1
tmp::validate_data_generics1
tmp::validate_data_match1
tmp::validate_data_simple1
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.func.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.func.html new file mode 100644 index 00000000..350c3bd9 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.func.html @@ -0,0 +1,160 @@ + + + + + + + LCOV - lcov - src/main.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)HitTotalCoverage
Test:lcovLines:707494.6 %
Date:2024-01-12 19:04:51Functions:182090.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::largest::<_>0
tmp::largest::<char>1
tmp::largest::<i32>1
tmp::largest::<u8>1
tmp::main0
tmp::tests::check_generic1
tmp::tests::check_generic::{closure#0}1
tmp::tests::check_match1
tmp::tests::check_match21
tmp::tests::check_match2::{closure#0}1
tmp::tests::check_match::{closure#0}1
tmp::tests::check_not_panic1
tmp::tests::check_not_panic::{closure#0}1
tmp::tests::check_panic1
tmp::tests::check_panic::{closure#0}1
tmp::tests::parser_detects_errors1
tmp::tests::parser_detects_errors::{closure#0}1
tmp::validate_data_generics1
tmp::validate_data_match1
tmp::validate_data_simple1
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.gcov.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.gcov.html new file mode 100644 index 00000000..926438e5 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/main.rs.gcov.html @@ -0,0 +1,191 @@ + + + + + + + LCOV - lcov - src/main.rs + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - main.rs (source / functions)HitTotalCoverage
Test:lcovLines:707494.6 %
Date:2024-01-12 19:04:51Functions:182090.0 %
Legend: Lines: + hit + not hit +
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : mod second;
+       2             : 
+       3           0 : fn main() { println!("Hello, world!"); }
+       4             : 
+       5           2 : fn validate_data_simple(data: &Data) -> Result<(), ()> {
+       6           2 :     if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
+       7           0 :     if data.len as usize != data.content.len() { return Err(()) }
+       8           0 :     return Ok(());
+       9           2 : }
+      10             : 
+      11           4 : fn validate_data_match(data: &Data) -> i32 {
+      12           4 :     let x: u32 = match data.content.parse::<u32>() {
+      13           2 :         Ok(_x) => {
+      14           2 :             let y = 2 * _x;
+      15           2 :             if y < 6 {
+      16           0 :                 y
+      17             :             } else {
+      18           2 :                 y * 2
+      19             :             }
+      20             :         }
+      21           2 :         Err(_) => 0
+      22             :     };
+      23           4 :     if x == 0 {
+      24           2 :         -1
+      25             :     } else {
+      26           2 :         (x as i32) + 1
+      27             :     }
+      28           4 : }
+      29             : 
+      30             : // https://doc.rust-lang.org/book/ch10-01-syntax.html
+      31           6 : fn largest<T: PartialOrd>(list: &[T]) -> &T {
+      32           6 :     let mut largest = &list[0];
+      33          30 :     for item in list {
+      34          24 :         if item > largest {
+      35           6 :             largest = item;
+      36          18 :         }
+      37             :     }
+      38           6 :     largest
+      39           6 : }
+      40             : 
+      41           2 : fn validate_data_generics(data: &Data) {
+      42           2 :     let number_list = vec![34, 50, 25, 100, 65];
+      43           2 : 
+      44           2 :     let result = largest(&number_list);
+      45           2 :     println!("The largest number is {}", result);
+      46           2 : 
+      47           2 :     let char_list = vec!['y', 'm', 'a', 'q'];
+      48           2 : 
+      49           2 :     let result = largest(&char_list);
+      50           2 :     println!("The largest char is {}", result);
+      51           2 : 
+      52           2 :     let result = largest(data.content.as_bytes());
+      53           2 :     println!("The largest content char is {}", result);
+      54           2 : }
+      55             : 
+      56             : struct Data {
+      57             :     magic: [u8; 2],
+      58             :     len: u8,
+      59             :     content: String
+      60             : }
+      61             : 
+      62             : #[cfg(test)]
+      63             : mod tests {
+      64             :     use crate::second::validate_data_panic;
+      65             :     use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
+      66             : 
+      67           2 :     #[test]
+      68           2 :     fn parser_detects_errors() {
+      69           2 :         let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
+      70           2 :         blob.content = blob.content + "Y";
+      71           2 :         let result = validate_data_simple(&blob);
+      72           2 :         assert!(result.is_err());
+      73           2 :     }
+      74             : 
+      75           2 :     #[test]
+      76           2 :     fn check_match() {
+      77           2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
+      78           2 :         let x = validate_data_match(&blob);
+      79           2 :         assert_eq!(x, -1);
+      80           2 :     }
+      81             : 
+      82           2 :     #[test]
+      83           2 :     fn check_match2() {
+      84           2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
+      85           2 :         let x = validate_data_match(&blob);
+      86           2 :         assert_eq!(x, 161);
+      87           2 :     }
+      88             : 
+      89           2 :     #[test]
+      90           2 :     fn check_generic() {
+      91           2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
+      92           2 :         validate_data_generics(&blob);
+      93           2 :     }
+      94             : 
+      95           2 :     #[test]
+      96             :     #[should_panic]
+      97           2 :     fn check_panic() {
+      98           2 :         let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
+      99           2 :         validate_data_panic(&blob);
+     100           2 :     }
+     101             : 
+     102           2 :     #[test]
+     103           2 :     fn check_not_panic() {
+     104           2 :         let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
+     105           2 :         validate_data_panic(&blob);
+     106           2 :     }
+     107             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.func-sort-c.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.func-sort-c.html new file mode 100644 index 00000000..f80aaefc --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov - src/second.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)HitTotalCoverage
Test:lcovLines:55100.0 %
Date:2024-01-12 19:04:51Functions:11100.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::second::validate_data_panic1
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.func.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.func.html new file mode 100644 index 00000000..825f29d2 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov - src/second.rs - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)HitTotalCoverage
Test:lcovLines:55100.0 %
Date:2024-01-12 19:04:51Functions:11100.0 %
Legend: Lines: + hit + not hit +
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
tmp::second::validate_data_panic1
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.gcov.html b/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.gcov.html new file mode 100644 index 00000000..937b7c96 --- /dev/null +++ b/static/samples_rust_coverage/grcov_llvm_lcov/src/second.rs.gcov.html @@ -0,0 +1,91 @@ + + + + + + + LCOV - lcov - src/second.rs + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - second.rs (source / functions)HitTotalCoverage
Test:lcovLines:55100.0 %
Date:2024-01-12 19:04:51Functions:11100.0 %
Legend: Lines: + hit + not hit +
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : use crate::Data;
+       2             : 
+       3           4 : pub(crate) fn validate_data_panic(data: &Data) {
+       4           4 :     if data.len == 0 {
+       5           2 :         panic!("panic")
+       6           2 :     }
+       7           2 : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/static/samples_rust_coverage/grcov_llvm_lcov/updown.png b/static/samples_rust_coverage/grcov_llvm_lcov/updown.png new file mode 100644 index 00000000..aa56a238 Binary files /dev/null and b/static/samples_rust_coverage/grcov_llvm_lcov/updown.png differ diff --git a/static/samples_rust_coverage/llvm_cov/coverage/home/test/src/main.rs.html b/static/samples_rust_coverage/llvm_cov/coverage/home/test/src/main.rs.html new file mode 100644 index 00000000..18b2527b --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov/coverage/home/test/src/main.rs.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2024-01-12 19:04

/home/test/src/main.rs
Line
Count
Source (jump to first uncovered line)
1
mod second;
2
3
0
fn main() { println!("Hello, world!"); }
4
5
1
fn validate_data_simple(data: &Data) -> Result<(), ()> {
6
1
    if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
7
0
    if data.len as usize != data.content.len() { return Err(()) }
8
0
    return Ok(());
9
1
}
10
11
2
fn validate_data_match(data: &Data) -> i32 {
12
2
    let x: u32 = match data.content.parse::<u32>() {
13
1
        Ok(_x) => {
14
1
            let y = 2 * _x;
15
1
            if y < 6 {
16
0
                y
17
            } else {
18
1
                y * 2
19
            }
20
        }
21
1
        Err(_) => 0
22
    };
23
2
    if x == 0 {
24
1
        -1
25
    } else {
26
1
        (x as i32) + 1
27
    }
28
2
}
29
30
// https://doc.rust-lang.org/book/ch10-01-syntax.html
31
3
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
3
    let mut largest = &list[0];
33
15
    for 
item12
in list {
34
12
        if item > largest {
35
3
            largest = item;
36
9
        }
37
    }
38
3
    largest
39
3
}
tmp::largest::<u8>
Line
Count
Source
31
1
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
1
    let mut largest = &list[0];
33
4
    for 
item3
in list {
34
3
        if item > largest {
35
1
            largest = item;
36
2
        }
37
    }
38
1
    largest
39
1
}
tmp::largest::<i32>
Line
Count
Source
31
1
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
1
    let mut largest = &list[0];
33
6
    for 
item5
in list {
34
5
        if item > largest {
35
2
            largest = item;
36
3
        }
37
    }
38
1
    largest
39
1
}
tmp::largest::<char>
Line
Count
Source
31
1
fn largest<T: PartialOrd>(list: &[T]) -> &T {
32
1
    let mut largest = &list[0];
33
5
    for 
item4
in list {
34
4
        if item > largest {
35
0
            largest = item;
36
4
        }
37
    }
38
1
    largest
39
1
}
40
41
1
fn validate_data_generics(data: &Data) {
42
1
    let number_list = vec![34, 50, 25, 100, 65];
43
1
44
1
    let result = largest(&number_list);
45
1
    println!("The largest number is {}", result);
46
1
47
1
    let char_list = vec!['y', 'm', 'a', 'q'];
48
1
49
1
    let result = largest(&char_list);
50
1
    println!("The largest char is {}", result);
51
1
52
1
    let result = largest(data.content.as_bytes());
53
1
    println!("The largest content char is {}", result);
54
1
}
55
56
struct Data {
57
    magic: [u8; 2],
58
    len: u8,
59
    content: String
60
}
61
62
#[cfg(test)]
63
mod tests {
64
    use crate::second::validate_data_panic;
65
    use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
66
67
1
    #[test]
68
1
    fn parser_detects_errors() {
69
1
        let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
70
1
        blob.content = blob.content + "Y";
71
1
        let result = validate_data_simple(&blob);
72
1
        assert!(result.is_err());
73
1
    }
74
75
1
    #[test]
76
1
    fn check_match() {
77
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
78
1
        let x = validate_data_match(&blob);
79
1
        assert_eq!(x, -1);
80
1
    }
81
82
1
    #[test]
83
1
    fn check_match2() {
84
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
85
1
        let x = validate_data_match(&blob);
86
1
        assert_eq!(x, 161);
87
1
    }
88
89
1
    #[test]
90
1
    fn check_generic() {
91
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
92
1
        validate_data_generics(&blob);
93
1
    }
94
95
1
    #[test]
96
    #[should_panic]
97
1
    fn check_panic() {
98
1
        let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
99
1
        validate_data_panic(&blob);
100
1
    }
101
102
1
    #[test]
103
1
    fn check_not_panic() {
104
1
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
105
1
        validate_data_panic(&blob);
106
1
    }
107
}
\ No newline at end of file diff --git a/static/samples_rust_coverage/llvm_cov/coverage/home/test/src/second.rs.html b/static/samples_rust_coverage/llvm_cov/coverage/home/test/src/second.rs.html new file mode 100644 index 00000000..eaa6faeb --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov/coverage/home/test/src/second.rs.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2024-01-12 19:04

/home/test/src/second.rs
Line
Count
Source
1
use crate::Data;
2
3
2
pub(crate) fn validate_data_panic(data: &Data) {
4
2
    if data.len == 0 {
5
1
        panic!("panic")
6
1
    }
7
1
}
\ No newline at end of file diff --git a/static/samples_rust_coverage/llvm_cov/index.html b/static/samples_rust_coverage/llvm_cov/index.html new file mode 100644 index 00000000..61e066ec --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov/index.html @@ -0,0 +1 @@ +

Coverage Report

Created: 2024-01-12 19:04

Click here for information about interpreting this report.

FilenameFunction CoverageLine CoverageRegion CoverageBranch Coverage
main.rs
  94.12% (16/17)
  94.59% (70/74)
  88.37% (38/43)
- (0/0)
second.rs
 100.00% (1/1)
 100.00% (5/5)
 100.00% (3/3)
- (0/0)
Totals
  94.44% (17/18)
  94.94% (75/79)
  89.13% (41/46)
- (0/0)
Generated by llvm-cov -- llvm version 17.0.4-rust-1.74.0-stable
\ No newline at end of file diff --git a/static/samples_rust_coverage/llvm_cov/style.css b/static/samples_rust_coverage/llvm_cov/style.css new file mode 100644 index 00000000..d95ffe27 --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov/style.css @@ -0,0 +1,143 @@ +.red { + background-color: #ffd0d0; +} +.cyan { + background-color: cyan; +} +body { + font-family: -apple-system, sans-serif; +} +pre { + margin-top: 0px !important; + margin-bottom: 0px !important; +} +.source-name-title { + padding: 5px 10px; + border-bottom: 1px solid #dbdbdb; + background-color: #eee; + line-height: 35px; +} +.centered { + display: table; + margin-left: left; + margin-right: auto; + border: 1px solid #dbdbdb; + border-radius: 3px; +} +.expansion-view { + background-color: rgba(0, 0, 0, 0); + margin-left: 0px; + margin-top: 5px; + margin-right: 5px; + margin-bottom: 5px; + border: 1px solid #dbdbdb; + border-radius: 3px; +} +table { + border-collapse: collapse; +} +.light-row { + background: #ffffff; + border: 1px solid #dbdbdb; +} +.light-row-bold { + background: #ffffff; + border: 1px solid #dbdbdb; + font-weight: bold; +} +.column-entry { + text-align: left; +} +.column-entry-bold { + font-weight: bold; + text-align: left; +} +.column-entry-yellow { + text-align: left; + background-color: #ffffd0; +} +.column-entry-yellow:hover { + background-color: #fffff0; +} +.column-entry-red { + text-align: left; + background-color: #ffd0d0; +} +.column-entry-red:hover { + background-color: #fff0f0; +} +.column-entry-green { + text-align: left; + background-color: #d0ffd0; +} +.column-entry-green:hover { + background-color: #f0fff0; +} +.line-number { + text-align: right; + color: #aaa; +} +.covered-line { + text-align: right; + color: #0080ff; +} +.uncovered-line { + text-align: right; + color: #ff3300; +} +.tooltip { + position: relative; + display: inline; + background-color: #b3e6ff; + text-decoration: none; +} +.tooltip span.tooltip-content { + position: absolute; + width: 100px; + margin-left: -50px; + color: #FFFFFF; + background: #000000; + height: 30px; + line-height: 30px; + text-align: center; + visibility: hidden; + border-radius: 6px; +} +.tooltip span.tooltip-content:after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + margin-left: -8px; + width: 0; height: 0; + border-top: 8px solid #000000; + border-right: 8px solid transparent; + border-left: 8px solid transparent; +} +:hover.tooltip span.tooltip-content { + visibility: visible; + opacity: 0.8; + bottom: 30px; + left: 50%; + z-index: 999; +} +th, td { + vertical-align: top; + padding: 2px 8px; + border-collapse: collapse; + border-right: solid 1px #eee; + border-left: solid 1px #eee; + text-align: left; +} +td pre { + display: inline-block; +} +td:first-child { + border-left: none; +} +td:last-child { + border-right: none; +} +tr:hover { + background-color: #f0f0f0; +} diff --git a/static/samples_rust_coverage/llvm_cov_pretty/index.html b/static/samples_rust_coverage/llvm_cov_pretty/index.html new file mode 100644 index 00000000..6e3a619e --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov_pretty/index.html @@ -0,0 +1 @@ +Index

Coverage Report

Created at 2024-01-12 19:04

FilenameLine Coverage

94.94 %

Function Coverage

94.44 %

Region Coverage

89.13 %

src/main.rs
94.59 %70 / 74
94.12 %16 / 17
88.37 %38 / 43
src/second.rs
100.00 %5 / 5
100.00 %1 / 1
100.00 %3 / 3
\ No newline at end of file diff --git a/static/samples_rust_coverage/llvm_cov_pretty/src/main.rs.html b/static/samples_rust_coverage/llvm_cov_pretty/src/main.rs.html new file mode 100644 index 00000000..fbc14725 --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov_pretty/src/main.rs.html @@ -0,0 +1 @@ +src/main.rs

src/main.rs

Lines

94.59 %

Functions

94.12 %

Regions

88.37 %

LineCountSource (jump to first uncovered line)
1
mod second;
2
30
fn main() { println!("Hello, world!"); }
4
51
fn validate_data_simple(data: &Data) -> Result<(), ()> {
61
    if !data.magic.eq(&[0x13, 0x37]) { return Err(()) }
70
    if data.len as usize != data.content.len() { return Err(()) }
80
    return Ok(());
91
}
10
112
fn validate_data_match(data: &Data) -> i32 {
122
    let x: u32 = match data.content.parse::<u32>() {
131
        Ok(_x) => {
141
            let y = 2 * _x;
151
            if y < 6 {
160
                y
17
            } else {
181
                y * 2
19
            }
20
        }
211
        Err(_) => 0
22
    };
232
    if x == 0 {
241
        -1
25
    } else {
261
        (x as i32) + 1
27
    }
282
}
29
30
// https://doc.rust-lang.org/book/ch10-01-syntax.html
313
fn largest<T: PartialOrd>(list: &[T]) -> &T {
323
    let mut largest = &list[0];
3315
    for item in list {
343
        if item > largest {
353
            largest = item;
369
        }
37
    }
383
    largest
393
}
40
411
fn validate_data_generics(data: &Data) {
421
    let number_list = vec![34, 50, 25, 100, 65];
431
441
    let result = largest(&number_list);
451
    println!("The largest number is {}", result);
461
471
    let char_list = vec!['y', 'm', 'a', 'q'];
481
491
    let result = largest(&char_list);
501
    println!("The largest char is {}", result);
511
521
    let result = largest(data.content.as_bytes());
531
    println!("The largest content char is {}", result);
541
}
55
56
struct Data {
57
    magic: [u8; 2],
58
    len: u8,
59
    content: String
60
}
61
62
#[cfg(test)]
63
mod tests {
64
    use crate::second::validate_data_panic;
65
    use crate::{Data, validate_data_generics, validate_data_match, validate_data_simple};
66
671
    #[test]
681
    fn parser_detects_errors() {
691
        let mut blob = Data{ magic: [0x73, 0x31], len: 2, content: "AB".parse().unwrap() };
701
        blob.content = blob.content + "Y";
711
        let result = validate_data_simple(&blob);
721
        assert!(result.is_err());
731
    }
74
751
    #[test]
761
    fn check_match() {
771
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "XX".parse().unwrap() };
781
        let x = validate_data_match(&blob);
791
        assert_eq!(x, -1);
801
    }
81
821
    #[test]
831
    fn check_match2() {
841
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "40".parse().unwrap() };
851
        let x = validate_data_match(&blob);
861
        assert_eq!(x, 161);
871
    }
88
891
    #[test]
901
    fn check_generic() {
911
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "QWE".parse().unwrap() };
921
        validate_data_generics(&blob);
931
    }
94
951
    #[test]
96
    #[should_panic]
971
    fn check_panic() {
981
        let blob = Data{ magic: [0x73, 0x31], len: 0, content: "4".parse().unwrap() };
991
        validate_data_panic(&blob);
1001
    }
101
1021
    #[test]
1031
    fn check_not_panic() {
1041
        let blob = Data{ magic: [0x73, 0x31], len: 2, content: "4".parse().unwrap() };
1051
        validate_data_panic(&blob);
1061
    }
107
}
\ No newline at end of file diff --git a/static/samples_rust_coverage/llvm_cov_pretty/src/second.rs.html b/static/samples_rust_coverage/llvm_cov_pretty/src/second.rs.html new file mode 100644 index 00000000..00a878dd --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov_pretty/src/second.rs.html @@ -0,0 +1 @@ +src/second.rs

src/second.rs

Lines

100.00 %

Functions

100.00 %

Regions

100.00 %

LineCountSource
1
use crate::Data;
2
32
pub(crate) fn validate_data_panic(data: &Data) {
42
    if data.len == 0 {
51
        panic!("panic")
61
    }
71
}
\ No newline at end of file diff --git a/static/samples_rust_coverage/llvm_cov_pretty/style.css b/static/samples_rust_coverage/llvm_cov_pretty/style.css new file mode 100644 index 00000000..b9fb4317 --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov_pretty/style.css @@ -0,0 +1 @@ +/*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}body{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){body{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(241 245 249/var(--tw-text-opacity))}}a{color:rgb(37 99 235/var(--tw-text-opacity))}a,a:hover{--tw-text-opacity:1}a:hover{color:rgb(29 78 216/var(--tw-text-opacity));text-decoration-line:underline}@media (prefers-color-scheme:dark){a{color:rgb(96 165 250/var(--tw-text-opacity))}a,a:hover{--tw-text-opacity:1}a:hover{color:rgb(147 197 253/var(--tw-text-opacity))}}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.index-area{margin:1rem}.index-title{padding-bottom:2rem;font-size:1.875rem;line-height:2.25rem}.index-date{padding-bottom:2rem;font-size:1.125rem;line-height:1.75rem;font-weight:700}.index-table{width:100%;border-collapse:collapse;border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.index-table{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity))}}.index-table td,.index-table th{border-top-width:1px;border-bottom-width:1px;--tw-border-opacity:1;border-color:rgb(100 116 139/var(--tw-border-opacity));padding-left:.5rem;padding-right:.5rem}.index-table td:hover,.index-table th:hover{background-color:#33415540}@media (prefers-color-scheme:dark){.index-table td:hover,.index-table th:hover{background-color:#cbd5e140}}.index-table tr:last-child td,.index-table tr:last-child th{border-style:none}.index-table td:not(:first-child){text-align:center}.index-table td:nth-child(2),.index-table td:nth-child(5),.index-table td:nth-child(8){visibility:collapse}@media (min-width:1024px){.index-table td:nth-child(2),.index-table td:nth-child(5),.index-table td:nth-child(8){visibility:visible}}.index-header th{padding-top:.5rem;padding-bottom:.5rem;vertical-align:top}.index-header p{font-size:1.25rem;line-height:1.75rem;font-weight:700}.progress-bar{height:.75rem;border-radius:9999px;--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.progress-bar{--tw-bg-opacity:1;background-color:rgb(100 116 139/var(--tw-bg-opacity))}}@media (min-width:1024px){.progress-bar{min-width:6rem}}.progress-bar div:only-child{height:.75rem;border-radius:9999px}@media (min-width:1024px){.progress-bar div:only-child{min-width:.75rem}}.source-area{margin:1rem;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.source-area{--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity))}}.source-path{-webkit-user-select:text;-moz-user-select:text;user-select:text;padding:1rem}.source-coverage{margin-top:1rem;margin-bottom:1rem;display:flex;flex-direction:row;justify-content:space-evenly;text-align:center;font-weight:700}.source-coverage p:first-child{font-size:.875rem;line-height:1.25rem}.source-coverage p:nth-child(2){font-size:1.25rem;line-height:1.75rem}.source-table{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:.875rem;line-height:1.25rem}.source-table td{padding:0}.source-table thead{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.source-table thead th{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity));padding:.5rem;text-align:left}@media (prefers-color-scheme:dark){.source-table thead th{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity))}}.source-table tbody tr{padding:0}.source-table tbody tr:hover{background-color:#33415540}@media (prefers-color-scheme:dark){.source-table tbody tr:hover{background-color:#cbd5e140}}.source-table tbody tr td:first-child,.source-table tbody tr td:nth-child(2){--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity));padding-left:.5rem;padding-right:.5rem;text-align:right;vertical-align:top}@media (prefers-color-scheme:dark){.source-table tbody tr td:first-child,.source-table tbody tr td:nth-child(2){--tw-bg-opacity:1;background-color:rgb(51 65 85/var(--tw-bg-opacity))}}.source-table tbody tr td:nth-child(3){width:100%;cursor:text;-webkit-user-select:text;-moz-user-select:text;user-select:text}.source-table tbody tr td:nth-child(3) pre{padding-left:.5rem}.source-message{margin:.5rem;border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity));padding:.5rem}@media (prefers-color-scheme:dark){.source-message{--tw-bg-opacity:1;background-color:rgb(71 85 105/var(--tw-bg-opacity))}}.covered{--tw-bg-opacity:1;background-color:rgb(74 222 128/var(--tw-bg-opacity))}.covered:hover{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.covered{--tw-bg-opacity:1;background-color:rgb(22 101 52/var(--tw-bg-opacity))}.covered:hover{--tw-bg-opacity:1;background-color:rgb(21 128 61/var(--tw-bg-opacity))}}.uncovered{--tw-bg-opacity:1;background-color:rgb(248 113 113/var(--tw-bg-opacity))}.uncovered:hover{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.uncovered{--tw-bg-opacity:1;background-color:rgb(153 27 27/var(--tw-bg-opacity))}.uncovered:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity))}}.partially-covered{--tw-bg-opacity:1;background-color:rgb(250 204 21/var(--tw-bg-opacity))}.partially-covered:hover{--tw-bg-opacity:1;background-color:rgb(234 179 8/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.partially-covered{--tw-bg-opacity:1;background-color:rgb(133 77 14/var(--tw-bg-opacity))}.partially-covered:hover{--tw-bg-opacity:1;background-color:rgb(161 98 7/var(--tw-bg-opacity))}}.gutter.covered{--tw-bg-opacity:1!important;background-color:rgb(74 222 128/var(--tw-bg-opacity))!important}@media (prefers-color-scheme:dark){.gutter.covered{--tw-bg-opacity:1!important;background-color:rgb(22 101 52/var(--tw-bg-opacity))!important}}.gutter.uncovered{--tw-bg-opacity:1!important;background-color:rgb(248 113 113/var(--tw-bg-opacity))!important}@media (prefers-color-scheme:dark){.gutter.uncovered{--tw-bg-opacity:1!important;background-color:rgb(153 27 27/var(--tw-bg-opacity))!important}}.gutter.partially-covered{--tw-bg-opacity:1!important;background-color:rgb(250 204 21/var(--tw-bg-opacity))!important}@media (prefers-color-scheme:dark){.gutter.partially-covered{--tw-bg-opacity:1!important;background-color:rgb(133 77 14/var(--tw-bg-opacity))!important}}.page-footer{padding-left:1rem;padding-top:1rem;font-size:.875rem;line-height:1.25rem;font-weight:700}.level-text-veryhigh{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-veryhigh{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity))}}.level-text-high{--tw-text-opacity:1;color:rgb(234 179 8/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-high{--tw-text-opacity:1;color:rgb(202 138 4/var(--tw-text-opacity))}}.level-text-medium{--tw-text-opacity:1;color:rgb(245 158 11/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-medium{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity))}}.level-text-low{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}@media (prefers-color-scheme:dark){.level-text-low{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}}.level-bg-veryhigh{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-veryhigh{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity))}}.level-bg-high{--tw-bg-opacity:1;background-color:rgb(234 179 8/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-high{--tw-bg-opacity:1;background-color:rgb(202 138 4/var(--tw-bg-opacity))}}.level-bg-medium{--tw-bg-opacity:1;background-color:rgb(245 158 11/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-medium{--tw-bg-opacity:1;background-color:rgb(217 119 6/var(--tw-bg-opacity))}}.level-bg-low{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}@media (prefers-color-scheme:dark){.level-bg-low{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity))}}.block{display:block}.table{display:table} \ No newline at end of file diff --git a/static/samples_rust_coverage/llvm_cov_pretty/syntax.css b/static/samples_rust_coverage/llvm_cov_pretty/syntax.css new file mode 100644 index 00000000..ed0020ed --- /dev/null +++ b/static/samples_rust_coverage/llvm_cov_pretty/syntax.css @@ -0,0 +1 @@ +.syntect-code{color:#383a42;background-color:#fafafa}.syntect-comment{color:#a0a1a7}.syntect-variable.syntect-parameter.syntect-function{color:#383a42}.syntect-keyword{color:#a626a4}.syntect-variable{color:#e45649}.syntect-entity.syntect-name.syntect-function,.syntect-meta.syntect-require,.syntect-support.syntect-function.syntect-any-method{color:#0184bc}.syntect-entity.syntect-name.syntect-class,.syntect-entity.syntect-name.syntect-type.syntect-class,.syntect-support.syntect-class{color:#c18401}.syntect-meta.syntect-class{color:#c18401}.syntect-keyword.syntect-other.syntect-special-method{color:#0184bc}.syntect-storage{color:#a626a4}.syntect-support.syntect-function{color:#0184bc}.syntect-string{color:#50a14f}.syntect-constant.syntect-numeric{color:#c18401}.syntect-none{color:#c18401}.syntect-none{color:#c18401}.syntect-constant{color:#c18401}.syntect-entity.syntect-name.syntect-tag{color:#e45649}.syntect-entity.syntect-other.syntect-attribute-name{color:#c18401}.syntect-entity.syntect-other.syntect-attribute-name.syntect-id,.syntect-punctuation.syntect-definition.syntect-entity{color:#c18401}.syntect-meta.syntect-selector{color:#a626a4}.syntect-entity.syntect-name.syntect-section,.syntect-markup.syntect-heading .syntect-punctuation.syntect-definition.syntect-heading{color:#0184bc}.syntect-markup.syntect-bold,.syntect-punctuation.syntect-definition.syntect-bold{color:#a626a4}.syntect-markup.syntect-italic,.syntect-punctuation.syntect-definition.syntect-italic{color:#a626a4}.syntect-markup.syntect-raw.syntect-inline{color:#50a14f}.syntect-meta.syntect-link{color:#50a14f}.syntect-markup.syntect-quote{color:#50a14f}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-method.syntect-java{color:#383a42}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-class.syntect-body.syntect-java{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-function.syntect-js .syntect-variable.syntect-parameter.syntect-function.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e45649}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-function.syntect-js{color:#383a42}.syntect-source.syntect-js .syntect-meta.syntect-property.syntect-object.syntect-js .syntect-entity.syntect-name.syntect-function.syntect-js{color:#0184bc}.syntect-source.syntect-js .syntect-support.syntect-constant.syntect-prototype.syntect-js{color:#383a42}.syntect-markup.syntect-inserted{color:#98c379}.syntect-markup.syntect-deleted{color:#e06c75}.syntect-markup.syntect-changed{color:#e5c07b}.syntect-string.syntect-regexp{color:#50a14f}.syntect-constant.syntect-character.syntect-escape{color:#0997b3}.syntect-invalid.syntect-illegal{color:#fafafa;background-color:#e06c75}.syntect-invalid.syntect-broken{color:#fafafa;background-color:#e5c07b}.syntect-invalid.syntect-deprecated{color:#fafafa;background-color:#e5c07b}.syntect-invalid.syntect-unimplemented{color:#fafafa;background-color:#c678dd}@media (prefers-color-scheme:dark){.syntect-code{color:#dcdfe4;background-color:#282c34}.syntect-comment{color:#5c6370}.syntect-variable.syntect-parameter.syntect-function{color:#dcdfe4}.syntect-keyword{color:#c678dd}.syntect-variable{color:#e06c75}.syntect-entity.syntect-name.syntect-function,.syntect-meta.syntect-require,.syntect-support.syntect-function.syntect-any-method{color:#61afef}.syntect-entity.syntect-name.syntect-class,.syntect-entity.syntect-name.syntect-type.syntect-class,.syntect-support.syntect-class{color:#e5c07b}.syntect-meta.syntect-class{color:#e5c07b}.syntect-keyword.syntect-other.syntect-special-method{color:#61afef}.syntect-storage{color:#c678dd}.syntect-support.syntect-function{color:#61afef}.syntect-string{color:#98c379}.syntect-constant.syntect-numeric{color:#e5c07b}.syntect-none{color:#e5c07b}.syntect-none{color:#e5c07b}.syntect-constant{color:#e5c07b}.syntect-entity.syntect-name.syntect-tag{color:#e06c75}.syntect-entity.syntect-other.syntect-attribute-name{color:#e5c07b}.syntect-entity.syntect-other.syntect-attribute-name.syntect-id,.syntect-punctuation.syntect-definition.syntect-entity{color:#e5c07b}.syntect-meta.syntect-selector{color:#c678dd}.syntect-entity.syntect-name.syntect-section,.syntect-markup.syntect-heading .syntect-punctuation.syntect-definition.syntect-heading{color:#61afef}.syntect-markup.syntect-bold,.syntect-punctuation.syntect-definition.syntect-bold{color:#c678dd}.syntect-markup.syntect-italic,.syntect-punctuation.syntect-definition.syntect-italic{color:#c678dd}.syntect-markup.syntect-raw.syntect-inline{color:#98c379}.syntect-meta.syntect-link{color:#98c379}.syntect-markup.syntect-quote{color:#98c379}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-method.syntect-java{color:#dcdfe4}.syntect-source.syntect-java .syntect-meta.syntect-class.syntect-java .syntect-meta.syntect-class.syntect-body.syntect-java{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-function.syntect-js .syntect-variable.syntect-parameter.syntect-function.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#e06c75}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-variable.syntect-other.syntect-object.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-block.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-other.syntect-readwrite.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-function-call.syntect-method.syntect-js .syntect-variable.syntect-function.syntect-js{color:#dcdfe4}.syntect-source.syntect-js .syntect-meta.syntect-property.syntect-object.syntect-js .syntect-entity.syntect-name.syntect-function.syntect-js{color:#61afef}.syntect-source.syntect-js .syntect-support.syntect-constant.syntect-prototype.syntect-js{color:#dcdfe4}.syntect-markup.syntect-inserted{color:#98c379}.syntect-markup.syntect-deleted{color:#e06c75}.syntect-markup.syntect-changed{color:#e5c07b}.syntect-string.syntect-regexp{color:#98c379}.syntect-constant.syntect-character.syntect-escape{color:#56b6c2}.syntect-invalid.syntect-illegal{color:#dcdfe4;background-color:#e06c75}.syntect-invalid.syntect-broken{color:#dcdfe4;background-color:#e5c07b}.syntect-invalid.syntect-deprecated{color:#dcdfe4;background-color:#e5c07b}.syntect-invalid.syntect-unimplemented{color:#dcdfe4;background-color:#c678dd}} \ No newline at end of file diff --git a/static/samples_rust_coverage/tarpaulin-report.html b/static/samples_rust_coverage/tarpaulin-report.html new file mode 100644 index 00000000..457cf2b3 --- /dev/null +++ b/static/samples_rust_coverage/tarpaulin-report.html @@ -0,0 +1,660 @@ + + + + + + + +
+ + + + + + \ No newline at end of file