]> git.proxmox.com Git - cargo.git/blobdiff - vendor/proptest/src/test_runner/config.rs
New upstream version 0.37.0
[cargo.git] / vendor / proptest / src / test_runner / config.rs
index 4361274417fa8b339cb6b805d0251b0cded4ece8..1289037d36631f4020799cde5fc8e3225caa96b1 100644 (file)
@@ -1,5 +1,5 @@
 //-
-// Copyright 2017, 2018 The proptest developers
+// Copyright 2017, 2018, 2019 The proptest developers
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
@@ -7,22 +7,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std_facade::Box;
+use crate::std_facade::Box;
 use core::u32;
 
 #[cfg(feature = "std")]
 use std::env;
 #[cfg(feature = "std")]
-use std::fmt;
-#[cfg(feature = "std")]
 use std::ffi::OsString;
 #[cfg(feature = "std")]
+use std::fmt;
+#[cfg(feature = "std")]
 use std::str::FromStr;
 
-use test_runner::FailurePersistence;
+use crate::test_runner::result_cache::{noop_result_cache, ResultCache};
+use crate::test_runner::rng::RngAlgorithm;
+use crate::test_runner::FailurePersistence;
 #[cfg(feature = "std")]
-use test_runner::FileFailurePersistence;
-use test_runner::result_cache::{noop_result_cache, ResultCache};
+use crate::test_runner::FileFailurePersistence;
 
 #[cfg(feature = "std")]
 const CASES: &str = "PROPTEST_CASES";
@@ -42,11 +43,15 @@ const FORK: &str = "PROPTEST_FORK";
 const TIMEOUT: &str = "PROPTEST_TIMEOUT";
 #[cfg(feature = "std")]
 const VERBOSE: &str = "PROPTEST_VERBOSE";
