Skip to content

Commit

Permalink
Merge pull request JuliaLang#16940 from JuliaLang/rf/srand-tests
Browse files Browse the repository at this point in the history
limit the scope of srand in tests
  • Loading branch information
rfourquet committed Oct 8, 2017
2 parents a830b6f + 98f0991 commit 47fbcc9
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 167 deletions.
19 changes: 19 additions & 0 deletions stdlib/Test/src/Test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export @testset
export @inferred
export detect_ambiguities, detect_unbound_args
export GenericString, GenericSet, GenericDict, GenericArray
export guardsrand

#-----------------------------------------------------------------------

Expand Down Expand Up @@ -1429,6 +1430,24 @@ Base.setindex!(a::GenericArray, x, i...) = a.a[i...] = x

Base.similar(A::GenericArray, s::Integer...) = GenericArray(similar(A.a, s...))

"`guardsrand(f)` runs the function `f()` and then restores the
state of the global RNG as it was before."
function guardsrand(f::Function, r::AbstractRNG=Base.GLOBAL_RNG)
old = copy(r)
try
f()
finally
copy!(r, old)
end
end

"`guardsrand(f, seed)` is equivalent to running `srand(seed); f()` and
then restoring the state of the global RNG as it was before."
guardsrand(f::Function, seed::Integer) = guardsrand() do
srand(seed)
f()
end

# 0.7 deprecations

begin
Expand Down
27 changes: 24 additions & 3 deletions stdlib/Test/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,11 @@ end
@test S(1) == T(1)
end
end
srand(123)
@testset "some loops fail" begin
@testset for i in 1:5
@test i <= rand(1:10)
guardsrand(123) do
@testset for i in 1:5
@test i <= rand(1:10)
end
end
# should add 3 errors and 3 passing tests
@testset for i in 1:6
Expand Down Expand Up @@ -599,3 +600,23 @@ msg = split(read(pipeline(ignorestatus(`$(Base.julia_cmd()) --startup-file=no --
Test.print_test_results(Test.DefaultTestSet(""))'`), stderr=DevNull), String), "\n")[1]

@test msg == rstrip(msg)

# test guarded srand
let seed = rand(UInt)
orig = copy(Base.GLOBAL_RNG)
@test guardsrand(()->rand(), seed) == guardsrand(()->rand(), seed)
@test guardsrand(()->rand(Int), seed) == guardsrand(()->rand(Int), seed)
r1, r2 = MersenneTwister(0), MersenneTwister(0)
a, b = guardsrand(r1) do
srand(r1, 0)
rand(r1), rand(r1, Int)
end::Tuple{Float64,Int}
c, d = guardsrand(r2) do
srand(r2, 0)
rand(r2), rand(r2, Int)
end::Tuple{Float64,Int}
@test a == c == rand(r1) == rand(r2)
@test b == d == rand(r1, Int) == rand(r2, Int)
@test orig == Base.GLOBAL_RNG
@test rand(orig) == rand()
end
5 changes: 3 additions & 2 deletions test/error.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
@test maximum(ExponentialBackOff(n=10, max_delay=0.06)) == 0.06
ratio(x) = x[2:end]./x[1:end-1]
@test all(x->x 10.0, ratio(collect(ExponentialBackOff(n=10, max_delay=Inf, factor=10, jitter=0.0))))
srand(12345)
@test (mean(ratio(collect(ExponentialBackOff(n=100, max_delay=Inf, factor=1, jitter=0.1)))) - 1.0) < 1e-4
guardsrand(12345) do
@test (mean(ratio(collect(ExponentialBackOff(n=100, max_delay=Inf, factor=1, jitter=0.1)))) - 1.0) < 1e-4
end
end
@testset "retrying after errors" begin
function foo_error(c, n)
Expand Down
135 changes: 68 additions & 67 deletions test/linalg/arnoldi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,86 +3,87 @@
using Test

