/* * 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(); } }