Annotating a method to turn on performance tracing - java

I have a Test class with a method called public void httpcall(), I need to get the execution time of this method. In order to do this, I have used System.nanoTime() before and after calling it. I get the execution time from that duration.
code snippet:
public class Test{
public void httpcall(){
try {
HttpResponse rs = HttpClientUtil.get("http://192.169.1.2:9090/plugins/restapi/v1/users/9223370580466120397/roster",RestOpenfire.ACCEPT, "8V9BUNA0f1gNQI3S");
} catch (Exception e) {
System.out.println("Error : "+e);
}
}
public static void main(String[] args) {
Test test=new Test();
long startTime = System.nanoTime();
test.httpcall();
long endTime = System.nanoTime();
long duration = (endTime-startTime);
System.out.println("Execution Time : "+duration);
}
}
I want to make an annotation like #Time that gives an execution time of the method, something like ..
#Time
public void httpcall(){
try {
HttpResponse rs = HttpClientUtil.get("http://192.169.1.2:9090/plugins/restapi/v1/users/9223370580466120397/roster",
RestOpenfire.ACCEPT, "8V9BUNA0f1gNQI3S");
} catch (Exception e) {
System.out.println("Error : " + e);
}
}
How could I do this?

You can try to use aspectj which can either change your source code as part of your build, change your .class files in a process called weaving or change it on runtime.
https://mathewjhall.wordpress.com/2011/03/31/tracing-java-method-execution-with-aspectj/
Thought, it can be an overkill.
Unless you have a huge system that will be hard to refactor, I recommend using template methods. That is,
abstract class Measurable
{
protected void abstract doWork();
public void execute(){
stopWatch = StopWatch.start();
doWork();
stopWatch.stop();
System.out.println(stopWatch.getTime());
}
}
class MyHttpClient extends Measurable
{
doWork(){
HttpResponse rs = HttpClientUtil.get("http://192.169.1.2:9090/plugins/restapi/v1/users/9223370580466120397/roster",RestOpenfire.ACCEPT, "8V9BUNA0f1gNQI3S");
}
}
public static void main(String[] args) {
MyHttpClient test=new MyHttpClient();
test.execute();
}
And all uses of MyHttpClient will call the execute() method.
Also note that I used StopWatch class, since it is more elegant and standard than using System.currentTimeMillis. https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/StopWatch.html

Related

How to prevent object from getting garbage collected

