Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test harness #49

Merged
merged 7 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Tests

on:
push:
branches: [ master, '0.[0-9]+' ]
pull_request:
branches: [ master, '0.[0-9]+' ]

jobs:
code-samples:
name: Test code samples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
- name: Generate harness
working-directory: ./tests
run: ./generate.sh
- name: Test code samples
working-directory: ./tests
run: cargo test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
book
tests/src/*
Cargo.lock
4 changes: 2 additions & 2 deletions src/contrib-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ When referring to an item from within another crate,

Examples:

```
```ignore
// We depend on rand_core, therefore can use the Rust path:
/// [`BlockRngCore`]: rand_core::block::BlockRngCore

Expand All @@ -95,7 +95,7 @@ example.
For the most part these files do not have any continuous testing.
Where examples are included (currently only for the `rand_jitter` crate),
we enable continuous testing via `doc_comment` (see
[lib.rs:62 onwards](https://github.com/rust-random/rand/blob/master/rand_jitter/src/lib.rs#L62)).
[lib.rs:62 onwards](https://github.com/rust-random/rngs/blob/master/rand_jitter/src/lib.rs#L62)).

### CHANGELOG files

Expand Down
2 changes: 1 addition & 1 deletion src/contrib-test.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Often test code needs some RNG to test with, but does not need any particular
RNG. In this case, we prefer use of `::test::rng` which is simple, fast to
initialise and deterministic:

```rust
```rust,ignore
let mut rng = ::test::rng(528); // just pick some number
```

Expand Down
2 changes: 1 addition & 1 deletion src/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ thus we may take considerable time to get back to you.

Our works are attributed to "The Rand Project Developers". This is not a
formal entity but merely the collection of all contributors to this project.
For more, see the [COPYRIGHT](COPYRIGHT) file.
For more, see the `COPYRIGHT` file.
vks marked this conversation as resolved.
Show resolved Hide resolved
- **Thank you!**
2 changes: 1 addition & 1 deletion src/crates-gen.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ The following crates implement pseudo-random number generators


[`rand_chacha`]: https://rust-random.github.io/rand/rand_chacha/index.html
[`rand_hc`]: https://rust-random.github.io/rand/rand_hc/index.html
[`rand_hc`]: https://docs.rs/rand_hc/
[`rand_isaac`]: https://docs.rs/rand_isaac/
[`rand_pcg`]: https://rust-random.github.io/rand/rand_pcg/index.html
[`rand_xoshiro`]: https://docs.rs/rand_xoshiro/
Expand Down
2 changes: 1 addition & 1 deletion src/crates.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ platform-dependent random number source, [`rand_core`] defines the API that
generators must implement, and a number of crates like [`rand_chacha`] and
[`rand_xoshiro`] provide pseudo-random generators.

```
```plain
getrandom ┐
└ rand_core ┐
├ rand_chacha ┐
Expand Down
5 changes: 4 additions & 1 deletion src/guide-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
```rust
# extern crate rand;
# use rand::RngCore;
# fn main() {
// get some random data:
let mut data = [0u8; 32];
let mut data = [0u8; 8];
rand::thread_rng().fill_bytes(&mut data);
println!("{:?}", data)
# }
```

## What is randomness?
Expand Down
84 changes: 27 additions & 57 deletions src/guide-dist.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ For maximum flexibility when producing random values, we define the
[`Distribution`] trait:

```rust
# use rand::{Rng, distributions::DistIter};
// a producer of data of type T:
pub trait Distribution<T> {
// the key function:
Expand All @@ -14,7 +15,10 @@ pub trait Distribution<T> {
where
Self: Sized,
R: Rng,
{ ... }
{
// [has a default implementation]
# todo!()
}
}
```

Expand Down Expand Up @@ -86,10 +90,11 @@ Lets go over the distributions by type:
- For SIMD types, each element is sampled as above, for [`Standard`] and
[`Uniform`] (for the latter, `low` and `high` parameters are *also* SIMD
types, effectively sampling from multiple ranges simultaneously). SIMD
support is gated behind a [feature flag](../features.html#simd-support).
support requires using the `simd_support` feature flag and nightly `rustc`.
- For enums, you have to implement uniform sampling yourself. For example, you
could use the following approach:
```rust
# use rand::{Rng, distributions::{Distribution, Standard}};
pub enum Food {
Burger,
Pizza,
Expand All @@ -111,29 +116,15 @@ Lets go over the distributions by type:

# Non-uniform distributions

Non-uniform distributions can be divided into two categories, as follows.
Some of these discrete and all of the continuous distributions have been moved
from the main [`rand`] crate to a dedicated [`rand_distr`] crate.

## Discrete non-uniform distributions

Discrete distributions sample from boolean or integer types. As above, these
can be sampled uniformly, or, as below, via a non-uniform distribution.

Potentially a discrete distribution could sample directly from a set of discrete
values such as a slice or an `enum`. See the section on [Sequences] regarding
Rand's traits for slice and iterator types. Rand does not provide direct
sampling from `enum`s, with the exception of `Option` (see above).

### Booleans
The [`rand`] crate provides only two non-uniform distributions:

The [`Bernoulli`] distribution is a fancy name for generating a boolean
with a given a probability `p` of being `true`, or defined via a
`success : failure` ratio. Often this is described as a *trial* with
probability `p` of *success* (`true`).
- The [`Bernoulli`] distribution simply generates a boolean where the
probability of sampling `true` is some constant (`Bernoulli::new(0.5)`) or
ratio (`Bernoulli::from_ratio(1, 6)`).
- The [`WeightedIndex`] distribution may be used to sample from a sequence of
weighted values. See the [Sequences] section.

The methods [`Rng::gen_bool`] and [`Rng::gen_ratio`] are short-cuts to this
distribution.
Many more distributions are provided by the [`rand_distr`] crate.
dhardy marked this conversation as resolved.
Show resolved Hide resolved

### Integers

Expand All @@ -154,26 +145,6 @@ For example, `u64` values can be attained with `rng.sample(Poisson) as u64`.
Note that out of range float to int conversions with `as` result in undefined
behavior for Rust <1.45 and a saturating conversion for Rust >=1.45.

### Weighted sequences

The [`WeightedIndex`] distribution samples an index from sequence of weights.
See the [Sequences] section for convenience wrappers directly sampling a slice
element.

For example, weighted sampling could be used to model the colour of a marble
sampled from a bucket containing 5 green, 15 red and 80 blue marbles.

Currently the Rand lib only implements *sampling with replacement*, i.e.
repeated sampling assumes the same distribution (that any sampled marble
has been replaced). An alternative distribution implementing
*sampling without replacement* has been
[requested](https://github.com/rust-random/rand/issues/596).

Note also that two implementations of [`WeightedIndex`] are available; the
first is optimised for a small number of samples while
[`alias_method::WeightedIndex`] is optimised for a large number of samples
(where "large" may mean "> 1000"; benchmarks recommended).

## Continuous non-uniform distributions

Continuous distributions model samples drawn from the real number line ℝ, or in
Expand All @@ -190,7 +161,7 @@ deviation. The [`LogNormal`] is related: for sample `X` from the log-normal
distribution, `log(X)` is normally distributed; this "skews" the normal
distribution to avoid negative values and to have a long positive tail.

The [`UnitCircle`] and [`UnitSphereSurface`] distributions simulate uniform
The [`UnitCircle`] and [`UnitSphere`] distributions simulate uniform
sampling from the edge of a circle or surface of a sphere.

The [`Cauchy`] distribution (also known as the Lorentz distribution) is the
Expand All @@ -201,7 +172,7 @@ The [`Beta`] distribution is a two-parameter probability distribution, whose
output values lie between 0 and 1. The [`Dirichlet`] distribution is a
generalisation to any positive number of parameters.

[Sequences]: ../guide-seq.html
[Sequences]: guide-seq.html
[`Distribution`]: ../rand/rand/distributions/trait.Distribution.html
[`distributions`]: ../rand/rand/distributions/index.html
[`rand`]: ../rand/rand/index.html
Expand All @@ -219,16 +190,15 @@ generalisation to any positive number of parameters.
[`Open01`]: ../rand/rand/distributions/struct.Open01.html
[`OpenClosed01`]: ../rand/rand/distributions/struct.OpenClosed01.html
[`Bernoulli`]: ../rand/rand/distributions/struct.Bernoulli.html
[`Binomial`]: ../rand/rand/distributions/struct.Binomial.html
[`Exp`]: ../rand/rand/distributions/struct.Exp.html
[`Normal`]: ../rand/rand/distributions/struct.Normal.html
[`LogNormal`]: ../rand/rand/distributions/struct.LogNormal.html
[`UnitCircle`]: ../rand/rand/distributions/struct.UnitCircle.html
[`UnitSphereSurface`]: ../rand/rand/distributions/struct.UnitSphereSurface.html
[`Cauchy`]: ../rand/rand/distributions/struct.Cauchy.html
[`Poisson`]: ../rand/rand/distributions/struct.Poisson.html
[`Beta`]: ../rand/rand/distributions/struct.Beta.html
[`Dirichlet`]: ../rand/rand/distributions/struct.Dirichlet.html
[`WeightedIndex`]: ../rand/rand/distributions/weighted/struct.WeightedIndex.html
[`alias_method::WeightedIndex`]: ../rand/rand/distributions/weighted/alias_method/struct.WeightedIndex.html
[`Binomial`]: ../rand/rand_distr/struct.Binomial.html
[`Exp`]: ../rand/rand_distr/struct.Exp.html
[`Normal`]: ../rand/rand_distr/struct.Normal.html
[`LogNormal`]: ../rand/rand_distr/struct.LogNormal.html
[`UnitCircle`]: ../rand/rand_distr/struct.UnitCircle.html
[`UnitSphere`]: ../rand/rand_distr/struct.UnitSphere.html
[`Cauchy`]: ../rand/rand_distr/struct.Cauchy.html
[`Poisson`]: ../rand/rand_distr/struct.Poisson.html
[`Beta`]: ../rand/rand_distr/struct.Beta.html
[`Dirichlet`]: ../rand/rand_distr/struct.Dirichlet.html
[`statrs`]: https://github.com/statrs-dev/statrs/
[`WeightedIndex`]: ../rand/rand/distributions/struct.WeightedIndex.html
19 changes: 5 additions & 14 deletions src/guide-err.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,15 @@ reduce to calls to [`RngCore`]'s "infallible" methods. Since most RNGs cannot
fail anyway this is usually not a problem, but the few generators which can may
be forced to fail in this case:

- [`OsRng`] interfaces with the Operating System's generator; in rare cases
this may fail as "not ready" or simply "unavailable".
- [`JitterRng`] is a generator based on timer jitter; if the timer does not
appear to be capable of sufficient precision or is too predictable, this
will fail.
- [`EntropyRng`] is an abstraction over the above, falling back to the next
option when the first fails but ultimately failing if all sources fail
- [`thread_rng`] seeds itself via [`EntropyRng`], thus can potentially fail
on its first use on each thread (though it never fails after the first use)
- [`ReadRng`] tries to read data from its source but fails when the stream
ends or errors (though it retries on interrupt).
- [`OsRng`] is a wrapper over [`getrandom`]. "In general, on supported
platforms, failure is highly unlikely, though not impossible."
dhardy marked this conversation as resolved.
Show resolved Hide resolved
- [`thread_rng`] seeds itself via [`OsRng`] on first use and periodically
thereafter, thus can potentially fail, though unlikely

[`Rng::try_fill`]: ../rand/rand/trait.Rng.html#method.try_fill
[`RngCore::try_fill_bytes`]: ../rand/rand_core/trait.RngCore.html#tymethod.try_fill_bytes
[`SeedableRng::from_rng`]: ../rand/rand_core/trait.SeedableRng.html#method.from_rng
[`RngCore`]: ../rand/rand_core/trait.RngCore.html
[`thread_rng`]: ../rand/rand/fn.thread_rng.html
[`OsRng`]: ../rand/rand/rngs/struct.OsRng.html
[`JitterRng`]: ../rand/rand/rngs/struct.JitterRng.html
[`EntropyRng`]: ../rand/rand/rngs/struct.EntropyRng.html
[`ReadRng`]: ../rand/rand/rngs/adapter/struct.ReadRng.html
[`getrandom`]: https://docs.rs/getrandom/latest/getrandom/
9 changes: 7 additions & 2 deletions src/guide-gen.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ This section concerns theory; see also the chapter on
```rust
# extern crate rand;
# extern crate rand_pcg;
use rand::{Rng, SeedableRng};

# fn main() {
// prepare a non-deterministic random number generator:
let mut rng = rand::thread_rng();
println!("{}", rng.gen::<i32>());

// prepare a deterministic generator:
use rand::SeedableRng;
let mut rng = rand_pcg::Pcg32::seed_from_u64(123);
println!("{}", rng.gen::<i32>());
# }
```

## True random number generators
Expand Down Expand Up @@ -125,4 +130,4 @@ couple of bits entropy is available per time-stamp, after running several tests
on the timer's quality).

[`RngCore`]: ../rand/rand_core/trait.RngCore.html
[`JitterRng`]: ../rand/rand/rngs/jitter/struct.JitterRng.html
[`JitterRng`]: https://docs.rs/rand_jitter/latest/rand_jitter/struct.JitterRng.html
16 changes: 9 additions & 7 deletions src/guide-rngs.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,11 @@ for recommendations.
It is worth noting that a CSPRNG's security relies absolutely on being
seeded with a secure random key. Should the key be known or guessable, all
output of the CSPRNG is easy to guess. This implies that the seed should
come from a trusted source; usually either the OS or another CSPRNG. Our
seeding helper trait, [`FromEntropy`], and the source it uses
([`EntropyRng`]), should be secure. Additionally, [`ThreadRng`] is a CSPRNG,
thus it is acceptable to seed from this (although for security applications
fresh/external entropy should be preferred).
come from a trusted source; usually either the OS or another CSPRNG. For this
purpose, we recommend using the [`getrandom`] crate which interfaces the OS's
secure random interface. [`SeedableRng::from_entropy`] is a wrapper around
[`getrandom`] for convenience. Alternatively, using a user-space CSPRNG such as
[`ThreadRng`] for seeding should be sufficient.

Further, it should be obvious that the internal state of a CSPRNG must be
kept secret. With that in mind, our implementations do not provide direct
Expand Down Expand Up @@ -305,10 +305,10 @@ by P. Hellekalek.
[`Xoshiro256PlusPlus`]: https://docs.rs/rand_xoshiro/latest/rand_xoshiro/struct.Xoshiro256PlusPlus.html
[`Xoshiro256Plus`]: https://docs.rs/rand_xoshiro/latest/rand_xoshiro/struct.Xoshiro256Plus.html
[`SplitMix64`]: https://docs.rs/rand_xoshiro/latest/rand_xoshiro/struct.SplitMix64.html
[`ChaChaRng`]: ../rand/rand_chacha/struct.ChaChaRng.html
[`ChaChaRng`]: ../rand/rand_chacha/type.ChaChaRng.html
[`ChaCha20Rng`]: ../rand/rand_chacha/struct.ChaCha20Rng.html
[`ChaCha8Rng`]: ../rand/rand_chacha/struct.ChaCha8Rng.html
[`Hc128Rng`]: ../rand/rand_hc/struct.Hc128Rng.html
[`Hc128Rng`]: https://docs.rs/rand_hc/latest/rand_hc/struct.Hc128Rng.html
[`IsaacRng`]: https://docs.rs/rand_isaac/latest/rand_isaac/isaac/struct.IsaacRng.html
[`Isaac64Rng`]: https://docs.rs/rand_isaac/latest/rand_isaac/isaac64/struct.Isaac64Rng.html
[`ThreadRng`]: ../rand/rand/rngs/struct.ThreadRng.html
Expand All @@ -325,3 +325,5 @@ by P. Hellekalek.
[next-bit test]: https://en.wikipedia.org/wiki/Next-bit_test
[NIST]: https://www.nist.gov/
[ECRYPT]: http://www.ecrypt.eu.org/
[`getrandom`]: https://docs.rs/getrandom/
[`SeedableRng::from_entropy`]: ../rand/rand/trait.SeedableRng.html#method.from_entropy
Loading