/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.f1x.alloc;
import com.google.monitoring.runtime.instrumentation.AllocationRecorder;
import com.google.monitoring.runtime.instrumentation.Sampler;
import org.f1x.SessionIDBean;
import org.f1x.api.session.SessionEventListener;
import org.f1x.api.session.SessionID;
import org.f1x.api.session.SessionStatus;
import org.f1x.tools.SimpleFixAcceptor;
import org.f1x.tools.SimpleFixInitiator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* This test verifies that there are no allocations in during session.
* NOTE: you must run JVM with -javaagent:allocation.jar option
*/
@Ignore
public class NoAllocationsTest /*extends TestCommon */{
private static final String INITIATOR_SENDER_ID = "INITIATOR";
private static final String ACCEPTOR_SENDER_ID = "ACCEPTOR";
private static class TestObject {
public TestObject(long orderId) {
if (System.currentTimeMillis() == orderId)
System.err.println("Never"); // prevent hotspot from optimizing this out
}
}
private static SimpleFixInitiator createInitiator(int port) {
return new SimpleFixInitiator("localhost", port, new SessionIDBean(ACCEPTOR_SENDER_ID, INITIATOR_SENDER_ID)) {
@Override
public void sendNewOrder(long orderId) throws IOException {
super.sendNewOrder(orderId);
new TestObject(orderId);
}
};
}
private static SimpleFixAcceptor createAcceptor(int port) {
return new SimpleFixAcceptor(port, new SessionIDBean(INITIATOR_SENDER_ID, ACCEPTOR_SENDER_ID));
}
@Test(timeout = 120000)
public void simpleMessageLoop() throws InterruptedException, IOException {
final CountDownLatch connected = new CountDownLatch(1);
final SessionEventListener eventListener = new SessionEventListener() {
@Override
public void onStatusChanged(SessionID sessionID, SessionStatus oldStatus, SessionStatus newStatus) {
if (newStatus == SessionStatus.ApplicationConnected)
connected.countDown();
}
};
final SimpleFixAcceptor acceptor = createAcceptor(7890);
final SimpleFixInitiator initiator = createInitiator(7890);
initiator.setEventListener(eventListener);
final Thread acceptorThread = new Thread(acceptor, "Acceptor");
acceptorThread.start();
final Thread initiatorThread = new Thread(initiator, "Initiator");
initiatorThread.start();
if ( ! connected.await(15, TimeUnit.SECONDS))
Assert.fail("Connection failed");
long orderId = 1;
AllocationDetector allocationDetector = AllocationDetector.create();
for(int i=1; i <= 10; i++) {
initiator.sendNewOrder(orderId++);
}
Thread.sleep(1000);
allocationDetector.enabled = true;
for(int i=1; i <= 1000; i++) {
initiator.sendNewOrder(orderId++);
}
Thread.sleep(1000);
allocationDetector.enabled = false;
if ( ! allocationDetector.isTestObjectAllocatonsDetected)
Assert.fail("Allocation detector is not working properly. Check that you added -agent:allocation.jar JVM argument");
if ( ! allocationDetector.allocs.isEmpty())
Assert.fail("There were " + allocationDetector.allocs.size() + " allocations");
initiator.disconnect("End of test");
initiator.close();
acceptor.close();
}
@After
public void disableTracing() {
//TODO: disable tracing
}
private static class AllocationDetector implements Sampler {
boolean isTestObjectAllocatonsDetected = false;
final List<Class> allocs = Collections.synchronizedList(new ArrayList<Class>(10000));
volatile boolean enabled;
static AllocationDetector create () {
AllocationDetector result = new AllocationDetector();
AllocationRecorder.addSampler(result);
return result;
}
@Override
public void sampleAllocation(int count, String desc, Object newObj, long size) {
//System.out.println("I just allocated the object " + newObj + " of type " + desc + " whose size is " + size);
if (enabled) {
Class allocatedClass = newObj.getClass();
if (allocatedClass == TestObject.class)
isTestObjectAllocatonsDetected = true;
else
allocs.add(allocatedClass);
}
}
}
}