> ## Rust SDK tutorial, times10 function

> Fetch the complete documentation index at: https://antithesis.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

---

You are a *10x programmer* and will soon have your annual performance review, so you are writing a function that takes any number and multiplies it by ten.
If your boss tells you how productive your coworker is, you can use this tool to calculate your 10x-greater productivity and impress him.

You write the function in Rust and at first you use print debugging.
However, this performance review is very important for your career so you decide not to take any chances.
You ultimately decide to thoroughly test this function using the [Antithesis Rust SDK](/docs/reference/sdk/rust/).

The rest of the document walks you through this process.

## Creating your project

### Step 0: Write your project

Begin by writing your function in Rust with `print!()` debugging.

Make a directory where you would like to create your Rust project and `cd` to that directory.

```bash
mkdir myapp
cd myapp
cargo init --bin
```

Edit the file `src/main.rs` with the following content:

```rust
fn main() {
    println!("Hello, world!");
    println!("{} x 10 = {}", 3, times10(3));
    println!("{} x 10 = {}", 8, times10(8));
}

fn times10(x: i32) -> i32 {
    x * 10
}
```

Now build and run.

```
cargo run
```

it will print

```
Hello, world!
3 x 10 = 30
8 x 10 = 80
```

## Using our SDK functions

Recall that the basic SDK workflow is

1. Include the Antithesis SDK dependency in your cargo.toml file.
2. Use SDK functions in your code.
3. Build your code.
4. Deploy your build.

### Step 1: Include the Rust SDK and serde\_json as dependencies

```toml
[package]
name = "myapp"
version = "0.1.0"
edition = "2021"

[dependencies]
antithesis_sdk = "0.1.5"
serde_json = "1.0.25"
```

Include the antithesis\_sdk and json!() macro in your project code by adding these lines to the top of `src/main.rs`:

```rust
use antithesis_sdk::prelude::*;
use serde_json::json;
```

### Step 2. Use SDK functions in your code

You wrote a function to multiply numbers by ten. What sorts of properties should it have? The output should always be even. You should also make sure you are testing a wide variety of inputs, such as both even and odd numbers.

Modify the code. The modifications are individually explained below.

```rust lines
use antithesis_sdk::prelude::*;
use serde_json::json;

fn main() {
    antithesis_init();
    println!("Hello, world!");
    for _i in 0..50 {
        let x = (random::get_random() % 500) as i32;
        println!("{} x 10 = {}", x, times10(x));
    }
}

fn times10(x: i32) -> i32 {
    assert_sometimes!(x % 2 == 1, "input is sometimes odd", &json!({"input": x}));
    let result = x * 10;
    assert_always!(result % 2 == 0, "result is always even", &json!({"result": result}));
    result
}
```

- **Line 1** You imported the Antithesis Rust SDK.

- **Line 2** You imported the json!() macro from the serde\_json crate.

- **Line 5** You called `antithesis_init()` so that assertions will work correctly.

- You added two assertions to times10.
  - **Line 16** You assert that the result is even using an Always Assertion. This is a fairly conventional assertion.
  - **Line 14** You insert a [Sometimes Assertion](/docs/concepts/properties_assertions/sometimes_assertions/), or an assertion that something will happen at least once across the entire testing session. You assert that sometimes during testing, the function will be called with an odd argument.

    The two types of assertions complement one another: *Always Assertions* assert that the behavior is correct,
    whereas *Sometimes Assertions* assert that you are testing under wide enough conditions to surface any potential incorrect behavior.
    In this case, the output would trivially be even if you only passed it even inputs -- you must ensure your properties are not being trivially satisfied!

- **Lines 7-10** You use randomness to call the function with many random values (between 0 and 500). Previously, you called the function with hardcoded values but now you will pass the function random values and test that the output is always even. [This approach is more powerful](/docs/resources/testing_techniques/#leverage-randomness) but makes [Sometimes Assertions](/docs/concepts/properties_assertions/sometimes_assertions/) necessary -- now you must test that you are passing the function odd values, whereas previously the tests were hardcoded so you were certain that you were passing it odd values.

  You call the [random](/docs/generated/sdk/rust/antithesis_sdk/random/) function `get_random` to draw a random number and then pass this random number to `times10`.
  You use a loop to do this fifty times in a row.
  Every time the `times10` function is called in this loop, it triggers the assertions in lines 14 & 16.

- **In summary** You'll test `times10` by passing it a random integer fifty times in a row.
  You've asserted that all fifty outputs must be even and that at least one random input must be odd.

You'll now build your project with [coverage instrumentation](/docs/reference/instrumentation/coverage_instrumentation/).

### Step 3: Build your code

Instrumentation requires a copy of `libvoidstar.so`, so follow
[the Rust instrumentation guide](/docs/reference/sdk/rust/instrumentation/) to obtain a copy.
Suppose it is downloaded to `/usr/lib`.

Change the build commandline as follows:

```bash
# Assumes libvoidstar.so is in /usr/lib
export LIBVOIDSTAR_PATH="/usr/lib"

LD_LIBRARY_PATH="${LIBVOIDSTAR_PATH}" \
RUSTFLAGS=" \
       -Ccodegen-units=1 \
       -Cpasses=sancov-module \
       -Cllvm-args=-sanitizer-coverage-level=3 \
       -Cllvm-args=-sanitizer-coverage-trace-pc-guard \
       -Clink-args=-Wl,--build-id \
       -L${LIBVOIDSTAR_PATH} \
       -lvoidstar \
       " \
cargo build
```

- **Line 2** defines an environment variable that is the absolute path to libvoidstar mentioned above. Yours may be **different**.
- **Line 7** adds the reference to the Antithesis Instrumentation library.
- **Lines 8-10** adds [instrumentation](/docs/reference/sdk/rust/instrumentation/)
- **Line 12** adds the search path for the Antithesis Instrumentation library.

This also requires clang version 14 or above, or else `cargo build` will fail when it encounters the Rust SDK.

### Step 4: Deploy your build

You're now ready to build your project. If you're building for local deployment then you'd be done here, but suppose instead you intend to send your project to Antithesis for testing. Antithesis will explore your software and search for violations of the properties you have defined.

You must send us containers [as described in getting started](/docs/getting_started/setup_guide/docker_compose/).

- The executable should be included in your container. In this example, `target/debug/myapp`.
- The instrumentation symbols should be symlinked (or moved) into a directory named `/symbols` in the root of the appropriate container image. In this case, we've generated an unstripped binary, so we'll just copy or symlink `myapp/myapp_executable` into `/symbols` in the appropriate image.

> **Note**
>
> This example is simplified compared to what the full [quickstart guide](/docs/getting_started/setup_guide/docker_compose/) describes. Note that the function `main` is the workload and `times10` is the software itself. There are no dependencies. The instrumentation symbols will go in the configuration image as stated.

Ultimately, you'll receive a [triage report](/docs/product/reports/) that confirms the properties you defined are true: the output of the function is always even and the inputs to the function are sometimes odd. You now have a well-tested function that can multiply numbers by ten, indisputably proving that you're a *10x programmer*.
