Elasticsearch 5.2 unit tests - multithreading

I am writing unit tests for ES5.2, and am having some issues. I need to create a client which connects to a local node for running tests, so I use
esClient = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
This causes problems
java.lang.IllegalStateException: running tests but failed to invoke RandomizedContext#getRandom
So then I used an annotation on my unit test classes as
#RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class)
but this gave me an error
SEVERE: 2 threads leaked from TEST scope at {method_name}):
1) Thread[id=36, name={project_name}writer-thread-0, state=WAITING, group={project_name}-writer]
And the unit tests threw errors as
org.mockito.exceptions.misusing.WrongTypeOfReturnValue
I tried to use the annotation as below on the unit test class
#ThreadLeakScope(ThreadLeakScope.Scope.NONE)
That got rid of some error messages, but there were still concurrency issues in the code.
Anyone knows how to handle this? Is there some explicit thread safety methods I should use?

Excluding com.carrotsearch.randomizedtesting:randomizedtesting-runner from dependencies works.
Example (build.gradle):
dependencies {
testCompile(project(path:':other-project')) {
exclude group:"com.carrotsearch.randomizedtesting", module:"randomizedtesting-runner"
}
}
Why?
If you have randomizedtesting-runner in your classpath, ES will load it:
https://github.com/elastic/elasticsearch/blob/7.10/server/src/main/java/org/elasticsearch/common/Randomness.java#L55
And use it:
https://github.com/elastic/elasticsearch/blob/7.10/server/src/main/java/org/elasticsearch/common/Randomness.java#L102

Related

mutation fails on initial test run with jest runner

i'm using strykerjs 5.6.0 with jest runner and react-testing-library. When I run the coverage with jest, all my test pass correctly, but when i run the mutation command (pointing to the same jest config file) i'm getting an error on initial test run because one test is getting a different value than the one i'm getting with the jest command in the coverage.
So, in thispicture it can be seen that the test is not getting the same value, this parseJSONString is a custom method to parse string type props to its js type (due to kill mutants i had to add this), its implementation is this, and it looks like the mutation is returning the fallback instead of the actual value of the array received in the coverage run.
The Stryker config is the following, any ideas? the jest version is the 26.6.3 also. I guess the issue must be related with the react testing library, but i do not understand what could be going on...
I could solve it using the waitFor hook, i don't know why, but stryker needs one render more than jest to get the test case properly mounted.

Mockito latest versions support to surpress static block

I am trying to add tests using latest (5.7.0) Mockito and using Mockito.mockStatic(...)
to mock class with static methods which works fine . However when I have class with static block it is unable to create mock and fais with java.lang.InternalError: class redefinition failed: invalid class .
Is this supported in latest mockito versions or still I have to live with other alternatives like powermock.
I did face the same error and couldn't find answer in the internet, so I see that it is 1 month old question but might help someone.
The problem was that mocked class (or classes that this static block used) was not in the classpath. Before you can mock the method all static blocks or fields initializators will be run, and it causes the problem.
You can verify what class is missing in your classpath by simply trying to use this static method before mocking it. You should get java.lang.NoClassDefFoundError with a class name.
When you resolve this problem, everything should work.
I had this issue, and for me it was due to an Error being thrown from instrumentation.retransformClasses called from org.mockito.internal.creation.bytebuddy.inlineBytecodeGenerator. Somewhere between there and findOrInsert in net.bytebuddy.TypeCache, the Throwable looses its context (for mockito-core 4.1.0 and bytebuddy 1.12.0)
In my case, the error being thrown was a NoClassDefFoundError for Jetty Servlet. This ultimately turned out to be a dodgy local build of a different maven module I had been working on, so clearing out my ~/.m2 and downloading a legit version fixed that right up.
You might be able to catch the Error being thrown in inlineBytecodeGenerator and taking a look at what's really going on, if this is in fact the same problem.

Error mocking a "non-strict" legacy module on Jest

