GameTestRunner.java
net.minecraft.gametest.framework.GameTestRunner
信息
- 全限定名:net.minecraft.gametest.framework.GameTestRunner
- 类型:public class
- 包:net.minecraft.gametest.framework
- 源码路径:src/main/java/net/minecraft/gametest/framework/GameTestRunner.java
- 起始行号:L20
- 职责:
TODO
字段/常量
-
DEFAULT_TESTS_PER_ROW- 类型:
int - 修饰符:
public static final - 源码定位:
L21 - 说明:
TODO
- 类型:
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L22 - 说明:
TODO
- 类型:
-
level- 类型:
ServerLevel - 修饰符:
private final - 源码定位:
L23 - 说明:
TODO
- 类型:
-
testTicker- 类型:
GameTestTicker - 修饰符:
private final - 源码定位:
L24 - 说明:
TODO
- 类型:
-
allTestInfos- 类型:
List<GameTestInfo> - 修饰符:
private final - 源码定位:
L25 - 说明:
TODO
- 类型:
-
batches- 类型:
ImmutableList<GameTestBatch> - 修饰符:
private - 源码定位:
L26 - 说明:
TODO
- 类型:
-
batchListeners- 类型:
List<GameTestBatchListener> - 修饰符:
private final - 源码定位:
L27 - 说明:
TODO
- 类型:
-
scheduledForRerun- 类型:
List<GameTestInfo> - 修饰符:
private final - 源码定位:
L28 - 说明:
TODO
- 类型:
-
testBatcher- 类型:
GameTestRunner.GameTestBatcher - 修饰符:
private final - 源码定位:
L29 - 说明:
TODO
- 类型:
-
stopped- 类型:
boolean - 修饰符:
private - 源码定位:
L30 - 说明:
TODO
- 类型:
-
currentEnvironment- 类型:
TestEnvironmentDefinition.Activation<?> - 修饰符:
private - 源码定位:
L31 - 说明:
TODO
- 类型:
-
existingStructureSpawner- 类型:
GameTestRunner.StructureSpawner - 修饰符:
private final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
newStructureSpawner- 类型:
GameTestRunner.StructureSpawner - 修饰符:
private final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
haltOnError- 类型:
boolean - 修饰符:
private final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
clearBetweenBatches- 类型:
boolean - 修饰符:
private final - 源码定位:
L35 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.gametest.framework.GameTestRunner.Builder- 类型:
class - 修饰符:
public static - 源码定位:
L191 - 说明:
TODO
- 类型:
-
net.minecraft.gametest.framework.GameTestRunner.GameTestBatcher- 类型:
interface - 修饰符:
public - 源码定位:
L253 - 说明:
TODO
- 类型:
-
net.minecraft.gametest.framework.GameTestRunner.StructureSpawner- 类型:
interface - 修饰符:
public - 源码定位:
L257 - 说明:
TODO
- 类型:
构造器
protected GameTestRunner(GameTestRunner.GameTestBatcher batcher, Collection<GameTestBatch> batches, ServerLevel level, GameTestTicker testTicker, GameTestRunner.StructureSpawner existingStructureSpawner, GameTestRunner.StructureSpawner newStructureSpawner, boolean haltOnError, boolean clearBetweenBatches) @ L37
- 构造器名:GameTestRunner
- 源码定位:L37
- 修饰符:protected
参数:
- batcher: GameTestRunner.GameTestBatcher
- batches: Collection
- level: ServerLevel
- testTicker: GameTestTicker
- existingStructureSpawner: GameTestRunner.StructureSpawner
- newStructureSpawner: GameTestRunner.StructureSpawner
- haltOnError: boolean
- clearBetweenBatches: boolean
说明:
TODO
方法
下面的方法块按源码顺序生成。
public List<GameTestInfo> getTestInfos() @ L60
- 方法名:getTestInfos
- 源码定位:L60
- 返回类型:List
- 修饰符:public
参数:
- 无
说明:
TODO
public void start() @ L64
- 方法名:start
- 源码定位:L64
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void stop() @ L69
- 方法名:stop
- 源码定位:L69
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void rerunTest(GameTestInfo info) @ L76
- 方法名:rerunTest
- 源码定位:L76
- 返回类型:void
- 修饰符:public
参数:
- info: GameTestInfo
说明:
TODO
private void runBatch(int batchIndex) @ L86
- 方法名:runBatch
- 源码定位:L86
- 返回类型:void
- 修饰符:private
参数:
- batchIndex: int
说明:
TODO
private void endCurrentEnvironment() @ L159
- 方法名:endCurrentEnvironment
- 源码定位:L159
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void runScheduledRerunTests() @ L166
- 方法名:runScheduledRerunTests
- 源码定位:L166
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public void addListener(GameTestBatchListener listener) @ L179
- 方法名:addListener
- 源码定位:L179
- 返回类型:void
- 修饰符:public
参数:
- listener: GameTestBatchListener
说明:
TODO
private Collection<GameTestInfo> createStructuresForBatch(Collection<GameTestInfo> batch) @ L183
- 方法名:createStructuresForBatch
- 源码定位:L183
- 返回类型:Collection
- 修饰符:private
参数:
- batch: Collection
说明:
TODO
private Optional<GameTestInfo> spawn(GameTestInfo testInfo) @ L187
- 方法名:spawn
- 源码定位:L187
- 返回类型:Optional
- 修饰符:private
参数:
- testInfo: GameTestInfo
说明:
TODO
代码
public class GameTestRunner {
public static final int DEFAULT_TESTS_PER_ROW = 8;
private static final Logger LOGGER = LogUtils.getLogger();
private final ServerLevel level;
private final GameTestTicker testTicker;
private final List<GameTestInfo> allTestInfos;
private ImmutableList<GameTestBatch> batches;
private final List<GameTestBatchListener> batchListeners = Lists.newArrayList();
private final List<GameTestInfo> scheduledForRerun = Lists.newArrayList();
private final GameTestRunner.GameTestBatcher testBatcher;
private boolean stopped = true;
private TestEnvironmentDefinition.@Nullable Activation<?> currentEnvironment;
private final GameTestRunner.StructureSpawner existingStructureSpawner;
private final GameTestRunner.StructureSpawner newStructureSpawner;
private final boolean haltOnError;
private final boolean clearBetweenBatches;
protected GameTestRunner(
GameTestRunner.GameTestBatcher batcher,
Collection<GameTestBatch> batches,
ServerLevel level,
GameTestTicker testTicker,
GameTestRunner.StructureSpawner existingStructureSpawner,
GameTestRunner.StructureSpawner newStructureSpawner,
boolean haltOnError,
boolean clearBetweenBatches
) {
this.level = level;
this.testTicker = testTicker;
this.testBatcher = batcher;
this.existingStructureSpawner = existingStructureSpawner;
this.newStructureSpawner = newStructureSpawner;
this.batches = ImmutableList.copyOf(batches);
this.haltOnError = haltOnError;
this.clearBetweenBatches = clearBetweenBatches;
this.allTestInfos = this.batches.stream().flatMap(batch -> batch.gameTestInfos().stream()).collect(Util.toMutableList());
testTicker.setRunner(this);
this.allTestInfos.forEach(info -> info.addListener(new ReportGameListener()));
}
public List<GameTestInfo> getTestInfos() {
return this.allTestInfos;
}
public void start() {
this.stopped = false;
this.runBatch(0);
}
public void stop() {
this.stopped = true;
if (this.currentEnvironment != null) {
this.endCurrentEnvironment();
}
}
public void rerunTest(GameTestInfo info) {
GameTestInfo copy = info.copyReset();
info.getListeners().forEach(listener -> listener.testAddedForRerun(info, copy, this));
this.allTestInfos.add(copy);
this.scheduledForRerun.add(copy);
if (this.stopped) {
this.runScheduledRerunTests();
}
}
private void runBatch(int batchIndex) {
if (batchIndex >= this.batches.size()) {
this.endCurrentEnvironment();
this.runScheduledRerunTests();
} else {
if (batchIndex > 0 && this.clearBetweenBatches) {
GameTestBatch lastBatch = this.batches.get(batchIndex - 1);
lastBatch.gameTestInfos().forEach(gameTestInfo -> {
TestInstanceBlockEntity testInstanceBlockEntity = gameTestInfo.getTestInstanceBlockEntity();
StructureUtils.clearSpaceForStructure(testInstanceBlockEntity.getTestBoundingBox(), this.level);
this.level.destroyBlock(testInstanceBlockEntity.getBlockPos(), false);
});
}
final GameTestBatch currentBatch = this.batches.get(batchIndex);
this.existingStructureSpawner.onBatchStart(this.level);
this.newStructureSpawner.onBatchStart(this.level);
Collection<GameTestInfo> testInfosForThisBatch = this.createStructuresForBatch(currentBatch.gameTestInfos());
LOGGER.info(
"Running test environment '{}' batch {} ({} tests)...",
currentBatch.environment().getRegisteredName(),
currentBatch.index(),
testInfosForThisBatch.size()
);
this.endCurrentEnvironment();
this.currentEnvironment = TestEnvironmentDefinition.activate(currentBatch.environment().value(), this.level);
this.batchListeners.forEach(listener -> listener.testBatchStarting(currentBatch));
final MultipleTestTracker currentBatchTracker = new MultipleTestTracker();
testInfosForThisBatch.forEach(currentBatchTracker::addTestToTrack);
currentBatchTracker.addListener(new GameTestListener() {
{
Objects.requireNonNull(GameTestRunner.this);
}
private void testCompleted(GameTestInfo testInfo) {
if (currentBatchTracker.isDone()) {
GameTestRunner.this.batchListeners.forEach(listener -> listener.testBatchFinished(currentBatch));
LongSet forcedChunks = new LongArraySet(GameTestRunner.this.level.getForceLoadedChunks());
forcedChunks.forEach(pos -> GameTestRunner.this.level.setChunkForced(ChunkPos.getX(pos), ChunkPos.getZ(pos), false));
GameTestRunner.this.runBatch(batchIndex + 1);
}
}
@Override
public void testStructureLoaded(GameTestInfo testInfo) {
}
@Override
public void testPassed(GameTestInfo testInfo, GameTestRunner runner) {
testInfo.getTestInstanceBlockEntity().removeBarriers();
this.testCompleted(testInfo);
}
@Override
public void testFailed(GameTestInfo testInfo, GameTestRunner runner) {
if (GameTestRunner.this.haltOnError) {
GameTestRunner.this.endCurrentEnvironment();
LongSet forcedChunks = new LongArraySet(GameTestRunner.this.level.getForceLoadedChunks());
forcedChunks.forEach(pos -> GameTestRunner.this.level.setChunkForced(ChunkPos.getX(pos), ChunkPos.getZ(pos), false));
GameTestTicker.SINGLETON.clear();
} else {
this.testCompleted(testInfo);
}
}
@Override
public void testAddedForRerun(GameTestInfo original, GameTestInfo copy, GameTestRunner runner) {
}
});
testInfosForThisBatch.forEach(this.testTicker::add);
}
}
private void endCurrentEnvironment() {
if (this.currentEnvironment != null) {
this.currentEnvironment.teardown();
this.currentEnvironment = null;
}
}
private void runScheduledRerunTests() {
if (!this.scheduledForRerun.isEmpty()) {
LOGGER.info("Starting re-run of tests: {}", this.scheduledForRerun.stream().map(info -> info.id().toString()).collect(Collectors.joining(", ")));
this.batches = ImmutableList.copyOf(this.testBatcher.batch(this.scheduledForRerun));
this.scheduledForRerun.clear();
this.stopped = false;
this.runBatch(0);
} else {
this.batches = ImmutableList.of();
this.stopped = true;
}
}
public void addListener(GameTestBatchListener listener) {
this.batchListeners.add(listener);
}
private Collection<GameTestInfo> createStructuresForBatch(Collection<GameTestInfo> batch) {
return batch.stream().map(this::spawn).flatMap(Optional::stream).toList();
}
private Optional<GameTestInfo> spawn(GameTestInfo testInfo) {
return testInfo.getTestBlockPos() == null ? this.newStructureSpawner.spawnStructure(testInfo) : this.existingStructureSpawner.spawnStructure(testInfo);
}
public static class Builder {
private final ServerLevel level;
private final GameTestTicker testTicker = GameTestTicker.SINGLETON;
private GameTestRunner.GameTestBatcher batcher = GameTestBatchFactory.fromGameTestInfo();
private GameTestRunner.StructureSpawner existingStructureSpawner = GameTestRunner.StructureSpawner.IN_PLACE;
private GameTestRunner.StructureSpawner newStructureSpawner = GameTestRunner.StructureSpawner.NOT_SET;
private final Collection<GameTestBatch> batches;
private boolean haltOnError = false;
private boolean clearBetweenBatches = false;
private Builder(Collection<GameTestBatch> batches, ServerLevel level) {
this.batches = batches;
this.level = level;
}
public static GameTestRunner.Builder fromBatches(Collection<GameTestBatch> batches, ServerLevel level) {
return new GameTestRunner.Builder(batches, level);
}
public static GameTestRunner.Builder fromInfo(Collection<GameTestInfo> tests, ServerLevel level) {
return fromBatches(GameTestBatchFactory.fromGameTestInfo().batch(tests), level);
}
public GameTestRunner.Builder haltOnError() {
this.haltOnError = true;
return this;
}
public GameTestRunner.Builder clearBetweenBatches() {
this.clearBetweenBatches = true;
return this;
}
public GameTestRunner.Builder newStructureSpawner(GameTestRunner.StructureSpawner structureSpawner) {
this.newStructureSpawner = structureSpawner;
return this;
}
public GameTestRunner.Builder existingStructureSpawner(StructureGridSpawner spawner) {
this.existingStructureSpawner = spawner;
return this;
}
public GameTestRunner.Builder batcher(GameTestRunner.GameTestBatcher batcher) {
this.batcher = batcher;
return this;
}
public GameTestRunner build() {
return new GameTestRunner(
this.batcher,
this.batches,
this.level,
this.testTicker,
this.existingStructureSpawner,
this.newStructureSpawner,
this.haltOnError,
this.clearBetweenBatches
);
}
}
public interface GameTestBatcher {
Collection<GameTestBatch> batch(Collection<GameTestInfo> infos);
}
public interface StructureSpawner {
GameTestRunner.StructureSpawner IN_PLACE = testInfo -> Optional.ofNullable(testInfo.prepareTestStructure()).map(e -> e.startExecution(1));
GameTestRunner.StructureSpawner NOT_SET = testInfo -> Optional.empty();
Optional<GameTestInfo> spawnStructure(GameTestInfo testInfo);
default void onBatchStart(ServerLevel level) {
}
}
}引用的其他类
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
GameTestBatchFactory.fromGameTestInfo()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GameTestListener()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
MultipleTestTracker()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ReportGameListener()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
StructureUtils.clearSpaceForStructure()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
TestEnvironmentDefinition.activate()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.toMutableList()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ChunkPos.getX(), ChunkPos.getZ()
- 引用位置: