|
1 | 1 | package com.carrotsearch.randomizedtesting.jupiter; |
2 | 2 |
|
3 | | -import java.io.Closeable; |
4 | | -import java.io.IOException; |
5 | | -import java.util.ArrayList; |
6 | | -import java.util.Collections; |
7 | | -import java.util.Locale; |
8 | | -import java.util.Objects; |
9 | 3 | import java.util.Random; |
10 | | -import org.junit.jupiter.api.extension.ExtensionContext; |
11 | 4 |
|
12 | | -public final class RandomizedContext implements Closeable { |
13 | | - private final RandomizedContext parent; |
14 | | - private final Seed seed; |
15 | | - final String contextId; |
| 5 | +public interface RandomizedContext { |
| 6 | + SeedChain getSeedChain(); |
16 | 7 |
|
17 | | - private final SeedChain remainingSeedChain; |
| 8 | + Seed getRootSeed(); |
18 | 9 |
|
19 | | - private final Random random; |
20 | | - private final RandomFactory randomFactory; |
21 | | - |
22 | | - RandomizedContext( |
23 | | - String contextId, |
24 | | - RandomizedContext parent, |
25 | | - RandomFactory randomFactory, |
26 | | - Seed seed, |
27 | | - SeedChain remainingSeedChain) { |
28 | | - this.contextId = contextId; |
29 | | - this.parent = parent; |
30 | | - this.remainingSeedChain = remainingSeedChain; |
31 | | - this.randomFactory = randomFactory; |
32 | | - |
33 | | - assert !seed.isUnspecified(); |
34 | | - this.seed = seed; |
35 | | - this.random = randomFactory.apply(seed.value()); |
36 | | - } |
37 | | - |
38 | | - @Override |
39 | | - public String toString() { |
40 | | - return "Randomized context [" + ("seedChain=" + getSeedChain() + ",") + "]"; |
41 | | - } |
42 | | - |
43 | | - public SeedChain getSeedChain() { |
44 | | - ArrayList<Seed> seeds = new ArrayList<>(); |
45 | | - for (RandomizedContext c = this; c != null; c = c.getParent()) { |
46 | | - seeds.add(c.seed); |
47 | | - } |
48 | | - Collections.reverse(seeds); |
49 | | - return new SeedChain(seeds); |
50 | | - } |
51 | | - |
52 | | - /** |
53 | | - * @return Returns the root seed (randomization source). |
54 | | - * @see RandomizedContextSupplier.SysProps#TESTS_SEED |
55 | | - */ |
56 | | - public Seed getRootSeed() { |
57 | | - return getSeedChain().seeds().getFirst(); |
58 | | - } |
59 | | - |
60 | | - private RandomizedContext getParent() { |
61 | | - return parent; |
62 | | - } |
63 | | - |
64 | | - public Random getRandom() { |
65 | | - return random; |
66 | | - } |
67 | | - |
68 | | - RandomizedContext deriveNew(ExtensionContext extensionContext) { |
69 | | - // sanity check. |
70 | | - { |
71 | | - var id = extensionContext.getUniqueId(); |
72 | | - for (var ctx = this; ctx != null; ctx = ctx.getParent()) { |
73 | | - if (Objects.equals(ctx.contextId, id)) { |
74 | | - throw new RuntimeException( |
75 | | - "deriveNew on a context that is already present in the parent chain: " + id); |
76 | | - } |
77 | | - } |
78 | | - } |
79 | | - |
80 | | - SeedChain seedChain; |
81 | | - var annotationSeed = extensionContext.getElement().map(e -> e.getAnnotation(FixSeed.class)); |
82 | | - if (annotationSeed.isPresent()) { |
83 | | - seedChain = SeedChain.parse(annotationSeed.get().value()); |
84 | | - for (var seed : seedChain.seeds()) { |
85 | | - if (seed.isUnspecified()) { |
86 | | - throw new RuntimeException( |
87 | | - String.format( |
88 | | - Locale.ROOT, |
89 | | - "@%s annotatoin must declare concrete seeds or seed chains on: %s", |
90 | | - FixSeed.class.getName(), |
91 | | - extensionContext.getElement().get())); |
92 | | - } |
93 | | - } |
94 | | - } else { |
95 | | - seedChain = this.remainingSeedChain; |
96 | | - } |
97 | | - |
98 | | - var firstAndRest = seedChain.pop(); |
99 | | - var nextSeed = firstAndRest.first(); |
100 | | - var remainingChain = firstAndRest.rest(); |
101 | | - if (nextSeed.isUnspecified()) { |
102 | | - nextSeed = new Seed(this.seed.value() ^ Hashing.longHash(extensionContext.getUniqueId())); |
103 | | - } |
104 | | - |
105 | | - return new RandomizedContext( |
106 | | - extensionContext.getUniqueId(), this, randomFactory, nextSeed, remainingChain); |
107 | | - } |
108 | | - |
109 | | - @Override |
110 | | - public void close() throws IOException { |
111 | | - if (random instanceof Closeable c) { |
112 | | - c.close(); |
113 | | - } |
114 | | - } |
| 10 | + Random getRandom(); |
115 | 11 | } |
0 commit comments