Skip to content

Instantly share code, notes, and snippets.

@geoand
Created April 8, 2020 09:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geoand/1f48161192f90a792495b50f1b073d09 to your computer and use it in GitHub Desktop.
Save geoand/1f48161192f90a792495b50f1b073d09 to your computer and use it in GitHub Desktop.
/*
* Copyright 2020 Red Hat
*
* 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 io.apicurio.registry.utils.tests;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import io.apicurio.registry.client.RegistryClient;
import io.apicurio.registry.client.RegistryService;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
import org.junit.platform.commons.util.AnnotationUtils;
import static java.util.Collections.singletonList;
/**
* @author Ales Justin
*/
public class RegistryServiceExtension implements TestTemplateInvocationContextProvider {
@Override
public boolean supportsTestTemplate(ExtensionContext context) {
return context.getTestMethod().map(method -> {
Class<?>[] parameterTypes = method.getParameterTypes();
return Arrays.stream(parameterTypes).map(Class::getName).anyMatch(s -> RegistryService.class.getName().equals(s));
}).orElse(false);
}
@Override
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
RegistryServiceTest rst = AnnotationUtils.findAnnotation(context.getRequiredTestMethod(), RegistryServiceTest.class)
.orElseThrow(IllegalStateException::new); // should be there
String registryUrl = TestUtils.getRegistryUrl(rst);
ExtensionContext.Store store = context.getStore(ExtensionContext.Namespace.GLOBAL);
Object plain = store.get("plain_client");
if (null == plain) {
plain = registryServiceWrapper("plain_client", registryUrl);
store.put("plain_client", plain);
}
Object cached = store.get("cached_client");
if (null == cached) {
cached = registryServiceWrapper("cached_client", registryUrl);
store.put("cached_client", cached);
}
return stream(plain, cached);
}
@SuppressWarnings("unchecked")
private Stream<TestTemplateInvocationContext> stream(Object plain, Object cached) {
try {
Constructor<RegistryServiceTestTemplateInvocationContext> invocationContextCtor = (Constructor<RegistryServiceTestTemplateInvocationContext>) Class.forName(RegistryServiceTestTemplateInvocationContext.class.getName(), false, properCL())
.getConstructor(Class.forName(RegistryServiceWrapper.class.getName(), false, properCL()));
return Stream.of(invocationContextCtor.newInstance(plain), invocationContextCtor.newInstance(cached));
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object registryServiceWrapper(String key, String registryUrl) {
try {
Method restClientCreateMethod = Class
.forName(RegistryClient.class.getName(), false, properCL())
.getMethod("create", String.class);
Object restClient = restClientCreateMethod.invoke(null, registryUrl);
Constructor<?> registryServiceWrapperCtor = Class
.forName(RegistryServiceWrapper.class.getName(), false, properCL())
.getConstructor(String.class, Class
.forName(RegistryService.class.getName(), false, properCL()));
return registryServiceWrapperCtor.newInstance(key, restClient);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
private Class<RegistryServiceWrapper> registryServiceWrapperClass() {
try {
return (Class<RegistryServiceWrapper>) Class.forName(RegistryServiceWrapper.class.getName(), false, properCL());
}
catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private ClassLoader properCL() {
return Thread.currentThread().getContextClassLoader();
}
public static class RegistryServiceWrapper implements ExtensionContext.Store.CloseableResource {
private final String key;
private final RegistryService service;
public RegistryServiceWrapper(String key, RegistryService service) {
this.key = key;
this.service = service;
}
@Override
public void close() throws Throwable {
service.close();
}
public String getKey() {
return key;
}
public RegistryService getService() {
return service;
}
}
public static class RegistryServiceTestTemplateInvocationContext implements TestTemplateInvocationContext, ParameterResolver {
private final RegistryServiceWrapper wrapper;
public RegistryServiceTestTemplateInvocationContext(RegistryServiceWrapper wrapper) {
this.wrapper = wrapper;
}
@Override
public String getDisplayName(int invocationIndex) {
return String.format("%s [%s]", wrapper.getKey(), invocationIndex);
}
@Override
public List<Extension> getAdditionalExtensions() {
return singletonList(this);
}
@Override
public boolean supportsParameter(ParameterContext pc, ExtensionContext extensionContext) throws ParameterResolutionException {
return RegistryService.class.getName().equals(pc.getParameter().getType().getName());
}
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
return wrapper.getService();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment