blob: b80c17077a4d8ba02c0d69c817608b83f2e65483 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.sling.ide.test.impl.helpers;
import static org.junit.Assert.fail;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.sling.ide.eclipse.core.internal.Activator;
import org.apache.sling.ide.transport.CommandExecutionProperties;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
/**
* The <tt>AbstractFailOnUnexpectedEventsRule</tt> implements the plumbing needed for rules to react on events
*
*/
public abstract class AbstractFailOnUnexpectedEventsRule implements EventHandler, TestRule {
private static final int SETTLE_TIMEOUT_MILLIS = 500;
private ServiceRegistration<EventHandler> registration;
private final List<Event> unexpectedEvents = new CopyOnWriteArrayList<Event>();
public Statement apply(Statement base, Description description) {
return statement(base);
}
private Statement statement(final Statement base) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
} finally {
after();
}
}
};
}
protected void before() {
Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put("event.topics", "org/apache/sling/ide/transport");
registration = Activator.getDefault().getBundle().getBundleContext()
.registerService(EventHandler.class, this, props);
}
protected void after() throws InterruptedException {
if (registration != null) {
registration.unregister();
}
waitForEventsToSettle();
if (unexpectedEvents.isEmpty()) {
return;
}
StringBuilder desc = new StringBuilder();
desc.append(getClass().getSimpleName() + " : " + unexpectedEvents.size() + " unexpected events captured:");
for (Event event : unexpectedEvents) {
String flags = (String) event.getProperty(CommandExecutionProperties.ACTION_FLAGS);
desc.append('\n');
desc.append(event.getProperty(CommandExecutionProperties.ACTION_TYPE));
if (flags != null && flags.length() > 0) {
desc.append(" (").append(flags).append(")");
}
desc.append(" -> ");
desc.append(event.getProperty(CommandExecutionProperties.ACTION_TARGET));
desc.append(" : ");
desc.append(event.getProperty(CommandExecutionProperties.RESULT_TEXT));
}
fail(desc.toString());
}
/**
* Clears the list of unexpected events after the event firing settles
*
* <p>
* This can be useful for instance when you want to validate that no import events take place after a certain point
* in time.
* </p>
*
* <p>
* Event firing settling is defined as no unexpected events being recorded for {@value #SETTLE_TIMEOUT_MILLIS}
* milliseconds
* </p>
*/
public void clearUnexpectedEventsAfterSettling() throws InterruptedException {
waitForEventsToSettle();
unexpectedEvents.clear();
}
protected void addUnexpectedEvent(Event event) {
unexpectedEvents.add(event);
}
protected List<Event> getUnexpectedEvents() {
return Collections.unmodifiableList(unexpectedEvents);
}
private void waitForEventsToSettle() throws InterruptedException {
int currentSize;
do {
currentSize = unexpectedEvents.size();
Thread.sleep(SETTLE_TIMEOUT_MILLIS);
} while (currentSize != unexpectedEvents.size());
}
}