I'm currently running some Cuke test with Selenium that hinge on preconditions in the system. A given run can include 1 or more Features. Features check for certain preconditions at the start of the run, for instance whether or not it can find the proper driver.exe file. If some of those preconditions fail, I would like to kill the run completely inside of a catch block an prevent any other scenario or Feature from being checked as they will all fail anyway. Is there a function or set of functions to accomplish this?
try {
//Gonna check for things here
} catch(Exception e) {
//Something went wrong, kill this thread.
}
I would consider a before step in Cucumber. It will be executed before each scenario in that particular feature file. This would result in the check being performed before each scenario. If you need, set a static flag that you can examine and fail fast if needed.
Related
Guys how to deal with such code and warning?
private void listenOnLogForResult() {
String logs = "";
int timeCounter = 1;
while (logs.isEmpty()) {
try {
timeCounter++;
Thread.sleep(2000); // Wait 2 seconds
} catch (InterruptedException e) {
log.error(e.getLocalizedMessage(), e);
}
if (timeCounter < 30) {
logs = checkLogs()
} else {
logs = "Time out";
}
}
}
I need to pause current thread for 2 seconds to wait file to be filled, but my Intelij Rise an issue here.
And also I am getting error from sonar:
SonarLint: Either re-interrupt this method or rethrow the "InterruptedException".
I've tried already with many ExecutorService, but it is always run in seperate thread, and I need to pause current one.
Please help..
The busy-waiting warning
This is a warning coming from intellij that is dubious, in the sense that what you're doing is often just straight up required. In other words, it is detecting a pattern that is overused, but whose usage cannot be reduced to 0. So, likely the right solution is to just tell intellij to shut up about it here.
The problem it is looking at is not that Thread.sleep. That is not the problem. However, intellij's detector of this pattern needs it to find this case, but it is not what it is complaining about, which might be a little hard to wrap your head around.
What IntelliJ is worried about, is that you're wasting cycles continually rechecking log.isEmpty() for no reason. It has a problem with the while aspect of this code, not the sleep. It would prefer to see code where you invoke some sort of logs.poll() method which will just wait until it is actively woken up by the act of new logs appearing.
If this is all running within a single java process, then you can indeed rewrite this entire system (which includes rewrites to whatever log is here, and a complete re-imagining of the checkLogs() method: Instead of going out and checking, whatever is making logs needs to wake up this code instead.
If it's not, it is likely that you need to tell intellij to shut it: What you are doing is unavoidable without a complete systems redesign.
The re-interrupt warning
You have some deplorable exception handling here.
Your exception handling in general
Do not write catch blocks that log something and keep moving. This is really bad error handling: The system's variables and fields are now in an unknown state (you just caught and logged some stuff: Surely that means you have no idea what conditions have occurred to cause this line of execution to happen!), and yet code will move right along. It is extremely likely that 'catch exceptions and just keep going' style code results in more exceptions down the line: Generally, code that operates on unknown state is going to crash and burn sooner rather than later.
Then, if that crash-and-burn is dealt with in the same fashion (catch it, log it, keep going), then you get another crash-and-burn. You end up with code that will, upon hitting a problem, print 186 exceptions to the log and they are all utterly irrelevant except the first one. That's bad yuyu.
You're also making it completely impossible for calling code to recover. The point of exceptions is that they need to bubble upwards endlessly: Either the exception is caught by code that actually knows how to deal with the problem (and logging it is not dealing with it!), which you are making impossible, or, the code exception should bubble up all the way to the entry-point handler which is the right place to log the error and abort the entry-point handler.
An entry-point handler is a generic module or application runner; out of the box, the code baked into java.exe itself that ends up invoking your psv main() method is the most obvious 'entry point runner', but there's more: Web frameworks will eventually invoke some code of yours that is supposed to handle a web request: That code of yours is analogous to psv main(): It is the entry-point, and the code in the web framework that invokes it, is the entry-point runner.
Entry-point runners have a good reason to catch (Throwable t), and to spend their catch block primarily logging it, though they should generally log a lot more than just the exception (a web handler should for example log the request details, such as which HTTP params were sent and which path request it was, maybe the headers, etc). Any other code should never do this, though.
If you have no idea what to do and don't want to think about what that exception might mean, the correct 'whatever, just compile already javac' code strategy is to add the exception type to your throws line. If that is not feasible, the right code in the catch block is:
} catch (ExceptionIDoNotWantToThinkAboutRightNow e) {
throw new RuntimeException("Uncaught", e);
}
This will ensure that code will not just merrily continue onwards, operating on unknown state, and will ensure you get complete details in logs, and ensures that calling code can catch and deal with it if it can, and ensures that any custom logging info such as the HTTP request details get a chance to make it to the logs. Win-win-win-win.
This case in particular: What does InterruptedEx mean?
When some code running in that java process invokes yourThread.interrupt(), that is how InterruptedException can happen, and it cannot possibly happen in any other way. If the user hits CTRL+C, or goes into task manager and clicks 'end process', or if your android phone decides it is time for your app to get out as the memory is needed for something else - none of those cases can possibly result in InterruptedExceptions. Your threads just get killed midstep by java (if you want to act on shutdowns, use Runtime.getRuntime().addShutdownHook). The only way is for some code to call .interrupt(), and nothing in the core libs is going to do that. Thus, InterruptedException means whatever you think 'call .interrupt() on this thread' means. It is up to you.
The most common definition is effectively 'I ask you to stop': Just shut down the thread nicely. Generally it is bad to try to shut down threads nicely if you want to exit the entire VM (just invoke System.shutdown - you already need to deal with users hitting CTRL+C, why write shutdown code twice in different ways?) - but sometimes you just want one thread to stop. So, usually the best code to put in a catch (InterruptedException e) block is just return; and nothing else. Don't log anything: The 'interrupt' is intentional: You wrote it. Most likely that is nowhere in your code base and the InterruptedException is moot: It won't ever happen.
In your specific code, what happens if your code decides to stop the logger thread is that the logger thread will log something to the error logs, and will then shortcut its 2 second wait period to immediately check the logs, and then just keeps going. That sounds completely useless.
But, it means whatever you want it to. If you want an ability for e.g. the user to hit a 'force check the logs right now' button, then you can define that interrupting the logging thread just shortcuts the 2 seconds (but then just have an empty catch block with a comment explaining that this is how you designed it, obviously don't log it). If you ALSO want a button to 'stop the logging thread', have an AtomicBoolean that tracks 'running' state: When the 'stop log-refreshes' button is hit, set the AB to 'false' and then interrupt the thread: Then the code you pasted needs to check the AB and return; to close the thread if it is false.
fun sleep(timeMillis: Long) {
val currentTimeMillis = System.currentTimeMillis()
while (true) {
if (System.currentTimeMillis() - currentTimeMillis >= timeMillis) {
break
}
}
}
and use this in your method(It's code by koltin,you should trans to java)
In C# I can write:
if(Debugger.IsAttached)
Debugger.Break();
This has no effect when the program is not being debugged. When a debugger is attached, it behaves like a breakpoint that can never be turned off. How can I achieve similar effect on Android?
Or maybe I should not focus on breakpoints at all. What I really want is to have no consequence in regular use (a generic error message will be shown to the user), but have the source of error become obvious the moment a dev will start looking at it. I've tried assert, but it's a sub-project that's compiled to release flavor most of the time and I can't rely on someone remembering to switch it to debug.
I think that Debug.isDebuggerConnected() is what you are looking for. This will return true only if the app is started with debugger attached and false otherwise, no matter of build type or flavor. Unfortunately, I don't think that you can stop the execution programatically, but with the above instruction you should be able to display an error message or throw an exception. Personally, I'm thinking to something like this:
if (Debug.isDebuggerConnected()) {
// throw an exception for the developer with a detailed message
} else {
// show the general error message to the user with a dialog/toast
}
I was also hoping that this could be done, but I've not found any reasonable way to programmatically cause the debugger to breakpoint. What I've done to get around this problem is to create a breakpoint class with a method call "br". When I'm debugging, I'll set a breakpoint in the "br" method. After that, whenever my code calls the "br" method, the debugger stops. I then step out of that method and then inspect the state of the program where the "br" method was called. Hope that helps!
If i clear understand you - try this snippet of code:
if (BuildConfig.DEBUG) {
// Your, developers behavior
}
else {
// release behavior
}
We have a task in our Gradle build file called integration which extends Test and is used to run all of our integration tests. Our integration tests take quite some time to run because we have, as you might expect, quite a few. And several of them can run for up to 10 minutes because of some lengthy DB interactions.
Right now all I can see when they are running is >Building > :integration. And it sits at that point for...a very long time. I'm often not sure if it's just in the middle of a bunch of long tests, or if it's hanging on something it really shouldn't be hanging on.
So, I was wondering if there is a way to get them to run verbosely? So I can see which test we are actually on? I just want the command line to spit out something like:
Running test <testName>: Started...Complete (231 sec)
I've looked through the Gradle documentation and haven't seen anything that shows how this might be done. Granted, I am a little new at this, so... If anyone has an idea how this could be done? I would prefer to have a flag that just does it, but if it can be done with some scripting I'm willing to learn. Just point me in that direction...
Have a look at this DSL doc. In general what You need is make use of beforeTest and afterTest closures. You can keep the invocation start in a global map.
def times = [:]
test {
beforeTest { td ->
times[td.name] = System.currentTimeMillis()
println "$td.name started"
}
afterTest { td ->
println "$td.name finished in ${System.currentTimeMillis() - times[td.name]}"
}
}
I'm not sure if this is synchronous. You need to try.
I have 100 test methods. After each test, I need to perform some actions (data cleanup). Each of these 100 tests have different actions. These 100 test are not in one package or class. They are distributed.
How can I achieve this?
Right now, if a test passes, the cleanup happens, since it is part of the test. However, if the test fails, the cleanup doesn't happen. How can I make this work?
Any pointers would help.
If the tests do not have any common cleanup, you can ensure the test gets cleaned up from within the test method using a try/finally block, something like:
try {
// do test
}
finally {
// do cleanup
}
If there is any common cleanup between the test methods you could use #AfterMethod to do the cleaup.
In your case, it doesn't sound like there is much common cleanup, so the first may work better for you. It might also be worth considering if you need 100 different cleanup methods or if there can be any common setup/cleanup.
#AfterMethod would mean that you would need that every class gets this method. So you would need to go and edit each class/method. Same for #AfterGroups.
What I would suggest is to implement the IInvokedMethodListener. This would give you beforeInvocation and afterInvocation methods. In the afterInvocation method, implement your cleanup code.
Create a suite file with all of your tests which need this cleanup and specify this listener.
Hope it helps.
It sounds like you may already be using #AfterMethod to cleanup after the tests. To make #AfterMethod work after a failure, you need to use:
#AfterMethod(alwaysRun=true)
You can use groups and run a #AfterGroups somewhere. There's a #BeforeGroups as well. Setting it up with build tooling is a bit tedious and there are some interactions with IDEs as well. There's a BeforeSuite and AfterSuite as well, I believe.
An alternative could be using Spring and using the same spring context in all your tests (spring context gets reused that way). You can then do some things when the context is destroyed after your tests.
I am evaluating user inputs as commands for my application. If the user presses Q, or q, and then hits enter, the application quits and execution terminates.
Is there a proper context, or best practices on how to do that? I do not have any resources to release, or anything like that. Should I just use System.exit(0);? Is there a recommended way to do that?
As my first approach I do something like this:
while (true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//Other logic goes here...
if (br.readLine().equalsIgnoreCase("Q")){
System.exit(0);
}
}
catch (IOException ioe) {
System.out.println("IO error trying to read your selection");
}
}
You might as well return up to main() and return from there.
private void loop() {
while (true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//other logic goes here...
if(br.readLine().equalsIgnoreCase("Q")){
return; // You're done and you are returning to the caller.
}
}
catch (IOException ioe) {
System.out.println("IO error trying to read your selection");
}
}
}
public static void main(String[] args) {
loop();
}
But if you don't have anything to release, System.exit(0) is fine.
Resources are cleaned up automatically by the OS when the process exits. There are two primary reasons to not just exit() from the middle of the code (this applies to all languages).
There may be some action that needs to be taken before the program ends. For example, you may need to save any open files (i.e. write changes that for performance or other reasons have not been sent to the file yet).
Someone may want to later use your code for some other purpose.
Take for example, the Git version control system. There's several efforts to turn the code into a library instead of a set of stand-alone executables so that it can be efficiently incorporated into other projects. One of the problems (from what I've heared) is that the code sometimes simply terminates instead of tracking and cleaning up the resources it's using. As an executable that's fine, but if it was imported as a library, you don't always want to just terminate the host application because you've finished your little part.
Returning all the way back to Returning out of main() is the cleanest way, of course, but if that's not easy to do, System.exit() is perfectly fine.
It's not directly relevant to your question, but throwing an (unhandled) exception is usually the way to terminate on a fatal condition, since it provides a lot of tracing info to the poor user.
I would like to say:
It doesn't matter, it's entirely up to
you!
And dough it sometimes is true, other times it depends on the program structure and code integrity.
The reasonable exit would be through main method, terminating all the threads.
System.exit forces termination of all the threads in the JVM. The System.exit never returns normally. It should be used for an error.
System.exit() is fine. And I agree with the other answers, returning to main would be the best way to exit - from a maintenance point of view. As your code expands you may forget the little method doing System.exit have to debug to remember it.
However you only need to use exit if you have a script which needs the information about an abnormal termination. Otherwise there is no need.
As I recall a Java program will exit with 0 by default - meaning normal termination. So you'd want to use System.exit(n) for cases where your program terminates due to some error.
Example (just using static methods you'd most likely want to instantiate...):
public static void main(String[] args) {
try {
doStuff();
} catch (SomeRuntimeException e) {
// marching orders! Exit with errorcode
<log the error with sufficient info for debugging>
System.exit(1);
}
}
private static doStuff() {
// doing my thing ...
...
//then some error occurs and I have no other choice but to do a hard exit
throw new SomeRuntimeException( ... some info would be nice ...)
...
return
}
Don't forget that if you perform a System.exit(), you can't easily later use your methods in a standalone library. If you want to reuse your code outside your existing solution (and you may not now, but decide to do so in the future), then you'll then have to revisit and refactor appropriately.
Otherwise the worst-case scenario is that you take the existing code without noticing the System.exit()s, use it and then have your library exit unexpectedly in a new application.
Just something to bear in mind re. code-reuse.