I have a utility class which starts a long running background thread. The utility class is initialized in main class. But utility class object is getting garbage collected. How can i prevent that. Here is my class structure.
public class Main {
public static void main(String[] args) throws Exception {
Utility u = new Utility();
u.startTask(); //This is not referenced after this and hence getting gc'ed
.....
....
api.addMessageCreateListener(event -> {
/////continuously running
}
}
}
What i want is to prevent Utility object from getting garbage collected.
I assume the Method Utility#startTask() starts Threads on its own, otherwise this would be a blocking call and the main-Method would not end before startTask returned.
However this should not stop you from implementing the Runnable Interface in Utility itself. As long as the Utility runs in its own Thread, you do not need to worry about the enclosing method returning. Since the Tread is still running, the Instance will not be collected.
public class Threading {
public static void main(String[] args) {
Utility utility = new Threading().new Utility();
Future utilFuture = Executors.newSingleThreadExecutor().submit(utility);
System.out.println("end main");
}
public class Utility implements Runnable {
#Override
public void run() {
System.out.println("Start Utility");
for(int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
System.out.println("foo: " + i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
}
}
}
}
Note: In your case you might not need the Future, but it is an extremely useful tool to interrupt the Execution if needed.

Testing of method which takes long time to execute

Let's say I have method like this:
public int toTest() {
try { Thread.sleep(60 * 1_000); }
catch (InterruptedException ignored) {}
return 8;
}
And I would like to test it e.g. check if returned value is correct, like this:
#Test
public void test() {
int actual = toTest();
assertThat(actual).isEqualTo(8);
}
Is there any way to "simulate" time lapse so during test execution I will not be force to wait for whole minute?
Edit:
Probably I described my question too concrete. I didn't want to focus on this exact one minute but on way to bypass it. There could be even 100 days but my question is if there is method to simulate this time lapse.
Like in project reactor methods with are using virtual time https://projectreactor.io/docs/test/snapshot/api/reactor/test/StepVerifier.html#withVirtualTime-java.util.function.Supplier-
You can achieve that using Powermock.
// This will mock sleep method
PowerMock.mockStatic(Thread.class, methods(Thread.class, "sleep"));
PowerMockito.doThrow(new InterruptedException()).when(Thread.class);
Thread.sleep(Mockito.anyLong());
At the start of class, you will need to add this
#PrepareForTest(YourClassToWhich_ToTest_MethodBelong.class)
JUnit test the method as is (unless you add mocking..) if you want you can test internal method as toTestInternal:
public int toTest() {
try { Thread.sleep(60 * 1_000); }
catch (InterruptedException ignored) {}
return toTestInternal();
}
public int toTestInternal() {
return 8;
}
and test the method you want (toTestInternal):
#Test
public void test() {
int actual = toTestInternal();
assertThat(actual).isEqualTo(8);
}
I would suggest to make the interval a dynamic parameter. It will save your time:
public int toTest(int interval) {
try {
Thread.sleep(interval);
}catch (InterruptedException ignored) {}
return 8;
}
and the test class to be like:
#Test
public void test() {
int actual = toTest(60);
assertThat(actual).isEqualTo(8);
}

Cleaning up after all JUnit tests without explicit test suite classes declaration

In Intelij and Eclipse IDEs (and probably some others too) it's possible to run all test classes from a package (or even all test classes in a project) without the need to put each of them explicitly in a test suite class (this is something I want to avoid). Just right click -> run all tests and voilĂ !
I've got one problem with that approach to testing though. I want to do some cleaning up after all the tests are done, but no matter what I do, nothing seems to work.
At first, I tried using RunListener and its testRunFinished() method, but it is called after every atomic test is done, so not what I want when running many of them.
Then I thought about finalizers and runFinalizersOnExit(true), unfortunatelly, it is deprecated and worked only on one of computers that tests are executed on.
Last thing I tried was to create a "listener" thread, that - given tests execution start and end time differences - would clean up, for instance, after five seconds of test completion. I used code below to test that solution:
import org.junit.Test;
public class Main {
static {
System.out.println("In a static block!");
new Thread(new Runnable() {
public void run() {
System.out.println("Starting static thread!");
try {
while (true) {
Thread.sleep(1000);
System.out.println("Static thread working...");
}
} catch (InterruptedException e) {
System.err.println("Static thread interrupted!");
e.printStackTrace();
} catch (Exception e) {
System.err.println("Static thread catches exception!");
e.printStackTrace();
} finally {
System.err.println("Static thread in finally method.");
Thread.currentThread().interrupt();
}
}
}).start();
System.out.println("Exiting static block!");
}
#Test
public void test() throws Exception {
System.out.println("Running test!");
Thread.sleep(3000);
System.out.println("Stopping test!");
}
}
With no luck. The thread is killed after the test is done. And even the finally block is never executed...
In a static block!
Exiting static block!
Running test!
Starting static thread!
Static thread working...
Static thread working...
Stopping test!
Static thread working...
Desired behavior would be:
right click
run all tests
TestA is running...
TestA done
TestB is running...
TestB done
... more test classes...
cleanup
Not sure if I fully have your question right, but I think you want before, beforeClass, after and afterClass methods. i.e.
#BeforeClass
public void beforeClass() {
// Do stuff before test class is run
}
#Before
public void before() {
// Do stuff before each test is run
}
#After
public void after() {
// DO stuff after each test is run
}
#AfterClass
public void afterClass() {
// DO stuff after test class is run
}
You can do things on a more global level with some hacking or other frameworks. Spring's test suites for example. But I would try to keep such things within the scope of a single test class.
I've found a solution to my problem. My colleague suggested "hey, can't you just count the test classes?" - and that's what I did.
A little bit of reflection magic is used here, so the code might not be portable:
public abstract class CleaningTestRunner extends BlockJUnit4ClassRunner {
protected abstract void cleanupAfterAllTestRuns();
private static long TEST_CLASSES_AMOUNT;
private static long TEST_RUNS_FINISHED = 0;
private static boolean CLASSES_COUNTED = false;
static {
while (!CLASSES_COUNTED) {
try {
Field f = ClassLoader.class.getDeclaredField("classes");
f.setAccessible(true);
Vector<Class> classes = (Vector<Class>) f.get(CleaningTestRunner.class.getClassLoader());
TEST_CLASSES_AMOUNT = 0;
for (Class<?> klass : classes) {
if (klass.isAnnotationPresent(RunWith.class)) {
if (CleaningTestRunner.class.isAssignableFrom(klass.getAnnotation(RunWith.class).value())) {
for (Method method : klass.getMethods()) {
if (method.isAnnotationPresent(Test.class)) {
++TEST_CLASSES_AMOUNT;
break;
}
}
}
}
}
CLASSES_COUNTED = true;
} catch (Exception ignored) {
}
}
}
public CleaningTestRunner(Class<?> klass) throws InitializationError {
super(klass);
}
#Override
public void run(RunNotifier notifier) {
notifier.addListener(new TestCleanupListener());
super.run(notifier);
}
private class TestCleanupListener extends RunListener {
#Override
public void testRunFinished(Result result) throws Exception {
++TEST_RUNS_FINISHED;
if (TEST_RUNS_FINISHED == TEST_CLASSES_AMOUNT) {
cleanupAfterAllTestRuns();
}
}
}
}

How to mock a class with loops and asynchronous methods

How would I go about mocking the class USBConnection with mockito when I have asynchronous methods, threads and loops?
The basic idea behind this prorotype is that the USBConnection should send data to the variable speed in Arduino.class every second and Arduino prints out the value every second.
The class USBConnection is the one I want to mock. Any tips and guidelines to achieve this is appreciated.
public abstract class Arduino {
private static int speed;
public static void setSpeed(int a) {
speed = a;
}
public static int getSpeed(){
return speed;
}
public static void printSpeed(){
System.out.println(speed);
}
public static void main(String[] args) throws InterruptedException {
USBConnection usb = new USBConnection();
Thread usbThread = new Thread(usb);
usbThread.start();
while(true){
printSpeed();
Thread.sleep(1000);
}
}}
the interface
interface USB {
public void sendSpeed(int a); }
the class we need to mock:
class USBConnection implements Runnable, USB {
public void sendSpeed(int a){
Arduino.setSpeed(a);
}
#Override
public void run() {
int i = 0;
while(true){
sendSpeed(i);
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}
Based on some trial and error and Christoper's comments I decided to not use mockito in this way mentioned above.
We redesigned the software architecture and wont mock the class with loops or threads.

How to run method at set time?

Right now, I'm working on a project, and my setup is something like this: I have a class (Foo) which has several methods inside of it which must be activated at different times by the main class.
I've been researching this for quite a while, and the only thing I can find is the Timer class, which doesn't quite work, as it can seemingly only time a class, and I don't want 25 different classes for such a basic program.
How do I activate each method in Foo individually?
The following class works using an extension of TimerTask (MethodTimerTask) which take in input the Foo instance and the method name to call.
In this way, using reflection, the different methods can be called at different times with only one extended TimerTask class.
public class MyTimerTaskExample {
/**
* #param args
*/
public static void main(String[] args) {
Timer timer = new Timer();
Foo foo = new Foo();
timer.schedule(new MethodTimerTask(foo, "method1"), 1000);
timer.schedule(new MethodTimerTask(foo, "method2"), 3000);
}
public static class MethodTimerTask extends TimerTask {
private String methodName;
private Foo fooInstance;
private Exception exception;
public MethodTimerTask(Foo fooInstance, String methodName) {
this.methodName = methodName;
this.fooInstance = fooInstance;
}
#Override
public void run() {
try {
Foo.class.getMethod(methodName).invoke(fooInstance);
} catch (Exception e) {
this.exception = e;
}
}
public Exception getException() {
return exception;
}
public boolean hasException() {
return this.exception != null;
}
}
public static class Foo {
public void method1() {
System.out.println("method1 executed");
}
public void method2() {
System.out.println("method2 executed");
}
}
}
Bonus: the method getException() returns the eventual Exception catched while executing methodName of Foo.

Categories