So I'm writing unit tests in which I'm testing capability to blacklist and unblacklist users (which is a feature in my code that is itself working fine).
Here's a sample command that works as expected:
assertThrows(ExecutionException.class, () -> onlineStore.lookup("533"));
If I blacklist user "533", and then run the above command, it works fine, because an ExecutionException is raised (because you're trying to lookup a user who is blacklisted). Similarly, if I had NOT blacklisted user "533" but still ran the above command, the test would fail, which is expected too for similar reason (i.e. no exception is now thrown as you're NOT fetching a blacklisted user).
However if I have a List of user IDs called userIds (which user "533" is now part of) and I blacklist them all (funtionality which I know is working fine), and then run the command below:
userIds.stream().map(id -> assertDoesNotThrow(() -> onlineStore.lookup(id)));
... the test passes, even through it should have FAILED. Why ? Because all users are now blacklisted, so when fetching these users, ExecutionExceptions should have been thrown ..
If I now, replace the streams command above with either of the following, they work as expected:
assertThrows(ExecutionException.class, () -> onlineStore.lookup("533"));
assertDoesNotThrow(() -> onlineStore.lookup("533"));
So this all leads me to believe that for some reason, when going through Java Streams, thrown ExecutionExceptions aren't getting caught.
Any explanation for this behavior ?
You're not calling any terminal operation on the stream, so your assertion is never executed.
You're abusing map(), which is supposed to create a new stream by transforming every element. What you actually want to do is to execute a method which has a side effect on every element. That's what forEach is for (and it's also a terminal operation which actually consumes the stream):
userIds.stream().forEach(id -> assertDoesNotThrow(() -> onlineStore.lookup(id)));
Related
doTask() is a method that performs something if previousStepResult is successful, otherwise logs and return previousStepResult as is. Below code works fine and conclude() is also executed but only when there no exceptions (errors). But if there are exceptions (which are well handled) the code returns false. So in case of error, the next step is called fine and as said, logs and return false. However conclude is not called at all. I am not sure if there is an impact of exceptions inside each step preventing thenAcceptAsync to be executed or what. Any clues ?
return CompletableFuture.supplyAsync(() -> doTask("task1", true), taskExecutor).
thenApplyAsync(previousStepResult -> doTask("task2", previousStepResult),taskExecutor).
thenApplyAsync(previousStepResult -> doTask("task3", previousStepResult),taskExecutor).
thenAcceptAsync(previousStepResult -> conclude(previousStepResult),taskExecutor);
Use CompletableFuture::handle or CompletableFuture::handleAsync after the step that is likely to throw error. This would result in further steps being called as it is, else would be skipped.
Oracle Openscript comes with the mechanism, to verify/assert , that certain form will appear. If the condition is not met, then script fails. E.g.
forms.listOfValues(40, "//forms:listOfValues").assertAttributes(
"My test",
forms.attributes(forms.attribute("title", "Find People",
TestOperator.StringExact), forms.attribute("name",
"FULL_NAME_LOV", TestOperator.StringExact)), 5);
The above test fails the script execution, if such form does not come up.
But the question is: how do I test exactly opposite: I want script to fail/ or to execute differently if the the given form will appear and I want it to execute normally if the from will Not appear
there are several methods , such as
if (forms.listOfValues(40, "//forms:listOfValues").isVisible()){
reportFailure("messag"); //just report a failure or
fail("message"); // fail and stop execution
// or what ever you do ..
}
I tried to execute jar from Java code with:
Runtime.getRuntime.exec("java -jar a.jar")
I could get InputStream with error from Process.getErrorStream().
Can I take this stream and if it has an Exception transform it to Exception and throw in my upper application?
Has Java some mechanism to convert string to Exception?
EDIT: Or maybe java has some mechanism like System.exit(int code) but with Exception? So in parent app I can do something like process.waitFor() but take an exception instead int code?
Process.getErrorStream() returns an IntputStream connected to the error output of the subprocess.
So, it is not exception in Java terms. It's an output information which must be considered as an error detected by the process during its execution.
Java don't convert automatically InputStream or String to Exception.
So, you could read this stream in a String and throw a custom exception with as message the string.
If you want that the caller may be able to handle this exception in a clean way, don't use a RuntimeException but a checked exception :
public class ProcessExecutionException extends Exception{
public ProcessExecutionException(String errorOutputMsg){
super(errorOutputMsg);
}
}
Edit for answering your comment :
Yeah, but how to check is inputstream line is a part of stacktrace of
child exception
it's not a stracktrace but error messages as explained.
and how much line from IS i should add to ProcessExecutionException?`
You have to read all the errorStream until it returns null if you want to capture all error output.
In my case my jar is a Spring Application and it write to error stream
nor only Exception that i really need to catch, also some information
like "Error, you have no sl4j xml file, etc - like example". And i
need only really important exception
How the classes producing errors in output may guess if it is important for you or not ?
You must decide yourself which error message pattern should be considered as an important error or not.
Personally, if when my process is run, I have a not well configured logger, I will kill it and correct this problem before starting it again.
If you have input in the ErroStream, you can also inspect the value of the Process.exitCode() (0: normal termination, else problem).
If it is different from 0, you can suspect that it not only a little problem.
Here, some tracks to try.
Can i return something to exit like in System.exit()
In the child process, you can try to intercept all exceptions not handled which may be triggered . You can do it whatever the way (aspect, global try/catch, filter...) .
In this way, if you intercept an exception not handled and that you consider that the application must be terminated, you can do a System.exit with the expected code by the parent process.
In this way, in the parent, if Process.exitCode() matchs with expected code for important exception, you can handle it as you wish.
Read through the docs and i'm still confused as the the advantages (if any) of using the mongoClient in a fluent way. Can anyone explain them to to me and if it will guarantee order;
Running in line - Both will be run at the same time with no guarentee of order.
mongoClient.runCommand("aggregate", getSomeCommand1(), res -> {});
mongoClient.runCommand("aggregate", getSomeCommand2(), res -> {});
Running nested - getSomeCommand1 will be run to completion first before getSomeCommand2.
mongoClient.runCommand("aggregate", getSomeCommand1(), res1 -> {
mongoClient.runCommand("aggregate", getSomeCommand2(), res2 -> {});
});
Running in a fluent way - is the same as running in line?
mongoClient.runCommand("aggregate", getSomeCommand1(), res -> {}).mongoClient.runCommand("aggregate", getSomeCommand2(), res -> {});
Far from a complete answer but running a few basic tests indicates that running in a fluent way is the same as running in line;
I ran a slow command (aggregate) and a fast command (count) on a large dataset.
mongoClient.runCommand("aggregate", getTotalRecsPerTypeCommand(sellerId, collection), res -> {
result.put("totalRecsPerType", res.result());
}).count(collection, new JsonObject().put("sellerId", sellerId), res -> {
result.put("totalRecs", res.result());
requestMessage.reply(result);
});
Initially only the total is returned however when the reply is moved from the fast command to the slow command then both results are returned. This indicates they are both run at the same time with no guarentee of order.
mongoClient.runCommand("aggregate", getTotalRecsPerTypeCommand(sellerId, collection), res -> {
result.put("totalRecsPerType", res.result());
requestMessage.reply(result);
}).count(collection, new JsonObject().put("sellerId", sellerId), res -> {
result.put("totalRecs", res.result());
});
Running in line does not guarantee the order of execution, that is maybe running the first code several times on not heavily loaded machine will preserve order.
The same thing is with fluent API. In this case it only helps you to omit semicolon. If you want to create a flow, where the next command will be fired after the first one ends, use RxJava (or the nested case, but in the long run you might end up with callback hell).
Take a look here: https://github.com/vert-x3/vertx-mongo-client/blob/master/vertx-mongo-service/src/main/generated/io/vertx/rxjava/ext/mongo/MongoService.java
Although I'm not a big fan of ObservableFuture used in this class (I recommend using http://reactivex.io/RxJava/javadoc/rx/subjects/AsyncSubject.html), it's a good starting point.
Background
I have read the documentation for the MultithreadingTester provided in junit-toolbox and still don't entirely grok if I'm using it correctly.
How I would expect it to work:
MultithreadingTester.add(callable1, callable2)
// validate my results from running callable1 and callable2
.run();
Where callable1 and callable2 would be executed and then I could verify the results ... then the MultithreadingTester would run the two callables again ... and once again I'd verify the results.
From what I've put together my expectations are misaligned with what's provided.
Question
Does someone have a simple example of using the MultithreadingTester to validate a synchronized code path?