Maven + Surefire/Failsafe - forkMode="perthread" is not working ... a workaround? - maven

We are developing an application based in an Embedded Infinispan Data-grid cluster. In the targeted environment of our application, each member of the data-grid will run in a independent JVM and using jgroup the cluster will be formed (this is done by Infinispan actually).
For do some automated testing over this data-grid we were working with maven-surefire-plugin (or maven-failsafe-plugin) with this configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkMode>perthread</forkMode>
<threadCount>4</threadCount>
</configuration>
</plugin>
Because this configuration should create a fork per each testcase class (using 4 parallel process) we create 4 test classes, where each one of them will simulate one cluster member. Inside each testcase class we will have several threads running in parallel the test methods thanks to TestNG like this:
#Test(threadPoolSize = 3, invocationCount = 2, timeOut = 10000, testName="Test 1")
public void testSomething() throws Throwable { ... }
The problem is that the maven-surefire-plugin forkMode="perthread" and threadCount=4 is buggy: It do not create one fork per class but a fork of the same class several times. So, in my scenario it takes one of the testcases and run it 4 times in parallel!!!
NOTE: check the jira bug here. Please vote!!!!
Do someone knows a workaround for this? We are doing some efforts using ant but is getting very messy.

The maven-surefire-plugin bug was resolved and it will be released in the version 2.13!
Check the Jira ticket for more info: http://jira.codehaus.org/browse/SUREFIRE-869

Related

Transaction synchronization in Spring Boot

