我正在尝试运行PAX考试,该考试启动了Karaf实例版本4.0.2,然后部署了一些功能。一切都运作到目前为止。
但是,我还想运行一些命令来检查捆绑包是否已经安装,即运行"捆绑:列表"命令。
我在这里添加了executeCommand和getOsgiService方法: https://github.com/christian-posta/rider-auto-osgi/blob/master/itests/src/test/java/org/jboss/fuse/example/support/FuseTestSupport.java#L80
但是我得到了RuntimeException:
root
这是导致异常的代码。
java.lang.RuntimeException: Gave up waiting for service (objectClass=org.apache.felix.service.command.CommandProcessor)
at com.axiell.tenantidlookup.integrationtest.TenantIdLookupTest.getOsgiService(TenantIdLookupTest.java:205)
at com.axiell.tenantidlookup.integrationtest.TenantIdLookupTest.getOsgiService(TenantIdLookupTest.java:171)
at com.axiell.tenantidlookup.integrationtest.TenantIdLookupTest.testProvisioning(TenantIdLookupTest.java:110)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:68)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:37)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.ops4j.pax.exam.rbc.internal.RemoteBundleContextImpl.remoteCall(RemoteBundleContextImpl.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
CommandProcessor的某些功能无效。任何提示或帮助将不胜感激。 Thakns
答案 0 :(得分:6)
使用Karaf 4.x命令确实发生了变化,因此您需要相应地更改它。 可以找到完整的样本here
作为快速总结,您需要在测试中使用SessionFactory,请参阅下文:
@Inject
protected SessionFactory sessionFactory;
并从那里创建一个会话对象:
@Before
public void setUpITestBase() throws Exception {
session = sessionFactory.create(System.in, printStream, errStream);
}
我在测试的前一部分做了这个,以确保会话总是创建新的。
以下是执行命令的关键部分:
String response;
FutureTask<String> commandFuture = new FutureTask<String>(new Callable<String>() {
public String call() {
try {
System.err.println(command);
session.execute(command);
} catch (Exception e) {
e.printStackTrace(System.err);
}
printStream.flush();
errStream.flush();
return byteArrayOutputStream.toString();
}
});
try {
executor.submit(commandFuture);
response = commandFuture.get(10000L, TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace(System.err);
response = "SHELL COMMAND TIMED OUT: ";
}
答案 1 :(得分:0)
Achim Nierbeck为我解决了这个问题,以便参考他的答案。如果有人只想在代码上找到适合我的高峰。
import static org.junit.Assert.*;
import static org.ops4j.pax.exam.CoreOptions.maven;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.*;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.model.language.ConstantExpression;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.features.BootFinished;
import org.apache.karaf.shell.api.console.Session;
import org.apache.karaf.shell.api.console.SessionFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.CoreOptions;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.ProbeBuilder;
import org.ops4j.pax.exam.TestProbeBuilder;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.karaf.options.LogLevelOption;
import org.ops4j.pax.exam.options.WrappedUrlProvisionOption;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.framework.Constants;
import javax.inject.Inject;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
@RunWith(PaxExam.class)
public class TenantIdLookupTest {
@Inject
protected BundleContext bc;
@Inject
protected FeaturesService featuresService;
@Inject
protected BootFinished bootFinished;
@Inject
protected SessionFactory sessionFactory;
private ExecutorService executor = Executors.newCachedThreadPool();
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
private PrintStream printStream = new PrintStream(byteArrayOutputStream);
private PrintStream errStream = new PrintStream(byteArrayOutputStream);
private Session session;
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE,
"*,org.apache.felix.service.*;status=provisional");
return probe;
}
@Configuration
public static Option[] configure() throws Exception {
return new Option[] {
karafDistributionConfiguration()
.frameworkUrl(
maven().groupId("org.apache.karaf")
.artifactId("apache-karaf").type("zip")
.version("4.0.2"))
.karafVersion("4.0.2").useDeployFolder(false)
.unpackDirectory(new File("target/paxexam/unpack")),
configureConsole().ignoreLocalConsole(),
features(
maven().groupId("org.apache.camel.karaf")
.artifactId("apache-camel").type("xml")
.classifier("features").version("2.15.1"),
"camel"),
features(
maven().groupId("org.apache.camel.karaf")
.artifactId("apache-camel").type("xml")
.classifier("features").version("2.15.1"),
"camel-blueprint"),
features(
maven().groupId("org.apache.camel.karaf")
.artifactId("apache-camel").type("xml")
.classifier("features").version("2.15.1"),
"camel-netty4"),
features(
maven().groupId("org.apache.camel.karaf")
.artifactId("apache-camel").type("xml")
.classifier("features").version("2.15.1"),
"camel-rabbitmq"),
CoreOptions.mavenBundle(CoreOptions.maven(
"com.google.code.gson", "gson").version("2.3")),
logLevel(LogLevelOption.LogLevel.INFO),
// features(maven().groupId("org.apache.camel.karaf").artifactId("apache-camel").type("xml").classifier("features").version("2.12.1"),
// "camel-blueprint", "camel-test"),
// features(maven().groupId("net.nanthrax.blog").artifactId("camel-blueprint").type("xml").classifier("features").version("1.0-SNAPSHOT"),
// "blog-camel-blueprint-route"),
keepRuntimeFolder(),
};
}
@Before
public void setUpITestBase() throws Exception {
session = sessionFactory.create(System.in, printStream, errStream);
}
@Test
public void testProvisioning() throws Exception {
assertTrue(featuresService.isInstalled(featuresService.getFeature("camel-blueprint")));
System.out.println(executeCommand("bundle:list"));
}
protected String executeCommand(final String command) throws IOException {
byteArrayOutputStream.flush();
byteArrayOutputStream.reset();
String response;
FutureTask<String> commandFuture = new FutureTask<String>(
new Callable<String>() {
public String call() {
try {
System.err.println(command);
session.execute(command);
} catch (Exception e) {
e.printStackTrace(System.err);
}
printStream.flush();
errStream.flush();
return byteArrayOutputStream.toString();
}
});
try {
executor.submit(commandFuture);
response = commandFuture.get(10000L, TimeUnit.MILLISECONDS);
} catch (Exception e) {
e.printStackTrace(System.err);
response = "SHELL COMMAND TIMED OUT: ";
}
System.err.println(response);
return response;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected <T> T getOsgiService(Class<T> type, String filter, long timeout) {
ServiceTracker tracker = null;
try {
String flt;
if (filter != null) {
if (filter.startsWith("(")) {
flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")" + filter + ")";
} else {
flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")(" + filter + "))";
}
} else {
flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
}
Filter osgiFilter = FrameworkUtil.createFilter(flt);
tracker = new ServiceTracker(bc, osgiFilter, null);
tracker.open(true);
// Note that the tracker is not closed to keep the reference
// This is buggy, as the service reference may change i think
Object svc = type.cast(tracker.waitForService(timeout));
if (svc == null) {
Dictionary dic = bc.getBundle().getHeaders();
System.err.println("Test bundle headers: " + explode(dic));
for (ServiceReference ref : asCollection(bc.getAllServiceReferences(null, null))) {
System.err.println("ServiceReference: " + ref);
}
for (ServiceReference ref : asCollection(bc.getAllServiceReferences(null, flt))) {
System.err.println("Filtered ServiceReference: " + ref);
}
//logger.error("Gave up waiting for service " + flt);
return null;
}
return type.cast(svc);
} catch (InvalidSyntaxException e) {
throw new IllegalArgumentException("Invalid filter", e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
/*
* Explode the dictionary into a ,-delimited list of key=value pairs
*/
@SuppressWarnings("rawtypes")
private static String explode(Dictionary dictionary) {
Enumeration keys = dictionary.keys();
StringBuffer result = new StringBuffer();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
result.append(String.format("%s=%s", key, dictionary.get(key)));
if (keys.hasMoreElements()) {
result.append(", ");
}
}
return result.toString();
}
/**
* Provides an iterable collection of references, even if the original array
* is null
*/
@SuppressWarnings("rawtypes")
private static Collection<ServiceReference> asCollection(ServiceReference[] references) {
return references != null ? Arrays.asList(references) : Collections.<ServiceReference> emptyList();
}
}
最后我正在等待输出:
START LEVEL 100 , List Threshold: 50
ID | State | Lvl | Version | Name
--------------------------------------------------------------------------------------
9 | Active | 80 | 2.3 | Gson
10 | Active | 80 | 3.3.4 | RabbitMQ Java AMQP client library
11 | Active | 80 | 4.0.26.Final | Netty/Buffer
12 | Active | 80 | 4.0.26.Final | Netty/Codec
13 | Active | 80 | 4.0.26.Final | Netty/Common
14 | Active | 80 | 4.0.26.Final | Netty/Handler
15 | Active | 80 | 4.0.26.Final | Netty/Transport
29 | Active | 80 | 2.15.1 | camel-blueprint
30 | Active | 80 | 2.15.1 | camel-catalog
31 | Active | 80 | 2.15.1 | camel-commands-core
32 | Active | 80 | 2.15.1 | camel-core
33 | Active | 80 | 2.15.1 | camel-netty4
34 | Active | 80 | 2.15.1 | camel-rabbitmq
35 | Active | 80 | 2.15.1 | camel-spring
36 | Active | 80 | 2.15.1 | camel-karaf-commands
37 | Active | 80 | 1.6.0 | Commons Pool
38 | Active | 80 | 1.0 | Apache Geronimo JSR-330 Spec API
39 | Active | 80 | 1.1.1 | geronimo-jta_1.1_spec
69 | Active | 80 | 2.2.6.1 | Apache ServiceMix :: Bundles :: jaxb-impl
81 | Active | 80 | 1.5.0 | OPS4J Base - IO
82 | Active | 80 | 1.5.0 | OPS4J Base - Lang
83 | Active | 80 | 1.5.0 | OPS4J Base - Monitors
84 | Active | 80 | 1.5.0 | OPS4J Base - Net
85 | Active | 80 | 1.5.0 | OPS4J Base - Service Provider Access
86 | Active | 80 | 1.5.0 | OPS4J Base - Store
87 | Active | 80 | 1.5.0 | OPS4J Base - Util - Property
88 | Active | 80 | 4.6.0 | OPS4J Pax Exam API
89 | Active | 80 | 4.6.0 | OPS4J Pax Exam Extender Service
90 | Active | 80 | 4.6.0 | OPS4J Pax Exam Injection
91 | Active | 80 | 4.6.0 | OPS4J Pax Exam JUnit Probe Invoker
92 | Active | 80 | 4.6.0 | OPS4J Pax Exam Remote Bundle Context
93 | Active | 80 | 1.8.1 | OPS4J Pax Swissbox :: OSGi Core
94 | Active | 80 | 1.8.1 | OPS4J Pax Swissbox :: Extender
95 | Active | 80 | 1.8.1 | OPS4J Pax Swissbox :: Framework Helpers
96 | Active | 80 | 1.8.1 | OPS4J Pax Swissbox :: Lifecycle
97 | Active | 80 | 1.8.1 | OPS4J Pax Swissbox :: Tracker
98 | Active | 80 | 1.3.0.1 | OPS4J Pax Tipi - hamcrest-core
99 | Active | 80 | 4.12.0.1 | OPS4J Pax Tipi - junit
112 | Active | 80 | 3.1.4 | Stax2 API
113 | Active | 80 | 4.4.1 | Woodstox XML-processor
114 | Active | 80 | | PAXEXAM-PROBE-bb084675-f072-481b-8f3e-6e3657762bc3