@testset "eigs" begin
srand(1234)
n = 10
areal = sprandn(n,n,0.4)
breal = sprandn(n,n,0.4)
acmplx = complex.(sprandn(n,n,0.4), sprandn(n,n,0.4))
bcmplx = complex.(sprandn(n,n,0.4), sprandn(n,n,0.4))

testtol = 1e-6

@testset for elty in (Float64, Complex128)
if elty == Complex64 || elty == Complex128
a = acmplx
b = bcmplx
else
a = areal
b = breal
end
a = convert(SparseMatrixCSC{elty}, a)
asym = a' + a # symmetric indefinite
apd = a'*a # symmetric positive-definite
guardsrand(1234) do
n = 10
areal = sprandn(n,n,0.4)
breal = sprandn(n,n,0.4)
acmplx = complex.(sprandn(n,n,0.4), sprandn(n,n,0.4))
bcmplx = complex.(sprandn(n,n,0.4), sprandn(n,n,0.4))

b = convert(SparseMatrixCSC{elty}, b)
bsym = b' + b
bpd = b'*b
testtol = 1e-6

(d,v) = eigs(a, nev=3)
@test a*v[:,2] d[2]*v[:,2]
@test norm(v) > testtol # eigenvectors cannot be null vectors
(d,v) = eigs(a, I, nev=3) # test eigs(A, B; kwargs...)
@test a*v[:,2] d[2]*v[:,2]
@test norm(v) > testtol # eigenvectors cannot be null vectors
@test_warn "Use symbols instead of strings for specifying which eigenvalues to compute" eigs(a, which="LM")
# (d,v) = eigs(a, b, nev=3, tol=1e-8) # not handled yet
# @test a*v[:,2] ≈ d[2]*b*v[:,2] atol=testtol
# @test norm(v) > testtol # eigenvectors cannot be null vectors
@testset for elty in (Float64, Complex128)
if elty == Complex64 || elty == Complex128
a = acmplx
b = bcmplx
else
a = areal
b = breal
end
a = convert(SparseMatrixCSC{elty}, a)
asym = a' + a # symmetric indefinite
apd = a'*a # symmetric positive-definite

(d,v) = eigs(asym, nev=3)
@test asym*v[:,1] d[1]*v[:,1]
@test eigs(asym; nev=1, sigma=d[3])[1][1] d[3]
@test norm(v) > testtol # eigenvectors cannot be null vectors
b = convert(SparseMatrixCSC{elty}, b)
bsym = b' + b
bpd = b'*b

(d,v) = eigs(apd, nev=3)
@test apd*v[:,3] d[3]*v[:,3]
@test eigs(apd; nev=1, sigma=d[3])[1][1] d[3]
(d,v) = eigs(a, nev=3)
@test a*v[:,2] d[2]*v[:,2]
@test norm(v) > testtol # eigenvectors cannot be null vectors
(d,v) = eigs(a, I, nev=3) # test eigs(A, B; kwargs...)
@test a*v[:,2] d[2]*v[:,2]
@test norm(v) > testtol # eigenvectors cannot be null vectors
@test_warn "Use symbols instead of strings for specifying which eigenvalues to compute" eigs(a, which="LM")
# (d,v) = eigs(a, b, nev=3, tol=1e-8) # not handled yet
# @test a*v[:,2] ≈ d[2]*b*v[:,2] atol=testtol
# @test norm(v) > testtol # eigenvectors cannot be null vectors

(d,v) = eigs(apd, bpd, nev=3, tol=1e-8)
@test apd*v[:,2] d[2]*bpd*v[:,2] atol=testtol
@test norm(v) > testtol # eigenvectors cannot be null vectors
(d,v) = eigs(asym, nev=3)
@test asym*v[:,1] d[1]*v[:,1]
@test eigs(asym; nev=1, sigma=d[3])[1][1] d[3]
@test norm(v) > testtol # eigenvectors cannot be null vectors