+const RNG_ALGORITHM: &str = "PROPTEST_RNG_ALGORITHM";
 
 #[cfg(feature = "std")]
 fn contextualize_config(mut result: Config) -> Config {
-    fn parse_or_warn<T : FromStr + fmt::Display>(
-        src: &OsString, dst: &mut T, typ: &str, var: &str
+    fn parse_or_warn<T: FromStr + fmt::Display>(
+        src: &OsString,
+        dst: &mut T,
+        typ: &str,
+        var: &str,
     ) {
         if let Some(src) = src.to_str() {
             if let Ok(value) = src.parse() {
@@ -54,44 +59,77 @@ fn contextualize_config(mut result: Config) -> Config {
             } else {
                 eprintln!(
                     "proptest: The env-var {}={} can't be parsed as {}, \
-                     using default of {}.", var, src, typ, *dst);
+                     using default of {}.",
+                    var, src, typ, *dst
+                );
             }
         } else {
             eprintln!(
                 "proptest: The env-var {} is not valid, using \
-                 default of {}.", var, *dst);
+                 default of {}.",
+                var, *dst
+            );
         }
     }
 
-    result.failure_persistence = Some(Box::new(FileFailurePersistence::default()));
-    for (var, value) in env::vars_os().filter_map(
-            |(k,v)| k.into_string().ok().map(|k| (k,v))) {
+    result.failure_persistence =
+        Some(Box::new(FileFailurePersistence::default()));
+    for (var, value) in
+        env::vars_os().filter_map(|(k, v)| k.into_string().ok().map(|k| (k, v)))
+    {
         match var.as_str() {
             CASES => parse_or_warn(&value, &mut result.cases, "u32", CASES),
             MAX_LOCAL_REJECTS => parse_or_warn(
-                &value, &mut result.max_local_rejects,
-                "u32", MAX_LOCAL_REJECTS),
+                &value,
+                &mut result.max_local_rejects,
+                "u32",
+                MAX_LOCAL_REJECTS,
+            ),
             MAX_GLOBAL_REJECTS => parse_or_warn(
-                &value, &mut result.max_global_rejects,
-                "u32", MAX_GLOBAL_REJECTS),
+                &value,
+                &mut result.max_global_rejects,
+                "u32",
+                MAX_GLOBAL_REJECTS,
+            ),
             MAX_FLAT_MAP_REGENS => parse_or_warn(
-                &value, &mut result.max_flat_map_regens,
-                "u32", MAX_FLAT_MAP_REGENS),
+                &value,
+                &mut result.max_flat_map_regens,
+                "u32",
+                MAX_FLAT_MAP_REGENS,
+            ),
             #[cfg(feature = "fork")]
             FORK => parse_or_warn(&value, &mut result.fork, "bool", FORK),
             #[cfg(feature = "timeout")]
-            TIMEOUT => parse_or_warn(
-                &value, &mut result.timeout, "timeout", TIMEOUT),
+            TIMEOUT => {
+                parse_or_warn(&value, &mut result.timeout, "timeout", TIMEOUT)
+            }
             MAX_SHRINK_TIME => parse_or_warn(
-                &value, &mut result.max_shrink_time, "u32", MAX_SHRINK_TIME),
+                &value,
+                &mut result.max_shrink_time,
+                "u32",
+                MAX_SHRINK_TIME,
+            ),
             MAX_SHRINK_ITERS => parse_or_warn(
-                &value, &mut result.max_shrink_iters, "u32", MAX_SHRINK_ITERS),
-            VERBOSE => parse_or_warn(
-                &value, &mut result.verbose, "u32", VERBOSE),
-
-            _ => if var.starts_with("PROPTEST_") {
-                eprintln!("proptest: Ignoring unknown env-var {}.", var);
-            },
+                &value,
+                &mut result.max_shrink_iters,
+                "u32",
+                MAX_SHRINK_ITERS,
+            ),
+            VERBOSE => {
+                parse_or_warn(&value, &mut result.verbose, "u32", VERBOSE)
+            }
+            RNG_ALGORITHM => parse_or_warn(
+                &value,
+                &mut result.rng_algorithm,
+                "RngAlgorithm",
+                RNG_ALGORITHM,
+            ),
+
+            _ => {
+                if var.starts_with("PROPTEST_") {
+                    eprintln!("proptest: Ignoring unknown env-var {}.", var);
+                }
+            }
         }
     }
 
@@ -99,35 +137,40 @@ fn contextualize_config(mut result: Config) -> Config {
 }
 
 #[cfg(not(feature = "std"))]
-fn contextualize_config(result: Config) -> Config { result }
+fn contextualize_config(result: Config) -> Config {
+    result
+}
 
-/// The default config, computed by combining environment variables and
-/// defaults.
+fn default_default_config() -> Config {
+    Config {
+        cases: 256,
+        max_local_rejects: 65_536,
+        max_global_rejects: 1024,
+        max_flat_map_regens: 1_000_000,
+        failure_persistence: None,
+        source_file: None,
+        test_name: None,
+        #[cfg(feature = "fork")]
+        fork: false,
+        #[cfg(feature = "timeout")]
+        timeout: 0,
+        #[cfg(feature = "std")]
+        max_shrink_time: 0,
+        max_shrink_iters: u32::MAX,
+        result_cache: noop_result_cache,
+        #[cfg(feature = "std")]
+        verbose: 0,
+        rng_algorithm: RngAlgorithm::default(),
+        _non_exhaustive: (),
+    }
+}
+
+// The default config, computed by combining environment variables and
+// defaults.
+#[cfg(feature = "std")]
 lazy_static! {
-    static ref DEFAULT_CONFIG: Config = {
-        let result = Config {
-            cases: 256,
-            max_local_rejects: 65_536,
-            max_global_rejects: 1024,
-            max_flat_map_regens: 1_000_000,
-            failure_persistence: None,
-            source_file: None,
-            test_name: None,
-            #[cfg(feature = "fork")]
-            fork: false,
-            #[cfg(feature = "timeout")]
-            timeout: 0,
-            #[cfg(feature = "std")]
-            max_shrink_time: 0,
-            max_shrink_iters: u32::MAX,
-            result_cache: noop_result_cache,
-            #[cfg(feature = "std")]
-            verbose: 0,
-            _non_exhaustive: (),
-        };
-
-        contextualize_config(result)
-    };
+    static ref DEFAULT_CONFIG: Config =
+        { contextualize_config(default_default_config()) };
 }
 
 /// Configuration for how a proptest test should be run.