I have some really messy non-strict-compliant legacy code on javascript, running just fine on NodeJs 12, and I'm trying to abstract it away and test the overlaying, new layers of code using Jest/Mocks.
But when I try to run the tests I receive the following error:
Test suite failed to run
SyntaxError: /legacy-path/messy_legacy_code.js: Legacy octal literals are not allowed in strict mode (557:66)
at Parser._raise (node_modules/#babel/parser/src/parser/error.js:60:45)
I'm trying to mock it away first thing on my test code, but still get this error. It seems that Jest is trying to parse it with Babel; it really won't find any compliant code there... It just runs on Node, nothing else.
I already tried mocking the legacy code itself and also tried making a container to "abstract" it away and mocking the container. But it seems Jest still tries to read every bit of noncompliant code behind it.
My modern.test.js code looks like this:
jest.mock('../../../../legacy-path/messy-container')
const { ModernLayer } = require('../../../../modern-path/modern-module');
Any ideas on how I cant completely block Jest from trying to read this noncompliant code and just mock it away?
jest.mock('...') performs auto-mock, unless a mock from __mocks__ is used. It tries to process module exports and fails on syntax error.
The module should be manually mocked instead:
jest.mock('../../../../legacy-path/messy-container', () => ({ ModernLayer: ... }));

Use of Method stubbed in Moles inside a Shims context

Recently while going through the automated test cases of a project I came across a piece of code which was something like this.
[TestMethod]
public void UpdateTtWebScResearchIdt()
{
using (ShimsContext.Create())
{
// Some code
SomeNamespace.Moles.MSubCom.StringFormatStringStringArray = (x, y) => "gLibErr";
//Assert
}
}
When I debug this test method, the compiler shows the following error
MolesInvalidOperationException.
At the line where Moles method is stubbed i.e.
SomeNamespace.Moles.MSubCom.StringFormatStringStringArray = (x, y) => "gLibErr";
The detailed message shows this.
"Moles requires tests to be IN an instrumented process.
In Visual Studio Unit Test, add the following attribute to your unit test method:
add this attribute
[TestMethod]
[HostType(Moles)]
public void Test()
{
...
}
Extensions are also available for most unit test frameworks. Please refer to the Moles manual.
But adding the aforementioned attribute does not solve my problem either.
I think that the use of moles inside a shimmed method is problematic.
I need an another opinion on this (or many for that matter).
And if someone can suggest a solution that'd be awesome.
Thanks.
The only problem with your initial code is the missing [HostType(Moles)]. Next you have to be sure you are running your tests with the Visual Studio test runner. If you have installed an other test runner, it could be that it is not loading the Moles host.
moles-requires-tests-to-be-in
I could not find why it was written like this so I rewrote the entire test method using fakes assembly. Now it is working fine.

drools linkage error with multiple threads

I have a junit test case which creating two threads to run a application. In this application, there is a method updateStatus which used for fire drools rules. And in this rules file, I have some functions like next :
function Object updateItem() {
.....
}
function boolean isNullOrEmpty(Object obj) {
...
}
function Object getValueFromFact(Object obj) {
....
}
I restart my tomcat, run this unit test, but one thread failed, the error was :
org.apache.cxf.interceptor.Fault: loader (instance of org/drools/rule/JavaDialectRuntimeData$PackageClassLoader): attempted duplicate class definition for name: "com/icil/sofs/booking/rules/GetValueFromFact"
'getValueFromFact' is a function which defined in rules file.
then run it again without restart tomcat, there is no error. then run third time without restart tomcat, there is no error too.
after tried, i found that the 'duplicate class' error only happened at the first time running after restarting tomcat.
i also found that at the first time, 2 threads are execute 'knowldegeSession.execute()' at the "same time", but 2 threads are run 'knowledgeSession.execute()' in sequence at 2nd time and 3rd time.
so why this error 'duplicate class definition' always happened at the first time running after restart tomcat?
and why the error is the function 'getValueFromFact'(this is the 3rd function in rules file) but not the first function 'updateItem'(this is the first function in rules file)?
thanks in advance!
Because there are multiple threads are running 'execute()', and they are loading functions at the 'same time', so this error thrown out.
When calling 'addKnowledgePackages()', drools will load rules, but the functions may not be loaded at this time, they may be loaded when calling 'execute()'.
After debugging, i found that drools will load functions if rules conditions use mvel expression instead of java expression when calling 'addKnowldegePackages()'.
I am using drools 5.5.0.Final, I cannot upgrade drools to 6.0 at present because 6.0 has big difference. But I have to figure out a solution as this problem need to be fixed as soon as possible :
Make your code 'addKnowledgePackages()' can be run when tomcat start, e.g. put it in a static block, as well as change your rules to use mvel expression rather than java expression.

Resources