【问题标题】:Transient mode for unit tests with jclouds and Openstack Swift doesn't work使用 jclouds 和 Openstack Swift 进行单元测试的瞬态模式不起作用
【发布时间】:2016-12-02 10:27:17
【问题描述】:

我刚刚迁移到 jclouds 2.0.0(假设存在一些不可重复操作的问题,但确实如此)。这是依赖项

    <dependency>
        <groupId>org.apache.jclouds.driver</groupId>
        <artifactId>jclouds-slf4j</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.jclouds.api</groupId>
        <artifactId>openstack-keystone</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.jclouds.api</groupId>
        <artifactId>openstack-swift</artifactId>
        <version>2.0.0</version>
    </dependency>

我想对我的代码进行单元测试。但是当我使用transient 作为提供者时:

SwiftApi swiftApi = ContextBuilder.newBuilder("transient")
                .endpoint(endpoint)
                .credentials(user, password)
                .modules(modules)
                .overrides(overrides)
                .buildApi(SwiftApi.class);

我得到了这个例外:

com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for org.jclouds.openstack.swift.v1.SwiftApi was bound.
  while locating org.jclouds.openstack.swift.v1.SwiftApi

1 error

    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1004)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1009)
    at org.jclouds.ContextBuilder.buildApi(ContextBuilder.java:651)
    at org.jclouds.ContextBuilder.buildApi(ContextBuilder.java:643)
    at eu.europeana.cloud.service.mcs.persistent.swift.SimpleSwiftConnectionProvider.openConnections(SimpleSwiftConnectionProvider.java:91)
    at eu.europeana.cloud.service.mcs.persistent.swift.SimpleSwiftConnectionProvider.<init>(SimpleSwiftConnectionProvider.java:67)
    at eu.europeana.cloud.service.mcs.persistent.swift.SimpleSwiftConnectionProviderTest.getContainer(SimpleSwiftConnectionProviderTest.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    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.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    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 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

openstack-swift 作为提供者(以及正确的凭据和端点)运行的相同代码可以正常工作。 将任何其他字符串作为newBuilder 函数参数传递原因:

java.util.NoSuchElementException: key [wrongstring] not in the list of providers or apis: {apis=[openstack-keystone, openstack-swift, transient]}
    at org.jclouds.ContextBuilder.newBuilder(ContextBuilder.java:175)

这让我觉得应该支持transient。但是如何让它发挥作用呢?

【问题讨论】:

    标签: java unit-testing openstack-swift jclouds


    【解决方案1】:

    您不能创建瞬态 blobstore 的 SwiftApi 视图;相反,您必须使用可移植的BlobStore 视图:

    String provider = ...;  // openstack-swift or transient
    BlobStoreContext context = ContextBuilder.newBuilder(provider)
                .endpoint(endpoint)
                .credentials(user, password)
                .buildApi(BlobStoreContext.class);
    BlobStore blobStore = context.getBlobStore();
    // interact with blobStore, e.g., get, put
    ...
    context.close();
    

    【讨论】:

    • 这就是我最后所做的并且它有效......但首先有点难过,你不能对 SwiftApi 代码进行单元测试。第二:例外是列出可用的提供者是错误的和误导性的。
    • SwiftApi 和瞬态有不同的 API,你不能只将一个插入另一个。 BlobStore 代码实现了这个可移植层。如果你想要一个测试 Swift 服务器,你可以使用 SwiftProxy:github.com/bouncestorage/swiftproxy
    • 感谢您的澄清。与 Blobstore 相比,使用 SwiftApi 有什么优势吗?我在 jclouds v2 之前使用它,现在它工作得很好,但是文档建议使用 SwiftApi:jclouds.apache.org/guides/openstack/#swift 我应该考虑一下吗?
    • 通常用户调用 BlobStore API 进行大多数操作,以便他们的应用程序是可移植的。当用户需要仅由 SwiftApi 公开的附加功能时,他们会在特定调用站点中调用该功能。一个示例是以字节为单位获取容器大小,并非由所有 blobstore 公开,因此只是 SwiftApi 的一部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    相关资源
    最近更新 更多