@@ -248,8 +291,14 @@ pub struct Config {
     /// Give up on shrinking if more than this number of iterations of the test
     /// code are run.
     ///
+    /// Setting this to `std::u32::MAX` causes the actual limit to be four
+    /// times the number of test cases.
+    ///
     /// Setting this value to `0` disables shrinking altogether.
     ///
+    /// Note that the type of this field will change in a future version of
+    /// proptest to better accommodate its special values.
+    ///
     /// The default is `std::u32::MAX`, which can be overridden by setting the
     /// `PROPTEST_MAX_SHRINK_ITERS` environment variable.
     pub max_shrink_iters: u32,
@@ -270,7 +319,7 @@ pub struct Config {
     ///
     /// Caching incurs its own overhead, and may very well make your test run
     /// more slowly.
-    pub result_cache: fn () -> Box<dyn ResultCache>,
+    pub result_cache: fn() -> Box<dyn ResultCache>,
 
     /// Set to non-zero values to cause proptest to emit human-targeted
     /// messages to stderr as it runs.
@@ -290,6 +339,15 @@ pub struct Config {
     #[cfg(feature = "std")]
     pub verbose: u32,
 
+    /// The RNG algorithm to use when not using a user-provided RNG.
+    ///
+    /// The default is `RngAlgorithm::default()`, which can be overridden by
+    /// setting the `PROPTEST_RNG_ALGORITHM` environment variable to one of the following:
+    ///
+    /// - `xs` — `RngAlgorithm::XorShift`
+    /// - `cc` — `RngAlgorithm::ChaCha`
+    pub rng_algorithm: RngAlgorithm,
+
     // Needs to be public so FRU syntax can be used.
     #[doc(hidden)]
     pub _non_exhaustive: (),
@@ -310,7 +368,10 @@ impl Config {
     /// );
     /// ```
     pub fn with_cases(cases: u32) -> Self {
-        Self { cases, .. Config::default() }
+        Self {
+            cases,
+            ..Config::default()
+        }
     }
 
     /// Constructs a `Config` only differing from the `default()` in the
@@ -327,7 +388,10 @@ impl Config {
     /// );
     /// ```
     pub fn with_source_file(source_file: &'static str) -> Self {
-        Self { source_file: Some(source_file), .. Config::default() }
+        Self {
+            source_file: Some(source_file),
+            ..Config::default()
+        }
     }
 
     /// Constructs a `Config` only differing from the provided Config instance, `self`,
@@ -391,6 +455,17 @@ impl Config {
         0
     }
 
+    /// Returns the configured limit on shrinking iterations.
+    ///
+    /// This takes into account the special "automatic" behaviour.
+    pub fn max_shrink_iters(&self) -> u32 {
+        if u32::MAX == self.max_shrink_iters {
+            self.cases.saturating_mul(4)
+        } else {
+            self.max_shrink_iters
+        }
+    }
+
     // Used by macros to force the config to be owned without depending on
     // certain traits being `use`d.
     #[allow(missing_docs)]
@@ -400,8 +475,16 @@ impl Config {
     }
 }
 
+#[cfg(feature = "std")]
 impl Default for Config {
     fn default() -> Self {
         DEFAULT_CONFIG.clone()
     }
 }
+
+#[cfg(not(feature = "std"))]
+impl Default for Config {
+    fn default() -> Self {
+        default_default_config()
+    }
+}