I have a small Spring Boot application with spring-boot-starter-web, spring-boot-starter-data-jpa, and postgresql as dependencies.
I'm able to use the #Transactional annotation and use JPA to fetch and save entities to the database. However, if I were to add afterCommit/afterCompletion hooks via registering a synchronization, it gives an IllegalStateException saying that Transaction synchronization is not active.
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronizationAdapter() {
#Override
public void afterCommit() {
//this doesn't get called
log.info("do something here");
}
});
Doing TransactionSynchronizationManager.initSynchronization(); gets rid of the error, but the hooks don't get called (eg: the afterCommit hook doesn't get called even though the transaction has committed.)
Any clues on how to debug this?
It turned out that I had forgotten to include the build plugin that is used to create the AoP-proxies for beans having #Transactional annotations.
In the absence of this plugin, no proxies would get generated, and the code would run non-transactionally; except for when it enters the JpaRepository methods where it would create a short-lived transaction for the duration of the call (such as save/findAll/delete).
This is the plugin that I missed including in my pom.xml (this got generated in the pom output by the spring initializr (https://start.spring.io/) but I didn't notice it at first and didn't copy it over into my pom)
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
I think you need #TransactionalEventListener annotation. It supports hooks BEFORE_COMMIT, AFTER_ROLLBACK, AFTER_COMPLETION, AFTER_COMMIT and AFTER_ROLLBACK.
More info in this post: Better application events in Spring Framework 4.2.

How to enable Rhino (or any JavaScript Engine) in CQ 5.6?

I have some custom logic where I need to evaluate a simple boolean expression. In my IDE I have some unit tests that run fine, but when I'm trying to use it on my CQ 5.6.1 instance, the ScriptEngineManager can't find a JavaScript engine. Though this should be part of a standard java installation on any environment.
ScriptEngineManager sef = new ScriptEngineManager();
ScriptEngine se = sef.getEngineByName("JavaScript");
In the pom I have the following which usually helps:
<Import-Package>*;resolution:=optional</Import-Package>
Usually some system libraries aren't exposed in OSGi when you don't put it into the bootdelegation in the sling.properties, but this didn't work either:
org.osgi.framework.bootdelegation=org.w3c.*,com.sun.script.*,com.yourkit.*, ${org.apache.sling.launcher.bootdelegation}
What else could I try?
EDIT:
Also regarding my comment to Christians answer. I found out that there should be a service in the OSGi:
http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java
But when I try to reference it with the following code, my servlet isn't active anymore:
#Reference
private transient ScriptEngineFactory sef = null;
So it seems it can't inject the factory for some reason. I've seen there could be more than one service implementing this interface, how would I target the correct one (linked above)?
EDIT2:
I now even tried to reference the Rhino factory directly:
#Reference(target = "(component.name=org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)")
private transient ScriptEngineFactory sef = null;
With this my servlet tells me it is satisfied:
["Satisfied","Service Name: javax.script.ScriptEngineFactory","Target Filter: (component.name=org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)","Multiple: single","Optional: mandatory","Policy: static","Bound Service ID 2004 (org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)"]
But if I access my servlet it doesn't get triggered and the SlingDefaultServlet takes over. Without the above #Reference it is accessible, so it has to do something with it.
You need an OSGi capable ScriptEngineManager. See https://devnotesblog.wordpress.com/2011/09/07/scripting-using-jsr-223-in-an-osgi-environment/
After almost a whole day of trial and error I found 2 major problems:
First: My compiler plugin was set to use 1.8; I had to revert that to 1.6 so my maven-scr-plugin would create proper manifests again and injection of OSGi services actually works:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
I have to investigate later how it would be possible to increase that to at least 1.7 (I tried but didn't work either).
Second and the actual answer for my question is simple:
#Reference
private transient ScriptEngineManager sem = null;
Also I had to use javascript instead of JavaScript for the getEngineByName method from the manager. To see what is registered for the engine, you can check out the following path in your OSGi console:
/system/console/status-slingscripting
There all available ScriptEngine are listed with their registered names, extensions and MIME Types.

How to run Selenium + Maven tests on specific browser which is mentioned in pom.xml?

By mentioning parameter tag like following in testng.xml:
<parameter name="browser" value="Firefox"></parameter>
and using following code:
#Parameters({"browser"})
public void test(String browser){ ... }
we can instantiate webdriver object for specific browser and run Selenium test on that browser.
But how can we achieve same using Selenium + Maven? I mean by mentioning browser name somewhere in testng.xml or pom.xml.
In order to achieve that, I went through Specifying Test Parameters section from http://maven.apache.org/surefire/maven-surefire-plugin/examples/testng.html but I didn't understand how parameters from Maven can be passed into your TestNG test.
Can someone help me on how this can be achieved or point me documentation/repository which will help me to achieve this?
The short answer is if you are using something like below in your pom.xml, you will not be able to access the value via the annotation #Parameters.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18</version>
<configuration>
<systemPropertyVariables>
<propertyName>firefox</propertyName>
</systemPropertyVariables>
</configuration>
</plugin>
#Parameters is a concept which only applies when parameters are passed via a TestNG suite file or programmatically by manipulating the Map<String, String> data structure which contains the #Parameters.
To access the system property defined you would use System.getProperty("propertyName");
For example;
Accessing the system property in the test method.
#Test
public void test() {
String browser = System.getProperty("browser");
}
Or accessing the system property in a before step and adding it the TestNG data structure.
#BeforeSuite
public void before(ITestContext ctx) {
ctx.getCurrentXmlTest().getSuite().getParameters().put("browser"), System.getProperty("browser");
}
#Test
#Parameters({"browser"})
public void test(String browser) {
//....
}
You can define your browser configuration in testNG.xml(exactly as you mentioned ) and simply kick start it using pom.xml.
You don't need to mention any browser specific details in POM.xml.I believe maven simply executes your testNG file with whatover configuration provided unless it requires an external libs/jars.
If you are facing any specific issues/errors while doing the same then share the details.

Loading a partial Spring context

I am not much of a Spring expert, but was given a legacy system with a huge context file (not separated into modules).
I want to add some unit tests - that validates different parts of the system, with the actual production configuration.
I started using the ClassPathXmlApplicationContext/FileSystemXmlApplicationContext classes to load the context, however - that takes forever.
Is it possible to load only parts of the context file (recursively) without the need to separate the original file into modules?
Update:
I'll just post here my implementation of Ralph's solution using maven:
my pom.xml:
<plugin>
<groupId>com.google.code.maven-config-processor-plugin</groupId>
<artifactId>maven-config-processor-plugin</artifactId>
<version>2.0</version>
<configuration>
<namespaceContexts>
<s>http://www.springframework.org/schema/beans</s>
</namespaceContexts>
<transformations>
<transformation>
<input>context.xml</input>
<output>context-test.xml</output>
<config>test-context-transformation.xml</config>
</transformation>
</transformations>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<phase>test</phase>
</execution>
</executions>
</plugin>
my test-context-transformation.xml:
<processor>
<add>
<name>/s:beans</name>
<value>
<![CDATA[
default-lazy-init="true"
]]>
</value>
</add>
</processor>
If you are trying to run "unit" tests, you will not require the full application context at all. Just instantiate the class you want to test (and maybe its collaborators, though mocking may be a better option) and off you go. Unit tests should concentrate on single components in isolation - otherwise they are not unit tests.
If you are trying to run a full integration test by creating the complete object hierarchy defined in your application context, then it may be easiest by first refactoring your context and splitting it into modules - as you were suggesting already.
I guess it does not work out of the box. But you can try this (it is just an idea, I don't know if it works)
Spring support so called lazy initialization the idea is to add this to all the beans.
I can imagine two ways.
A simple tool that create an copy of the orignal configuration xml file and add default-lazy-init="true" the container level beans (with s) declaration.
Try do do it programmatic. With a Bean Post Processor, or try to "inject" the default-lazy-init="true" configuration programmatic

Integration testing against an http server - junit?

I want to to integration tests against an http server. So far I have only experiences with junit for unit testing.
I have two requirements: The framework must have a maven plugin and the tests cases code must be clean - so no dirty hacks and no boilerplate code.
Plain JUnit is good for unit testings, #Test methods are individual. But for integration testing I have to process several dependant steps which must exchange some kind of state (variables).
I already read:
Can we use JUNIT for Automated Integration Testing? and Passing JUnit data between tests and came to the conclusion that I don't like static fields in unit test and I don't want to use TestNG and add dependency annotations on tests and I don't want to put my test into one long unreadable test method.
I though more about some syntax like:
public class MyIntegrationTest() {
#Step
public void testCreate(Context context) {context.put("foo");}
#Step
public void testUpdate(Context context) {context.get();}
#Step
public void testDelete(Context context) {context.get()}
}
So I want to enhance/use ?Unit in a way that it executes #Step methods with a context instance as argument. The methods must be called by the framework in order and cannot be called individually. In a perfect world, all ?Unit guis would show the #Step like an #Test but this is optional...
Any hints how to do this?
Jan
The first point is to check the Maven Failsafe Plugin which is intended for doing integration tests with Maven. Second you have to name your Integration tests based on the conventions used by Maven FailSafe Plugin after that you should be able to run your integration tests simply with maven (by mvn clean verify).
So this means you have to name your integration test like MyIntegrationIT.java...To define the order of executions you have to use a different framework than JUnit may be TestNG which supports this kind of needs, but you already excluded it. So the questions is what kind of tests would you like to do? Page-flows etc. may be a look at JWebUnit might be look worth...
You might also want to consider http://httpunit.sourceforge.net/. It's useful for checking to see if responses come back from the http server.
However, it doesn't do the #Step functionality. Normally I'd do that by :
#Test
public void MasterTest() {
step1(..);
step2(..);
....
}
public void step1(...){...}
public void step2(...){...}

Resources