-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:stellar/stellar-docs into homepage-…
…wayfinding
- Loading branch information
Showing
39 changed files
with
881 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Crowdin Translator How-To | ||
|
||
Stellar Developer Docs use [Crowdin](https://crowdin.com/) for localization. This document provides steps and resources for managing Stellar Docusaurus Crowdin translations as a Crowdin user with a Translator role. | ||
|
||
--- | ||
|
||
## Overview | ||
|
||
As new English source files are added to the Stellar Docusaurus Documentation GitHub repository, they are automatically uploaded to Crowdin. From there, an automated AI translation is run on the files to translate them into other target languages (currently only Spanish at the time of writing). | ||
|
||
In cases where the AI translation is inaccurate, a user with the Translator role will need to update and edit the translations manually. | ||
|
||
--- | ||
|
||
## Translator User | ||
|
||
To get started, you need to set up a Crowdin account and be added to the Stellar Documents Crowdin project. This involves creating a Crowdin user account and requesting access to the project from a project owner. | ||
|
||
For more details, see the following documentation: | ||
[Create an Account](https://support.crowdin.com/for-translators/#create-an-account) | ||
|
||
--- | ||
|
||
## Editor | ||
|
||
As a translator, you will have access to the editor, where you can make changes to the content. | ||
|
||
**Note:** Crowdin uses the term "strings" for content being translated. | ||
|
||
You can access all translated documents via the Crowdin dashboard. From there, you can view each document in the editor. | ||
|
||
For more details on working within the editor, see the following documentation: | ||
[Working in the Editor](https://support.crowdin.com/for-translators/#working-in-the-editor) | ||
|
||
For a more in-depth look, see: | ||
[Online Editor Guide](https://support.crowdin.com/online-editor/) | ||
|
||
--- | ||
|
||
## Glossary | ||
|
||
For common words or phrases, it is good practice to add them to the glossary. The glossary helps the AI translator provide more accurate translations. | ||
|
||
Examples include: | ||
- Words or phrases that need to be translated in a specific manner. | ||
- Words or phrases that should not be translated at all. | ||
|
||
For more information, see the following documentation: | ||
[Glossary](https://support.crowdin.com/glossary/) | ||
|
||
--- | ||
|
||
## Approving Translations | ||
|
||
As documents are translated, they will be assigned a translation percentage highlighted in blue. | ||
|
||
To manage files that have been checked or proofread, it is recommended to mark them as approved. Approved files will display an approved percentage highlighted in green. | ||
|
||
**Note:** All translations are synced with the Stellar Docusaurus Documentation after they are reviewed and approved. Approval is a check for managing translation files that have been edited. | ||
|
||
For more information on approving translations, see the following documentation: | ||
[Proofreading](https://support.crowdin.com/online-editor/#proofreading) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
title: Coverage Testing | ||
hide_table_of_contents: true | ||
description: Coverage testing finds code not tested. | ||
sidebar_position: 10 | ||
draft: true | ||
--- | ||
|
||
**TODO: Fill in example.** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
--- | ||
title: Differential Tests | ||
hide_table_of_contents: true | ||
description: Differential testing detects unintended changes. | ||
sidebar_position: 7 | ||
--- | ||
|
||
Differential testing is the testing of two things to discover differences in their behavior. | ||
|
||
The goal is to prove that the two things behave consistently, and that they do not diverge in behavior except for some expected differences. The assertions should be as broad as possible, broadly testing that all observable outcomes do not change, except for any expected changes. | ||
|
||
This strategy is effective when building something new that should behave like something that already exists. That could be a new version of a contract that has unchanged behavior from it's previous version. Or it could be the same contract with an updated SDK or other dependency. Or it could be a refactor that expects no functional changes. | ||
|
||
This strategy can be used in the context of unit and integration tests, or in the context of fuzz tests as well. | ||
|
||
:::tip | ||
|
||
All contracts built with the Rust Soroban SDK have a form of differential testing built-in and enabled by default. See [Differential Testing with Test Snapshots]. | ||
|
||
::: | ||
|
||
## How to Write Differential Tests | ||
|
||
To experiment with writing a differential test, open a contract that you've deployed, or checkout an example from the [soroban-examples] repository and deploy it. | ||
|
||
Assuming the contract has been deployed, and changes are being made to the local copy. We need to check that unchanged behavior in the contract hasn't changed compared to what is deployed. | ||
|
||
1. Use the [stellar contract fetch] command to fetch the contract that's already deployed. The contract already deployed will be used as a baseline that the local copy is expected to behave like. | ||
|
||
```shell | ||
stellar contract fetch --id C... --out-file contract.wasm | ||
``` | ||
|
||
2. Import the contract into the tests with the `contractimport!` macro. | ||
|
||
```rust | ||
mod deployed { | ||
soroban_sdk::contractimport!(file = "contract.wasm"); | ||
} | ||
``` | ||
|
||
3. Write a test that runs the same logic for the deployed contract and the local contract, comparing the result. Assuming the [increment example] is in use, the test would look something like the following. | ||
|
||
```rust | ||
#![cfg(test)] | ||
use crate::{IncrementContract, IncrementContractClient}; | ||
use soroban_sdk::{testutils::Events as _, Env}; | ||
|
||
mod deployed { | ||
soroban_sdk::contractimport!(file = "contract.wasm"); | ||
} | ||
|
||
#[test] | ||
fn differential_test() { | ||
let env = Env::default(); | ||
assert_eq!( | ||
// Baseline – the deployed contract | ||
{ | ||
let contract_id = env.register(deployed::WASM, ()); | ||
let client = IncrementContractClient::new(&env, &contract_id); | ||
( | ||
// Return Values | ||
( | ||
client.increment(), | ||
client.increment(), | ||
client.increment(), | ||
), | ||
// Events | ||
env.events.all(), | ||
) | ||
}, | ||
// Local – the changed or refactored contract | ||
{ | ||
let contract_id = env.register(IncrementContract, ()); | ||
let client = IncrementContractClient::new(&env, &contract_id); | ||
( | ||
// Return Values | ||
( | ||
client.increment(), | ||
client.increment(), | ||
client.increment(), | ||
), | ||
// Events | ||
env.events.all(), | ||
) | ||
}, | ||
); | ||
} | ||
``` | ||
|
||
4. Run the test to compare the baseline and local observable outcomes. | ||
|
||
This test uses the same patterns used in [unit tests] and [integration tests]: | ||
|
||
1. Create an environment, the `Env`. | ||
2. Import the Wasm contract to compare with. | ||
3. Register the local contract to be tested. | ||
4. Invoke functions using a client. | ||
5. Assert equality. | ||
|
||
:::tip | ||
|
||
Differential tests work best when less assumptions are made. Rather than asserting only on specific return values or on implementation details like specific state, asserting on all observable outcomes and including things like events published or return values of other read-only contract functions will help to discover unexpected changes. | ||
|
||
::: | ||
|
||
:::info | ||
|
||
Depending on the test complexity it can be desirable to use an independent `Env` for testing the deployed vs local. However at the moment it is only possible to compare host values, like `String`, `Bytes`, `Vec`, `Map`, if they've been created using the same `Env`. The tracking issue for supportin comparisons across environments is [stellar/rs-soroban-sdk#1360]. | ||
|
||
::: | ||
|
||
[Getting Started]: ../../smart-contracts/getting-started | ||
[increment example]: https://github.com/stellar/soroban-examples/blob/main/increment/src/lib.rs | ||
[Differential Testing with Test Snapshots]: ./differential-tests-with-test-snapshots.mdx | ||
[stellar contract fetch]: ../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-fetch | ||
[integration tests]: ./integration-tests.mdx | ||
[unit tests]: ./unit-tests.mdx | ||
[stellar/rs-soroban-sdk#1360]: https://github.com/stellar/rs-soroban-sdk/issues/1360 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
--- | ||
title: Fuzzing | ||
hide_table_of_contents: true | ||
description: Fuzzing and property testing to find unexpected behavior. | ||
sidebar_position: 5 | ||
--- | ||
|
||
Fuzzing is the process of providing random data to programs to identify unexpected behavior, such as crashes and panics. | ||
|
||
Fuzz tests can also be written as property tests that instead of seeking to identify panics and crashes, assert on some property remaining true. Fuzzing as demonstrated here and elsewhere in these docs will use principles from both property testing and fuzzing, but will only use the term fuzzing to refer to both. | ||
|
||
The following steps can be used in any Stellar contract workspace. If experimenting, try them in the [increment example]. The contract has an `increment` function that increases a counter value by one on every invocation. | ||
|
||
## How to Write Fuzz Tests | ||
|
||
1. Install `cargo-fuzz`. | ||
|
||
```shell | ||
cargo install --locked cargo-fuzz | ||
``` | ||
|
||
2. Initialize a fuzz project by running the following command inside your contract directory. | ||
|
||
```shell | ||
cargo fuzz init | ||
``` | ||
|
||
3. Open the contract's `Cargo.toml` file. Add `lib` as a `crate-type`. | ||
|
||
```diff | ||
[lib] | ||
-crate-type = ["cdylib"] | ||
+crate-type = ["lib", "cdylib"] | ||
``` | ||
|
||
4. Open the generated `fuzz/Cargo.toml` file. Add the `soroban-sdk` dependency. | ||
|
||
```diff | ||
[dependencies] | ||
libfuzzer-sys = "0.4" | ||
+soroban-sdk = { version = "*", features = ["testutils"] } | ||
``` | ||
|
||
5. Open the generated `fuzz/src/fuzz_target_1.rs` file. It will look like the below. | ||
|
||
```rust | ||
#![no_main] | ||
use libfuzzer_sys::fuzz_target; | ||
|
||
fuzz_target!(|data: &[u8]| { | ||
// fuzzed code goes here | ||
}); | ||
``` | ||
|
||
6. Fill out the `fuzz_target!` call with test setup and assertions. For example, for the [increment example]: | ||
|
||
```rust | ||
#![no_main] | ||
use libfuzzer_sys::fuzz_target; | ||
use soroban_increment_with_fuzz_contract::{IncrementContract, IncrementContractClient}; | ||
use soroban_sdk::{ | ||
testutils::arbitrary::{self, Arbitrary}, | ||
Env, | ||
}; | ||
|
||
#[derive(Debug, Arbitrary)] | ||
pub struct Input { | ||
pub by: u64, | ||
} | ||
|
||
fuzz_target!(|input: Input| { | ||
let env = Env::default(); | ||
let id = env.register(IncrementContract, ()); | ||
let client = IncrementContractClient::new(&env, &id); | ||
|
||
let mut last: Option<u32> = None; | ||
for _ in input.by.. { | ||
match client.try_increment() { | ||
Ok(Ok(current)) => assert!(Some(current) > last), | ||
Err(Ok(_)) => {} // Expected error | ||
Ok(Err(_)) => panic!("success with wrong type returned"), | ||
Err(Err(_)) => panic!("unrecognised error"), | ||
} | ||
} | ||
}); | ||
``` | ||
|
||
7. Execute the fuzz target. | ||
|
||
```shell | ||
cargo +nightly fuzz run --sanitizer=thread fuzz_target_1 | ||
``` | ||
|
||
:::info | ||
|
||
If you're developing on MacOS you need to add the `--sanitizer=thread` flag in order to work around a [known issue](https://github.com/stellar/rs-soroban-sdk/issues/1056). | ||
|
||
::: | ||
|
||
This test uses the same patterns used in [unit tests] and [integration tests]: | ||
|
||
1. Create an environment, the `Env`. | ||
2. Register the contract to be tested. | ||
3. Invoke functions using a client. | ||
4. Assert expectations. | ||
|
||
:::tip | ||
|
||
For a full detailed example, see the [fuzzing example]. | ||
|
||
::: | ||
|
||
:::info | ||
|
||
There is another tool for fuzzing Rust code, `cargo-afl`. See the [Rust Fuzz book] for a tutorial for how to use it. | ||
|
||
::: | ||
|
||
[increment example]: https://github.com/stellar/soroban-examples/blob/main/increment/src/lib.rs | ||
[Differential Testing with Test Snapshots]: ./differential-tests-with-test-snapshots.mdx | ||
[stellar contract fetch]: ../../../tools/developer-tools/cli/stellar-cli.mdx#stellar-contract-fetch | ||
[integration tests]: ./integration-tests.mdx | ||
[unit tests]: ./unit-tests.mdx | ||
[stellar/rs-soroban-sdk#1360]: https://github.com/stellar/rs-soroban-sdk/issues/1360 | ||
[fuzzing example]: ../../smart-contracts/example-contracts/fuzzing.mdx | ||
[Rust Fuzz Book]: https://rust-fuzz.github.io/book |
Oops, something went wrong.