junit test skips after 600 seconds - java

I'm working on the system test of a IOT device that has various webservices.
We have 2 types, one with slow flash and the newer with faster flash memory. in the new flash the fw update can be done with aprox. 4 minutes while the slow ones take something around 12 minutes.
The problem comes in the junit test that tests the update and go back to the "previous" version. After sending the file and the update signal to the device, i use a Thread.sleep(6*60*1000) to wait for the device to expand the file, update and restart.
The junit test "skips" the test after 600s have passed, not failure, not error, just skips to the next test class..
It looks like it finished, but it just skipped the rest of the test WHILE it is inside the sleep
a small snippet of the test code althought it is mostly propietary:
public RequestCase(String path, WebServiceRequest req, WebServiceResponse resExp, String tcDesc, boolean validateResXSD) {
//super();
this.setPath(path);
this.setReq(req);
this.setResExp(resExp);
this.res = new WebServiceResponse();
this.setTcDesc(tcDesc);
this.setValidateResXSD(validateResXSD);
}
and the test snippet:
// now apply Software
String s06Req = null;
try {
s06Req = WebServiceRequestS06.makeCommandPsu(updFile.getRevision(), WebServiceRequestS06.SW_UPD);
} catch (WebServiceXMLException e) {
fail("Error creating S06 XML request. Error is: "+e.getMessage()+"\nAnd cause is :"+e.getCause());
}
RequestCase s06CommandPsu = new RequestCase(
null,
new WebServiceRequest("commandPsu", "POST", s06Req),
WebServiceResponse.RESULT_STATUS_CMD_SW_RECEIVED,
"Apply valid SW, and it is only received, but not apply now (imply Y03)",
true
);
executeCase(s06CommandPsu, WebServicesXSDValidator.S06_CommandPsu);
// Wait some time to wait charger apply new SW and reboot
try {
if (this.charger.getProductType() == Charger.ID_CT1_OLD_FLASH) {
Thread.sleep(6*60*1000);
} else {
Thread.sleep(2*60*1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
can someone help me a bit? Thanks in advance!

The test code snippet provided hre is not showing any assert/verify operation.
You have a test that sits there, waiting 600 seconds. Then it will end.
And the test will show up as passed (as it didn't cause a failure or error).
Thus:
If your tests should do something after 600 seconds, you have to code that.
Unrelated: you really should step back first. Unit tests should pass quickly, having it wait 600 seconds is not a good idea (assuming that we are talking real unit tests here, not an integration test)

Finally i found what was causing this, i will post it just in case someone stomps at the same problem.
it was caused due to the Parallelized class, more specifically in the ExecutorService awaitTermination() method where you can set a timeout..

Related

Mockito: Verify if a method specified in any thread got executed?

I have a method like the following one :
void enact(#NonNull final Request request) {
XInput input = this.xBuilder.buildInputPayload(request);
final Thread componentThread = new Thread(()->this.component.runJob(input));
componentThread.start();
return;
}
void testVTService_Success() {
when(xBuilder.buildInputPayload(any(Request.class))).thenReturn(inputPayloadWithAllArguments);
activity.enact(TestConstants.request);
verify(component, times(1)). runJob(any(XInput.class)); //Verification
}
Upon verification that the component.runJob() method is being executed it is throwing an error stating that Wanted but not invoked: component.runJob() Actually, there were zero interactions with this mock.
How do I fix this? And verify if the thread is starting & executing the runJob method?
Your test is running on one thread, and your code under test runs a new thread.
This means that your test verification runs before the runJob method because of multithreading.
At that point the test saying "Wanted but not invoked" is correct (the test code ran, checked if the production method had ran, it had not ... aand then in the background the production code ran (too late)).
Ideally you should separate the control of threading from the logic in your app. Wrap the Thread in a ThreadFactory, for real code you can pass an actual Thread, for test code you can pass an object that runs the code instantly (on the same thread).
Or (not recommended) you hack your test (this will help you understand):
void testVTService_Success() {
when(xBuilder.buildInputPayload(any(Request.class)))
.thenReturn(inputPayloadWithAllArguments);
activity.enact(TestConstants.request);
try { Thread.sleep(TimeUnit.SECONDS.toMillis(10)); } catch (Exception e) { assertTrue(false); }
verify(component, times(1)). runJob(any(XInput.class));
}
Now your test will always take 10 seconds, but hopefully the production code doesn't take 10 seconds to complete execution?
This is not ideal, like I said originally you would want to pull the Thread out of that Method, pass in some type of Factory to the class and pass a Fake object in the test. (Thus avoiding trying to test multithreaded code.)

Android: Runtime.getRuntime().exec(String) command is too slow? or I am doing something wrong?

I am trying to create an app which I use it for remote control an android device(TV). Actually I did it however when I click a button on the controller device(mobile), it takes apprx. 1 sec to do the work in the device(TV) that I want to control.
When I checked all logs in the code and I see that method spends that much time...
String commandStr;
commandStr = String.format("%s"," input keyevent "+keyCode);
try {
process = runTimeExec(commandStr);
runTimeExec(commandStr);
} catch (IOException e) {
}
And the runTimeExec defined as;
public static Process runTimeExec(String commandStr) throws IOException {
Runtime.getRuntime().exec(commandString);
}
I just wanna learn if there is any other solution to run command immediately on the TV device itself? Or how can I make faster this code here?
I've used the getevent/sendevent code for this purpose. Its very fast and works immediately on the TV device. Just try it. You can find detailed documentations in https://source.android.com

IO Exception, my program with input data of x,y sometimes works without any error and randomly sometimes doesnt work with the same x,y input data

i am looping a method with a Thread which reads from a website(dynamically)
all the methods work perfectly, but my problem is that sometimes (3 out of 10 times) that i start the program it throws IO exception at me although i haven't changed my input data from the last known good execution , the exception is coming from the method below:
public String readThisUrlContent() throws ExceptionHandler
{
try {
#SuppressWarnings("static-access")
Document doc = Jsoup.connect(url).timeout(1000).get();
return doc.body().text();
} catch (IOException e) {
throw new ExceptionHandler("IO Exception for reading the site in method setUrlContent in Url class");
}
}
my best guess is that since i'm reading more than one Url with looping this method but the timeout is not sometimes at the best range (considering the internet speed etc. it sometimes doesn't work) but its just my theory and it can be dead wrong but even if its correct i have no idea how to handle it
The problem exactly was the time to live of the opened port. since i had other functions working at the same time program simply needed more connected time so i expanded timeout to (5000) and also reduced the timer of another Time.Schedule method in another method, and so it worked

How to override the behavior of a failed JUnit test case

I need to write a JUnit test case for a never ending main() method. This main() method after processing some files sleeps for a minute and then resumes its execution. This process goes on and on and on.
I used the below code to write JUnit for it:
#Test (timeout = 10000)
public void testMainMethod()
{
ClassName.main(null);
assertEquals(true, true);
}
And with no surprise, my test case failed with java.lang.Exception: test timed out after 10000 milliseconds message. Even when the main() method works as expected, this test case is going to be failed with the timeout exception. How could i override the behavior of this failing test case so that in case of timeout exception it should show the result as "Succeeded" for this test case.
Edit
The actual requirement is:
I need to search the files from a particular location and, if found any, then move them to different folder. This search should be done every 30 minutes. For this i have used below code:
public class FaxProcessor {
public static void main(String[] args) {
LOGGER.info("*** Starting Fax Server Processor ***");
int poll_time = 1800000;
LOGGER.info("Poll Time set to " + poll_time + " millisec");
FaxProcessor faxProcessor = new FaxProcessor();
while (true) {
try {
if(LOGGER.debugEnabled()){
LOGGER.debug("Starting new pass of fax processor");
}
faxProcessor.startProcessing();
} catch (Exception e) {
LOGGER.error("Processing Error", e);
} finally {
try {
// Wait for next loop
Thread.sleep(poll_time);
} catch (InterruptedException e) {
LOGGER.error("Thread Exception", e);
}
}
}
}
// startProcessing and other private methods here
}
The biggest problem is, I have only one public method {main() method} and all others are private, so i cant write JUnit test case for them. Also, main() method is not returning anything, it only moves files from one folder to another, and in case it fails in moving files in one pass, it tries to do the same in next pass. So using JUnit test case, i only want to check whether an unexpected exception is coming during whole process or not.
If i will not specify timeout in JUnit, the test case is never gonna complete then. As soon as the timeout occurs, i want to check, whether the test case is completed due to Timeout exception or some other exception has come from inside main() method that haulted JUnit test case.
In case it's Timeout exception, this implies, everything inside my program, went in the right direction till the timeout occured, so the test case should SUCCEED. In all other case it should show FAILED as JUnit status.
You have artificially constrained your testing environment, with this statement: "I have only one public method {main() method} and all others are private" -- who says? If this is a requirement imposed by your teacher, then you should seriously consider getting out of the class.
1) Proper testing means testing a) that candidate files are recognized, b) that candidate files are moved, and c) the operation occurs periodically.
2) Factor your main routine into the infinite-loop control part and the worker part. Even better, make the wait interval be a computed value.
3) Use protected methods instead of private methods. Since they are protected, you can now use a sub-class to get access to methods as you need, without violating necessary encapsulation.
You should think of separating long running unit tests. How to achieve that is for example shown here or here.
I don't understand what you want to do.
If you got Timeout Exception, that means the test case ran too long.
If you want to test the main method, and it contains an infinite loop, how can you determine that the method works as expected?
For your problem, use
#Test (timeout = 10000, expected=Exception.class)

