/*
* Copyright 2015-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.apple;
import com.facebook.buck.rules.TestRule;
import com.facebook.buck.test.TestCaseSummary;
import com.facebook.buck.test.TestResultSummary;
import com.facebook.buck.test.TestStatusMessage;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Implementation of {@link XctoolOutputParsing.XctoolEventCallback} that collects {@code xctool}
* events and converts them to {@link TestCaseSummary} objects, reporting progress to a {@code
* TestRule.TestReportingCallback}.
*/
class TestCaseSummariesBuildingXctoolEventHandler
implements XctoolOutputParsing.XctoolEventCallback {
private final TestRule.TestReportingCallback testReportingCallback;
private final ImmutableListMultimap.Builder<String, TestResultSummary> testResultSummariesBuilder;
private final ImmutableList.Builder<TestCaseSummary> testCaseSummariesBuilder;
private AtomicBoolean testsDidEnd;
public TestCaseSummariesBuildingXctoolEventHandler(
TestRule.TestReportingCallback testReportingCallback) {
this.testReportingCallback = testReportingCallback;
this.testResultSummariesBuilder = ImmutableListMultimap.builder();
this.testCaseSummariesBuilder = ImmutableList.builder();
this.testsDidEnd = new AtomicBoolean(false);
}
@Override
public void handleBeginOcunitEvent(XctoolOutputParsing.BeginOcunitEvent event) {
testReportingCallback.testsDidBegin();
}
@Override
public void handleEndOcunitEvent(XctoolOutputParsing.EndOcunitEvent event) {
boolean testsDidEndChangedToTrue = testsDidEnd.compareAndSet(false, true);
Preconditions.checkState(
testsDidEndChangedToTrue, "handleEndOcunitEvent() should not be called twice");
Optional<TestResultSummary> internalError =
XctoolOutputParsing.internalErrorForEndOcunitEvent(event);
if (internalError.isPresent()) {
testResultSummariesBuilder.put("Internal error from test runner", internalError.get());
}
for (Map.Entry<String, Collection<TestResultSummary>> testCaseSummary :
testResultSummariesBuilder.build().asMap().entrySet()) {
testCaseSummariesBuilder.add(
new TestCaseSummary(
testCaseSummary.getKey(), ImmutableList.copyOf(testCaseSummary.getValue())));
}
testReportingCallback.testsDidEnd(testCaseSummariesBuilder.build());
}
@Override
public void handleBeginTestSuiteEvent(XctoolOutputParsing.BeginTestSuiteEvent event) {}
@Override
public void handleEndTestSuiteEvent(XctoolOutputParsing.EndTestSuiteEvent event) {}
@Override
public void handleBeginStatusEvent(XctoolOutputParsing.StatusEvent event) {
Optional<TestStatusMessage> message =
XctoolOutputParsing.testStatusMessageForStatusEvent(event);
if (message.isPresent()) {
testReportingCallback.statusDidBegin(message.get());
}
}
@Override
public void handleEndStatusEvent(XctoolOutputParsing.StatusEvent event) {
Optional<TestStatusMessage> message =
XctoolOutputParsing.testStatusMessageForStatusEvent(event);
if (message.isPresent()) {
testReportingCallback.statusDidEnd(message.get());
}
}
@Override
public void handleBeginTestEvent(XctoolOutputParsing.BeginTestEvent event) {
testReportingCallback.testDidBegin(
Preconditions.checkNotNull(event.className), Preconditions.checkNotNull(event.test));
}
@Override
public void handleEndTestEvent(XctoolOutputParsing.EndTestEvent event) {
TestResultSummary testResultSummary =
XctoolOutputParsing.testResultSummaryForEndTestEvent(event);
testResultSummariesBuilder.put(Preconditions.checkNotNull(event.className), testResultSummary);
testReportingCallback.testDidEnd(testResultSummary);
}
public ImmutableList<TestCaseSummary> getTestCaseSummaries() {
Preconditions.checkState(
testsDidEnd.get(), "Call this method only after testsDidEnd() callback is invoked.");
return testCaseSummariesBuilder.build();
}
}