/** * Does not mutate the TestMatrix. * * <p>Verifies that the test matrix contains all the required tests and that each required test is * valid. * * @param testMatrix * @param matrixSource * @param requiredTests * @return */ public static ProctorLoadResult verify( @Nonnull final TestMatrixArtifact testMatrix, final String matrixSource, @Nonnull final Map<String, TestSpecification> requiredTests, @Nonnull final FunctionMapper functionMapper) { final ProctorLoadResult.Builder resultBuilder = ProctorLoadResult.newBuilder(); final Map<String, Map<Integer, String>> allTestsKnownBuckets = Maps.newHashMapWithExpectedSize(requiredTests.size()); for (final Entry<String, TestSpecification> entry : requiredTests.entrySet()) { final Map<Integer, String> bucketValueToName = Maps.newHashMap(); for (final Entry<String, Integer> bucket : entry.getValue().getBuckets().entrySet()) { bucketValueToName.put(bucket.getValue(), bucket.getKey()); } allTestsKnownBuckets.put(entry.getKey(), bucketValueToName); } final Map<String, ConsumableTestDefinition> definedTests = testMatrix.getTests(); final SetView<String> missingTests = Sets.difference(requiredTests.keySet(), definedTests.keySet()); resultBuilder.recordAllMissing(missingTests); for (final Entry<String, ConsumableTestDefinition> entry : definedTests.entrySet()) { final String testName = entry.getKey(); final Map<Integer, String> knownBuckets = allTestsKnownBuckets.remove(testName); if (knownBuckets == null) { // we don't care about this test // iterator.remove(); DO NOT CONSOLIDATE continue; } final ConsumableTestDefinition testDefinition = entry.getValue(); try { verifyTest( testName, testDefinition, requiredTests.get(testName), knownBuckets, matrixSource, functionMapper); } catch (IncompatibleTestMatrixException e) { LOGGER.error(String.format("Unable to load test matrix for %s", testName), e); resultBuilder.recordError(testName); } } // TODO mjs - is this check additive? resultBuilder.recordAllMissing(allTestsKnownBuckets.keySet()); final ProctorLoadResult loadResult = resultBuilder.build(); return loadResult; }