/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.regression.multithread; import com.espertech.esper.client.*; import com.espertech.esper.client.deploy.DeploymentResult; import com.espertech.esper.collection.Pair; import com.espertech.esper.collection.UniformPair; import com.espertech.esper.supportregression.bean.SupportBean; import com.espertech.esper.supportregression.client.SupportConfigFactory; import junit.framework.TestCase; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; /** * Test for multithread-safety for atomic module deployment. */ public class TestMTDeployAtomic extends TestCase { private EPServiceProvider engine; private final static int NUM_STMTS = 100; public void setUp() { engine = EPServiceProviderManager.getDefaultProvider(SupportConfigFactory.getConfiguration()); engine.initialize(); engine.getEPAdministrator().getConfiguration().addEventType(SupportBean.class); } public void tearDown() { engine.destroy(); } public void testSendEventsAndDeploy() throws Exception { MySendRunnable runnable = new MySendRunnable(engine); Thread thread = new Thread(runnable); thread.start(); MyKeepFirstPerStmtListener listener = new MyKeepFirstPerStmtListener(); engine.addStatementStateListener(new EPStatementStateListener() { public void onStatementCreate(EPServiceProvider serviceProvider, EPStatement statement) { statement.addListener(listener); } public void onStatementStateChange(EPServiceProvider serviceProvider, EPStatement statement) { } }); // deploy StringWriter buf = new StringWriter(); for (int i = 0; i < NUM_STMTS; i++) { buf.append("select * from SupportBean;"); } DeploymentResult deploymentResult = engine.getEPAdministrator().getDeploymentAdmin().parseDeploy(buf.toString()); // wait for some deliveries Thread.sleep(1000); // undeploy engine.getEPAdministrator().getDeploymentAdmin().undeploy(deploymentResult.getDeploymentId()); // cooldown Thread.sleep(500); runnable.setShutdown(true); thread.join(); assertNull(runnable.getThrowable()); assertEquals(NUM_STMTS, listener.getFirstLastPerStmt().size()); // all first events should be the same UniformPair<EventBean> reference = listener.firstLastPerStmt.values().iterator().next(); assertNotNull(reference.getFirst()); assertNotNull(reference.getSecond()); assertNotSame(reference.getFirst(), reference.getSecond()); for (UniformPair<EventBean> other : listener.firstLastPerStmt.values()) { assertSame(reference.getFirst(), other.getFirst()); assertSame(reference.getSecond(), other.getSecond()); } } private final static class MyKeepFirstPerStmtListener implements StatementAwareUpdateListener { private final Map<EPStatement, UniformPair<EventBean>> firstLastPerStmt = new HashMap<>(); public void update(EventBean[] newEvents, EventBean[] oldEvents, EPStatement statement, EPServiceProvider epServiceProvider) { UniformPair<EventBean> pair = firstLastPerStmt.get(statement); if (pair == null) { firstLastPerStmt.put(statement, new UniformPair<>(newEvents[0], null)); } else { pair.setSecond(newEvents[0]); } } public Map<EPStatement, UniformPair<EventBean>> getFirstLastPerStmt() { return firstLastPerStmt; } } private final static class MySendRunnable implements Runnable { private final EPServiceProvider engine; private int current; private boolean shutdown; private Throwable throwable; public MySendRunnable(EPServiceProvider engine) { this.engine = engine; } public void setShutdown(boolean shutdown) { this.shutdown = shutdown; } public void run() { try { while (!shutdown) { engine.getEPRuntime().sendEvent(new SupportBean(null, current++)); } } catch (Throwable t) { throwable = t; } } public Throwable getThrowable() { return throwable; } } }