java process is frozen(?) on linux

This is my first question on S.O.
I have a very odd problem.
Below is my problem...
I write very simple method that write some text to a file.
Of course it works well my machine(XP, 4CPU, jdk1.5.0_17[SUN])
But it somtimes freezes on operating server
(Linux Accounting240 2.4.20-8smp, 4CPU, jdk1.5.0_22[SUN]).
kill -3 doesn't work.
ctrl + \ doesn't work.
So, I can't show you the thread dump.
It freezes well..
When I just write some Thread.sleep(XX) at this method, the problem is gone well(?)...
sleep(XX) break... it happened again today with Thread.sleep(XX)...
Do you know this problem?
Do you have the some solution about that?
Thanks. :-)
P.S.
linux distribution: Red Hat Linux 3.2.2-5
command: java -cp . T
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class T {
private BufferedWriter writer = null;
private void log(String log) {
try {
if (writer == null) {
File logFile = new File("test.log");
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(logFile, true)));
}
writer.write(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss] ")
.format(new Date()));
writer.write("[" + log + "]" + "\n");
writer.flush();
/*
* this is ad hoc solution ???
*/
//Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
public void test() {
long startTime = System.currentTimeMillis();
while (true) {
log(String.valueOf(System.currentTimeMillis()));
System.out.println(System.currentTimeMillis());
try {
//Thread.sleep((int) (Math.random() * 100));
} catch (Exception e) {
break;
}
if (System.currentTimeMillis() - startTime > 1000 * 5) {
break;
}
}
if (writer != null) {
try {
writer.close();
} catch (Exception e) {
}
}
System.out.println("OK");
}
public static void main(String[] args) {
new T().test();
}
}
If the JVM does not respond to kill -3 then it is not your program but the JVM that is failing which is bad and would require a bug report to Sun.
I noticed you are running a 2.4.20-8smp kernel. This is not a typical kernel for a current open source Linux distribution, so I would suggest you have a look at http://java.sun.com/j2se/1.5.0/system-configurations.html to see if you are deploying to a supported configuration. If not, you should let the responsible people know this!
The first step is to get a thread dump of where the program is when it "freezes". If this were on Java 6, you could connect JVisualVM or JConsole to it by default, and get the stacktraces of all the threads from there. Since it's Java 5, you should be able to use the jstack command to get a thread dump (or you could enable JMX with a command-line option to attach the aforementioned tools, but I don't think it's worth it in this case). In all cases, pressing Ctrl-Break from the console that launched the application may also produce a thread dump, depending on the environment.
Do this several times a few seconds apart and then compare the thread dumps. If they're always identical, then it looks like your application is deadlocked; and the top line of the dump will show exactly where the threads are blocking (which will give a very good clue, when you look at that line of the code, which resources they're blocked on).
On the other hand if the thread dumps change from time to time, the program is not strictly deadlocked but looks like it's running in an infinite loop - perhaps one of your loop conditions is not declared properly so the threads never exit or something of that sort. Again, look at the set of thread dumps to see what area of code each thread is looping around in, which will give you an idea of the loop condition that is never evaluating to an exit condition.
If the issue isn't obvious from this analysis, post back the dumps as it will help people debug your above code.
I think this is a race condition. The while(true) will force the VM on linux to write and flush continuously, and the linux kernel VM will try to intercept those calls and buffer the writing. This will make the process spinloop while waiting for the syscall to be completed; at the same time, it will be picked up by the scheduler and assigned to another CPU (I might be wrong here, tho). The new CPU will try to acquire a lock on the resource, and everything will result in a deadlock.
This might be a sign of other issues to come. I suggest:
first of all, for clarity's sake: move the file creation outside of the log() method. That's what constructors are for.
secondly, why are you trying to write to a file like that? Are you sure your program logic makes sense in the first place? Would you not rather write your log messages to a container (say, an ArrayList) and every XX seconds dump that to disk in a separate thread? Right now you're limiting your logging ability to your disk speed: something you might want to avoid.

Categories