diff --git a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java index 776c1bef9..79eccd126 100644 --- a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java +++ b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/container/internal/KarafTestContainer.java @@ -16,78 +16,39 @@ */ package org.ops4j.pax.exam.karaf.container.internal; -import static org.ops4j.pax.exam.CoreOptions.maven; -import static org.ops4j.pax.exam.CoreOptions.options; -import static org.ops4j.pax.exam.CoreOptions.systemProperty; -import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFileExtend; -import static org.ops4j.pax.exam.rbc.Constants.RMI_HOST_PROPERTY; -import static org.ops4j.pax.exam.rbc.Constants.RMI_NAME_PROPERTY; -import static org.ops4j.pax.exam.rbc.Constants.RMI_PORT_PROPERTY; - -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.URL; -import java.rmi.NoSuchObjectException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.UnicastRemoteObject; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; -import java.util.Queue; -import java.util.Set; -import java.util.UUID; - import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; import org.ops4j.net.FreePort; -import org.ops4j.pax.exam.ExamSystem; -import org.ops4j.pax.exam.Info; -import org.ops4j.pax.exam.Option; -import org.ops4j.pax.exam.RelativeTimeout; -import org.ops4j.pax.exam.TestAddress; -import org.ops4j.pax.exam.TestContainer; -import org.ops4j.pax.exam.TestContainerException; +import org.ops4j.pax.exam.*; import org.ops4j.pax.exam.container.remote.RBCRemoteTarget; import org.ops4j.pax.exam.karaf.container.internal.adaptions.KarafManipulator; import org.ops4j.pax.exam.karaf.container.internal.adaptions.KarafManipulatorFactory; import org.ops4j.pax.exam.karaf.container.internal.runner.Runner; -import org.ops4j.pax.exam.karaf.options.DoNotModifyLogOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionBaseConfigurationOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionConfigurationConsoleOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionConfigurationFileExtendOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionConfigurationFileOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionConfigurationFilePutOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionConfigurationFileReplacementOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionConfigurationSecurityOption; -import org.ops4j.pax.exam.karaf.options.KarafDistributionOption; -import org.ops4j.pax.exam.karaf.options.KarafExamSystemConfigurationOption; -import org.ops4j.pax.exam.karaf.options.KarafFeaturesOption; -import org.ops4j.pax.exam.karaf.options.KeepRuntimeFolderOption; -import org.ops4j.pax.exam.karaf.options.LogLevelOption; +import org.ops4j.pax.exam.karaf.options.*; import org.ops4j.pax.exam.karaf.options.configs.CustomProperties; import org.ops4j.pax.exam.karaf.options.configs.FeaturesCfg; -import org.ops4j.pax.exam.options.BootDelegationOption; -import org.ops4j.pax.exam.options.MavenArtifactUrlReference; -import org.ops4j.pax.exam.options.PropagateSystemPropertyOption; -import org.ops4j.pax.exam.options.ServerModeOption; -import org.ops4j.pax.exam.options.SystemPackageOption; -import org.ops4j.pax.exam.options.SystemPropertyOption; +import org.ops4j.pax.exam.options.*; import org.ops4j.pax.exam.options.extra.VMOption; import org.ops4j.pax.exam.rbc.client.RemoteBundleContextClient; +import org.ops4j.pax.exam.rbc.internal.NoSuchServiceException; import org.osgi.framework.Bundle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.*; +import java.net.InetAddress; +import java.net.URL; +import java.rmi.NoSuchObjectException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; +import java.util.*; + +import static org.ops4j.pax.exam.CoreOptions.*; +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFileExtend; +import static org.ops4j.pax.exam.rbc.Constants.*; + public class KarafTestContainer implements TestContainer { private static final Logger LOGGER = LoggerFactory.getLogger(KarafTestContainer.class); @@ -231,8 +192,19 @@ private void startKaraf(ExamSystem subsystem, File karafBase, File karafHome) { Bundle.ACTIVE, subsystem.getTimeout()); } else { - LOGGER - .info("System runs in Server Mode. Which means, no Test facility bundles available on target system."); + LOGGER.info("System runs in Server Mode. Which means, no Test facility bundles available on target system."); + } + + for (WaitForServiceOption waitForServiceOption : subsystem.getOptions(WaitForServiceOption.class)) { + LOGGER.info("Waiting for service {}, timeout:[{}]", waitForServiceOption.getServiceClassName(), waitForServiceOption.getTimeout().toString()); + try { + waitForService(waitForServiceOption.getServiceClassName(), waitForServiceOption.getTimeout()); + LOGGER.info("Service {} has been found in the test container", waitForServiceOption.getServiceClassName()); + } catch (NoSuchServiceException e) { + LOGGER.error("Service {} could not be found in the test container", waitForServiceOption.getServiceClassName()); + } catch (RemoteException e) { + LOGGER.error("Error waiting for service {} in the test container: {}", waitForServiceOption.getServiceClassName(), e.toString()); + } } } @@ -580,6 +552,10 @@ private void waitForState(final long bundleId, final int state, final RelativeTi target.getClientRBC().waitForState(bundleId, state, timeout); } + private void waitForService(String serviceClassName, final RelativeTimeout timeout) throws NoSuchServiceException, RemoteException { + target.getClientRBC().waitForService(serviceClassName, timeout); + } + @Override public synchronized void call(TestAddress address) { target.call(address); diff --git a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java index 2ffb4859b..fbeaaec15 100644 --- a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java +++ b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/KarafDistributionOption.java @@ -65,6 +65,10 @@ public static Option useOwnKarafExamSystemConfiguration(String invoker) { return new KarafExamSystemConfigurationOption(invoker); } + public static Option waitForServiceOption(String serviceClassName, long timeout){ + return new WaitForServiceOption(serviceClassName, timeout); + } + /** * The karaf pax-logging configuration is typically not a file manipulated very often. Therefore * we take the freedom of adding a console logger and changing the log level directly. IF you diff --git a/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/WaitForServiceOption.java b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/WaitForServiceOption.java new file mode 100644 index 000000000..359c0c499 --- /dev/null +++ b/containers/pax-exam-container-karaf/src/main/java/org/ops4j/pax/exam/karaf/options/WaitForServiceOption.java @@ -0,0 +1,43 @@ +/* + * 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.ops4j.pax.exam.karaf.options; + +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.RelativeTimeout; + +/** + * Per default the folder pax-exam is deleting the test directories after a test is over. If you want to keep those + * directories (for later evaluation) simply set this option. + */ +public class WaitForServiceOption implements Option { + final private String serviceClassName; + + final private RelativeTimeout timeout; + + public WaitForServiceOption(String serviceClassName, long timeout) { + this.serviceClassName = serviceClassName; + this.timeout = new RelativeTimeout(timeout); + } + + public String getServiceClassName() { + return serviceClassName; + } + + public RelativeTimeout getTimeout() { + return timeout; + } +} diff --git a/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/RemoteBundleContextClient.java b/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/RemoteBundleContextClient.java index bd1d3d21a..7ad03af40 100644 --- a/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/RemoteBundleContextClient.java +++ b/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/RemoteBundleContextClient.java @@ -17,12 +17,14 @@ */ package org.ops4j.pax.exam.rbc.client; -import java.io.InputStream; - import org.ops4j.pax.exam.RelativeTimeout; import org.ops4j.pax.exam.TestAddress; +import org.ops4j.pax.exam.rbc.internal.NoSuchServiceException; import org.ops4j.pax.exam.rbc.internal.RemoteBundleContext; +import java.io.InputStream; +import java.rmi.RemoteException; + /** * A {@link RemoteBundleContext} client, that takes away RMI handling. * @@ -46,5 +48,7 @@ public interface RemoteBundleContextClient { void waitForState(final long bundleId, final int state, final RelativeTimeout timeout); + void waitForService(String serviceClassName, RelativeTimeout timeout) throws NoSuchServiceException, RemoteException; + void call(TestAddress address); } diff --git a/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RemoteBundleContextClientImpl.java b/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RemoteBundleContextClientImpl.java index 3403df679..e06c6e70e 100644 --- a/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RemoteBundleContextClientImpl.java +++ b/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RemoteBundleContextClientImpl.java @@ -218,6 +218,11 @@ public void waitForState(final long bundleId, final int state, final RelativeTim } } + @Override + public void waitForService(String serviceClassName, RelativeTimeout timeout) throws NoSuchServiceException, RemoteException { + getRemoteBundleContext().waitForService(serviceClassName, null, timeout); + } + /** * Looks up the {@link RemoteBundleContext} via RMI. The lookup will timeout in the specified * number of millis. diff --git a/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RetryRemoteBundleContextClient.java b/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RetryRemoteBundleContextClient.java index 2711cc861..664c97afc 100644 --- a/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RetryRemoteBundleContextClient.java +++ b/core/pax-exam-container-rbc-client/src/main/java/org/ops4j/pax/exam/rbc/client/intern/RetryRemoteBundleContextClient.java @@ -17,17 +17,20 @@ */ package org.ops4j.pax.exam.rbc.client.intern; +import org.ops4j.pax.exam.ExceptionHelper; +import org.ops4j.pax.exam.RelativeTimeout; +import org.ops4j.pax.exam.TestAddress; +import org.ops4j.pax.exam.rbc.client.RemoteBundleContextClient; +import org.ops4j.pax.exam.rbc.internal.NoSuchServiceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.InputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.rmi.NoSuchObjectException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.ops4j.pax.exam.ExceptionHelper; -import org.ops4j.pax.exam.RelativeTimeout; -import org.ops4j.pax.exam.TestAddress; -import org.ops4j.pax.exam.rbc.client.RemoteBundleContextClient; +import java.rmi.RemoteException; /** * @@ -122,6 +125,11 @@ public void waitForState(long bundleId, int state, RelativeTimeout timeout) { proxy.waitForState(bundleId, state, timeout); } + @Override + public void waitForService(String serviceClassName, RelativeTimeout timeout) throws NoSuchServiceException, RemoteException { + proxy.waitForService(serviceClassName, timeout); + } + public void call(TestAddress address) { proxy.call(address); } diff --git a/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContext.java b/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContext.java index d582c7d03..f358d0cfc 100644 --- a/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContext.java +++ b/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContext.java @@ -75,6 +75,8 @@ Object remoteCall(Class serviceType, String methodName, Class[] methodPara NoSuchServiceException, NoSuchMethodException, IllegalAccessException, InvocationTargetException; + void waitForService(final String serviceClassName, final String filter, final RelativeTimeout timeout) throws NoSuchServiceException, RemoteException; + /** * Installs a bundle remotly. * diff --git a/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContextImpl.java b/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContextImpl.java index 91d3b6f99..354c9961c 100644 --- a/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContextImpl.java +++ b/core/pax-exam-container-rbc/src/main/java/org/ops4j/pax/exam/rbc/internal/RemoteBundleContextImpl.java @@ -80,6 +80,12 @@ public Object remoteCall(final Class serviceType, final String methodName, return serviceType.getMethod(methodName, methodParams).invoke(service, actualParams); } + @Override + public void waitForService(String serviceClassName, String filter, RelativeTimeout timeout) throws NoSuchServiceException, RemoteException { + LOG.trace("Retrieving service of [" + serviceClassName + "]"); + ServiceLookup.getService(bundleContext, serviceClassName, timeout.getValue(), filter); + } + public long installBundle(final String bundleUrl) throws BundleException { LOG.trace("Install bundle from URL [" + bundleUrl + "]"); return bundleContext.installBundle(bundleUrl).getBundleId();