Merge: Less randomness and race conditions in tests
authorJean Privat <jean@pryen.org>
Thu, 26 May 2016 13:06:47 +0000 (09:06 -0400)
committerJean Privat <jean@pryen.org>
Thu, 26 May 2016 13:06:47 +0000 (09:06 -0400)
Parallel executions can cause some race collisions on named resources (e.g. DB table names).

To solve this issue, `tests.sh` and `nitunit` initialize  `NIT_TESTING_ID` with a distinct integer identifier that can be used to give unique names to resources.

`rand` is not a recommended way to get a distinct identifier because its randomness is disabled by default.

Pull-Request: #2129
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>

contrib/nitrpg/src/test_helper.nit
lib/core/exec.nit
share/man/nitunit.md
src/nitunit.nit
tests/test_nitcorn.nit
tests/tests.sh

index 1ac8314..904862c 100644 (file)
@@ -57,7 +57,8 @@ abstract class NitrpgTestHelper
 
        # Gen a test db with a random name (to avoid race conditions).
        fun gen_test_db: MongoDb do
-               var db_name = "test_nitrpg_{get_time}_{1000.rand}"
+               var testid = "NIT_TESTING_ID".environ.to_i
+               var db_name = "test_nitrpg_{testid}"
                var db = load_db(db_name)
                test_dbs.add db
                return db
index 10c5374..76d9d63 100644 (file)
@@ -324,6 +324,9 @@ redef class Sys
        do
                return command.to_cstring.system
        end
+
+       # The pid of the program
+       fun pid: Int `{ return getpid(); `}
 end
 
 redef class NativeString
index 0576201..e80e80e 100644 (file)
@@ -312,6 +312,29 @@ Only display the skeleton, do not write any file.
 
 Indicate the specific Nit compiler executable to use. See `--nitc`.
 
+### `NIT_TESTING`
+
+The environment variable `NIT_TESTING` is set to `true` during the execution of program tests.
+Some libraries of programs can use it to produce specific reproducible results; or just to exit their executions.
+
+Unit-tests may unset this environment variable to retrieve the original behavior of such piece of software.
+
+### `SRAND`
+
+In order to maximize reproducibility, `SRAND` is set to 0.
+This make the pseudo-random generator no random at all.
+See `Sys::srand` for details.
+
+To retrieve the randomness, unit-tests may unset this environment variable then call `srand`.
+
+### `NIT_TESTING_ID`
+
+Parallel executions can cause some race collisions on named resources (e.g. DB table names).
+To solve this issue, `NIT_TESTING_ID` is initialized with a distinct integer identifier that can be used to give unique names to resources.
+
+Note: `rand` is not a recommended way to get a distinct identifier because its randomness is disabled by default. See `SRAND`.
+
+
 # SEE ALSO
 
 The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>
index 0d89dc6..878d3f2 100644 (file)
@@ -64,6 +64,8 @@ if toolcontext.opt_gen_unit.value then
 end
 
 "NIT_TESTING".setenv("true")
+"NIT_TESTING_ID".setenv(pid.to_s)
+"SRAND".setenv("0")
 
 var test_dir = toolcontext.test_dir
 test_dir.mkdir
index e4088a2..5f2ca1c 100644 (file)
@@ -17,8 +17,8 @@ import pthreads
 
 redef class Sys
        var iface: String is lazy do
-               srand
-               return "localhost:{10000+20000.rand}"
+               var testid = "NIT_TESTING_ID".environ.to_i
+               return "localhost:{10000+testid}"
        end
 
        var fs_path: String = getcwd / "../lib/nitcorn/examples/www/hello_world/dir" is lazy
index 84ba34a..d11c60a 100755 (executable)
@@ -21,6 +21,8 @@
 export LANG=C
 export LC_ALL=C
 export NIT_TESTING=true
+# Use the pid as a collision prevention
+export NIT_TESTING_ID=$$
 export NIT_SRAND=0
 
 unset NIT_DIR