shiro configuration for integration testsing - java

For most of my integration test I don't need any security checks. I just want to have shiro out of my way. Beeing a shiro noob I'm wondering whether there's a better way than the one I found.
In my ShiroFilter class, if authentication fails I added this code:
try {
currentUser.login(token);
return CONTINUE;
} catch (AuthenticationException e1) {
// if everything failed, we might actualy have the integration test configuration, let's try
UsernamePasswordToken testToken = new UsernamePasswordToken("testUser", "testPassword", true, host);
try {
currentUser.login(testToken);
return CONTINUE;
} catch (AuthenticationException e2) {
LOGGER.info("Unable to login", e2);
}
}
And this is the shiro.ini for the integration tests:
[users]
testUser = testPassword, administrator
[roles]
administrator = *

Create a class for mock Shiro on integration tests.
package util;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.SubjectThreadState;
import org.apache.shiro.util.LifecycleUtils;
import org.apache.shiro.util.ThreadState;
import org.junit.AfterClass;
/**
* Abstract test case enabling Shiro in test environments.
*/
public abstract class AbstractShiroTest {
private static ThreadState subjectThreadState;
public AbstractShiroTest() {
}
/**
* Allows subclasses to set the currently executing {#link Subject} instance.
*
* #param subject the Subject instance
*/
protected void setSubject(Subject subject) {
clearSubject();
subjectThreadState = createThreadState(subject);
subjectThreadState.bind();
}
protected Subject getSubject() {
return SecurityUtils.getSubject();
}
protected ThreadState createThreadState(Subject subject) {
return new SubjectThreadState(subject);
}
/**
* Clears Shiro's thread state, ensuring the thread remains clean for future test execution.
*/
protected void clearSubject() {
doClearSubject();
}
private static void doClearSubject() {
if (subjectThreadState != null) {
subjectThreadState.clear();
subjectThreadState = null;
}
}
protected static void setSecurityManager(SecurityManager securityManager) {
SecurityUtils.setSecurityManager(securityManager);
}
protected static SecurityManager getSecurityManager() {
return SecurityUtils.getSecurityManager();
}
#AfterClass
public static void tearDownShiro() {
doClearSubject();
try {
SecurityManager securityManager = getSecurityManager();
LifecycleUtils.destroy(securityManager);
} catch (UnavailableSecurityManagerException e) {
//we don't care about this when cleaning up the test environment
//(for example, maybe the subclass is a unit test and it didn't
// need a SecurityManager instance because it was using only
// mock Subject instances)
}
setSecurityManager(null);
}
}
Then on test classes that you have Shiro dependency:
#RunWith(MockitoJUnitRunner.class)
public class ManterCampanhaServiceImplTest extends AbstractShiroTest {
#Test
public void someTest() throws Exception {
Subject subjectUnderTest = Mockito.mock(Subject.class);
when(subjectUnderTest.getPrincipal()).thenReturn(EntityObjectMother.getUserData()); //Subject for test
setSubject(subjectUnderTest);
// Now you have a test with a mock subject
// Write the test...
}}

Related

Prometheus requires that all meters with the same name have the same set of tag keys

