/*
* Copyright 2012 Research Studios Austria Forschungsges.m.b.H.
*
* 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 won.bot.integrationtest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import won.bot.framework.eventbot.event.impl.lifecycle.WorkDoneEvent;
import won.bot.framework.eventbot.listener.BaseEventListener;
import won.bot.framework.eventbot.listener.CountingListener;
import won.bot.framework.eventbot.listener.impl.ActionOnEventListener;
import won.bot.framework.manager.impl.SpringAwareBotManagerImpl;
import won.bot.impl.GroupingBot;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
/**
* Integration test.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/spring/app/simple2NeedGroupingTest.xml"})
public class GroupingBotTest
{
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final int RUN_ONCE = 1;
private static final long ACT_LOOP_TIMEOUT_MILLIS = 100;
private static final long ACT_LOOP_INITIAL_DELAY_MILLIS = 100;
private static boolean run = false;
private static MyBot bot;
@Autowired
ApplicationContext applicationContext;
@Autowired
SpringAwareBotManagerImpl botManager;
/**
* This is run before each @TestD method.
*/
@Before
public void before(){
if (!run)
{
AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
bot = (MyBot) beanFactory.autowire(MyBot.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
Object botBean = beanFactory.initializeBean(bot, "mybot");
bot = (MyBot) botBean;
//the bot also needs a trigger so its act() method is called regularly.
// (there is no trigger bean in the context)
PeriodicTrigger trigger = new PeriodicTrigger(ACT_LOOP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
trigger.setInitialDelay(ACT_LOOP_INITIAL_DELAY_MILLIS);
bot.setTrigger(trigger);
logger.info("starting test case testGroupBot");
//adding the bot to the bot manager will cause it to be initialized.
//at that point, the trigger starts.
botManager.addBot(bot);
//the bot should now be running. We have to wait for it to finish before we
//can check the results:
//Together with the barrier.await() in the bot's listener, this trips the barrier
//and both threads continue.
try {
bot.getBarrier().await();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (BrokenBarrierException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
run = true;
}
}
/**
* The main test method.
* @throws Exception
*/
@Test
public void testGroupingBot() throws Exception
{
logger.info("starting test case testCreate2NeedsGroupingBot");
this.bot.executeAsserts();
logger.info("finishing test case testCreate2NeedsGroupingBot");
}
/*@Test
public void testGroupRDFBot() throws Exception
{
logger.info("starting test case testCreate2NeedsGroupingBot");
this.bot.executeGroupRDFValidationAssert();
logger.info("finishing test case testCreate2NeedsGroupingBot");
} */
/**
* We create a subclass of the bot we want to test here so that we can
* add a listener to its internal event bus and to access its listeners, which
* record information during the run that we later check with asserts.
*/
public static class MyBot extends GroupingBot
{
/**
* Used for synchronization with the @TestD method: it should wait at the
* barrier until our bot is done, then execute the asserts.
*/
CyclicBarrier barrier = new CyclicBarrier(2);
private static final String sparqlPrefix =
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>"+
"PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>"+
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>"+
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>"+
"PREFIX won: <http://purl.org/webofneeds/model#>"+
"PREFIX gr: <http://purl.org/goodrelations/v1#>"+
"PREFIX ldp: <http://www.w3.org/ns/ldp#>";
/**
* Default constructor is required for instantiation through Spring.
*/
public MyBot(){
}
@Override
protected void initializeEventListeners()
{
//of course, let the real bot implementation initialize itself
super.initializeEventListeners();
//now, add a listener to the WorkDoneEvent.
//its only purpose is to trip the CyclicBarrier instance that
// the test method is waiting on
getEventBus().subscribe(WorkDoneEvent.class,
new ActionOnEventListener(
getEventListenerContext(),
new TripBarrierAction(getEventListenerContext(), barrier)));
}
public CyclicBarrier getBarrier()
{
return barrier;
}
/**
* Here we check the results of the bot's execution.
*/
public void executeAsserts()
{
//2 act events
Assert.assertEquals(NO_OF_GROUPMEMBERS, this.groupMemberCreator.getEventCount());
Assert.assertEquals(0, this.groupMemberCreator.getExceptionCount());
//2 create need events
Assert.assertEquals(NO_OF_GROUPMEMBERS, this.groupCreator.getEventCount());
Assert.assertEquals(0, this.groupCreator.getExceptionCount());
//1 create group events
Assert.assertEquals(NO_OF_GROUPMEMBERS+1, this.needConnector.getEventCount());
Assert.assertEquals(0, this.needConnector.getExceptionCount());
//2 connect, 2 open
Assert.assertEquals(NO_OF_GROUPMEMBERS, this.autoOpener.getEventCount());
Assert.assertEquals(0, this.autoOpener.getExceptionCount());
//41 messages
Assert.assertEquals(NO_OF_GROUPMEMBERS*2, this.messagesDoneListener.getEventCount());
Assert.assertEquals(0, this.messagesDoneListener.getExceptionCount());
//check that the autoresponder creator was called
Assert.assertEquals(NO_OF_GROUPMEMBERS, this.autoResponderCreator.getEventCount());
Assert.assertEquals(0, this.autoResponderCreator.getExceptionCount());
//check that the autoresponders were created
Assert.assertEquals(NO_OF_GROUPMEMBERS, this.autoResponders.size());
//check that the autoresponders responded as they should
for (BaseEventListener autoResponder: this.autoResponders){
Assert.assertEquals(NO_OF_MESSAGES, ((CountingListener) autoResponder).getCount());
Assert.assertEquals(0, autoResponder.getExceptionCount());
}
//4 NeedDeactivated events
Assert.assertEquals(NO_OF_GROUPMEMBERS, this.workDoneSignaller.getEventCount());
Assert.assertEquals(0, this.workDoneSignaller.getExceptionCount());
//TODO: there is more to check:
//* what does the RDF look like?
// --> pull it from the needURI/ConnectionURI and check contents
//* what does the database look like? */
}
}
}