@testset "(shift-and-)invert mode" begin
(d,v) = eigs(apd, nev=3, sigma=0)
(d,v) = eigs(apd, nev=3)
@test apd*v[:,3] d[3]*v[:,3]
@test norm(v) > testtol # eigenvectors cannot be null vectors
@test eigs(apd; nev=1, sigma=d[3])[1][1] d[3]

(d,v) = eigs(apd, bpd, nev=3, sigma=0, tol=1e-8)
@test apd*v[:,1] d[1]*bpd*v[:,1] atol=testtol
(d,v) = eigs(apd, bpd, nev=3, tol=1e-8)
@test apd*v[:,2] d[2]*bpd*v[:,2] atol=testtol
@test norm(v) > testtol # eigenvectors cannot be null vectors
end

@testset "ArgumentErrors" begin
@test_throws ArgumentError eigs(rand(elty,2,2))
@test_throws ArgumentError eigs(a, nev=-1)
@test_throws ArgumentError eigs(a, which=:Z)
@test_throws ArgumentError eigs(a, which=:BE)
@test_throws DimensionMismatch eigs(a, v0=zeros(elty,n+2))
@test_throws ArgumentError eigs(a, v0=zeros(Int,n))
if elty == Float64
@test_throws ArgumentError eigs(a+a.',which=:SI)
@test_throws ArgumentError eigs(a+a.',which=:LI)
@test_throws ArgumentError eigs(a,sigma=rand(Complex64))
@testset "(shift-and-)invert mode" begin
(d,v) = eigs(apd, nev=3, sigma=0)
@test apd*v[:,3] d[3]*v[:,3]
@test norm(v) > testtol # eigenvectors cannot be null vectors

(d,v) = eigs(apd, bpd, nev=3, sigma=0, tol=1e-8)
@test apd*v[:,1] d[1]*bpd*v[:,1] atol=testtol
@test norm(v) > testtol # eigenvectors cannot be null vectors
end

@testset "ArgumentErrors" begin
@test_throws ArgumentError eigs(rand(elty,2,2))
@test_throws ArgumentError eigs(a, nev=-1)
@test_throws ArgumentError eigs(a, which=:Z)
@test_throws ArgumentError eigs(a, which=:BE)
@test_throws DimensionMismatch eigs(a, v0=zeros(elty,n+2))
@test_throws ArgumentError eigs(a, v0=zeros(Int,n))
if elty == Float64
@test_throws ArgumentError eigs(a+a.',which=:SI)
@test_throws ArgumentError eigs(a+a.',which=:LI)
@test_throws ArgumentError eigs(a,sigma=rand(Complex64))
end
end
end
end

@testset "Symmetric generalized with singular B" begin
n = 10
k = 3
A = randn(n,n); A = A'A
B = randn(n,k); B = B*B'
@test sort(eigs(A, B, nev = k, sigma = 1.0)[1]) sort(eigvals(A, B)[1:k])
@testset "Symmetric generalized with singular B" begin
n = 10
k = 3
A = randn(n,n); A = A'A
B = randn(n,k); B = B*B'
@test sort(eigs(A, B, nev = k, sigma = 1.0)[1]) sort(eigvals(A, B)[1:k])
end
end
end

Expand Down
3 changes: 1 addition & 2 deletions test/linalg/lapack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import Base.LinAlg.BlasInt
@test_throws ArgumentError Base.LinAlg.LAPACK.chktrans('Z')

@testset "syevr" begin
let
srand(123)
guardsrand(123) do
Ainit = randn(5,5)
@testset for elty in (Float32, Float64, Complex64, Complex128)
if elty == Complex64 || elty == Complex128
Expand Down
4 changes: 2 additions & 2 deletions test/linalg/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ function test_approx_eq_vecs(a::StridedVecOrMat{S}, b::StridedVecOrMat{T}, error
end
end

let n = 12 #Size of matrix problem to test
srand(123)
guardsrand(123) do
n = 12 #Size of matrix problem to test
@testset for elty in (Float32, Float64, Complex64, Complex128, Int)
if elty == Int
srand(61516384)
Expand Down
45 changes: 25 additions & 20 deletions test/random.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

srand(0)


# Issue #6573
let
guardsrand(0) do
rand()
x = rand(384)
@test find(x .== rand()) == []
Expand Down Expand Up @@ -119,11 +119,12 @@ for T in [UInt32, UInt64, UInt128, Int128]
r = rand(s, 1, 2)
@test size(r) == (1, 2)
@test typeof(r) == Matrix{BigInt}

srand(0)
r = rand(s)
srand(0)
@test rand(s) == r
guardsrand() do
srand(0)
r = rand(s)
srand(0)
@test rand(s) == r
end
end

# Test ziggurat tables
Expand Down Expand Up @@ -211,16 +212,15 @@ randmtzig_fill_ziggurat_tables()
@test all(fe == Base.Random.fe)

#same random numbers on for small ranges on all systems

let
global global_seed = rand(UInt) #leave state nondeterministic as above
srand(global_seed)
guardsrand() do
seed = rand(UInt)
srand(seed)
r = map(Int64, rand(map(Int32, 97:122)))
srand(global_seed)
srand(seed)
@test r == rand(map(Int64, 97:122))
srand(global_seed)
srand(seed)
r = map(UInt64, rand(map(UInt32, 97:122)))
srand(global_seed)
srand(seed)
@test r == rand(map(UInt64, 97:122))
end

Expand Down Expand Up @@ -268,7 +268,7 @@ let mt = MersenneTwister(0)
0x4b54632b4619f4eca22675166784d229][i]
end

srand(mt,0)
srand(mt, 0)
for (i,T) in enumerate([Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, Float16, Float32])
A = Array{T}(16)
B = Array{T}(31)
Expand All @@ -281,7 +281,7 @@ let mt = MersenneTwister(0)
-33032345278809823492812856023466859769,Float16(0.95),0.51829386f0][i]
end

srand(mt,0)
srand(mt, 0)
AF64 = Array{Float64}(Base.Random.dsfmt_get_min_array_size()-1)
@test rand!(mt, AF64)[end] == 0.957735065345398
@test rand!(mt, AF64)[end] == 0.6492481059865669
Expand Down Expand Up @@ -497,7 +497,9 @@ let mta = MersenneTwister(42), mtb = MersenneTwister(42)
end

# test PRNG jump
let mta = MersenneTwister(global_seed), mtb = MersenneTwister(global_seed)
let seed = rand(UInt)
mta = MersenneTwister(seed)
mtb = MersenneTwister(seed)
step = 25000*2
size = 4
jump25000 = "35931a4947eeab70a9abbfaca4a79cfcf2610a35a586c6f4e4bdfa826d538cbfb0432c37321fcec4f6c98de3df06685087032988b0ad9a2144562aa82e06f2f6f256b5b412c524e35383a894da7b04e142c4156290585186d8fc06d3141a778220c2519a851b5a9e5947a3f745b71804631988825e21dba40392ff4c036b30d2d013b45e2be94b5e130a9c6424d2e82f48c855c81bd10757fdb5a91e23e9e312e430514ea31631d8897b4cf26eb39b37be0c92706e5637d4b34c1e4046b741e455df195cb512e8e0f8d578175a3da5e00d7ce247d9b92042b1b515d01f7f89fe661ebccb06dfb77bc0fbb99806921b472ccce58f2166ac058d9cf427ad7d74986e60a56d2fee0a8b680e466a8ea4e508a76c058b6f97b99c9aa5b10297b1a1bd6a8e80f3a79e008fa55a4a8915fbdec78b6b117ad67e195311fe79fc084c33f6db546f5b7602d010fa8b830e3f1b00cef00ee16840178fc7e9aa5f1cee625d43de8488bf6c8bd379ea6f97c55c7a9ee091477a23533d5e52e194bd9d4e17b02a64a2736feb3779fabd5777e448ffee0f2d4b38a8e7441822b882fc6df0bde8541e85c0c78a05936cff0c88a50980b7a84971fba3650991fe2cba425ac4b4289e7b06ce2cfabfcc8a553201e8c74b45e4ae74b6d054e37af95e6fd55e029b7c526b85ecfb3be8db670218ee3dda7b2a54ab1ed26eefe4cd1d2a9c589a6e94d0aa3ebe29e40e616aa0b731061c3d6e247ec610024a1a97b7adb7919308b0fb5dd5d51a58aa2f55d77b88037de7c1a74823c96cb09d22dd7f90dba14eefdcffaab34d323c829f24742f6f6b32b0724a26ae4a81130a8a275d30c21e6245fa27cf26d606a49bccba2980697c32d9efe583c4ee2140569025c4f044d744bc40cec1660d9e4d2de3a4de83bae4f0a9fdb34ef4509b2b4e6c37967a485a52d69d1573bb826bc64c966de9c792b7c2f07b645c56a29381911a98928e48516f246a55bcaa78f3c7d1c30127df5f06ba0a2d6a5e54605a20e60fab30c01a9472cb610ca0ef2418a985af00c7e47539111bf539dd554297d0374a7ff627d879600595b442c8dcffcffa3bbb07e5c7882ff0858142be4deac448698f0917fe2b7a9b686a9df1fa929f06a51aff992a6ee0b0605f8b34b87600cfa0af2475333b78625ce1520c793dc5080218247b4e41bbd7d9dab163470fe17a3d2622cdce979cc5565b0bc04eabaf656f21fa072a18ab33c656b665248ef20321407fef263b1c67316f2c6f236951990099e42d4614d8e08b27aa89d9f4548fa321d4b381d2da04fd7f17d6b9a68adfd0e4427196d25dcad869f8a155c6242f7d072baa5e7405ceb65dfaa3eb864bfe679a17df34273fde5037befe9ed5391b932cee271f59128c61ab3f0fc3f7cf8ff051fbda8382c64579efddd494c79850c56bda73bcd39c20c2820d191995b3335253c3b0ac8f5e5373f40c228886e6c526c2c249a5304578ba2a80f591c34ca1eaa84d6cc9399cf3f1207e61c4acada647e4e87ad5fba84aeeff6b6881d35bda77c74384fc5e279a0f495d509bc882c2b8bc790651a6d7a4ecba23a3f05111e1d8be37c03439fbd484668ceab69a52b7d519b169cbbcf634ee5e3bf78a5f8771f95fea03f2cb889e116a9f5de3abeacb8e42475fb5d022484b02d11f1e406332e0a773098fc4f0baa57cda2863c554f291d4eb74e63e4b3d44b0ed156bff1820003d407a3aaa9e6dfaa226ba7ef2fd0eff90a5482926f47f24f67019edccb6fd329eef30b5fb2125276aa1fe75a702b32c907ab133c72a74e77e0a5eb48fc5176b9d65b75b0038e1a9ed74ec2a3dcd2348fa54256f082abc01a301bacef7380f20ee0411c08a35dafdaae9f9fc123448da28626ffcc654e9d522bc8b8776b13a3310f7eeb4d27290ef4cbc7492fbcb5409d455748a8a1f087430cf5e6f453e2caa0c5343fcf4374cc38bead49941d8ab59b4d5181716c238aa88dbf1c4a2da3a9a9b9435d5ee1d51d27b0655a4308c1252aaf633cd8f44a351ffc8cec65de0b7e4e2556100e2ae9bc511044351109a6254b2d387b1a72c768f43fa7be6b93806e323b55c3e7925ed627dc708fde0954b299b1ca33bb7fbe33e0f9e4ce5b4f26efaf8e5b9507ada4f8658998eb7167afbd4482ee47cc60f4039d6a77c1fb126033bfc2e7c6162ff7561f22e263325c53a014a4ac9390fe6fab5d433c1e9896fe561f22fc8290f3f4560b676f3dfbfd1fe605343a0685349241b83a28d61cc0292d1f638a36d3d87bfa9f72f9df1cfe90692dfda5bd5e698362f5316984cbe73a132a801acbca76b5f5c23d98a217f2159b6cbbcdf8f52d23ea24c9471a31562a651b20e05cd0300ee500a450cfdaa4d2d83f7e7e27f8b7c793cf80f8067dadef77e49a64c373b97bac4dd472e5145072c73d0fdd68d9646c8a8ed9aec6c40bc915ae44ae27391ca0f1a4d2cb1c3d097be614e6eba807f4549d769a5872f268ccf770f2682d844490348f0b6a0d2b51aadbb5523cf708b66f9928eed12b35a39cf42d283b29f5283e1c8ba1f73457af17b14cdfdf9a85b0589acf1f9504e46b0bab8be848dac5673587035b99f56c41d3195bbba1616b149a22193cfb760d6bf2d84861653cd21be9a2d33187cb25d47fbecdd4626d1d97202f460a39b7128cadb77ddf682feca61fb6de0290df598a565a6361a91d76c0c685046489ed4cb1dcc4f1cea849c12dc4a3d38d3010567f387590532b78927e92f0b718c84e882b3df071a78a011d0fd56d4101dcb009914a16a781b240a6fb2440c72b0ffb365be9d3459d114e665a0d35d7b8bd280101d85d1211d939ba0b15ab528c4f9dd2b001172561d211671b96873010ae3c2b8317f773d735698914228764b831423ae19dd4bbb008b9f1bd1e3ebdd626e629a46a9dd70bdd4bb30e2279e83c12bbbead6479b5f9980b1a9c785395520703a9367d931b45c1566c9d314b1745cafc6d0667cc9bc94d0c53a960c829eb09b768ab6bb2133e4fea1d939f3d3f8e1237210cf3577c830f0493073dc1d189abf27402b8b31b7c172c43dbf331a0828adfe737380e763d0ab0bfaaf94ec04830f94380a83718f340c4eeb20d7eb22b94613be84a9ed332ab364efff6cb37eec35d186185cca725e7a748f6bdb427604fb1628d49a7424a5a62a2e930fe142b035503af332fe748d5e63591b9ac54071ca843d5e474a48837de8b80387f3269ab50d2fd99c08c971e015d13fa02c7c315922ce58bdacbf8ee48827851a61fca59882d7eadcce3166dfe012aa9ec849e698e776a4d384f4755b506a222636942a81bbbffa1ff47e4d81fe68120aebcfd1a7e0000fd0cffdc44e1f0cd69ea2b4936564c78af51fed1cc8e34f0b46d6330b4b50ddee09335b7b0be0bc9f7f8e48415e15d08f811653d21bc6dd152742b086caadcc6dff5e27b40da42c2f1ebf3dd2bd51c418718e499859239317fcab10892eadf1c0ebf7a4246bce4cce3617193032f3e41b977dc8650298ac39631c527460364effea0f0bfd043df72ead0406aba1bcd636d65d7b89979eb8e1";
Expand All @@ -518,8 +520,10 @@ let mta = MersenneTwister(global_seed), mtb = MersenneTwister(global_seed)
end

# test that the following is not an error (#16925)
srand(typemax(UInt))
srand(typemax(UInt128))
guardsrand() do
srand(typemax(UInt))
srand(typemax(UInt128))
end

# copy, == and hash
let seed = rand(UInt32, 10)
Expand Down Expand Up @@ -563,7 +567,8 @@ let seed = rand(UInt32, 10)
end

# srand(rng, ...) returns rng (#21248)
let g = Base.Random.GLOBAL_RNG,
guardsrand() do
g = Base.Random.GLOBAL_RNG
m = MersenneTwister(0)
@test srand() === g
@test srand(rand(UInt)) === g
Expand Down
Loading

0 comments on commit 47fbcc9

Please sign in to comment.