If #Around only #Timed annotated method like this:
package ru.fabit.visor.config.aop;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.lang.NonNullApi;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.scheduling.annotation.Scheduled;
import java.lang.reflect.Method;
import java.util.function.Function;
/**
* The type Targeted timed aspect.
*/
#Aspect
#NonNullApi
public class TargetedTimedAspect {
public static final String DEFAULT_METRIC_NAME = "method.timed";
public static final String EXCEPTION_TAG = "exception";
public static final String BINDING_TAG = "binding";
public static final String SCHEDULED_CRON_TAG = "cron";
private final MeterRegistry registry;
private final Function<ProceedingJoinPoint, Iterable<Tag>> tagsBasedOnJoinPoint;
public TargetedTimedAspect(MeterRegistry registry) {
this(registry, pjp ->
Tags.of("class", pjp.getStaticPart().getSignature().getDeclaringTypeName(),
"method", pjp.getStaticPart().getSignature().getName())
);
}
public TargetedTimedAspect(MeterRegistry registry, Function<ProceedingJoinPoint, Iterable<Tag>> tagsBasedOnJoinPoint) {
this.registry = registry;
this.tagsBasedOnJoinPoint = tagsBasedOnJoinPoint;
}
// enable TimedAspect only for #StreamListener and #Scheduled annotated methods or allowed methods pointcut
#Around("timedAnnotatedPointcut() )")
public Object timedMethod(ProceedingJoinPoint pjp) throws Throwable {
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
StreamListener streamListener = method.getAnnotation(StreamListener.class);
Scheduled scheduled = method.getAnnotation(Scheduled.class);
// timed can be on method or class
Timed timed = method.getAnnotation(Timed.class);
if (timed == null) {
method = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
timed = method.getAnnotation(Timed.class);
}
final String metricName = timed.value().isEmpty() ? DEFAULT_METRIC_NAME : timed.value();
Timer.Sample sample = Timer.start(registry);
String exceptionClass = "none";
try {
return pjp.proceed();
} catch (Exception ex) {
exceptionClass = ex.getClass().getSimpleName();
throw ex;
} finally {
try {
Timer.Builder timerBuilder = Timer.builder(metricName)
.description(timed.description().isEmpty() ? null : timed.description())
.tags(timed.extraTags())
.tags(EXCEPTION_TAG, exceptionClass)
.tags(tagsBasedOnJoinPoint.apply(pjp))
.publishPercentileHistogram(timed.histogram())
.publishPercentiles(timed.percentiles().length == 0 ? null : timed.percentiles());
if (streamListener != null) {
timerBuilder.tags(
BINDING_TAG,
streamListener.value().isEmpty() ? streamListener.target() : streamListener.value()
);
} else if (scheduled != null) {
timerBuilder.tags(SCHEDULED_CRON_TAG, scheduled.cron());
}
sample.stop(timerBuilder.register(registry));
} catch (Exception e) {
// ignoring on purpose
}
}
}
#Pointcut(
"(#annotation(org.springframework.cloud.stream.annotation.StreamListener) ||" +
"#annotation(org.springframework.scheduling.annotation.Scheduled))"
)
public void asyncAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
#Pointcut("execution(public * ru.fabit.visor.service.impl.StorageClientImpl.*(..)) ||" +
"execution(public * ru.fabit.visor.service.s3storage.S3StorageClientImpl.*(..))")
public void allowedMethodPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
#Pointcut("#annotation(io.micrometer.core.annotation.Timed)")
public void timedAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
}
Then return: java.lang.IllegalArgumentException: Prometheus requires that all meters with the same name have the same set of tag keys. There is already an existing meter named 'web_photos_gotten_list_seconds' containing tag keys [class, exception, method]. The meter you are attempting to register has keys [exception, method, outcome, status, uri].
But, if add all #Timed method in Pointcut, all good work, i dont understand, why we need all annotated method add to Pointcut separately?
This work:
package ru.fabit.visor.config.aop;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.lang.NonNullApi;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.scheduling.annotation.Scheduled;
import java.lang.reflect.Method;
import java.util.function.Function;
/**
* The type Targeted timed aspect.
*/
#Aspect
#NonNullApi
public class TargetedTimedAspect {
public static final String DEFAULT_METRIC_NAME = "method.timed";
public static final String EXCEPTION_TAG = "exception";
public static final String BINDING_TAG = "binding";
public static final String SCHEDULED_CRON_TAG = "cron";
private final MeterRegistry registry;
private final Function<ProceedingJoinPoint, Iterable<Tag>> tagsBasedOnJoinPoint;
public TargetedTimedAspect(MeterRegistry registry) {
this(registry, pjp ->
Tags.of("class", pjp.getStaticPart().getSignature().getDeclaringTypeName(),
"method", pjp.getStaticPart().getSignature().getName())
);
}
public TargetedTimedAspect(MeterRegistry registry, Function<ProceedingJoinPoint, Iterable<Tag>> tagsBasedOnJoinPoint) {
this.registry = registry;
this.tagsBasedOnJoinPoint = tagsBasedOnJoinPoint;
}
// enable TimedAspect only for #StreamListener and #Scheduled annotated methods or allowed methods pointcut
#Around("timedAnnotatedPointcut() && (asyncAnnotatedPointcut() || allowedMethodPointcut())")
public Object timedMethod(ProceedingJoinPoint pjp) throws Throwable {
Method method = ((MethodSignature) pjp.getSignature()).getMethod();
StreamListener streamListener = method.getAnnotation(StreamListener.class);
Scheduled scheduled = method.getAnnotation(Scheduled.class);
// timed can be on method or class
Timed timed = method.getAnnotation(Timed.class);
if (timed == null) {
method = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
timed = method.getAnnotation(Timed.class);
}
final String metricName = timed.value().isEmpty() ? DEFAULT_METRIC_NAME : timed.value();
Timer.Sample sample = Timer.start(registry);
String exceptionClass = "none";
try {
return pjp.proceed();
} catch (Exception ex) {
exceptionClass = ex.getClass().getSimpleName();
throw ex;
} finally {
try {
Timer.Builder timerBuilder = Timer.builder(metricName)
.description(timed.description().isEmpty() ? null : timed.description())
.tags(timed.extraTags())
.tags(EXCEPTION_TAG, exceptionClass)
.tags(tagsBasedOnJoinPoint.apply(pjp))
.publishPercentileHistogram(timed.histogram())
.publishPercentiles(timed.percentiles().length == 0 ? null : timed.percentiles());
if (streamListener != null) {
timerBuilder.tags(
BINDING_TAG,
streamListener.value().isEmpty() ? streamListener.target() : streamListener.value()
);
} else if (scheduled != null) {
timerBuilder.tags(SCHEDULED_CRON_TAG, scheduled.cron());
}
sample.stop(timerBuilder.register(registry));
} catch (Exception e) {
// ignoring on purpose
}
}
}
#Pointcut(
"(#annotation(org.springframework.cloud.stream.annotation.StreamListener) ||" +
"#annotation(org.springframework.scheduling.annotation.Scheduled))"
)
public void asyncAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
#Pointcut("execution(public * ru.fabit.visor.service.impl.StorageClientImpl.*(..)) ||" +
"execution(public * ru.fabit.visor.service.s3storage.S3StorageClientImpl.*(..))")
public void allowedMethodPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
#Pointcut("#annotation(io.micrometer.core.annotation.Timed)")
public void timedAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}
}
pom.xml:
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
The problem youre discribing has nothing to do with pointcuts. There is one piece of code that generates a Timer with three tags (class, exception, method) and another one creating the timer with the exact same same with 5 tags (exception, method, outcome, status, uri) and the framework clearly says, that this is now allowed.
There are several possibilites to solve the issue:
simply use another name for the timer (if you need the other one)
find the other piece of code that generates that timer and deactivate it. Maybe you need to use the debugger and set an conditional breakpoint in MeterRegistry.register()` that registers the meters with the condition that the meter name matches.
PS: using the URI as a tag is not a good practice. The issue is that anyone access your service using different URIs (e.g. by just adding a random number) that will end up in a very high number of meters, which will finally kill your prometheus.

How can i check the proxy settings done by 'System.setProperty' in Java?

i'm developing an Java application that will be used to launch some Test Automation scripts on dedicated environment.
It is required to set also the proxy when necessary.
I developed a class that will be used to configure the proxy settings once a properties read from external contains the flag 'ENABLE_PROXY' equals 'True'.
Following is my snippet code:
package proxy;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Properties;
import org.apache.commons.lang3.exception.ExceptionUtils;
public class ProxyConfiguration {
private static String proxyHost;
private static String proxyPort; //80 if it isn't provided
private static String nonProxyHosts;
private static String protocolType;
public static boolean flagProxy;
//Set method used to read the flag Proxy
public static boolean isProxyEnabled(Properties myPropertiesFile) {
flagProxy = Boolean.parseBoolean(myPropertiesFile.getProperty("ENABLE_PROXY").toLowerCase());
return flagProxy;
}
public static String getProxyHost() {
return proxyHost;
}
//Set method used to read the Proxy host from properties
public static void setProxyHost(Properties myPropertiesFile) {
ProxyConfiguration.proxyHost = myPropertiesFile.getProperty("PROXY_HOST");
}
public static String getProxyPort() {
return proxyPort;
}
//Set method used to read the Proxy port from properties
public static void setProxyPort(Properties myPropertiesFile) {
ProxyConfiguration.proxyPort = myPropertiesFile.getProperty("PROXY_PORT");
}
public static String getNonProxyHosts() {
return nonProxyHosts.replace(",", "|");
}
//Set method used to read the exception from properties
public static void setNonProxyHosts(Properties myPropertiesFile) {
ProxyConfiguration.nonProxyHosts = myPropertiesFile.getProperty("PROXY_EXCEPTION");
}
public static String getProtocolType() {
return protocolType;
}
//Set method used to read the exception from properties
public static void setProtocolType(Properties myPropertiesFile) {
ProxyConfiguration.protocolType = myPropertiesFile.getProperty("PROTOCOL_TYPE");
}
//Method used to set the Proxy settings on system
public static void setProxyConfiguration(Properties myPropertiesFile) {
try {
ProxyConfiguration.setProtocolType(myPropertiesFile);
ProxyConfiguration.setProxyHost(myPropertiesFile);
ProxyConfiguration.setProxyPort(myPropertiesFile);
ProxyConfiguration.setNonProxyHosts(myPropertiesFile);
System.setProperty("java.net.useSystemProxies", "true");
System.setProperty(ProxyConfiguration.getProtocolType() +".proxyHost", ProxyConfiguration.getProxyHost());
System.setProperty(ProxyConfiguration.getProtocolType() +".proxyPort", ProxyConfiguration.getProxyPort());
boolean exceptions = ProxyConfiguration.getNonProxyHosts().isEmpty();
if(!exceptions) {
System.setProperty(ProxyConfiguration.getProtocolType() +".nonProxyHosts", ProxyConfiguration.getNonProxyHosts());
}
try {
URL url = new URL("http://java.sun.com/");
InputStream in = url.openStream();
//return true;
} catch (Exception e) {
//return false;
}
} catch (Exception e) {
System.err.println("Si รจ verificato un errore nella setProxyConfiguration: ");
String exc = ExceptionUtils.getStackTrace(e);
System.err.println(exc);
System.exit(-1);
}
}
}
How can i check if the proxy settings are set correctly?
I tried also to used the command prompt of my local machine and launch the follwing command:
netsh winhttp show proxy
but i receive:
Current WinHTTP proxy settings:
Direct access (no proxy server).
The properties read are:
PROTOCOL_TYPE=http
PROXY_HOST=webcache.mydomain.com (it is an example found on Java Networking)
PROXY_PORT=8080
PROXY_EXCEPTION=
Thanks for supporting!

Android Handler is null during testing with junit

I'm trying to test my network module. When I run this on simulator or device, handler is ok, but when I'm trying to do it from tests, handler = null and callback doesn't get called. How can I solve this problem?
public void performCall(Call callToPerform){
callToPerform.call.enqueue(new okhttp3.Callback() {
Handler handler = new Handler();
#Override
public void onFailure(okhttp3.Call call, IOException e) {
handler.post(() -> {
for (Callback callback : callToPerform.callbacks) {
callback.onFailure(callToPerform, e);
}
});
}
#Override
public void onResponse(okhttp3.Call call, final okhttp3.Response response){
handler.post(() -> {
for (Callback callback : callToPerform.callbacks) {
try {
callback.onResponse(callToPerform, new Response(response.body().bytes(), response.headers().toMultimap()));
} catch (IOException e) {
callback.onFailure(call, e);
}
}
});
}
});
}
My graddle app file contains this params.
testOptions {
unitTests.returnDefaultValues = true
}
Ok, after a few hours of research I've found solution and it's similar to this:
package com.dpmedeiros.androidtestsupportlibrary;
import android.os.Handler;
import android.os.Looper;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static org.mockito.Mockito.*;
/**
* Utility methods that unit tests can use to do common android library mocking that might be needed.
*/
public class AndroidMockUtil {
private AndroidMockUtil() {}
/**
* Mocks main thread handler post() and postDelayed() for use in Android unit tests
*
* To use this:
* <ol>
* <li>Call this method in an {#literal #}Before method of your test.</li>
* <li>Place Looper.class in the {#literal #}PrepareForTest annotation before your test class.</li>
* <li>any class under test that needs to call {#code new Handler(Looper.getMainLooper())} should be placed
* in the {#literal #}PrepareForTest annotation as well.</li>
* </ol>
*
* #throws Exception
*/
public static void mockMainThreadHandler() throws Exception {
PowerMockito.mockStatic(Looper.class);
Looper mockMainThreadLooper = mock(Looper.class);
when(Looper.getMainLooper()).thenReturn(mockMainThreadLooper);
Handler mockMainThreadHandler = mock(Handler.class);
Answer<Boolean> handlerPostAnswer = new Answer<Boolean>() {
#Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
Runnable runnable = invocation.getArgumentAt(0, Runnable.class);
Long delay = 0L;
if (invocation.getArguments().length > 1) {
delay = invocation.getArgumentAt(1, Long.class);
}
if (runnable != null) {
mainThread.schedule(runnable, delay, TimeUnit.MILLISECONDS);
}
return true;
}
};
doAnswer(handlerPostAnswer).when(mockMainThreadHandler).post(any(Runnable.class));
doAnswer(handlerPostAnswer).when(mockMainThreadHandler).postDelayed(any(Runnable.class), anyLong());
PowerMockito.whenNew(Handler.class).withArguments(mockMainThreadLooper).thenReturn(mockMainThreadHandler);
}
private final static ScheduledExecutorService mainThread = Executors.newSingleThreadScheduledExecutor();
}
If you run this sample code on JUnit, this will not work because JUnit tests are running on a JVM, and Instrumented tests are running on a Simulator or Real Device
You can take a look at this link, it explains why :
Instrumented tests or Local tests

How take screenshot and attach it to Allure report, while using Cucumber and JUnit?

I'm using Cucumber, Selenium, Java, Maven and JUnit stack in my automation-test-project.
The goal is to take screenshots on fails and broken tests. I have found the solution for Java/Maven/JUnit stack:
#Rule
public TestWatcher screenshotOnFailure = new TestWatcher() {
#Override
protected void failed(Throwable e, Description description) {
makeScreenshotOnFailure();
}
#Attachment("Screenshot on failure")
public byte[] makeScreenshotOnFailure() {
return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
}
};
But, of course it does not work in case of using Cucumber, because it does not use any #Test methods.
So, I've decided to change #Rule to #ClassRule, to make it listen to any fails, so here it is:
#ClassRule
public static TestWatcher screenshotOnFailure = new TestWatcher() {
#Override
protected void failed(Throwable e, Description description) {
makeScreenshotOnFailure();
}
#Attachment("Screenshot on failure")
public byte[] makeScreenshotOnFailure() {
logger.debug("Taking screenshot");
return ((TakesScreenshot) Application.getInstance().getWebDriver()).getScreenshotAs(OutputType.BYTES);
}
};
And this solution didn't help me.
So, the question is: "How to attach screenshots on fail, when I use Java/Selenium/Cucumber/JUnit/Maven in my test project?"
The solution is just to add following code to your definition classes:
#After
public void embedScreenshot(Scenario scenario) {
if (scenario.isFailed()) {
try {
byte[] screenshot = ((TakesScreenshot) Application.getInstance().getWebDriver())
.getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
} catch (Exception e) {
e.printStackTrace();
}
}
}
In the GlobalGlue
public class GlobalGlue {
#Before
public void before(Scenario scenario) throws Exception {
CONTEXT.setScenario(scenario);
}
#After
public void after() {
WebDriverUtility.after(getDriver(), CONTEXT.getScenario());
}
}
Create another class WebDriverUtility and in that add method:
public static void after(WebDriver driver, Scenario scenario) {
getScreenshot(driver, scenario);
driver.close();
}
and
public static void getScreenshot(WebDriver driver, Scenario scenario) {
if (scenario.isFailed()) {
final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
log.info("Thread: " + Thread.currentThread().getId() + " :: "
+ "Screenshot taken and inserted in scenario report");
}
}
the main part is you need to embed the screen shot in scenario when scenario is failed:
final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
ExecutionContext.java
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import cucumber.api.Scenario;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.WebDriver;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
/**
* Maintains one webdriver per scenario and one scenario per thread.
* Can be used for parallel execution.
* Assumes that scenarios within one feature are not parallel.
* Can be rewritten using <code>ThreadLocal</code>.
*
* #author dkhvatov
*/
public enum ExecutionContext {
CONTEXT;
private static final Logger log = LogManager.getLogger(ExecutionContext.class);
private final LoadingCache<Scenario, WebDriver> webDrivers =
CacheBuilder.newBuilder()
.build(CacheLoader.from(scenario ->
WebDriverUtility.createDriver()));
private final Map<String, Scenario> scenarios = new ConcurrentHashMap<>();
/**
* Lazily gets a webdriver for the current scenario.
*
* #return webdriver
*/
public WebDriver getDriver() {
try {
Scenario scenario = getScenario();
if (scenario == null) {
throw new IllegalStateException("Scenario is not set for context. " +
"Please verify your glue settings. Either use GlobalGlue, or set " +
"scenario manually: CONTEXT.setScenario(scenario)");
}
return webDrivers.get(scenario);
} catch (ExecutionException e) {
log.error("Unable to start webdriver", e);
throw new RuntimeException(e);
}
}
/**
* Gets scenario for a current thread.
*
* #return scenario
*/
public Scenario getScenario() {
return scenarios.get(Thread.currentThread().getName());
}
/**
* Sets current scenario. Overwrites current scenario in a map.
*
* #param scenario scenario
*/
public void setScenario(Scenario scenario) {
scenarios.put(Thread.currentThread().getName(), scenario);
}
}
This way you can attach screens to your allure report.
Also use the Latest allure version in your pom file
import com.google.common.io.Files;
import io.qameta.allure.Attachment;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import java.io.File;
import java.io.IOException;
public class ScreenshotUtils {
#Attachment(type = "image/png")
public static byte[] screenshot(WebDriver driver)/* throws IOException */ {
try {
File screen = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
return Files.toByteArray(screen);
} catch (IOException e) {
return null;
}
}
}
Pom File :
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-cucumber4-jvm</artifactId>
<version>${allure.version}</version>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit4</artifactId>
<version>${allure.version}</version>
<scope>test</scope>
</dependency>
public static void TakeScreenshot(string text)
{
byte[] content = ((ITakesScreenshot)driver).GetScreenshot().AsByteArray;
AllureLifecycle.Instance.AddAttachment(text, "image/png", content);
}
public static void Write(By by, string text)
{
try
{
driver.FindElement(by).SendKeys(text);
TakeScreenshot( "Write : " + text);
}
catch (Exception ex)
{
TakeScreenshot( "Write Failed : " + ex.ToString());
Assert.Fail();
}
}

Wildfly 10.x remote EJB client hangs when sending an enum value with CONNECT in the name

I've got a simple stateless EJB with a method that takes a basic enum as an argument and returns the same enum.
#Stateless
#LocalBean
public class SerialBean implements RemoteSerial {
#Override
public Whatever enumTest(Whatever type) {
return type;
}
}
Here's the simple enum:
public enum Whatever {
TEST,
CONNECT_TEST
}
And a simple client:
Properties jndiProps = new Properties();
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
jndiProps.put("jboss.naming.client.ejb.context", true);
try {
Context ctx = new InitialContext(jndiProps);
RemoteSerial serial = (RemoteSerial)ctx.lookup("rmi_test/rmi_ejb/SerialBean!test.RemoteSerial");
System.out.println(serial.enumTest(Whatever.TEST));
System.out.println(serial.enumTest(Whatever.CONNECT_TEST));
} catch (NamingException ex) {
ex.printStackTrace();
}
When I run this code, the client successfully connects to WildFly and returns the first result (TEST). However, the client then freezes when performing the second method call (CONNECT_TEST). No response is received.
If I change the name of CONNECT_TEST to something that doesn't have CONNECT in it, the code works. I can even change CONNECT to cONNECT and that works.
I've tried this in both 10.0 and 10.1 on Windows 7 using jdk1.8.0_102 and 121.
What could possibly be going on here?
I was unable to reproduce your results. For comparison, here's my code, in full.
Server (ejb module rmi_test):
TestEnum.java
package com.example.rmitest;
public enum TestEnum {
TEST, CONNECT_TEST
}
SerialBean.java
package com.example.rmitest;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
#Stateless
#LocalBean
public class SerialBean implements RemoteSerial {
#Override
public TestEnum enumTest(TestEnum input) {
return input;
}
}
RemoteSerial.java
package com.example.rmitest;
import javax.ejb.Remote;
#Remote
public interface RemoteSerial {
TestEnum enumTest(TestEnum input);
}
Client (standalone JSE app, with wildfly-10.1.0.Final/bin/client/jboss-client.jar on it's classpath):
Client.java
package com.example.rmitest;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class Client {
public static void main(String... args) {
RemoteSerial remoteSerial = lookupRemoteService();
System.out.println(remoteSerial.enumTest(TestEnum.TEST));
System.out.println(remoteSerial.enumTest(TestEnum.CONNECT_TEST));
}
private static RemoteSerial lookupRemoteService() {
try {
return (RemoteSerial) jndiConnect().lookup("/rmi_ejb/SerialBean!com.example.rmitest.RemoteSerial");
} catch (NamingException e) {
throw new RuntimeException("Failed to lookup a remote interface", e);
}
}
private static Context jndiConnect() {
try {
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
properties.setProperty(Context.PROVIDER_URL, "http-remoting://localhost:8080");
properties.setProperty("jboss.naming.client.ejb.context", "true");
return new InitialContext(properties);
} catch (NamingException e) {
throw new RuntimeException("Failed to establish a connection", e);
}
}
}
And finally, my console output:
TEST
CONNECT_TEST

Categories

Resources