blob: 7adc9af289134d862c05b7153ec10fc5af61b73c [file] [log] [blame]
/*
* Copyright 2011 Marc Grue.
*
* 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.qi4j.sample.dcicargo.sample_b.bootstrap.test;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.qi4j.api.composite.TransientBuilderFactory;
import org.qi4j.api.entity.EntityBuilder;
import org.qi4j.api.query.QueryBuilderFactory;
import org.qi4j.api.service.ServiceReference;
import org.qi4j.api.structure.Application;
import org.qi4j.api.structure.Module;
import org.qi4j.api.unitofwork.UnitOfWork;
import org.qi4j.api.unitofwork.UnitOfWorkFactory;
import org.qi4j.api.usecase.Usecase;
import org.qi4j.api.usecase.UsecaseBuilder;
import org.qi4j.api.value.ValueBuilder;
import org.qi4j.bootstrap.Energy4Java;
import org.qi4j.sample.dcicargo.sample_b.bootstrap.sampledata.BaseData;
import org.qi4j.sample.dcicargo.sample_b.data.factory.RouteSpecificationFactoryService;
import org.qi4j.sample.dcicargo.sample_b.data.structure.cargo.Cargo;
import org.qi4j.sample.dcicargo.sample_b.data.structure.cargo.RouteSpecification;
import org.qi4j.sample.dcicargo.sample_b.data.structure.delivery.Delivery;
import org.qi4j.sample.dcicargo.sample_b.data.structure.delivery.NextHandlingEvent;
import org.qi4j.sample.dcicargo.sample_b.data.structure.delivery.RoutingStatus;
import org.qi4j.sample.dcicargo.sample_b.data.structure.delivery.TransportStatus;
import org.qi4j.sample.dcicargo.sample_b.data.structure.handling.HandlingEvent;
import org.qi4j.sample.dcicargo.sample_b.data.structure.handling.HandlingEventType;
import org.qi4j.sample.dcicargo.sample_b.data.structure.itinerary.Itinerary;
import org.qi4j.sample.dcicargo.sample_b.data.structure.location.Location;
import org.qi4j.sample.dcicargo.sample_b.data.structure.tracking.TrackingId;
import org.qi4j.sample.dcicargo.sample_b.data.structure.voyage.Schedule;
import org.qi4j.sample.dcicargo.sample_b.data.structure.voyage.Voyage;
import org.qi4j.sample.dcicargo.sample_b.data.structure.voyage.VoyageNumber;
import org.qi4j.sample.dcicargo.sample_b.infrastructure.dci.Context;
import org.qi4j.sample.dcicargo.sample_b.infrastructure.testing.ExpectedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
/**
* Base class for testing Context Interactions
*/
public class TestApplication
extends BaseData
{
// Logger for sub classes
protected Logger logger = LoggerFactory.getLogger( getClass() );
protected static Application app;
protected static RouteSpecificationFactoryService routeSpecFactory;
final protected static Date TODAY = new Date();
final protected static Date DAY1 = day( 1 );
final protected static Date DAY2 = day( 2 );
final protected static Date DAY3 = day( 3 );
final protected static Date DAY4 = day( 4 );
final protected static Date DAY5 = day( 5 );
final protected static Date DAY6 = day( 6 );
final protected static Date DAY7 = day( 7 );
final protected static Date DAY8 = day( 8 );
final protected static Date DAY9 = day( 9 );
final protected static Date DAY10 = day( 10 );
final protected static Date DAY11 = day( 11 );
final protected static Date DAY12 = day( 12 );
final protected static Date DAY13 = day( 13 );
final protected static Date DAY14 = day( 14 );
final protected static Date DAY15 = day( 15 );
final protected static Date DAY16 = day( 16 );
final protected static Date DAY17 = day( 17 );
final protected static Date DAY18 = day( 18 );
final protected static Date DAY19 = day( 19 );
final protected static Date DAY20 = day( 20 );
final protected static Date DAY21 = day( 21 );
final protected static Date DAY22 = day( 22 );
final protected static Date DAY23 = day( 23 );
final protected static Date DAY24 = day( 24 );
final protected static Date DAY25 = day( 25 );
protected static Voyage V201;
protected static Voyage V202;
protected static Voyage V203;
protected static Voyage V204;
protected static Voyage V205;
final protected static Voyage noVoyage = null;
final protected static boolean notArrived = false;
final protected static boolean arrived = true;
final protected static boolean directed = false;
final protected static boolean misdirected = true;
final protected static Date unknownETA = null;
final protected static Date noSpecificDate = null;
final protected static Integer leg1 = 0;
final protected static Integer leg2 = 1;
final protected static Integer leg3 = 2;
final protected static Integer leg4 = 3;
final protected static Integer leg5 = 4;
final protected static Integer unknownLeg = 0;
final protected static NextHandlingEvent unknownNextHandlingEvent = null;
protected Date deadline;
protected Date arrival;
protected RouteSpecification routeSpec;
protected RouteSpecification newRouteSpec;
protected Delivery delivery;
protected Cargo cargo;
protected TrackingId trackingId;
protected String trackingIdString;
protected Itinerary itinerary;
protected Itinerary wrongItinerary;
protected HandlingEvent handlingEvent;
protected Location MELBOURNE;
protected Location HANGZHOU;
protected Location HONGKONG;
protected Location SHANGHAI;
protected Location HAMBURG;
protected Location STOCKHOLM;
protected Location DALLAS;
protected Location NEWYORK;
protected Location MOGADISHU;
protected Location ROTTERDAM;
protected Location HELSINKI;
protected Location GOTHENBURG;
protected Location TOKYO;
protected Location CHICAGO;
protected TestApplication()
{
super( findHostingModule() );
}
@BeforeClass
public static void setup() throws Exception
{
System.out.println( "\n@@@@@@@@@@@ TEST SUITE @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" );
app = new Energy4Java().newApplication( new TestAssembler() );
app.activate();
Context.prepareContextBaseClass( findHostingModule() );
}
// Allow to test message output from exceptions after they have been thrown
@Rule
public ExpectedException thrown = ExpectedException.none();
// Print current test method name to console
@Rule
public TestName name = new TestName();
@Before
public void prepareTest()
throws Exception
{
logger.info( name.getMethodName() );
Usecase usecase = UsecaseBuilder.newUsecase( "Usecase:" + name );
UnitOfWork uow = module.newUnitOfWork(usecase);
populateTestData();
ServiceReference<RouteSpecificationFactoryService> routeSpecFactoryServiceRef =
module.findService( RouteSpecificationFactoryService.class );
routeSpecFactory = routeSpecFactoryServiceRef.get();
// Separate test suites in console output
System.out.println();
}
@After
public void concludeTests()
{
UnitOfWork uow = module.currentUnitOfWork();
if (uow != null)
{
uow.discard();
}
if( module.isUnitOfWorkActive() )
{
while( module.isUnitOfWorkActive() )
{
uow = module.currentUnitOfWork();
if( uow.isOpen() )
{
System.err.println( "UnitOfWork not cleaned up:" + uow.usecase().name() );
uow.discard();
}
else
{
throw new InternalError( "I have seen a case where a UoW is on the stack, but not opened. First is: " + uow.usecase().name() );
}
}
new Exception( "UnitOfWork not properly cleaned up" ).printStackTrace();
}
}
@AfterClass
public static void terminateApplication() throws Exception
{
if( app != null )
{
app.passivate();
}
}
public void assertMessage( Exception e, String msg )
{
String message = "\nEXPECTED: " + msg + "\nGOT: " + e.getMessage();
assertTrue( message, e.getMessage().contains( msg ) );
}
private void populateTestData() throws Exception
{
// UnLocode value objects
AUMEL = unlocode( "AUMEL" ); // Melbourne
CNHGH = unlocode( "CNHGH" ); // Hangzou
CNHKG = unlocode( "CNHKG" ); // Hong Kong
CNSHA = unlocode( "CNSHA" ); // Shanghai
DEHAM = unlocode( "DEHAM" ); // Hamburg
FIHEL = unlocode( "FIHEL" ); // Helsinki
JNTKO = unlocode( "JNTKO" ); // Tokyo
NLRTM = unlocode( "NLRTM" ); // Rotterdam
SEGOT = unlocode( "SEGOT" ); // Gothenburg
SESTO = unlocode( "SESTO" ); // Stockholm
SOMGQ = unlocode( "SOMGQ" ); // Mogadishu
USCHI = unlocode( "USCHI" ); // Chicago
USDAL = unlocode( "USDAL" ); // Dallas
USNYC = unlocode( "USNYC" ); // New York
UnitOfWork uow = module.currentUnitOfWork();
// Get locations created in BaseDataService on startup
MELBOURNE = uow.get( Location.class, "AUMEL" );
HANGZHOU = uow.get( Location.class, "CNHGH" );
HONGKONG = uow.get( Location.class, "CNHKG" );
SHANGHAI = uow.get( Location.class, "CNSHA" );
HAMBURG = uow.get( Location.class, "DEHAM" );
HELSINKI = uow.get( Location.class, "FIHEL" );
TOKYO = uow.get( Location.class, "JNTKO" );
ROTTERDAM = uow.get( Location.class, "NLRTM" );
GOTHENBURG = uow.get( Location.class, "SEGOT" );
STOCKHOLM = uow.get( Location.class, "SESTO" );
MOGADISHU = uow.get( Location.class, "SOMGQ" );
CHICAGO = uow.get( Location.class, "USCHI" );
DALLAS = uow.get( Location.class, "USDAL" );
NEWYORK = uow.get( Location.class, "USNYC" );
// Voyage entity objects for testing
V201 = voyage( "V201", schedule(
carrierMovement( HONGKONG, CHICAGO, DAY1, DAY5 ),
carrierMovement( CHICAGO, NEWYORK, DAY5, DAY6 ),
carrierMovement( NEWYORK, GOTHENBURG, DAY6, DAY12 )
) );
V202 = voyage( "V202", schedule(
carrierMovement( CHICAGO, NEWYORK, DAY3, DAY5 ),
carrierMovement( NEWYORK, DALLAS, DAY7, DAY8 ),
carrierMovement( DALLAS, ROTTERDAM, DAY10, DAY17 ),
carrierMovement( ROTTERDAM, HAMBURG, DAY17, DAY19 ),
carrierMovement( HAMBURG, GOTHENBURG, DAY20, DAY24 )
) );
V203 = voyage( "V203", schedule(
carrierMovement( NEWYORK, HAMBURG, DAY3, DAY12 ),
carrierMovement( HAMBURG, ROTTERDAM, DAY13, DAY18 ),
carrierMovement( ROTTERDAM, STOCKHOLM, DAY20, DAY23 ),
carrierMovement( STOCKHOLM, HELSINKI, DAY24, DAY25 )
) );
V204 = voyage( "V204", schedule(
carrierMovement( TOKYO, HANGZHOU, DAY3, DAY6 ),
carrierMovement( HANGZHOU, HONGKONG, DAY7, DAY8 ),
carrierMovement( HONGKONG, NEWYORK, DAY9, DAY12 ),
carrierMovement( NEWYORK, MELBOURNE, DAY13, DAY19 )
) );
V205 = voyage( "V205", schedule(
carrierMovement( HANGZHOU, MOGADISHU, DAY1, DAY2 ),
carrierMovement( MOGADISHU, ROTTERDAM, DAY2, DAY4 ),
carrierMovement( ROTTERDAM, NEWYORK, DAY4, DAY7 ),
carrierMovement( NEWYORK, DALLAS, DAY9, DAY10 )
) );
itinerary = itinerary(
leg( V201, HONGKONG, CHICAGO, DAY1, DAY5 ),
leg( V201, CHICAGO, NEWYORK, DAY5, DAY6 ),
leg( V202, NEWYORK, DALLAS, DAY7, DAY8 ),
leg( V202, DALLAS, ROTTERDAM, DAY10, DAY17 ),
leg( V203, ROTTERDAM, STOCKHOLM, DAY20, DAY23 )
);
wrongItinerary = itinerary(
leg( V201, HONGKONG, CHICAGO, DAY1, DAY5 ),
leg( V201, CHICAGO, NEWYORK, DAY5, DAY6 ),
leg( V204, NEWYORK, MELBOURNE, DAY13, DAY19 )
);
}
public void assertDelivery( HandlingEventType handlingEventType,
Location location,
Date completion,
Voyage voyage,
TransportStatus transportStatus,
Boolean isUnloadedAtDestination,
RoutingStatus routingStatus,
Boolean isMisdirected,
Date eta,
Integer itineraryProgress,
HandlingEventType nextHandlingEventType,
Location nextLocation,
Date nextTime,
Voyage nextVoyage
) throws Exception
{
delivery = cargo.delivery().get();
// Last handling event
if (delivery.lastHandlingEvent().get() != null
|| handlingEventType != null || location != null || completion != null || voyage != null)
{
assertThat( "lastHandlingEvent - handlingEventType",
delivery.lastHandlingEvent().get().handlingEventType().get(), is( equalTo( handlingEventType ) ) );
assertThat( "lastHandlingEvent - location",
delivery.lastHandlingEvent().get().location().get(), is( equalTo( location ) ) );
assertThat( "lastHandlingEvent - completionTime",
delivery.lastHandlingEvent().get().completionTime().get(), is( equalTo( completion ) ) );
assertThat( "lastHandlingEvent - voyage",
delivery.lastHandlingEvent().get().voyage().get(), is( equalTo( voyage ) ) );
}
// Other transport status
assertThat( "transportStatus",
delivery.transportStatus().get(), is( equalTo( transportStatus ) ) );
assertThat( "isUnloadedAtDestination",
delivery.isUnloadedAtDestination().get(), is( equalTo( isUnloadedAtDestination ) ) );
// Routing and direction
assertThat( "routingStatus",
delivery.routingStatus().get(), is( equalTo( routingStatus ) ) );
assertThat( "isMisdirected",
delivery.isMisdirected().get(), is( equalTo( isMisdirected ) ) );
assertThat( "eta",
delivery.eta().get(), is( equalTo( eta ) ) );
assertThat( "itineraryProgressIndex",
delivery.itineraryProgressIndex().get(), is( equalTo( itineraryProgress ) ) );
// Next handling event
if (nextHandlingEventType == null)
{
assertThat( "nextHandlingEvent - handlingEventType",
delivery.nextHandlingEvent().get(), is( equalTo( null ) ) );
}
else
{
assertThat( "nextHandlingEvent - handlingEventType",
delivery.nextHandlingEvent().get().handlingEventType().get(), is( equalTo( nextHandlingEventType ) ) );
assertThat( "nextHandlingEvent - location",
delivery.nextHandlingEvent().get().location().get(), is( equalTo( nextLocation ) ) );
if (delivery.nextHandlingEvent().get().time().get() != null)
{
// Estimating a new carrier arrival time might be calculated a second
// after initial dates are set, so we skip the seconds
SimpleDateFormat parser = new SimpleDateFormat( "yyyy-MM-dd HH:mm" );
String calculatedTime = parser.format( delivery.nextHandlingEvent().get().time().get() );
String expectedTime = parser.format( nextTime );
assertThat( "nextHandlingEvent - time", calculatedTime, is( equalTo( expectedTime ) ) );
}
else
assertThat( "nextHandlingEvent - time", delivery.nextHandlingEvent().get().time().get(), is( equalTo( nextTime ) ) );
assertThat( "nextHandlingEvent - voyage",
delivery.nextHandlingEvent().get().voyage().get(), is( equalTo( nextVoyage ) ) );
}
}
public void assertDelivery( HandlingEventType handlingEventType,
Location location,
Date completion,
Voyage voyage,
TransportStatus transportStatus,
Boolean isUnloadedAtDestination,
RoutingStatus routingStatus,
Boolean isMisdirected,
Date eta,
Integer itineraryProgress,
NextHandlingEvent noNextHandlingEvent
) throws Exception
{
assertDelivery( handlingEventType, location, completion, voyage,
transportStatus, isUnloadedAtDestination, routingStatus, isMisdirected, eta,
itineraryProgress, null, null, null, null );
}
public void assertRouteSpec( Location origin, Location destination, Date earliestDeparture, Date deadline )
{
newRouteSpec = cargo.routeSpecification().get();
assertThat( newRouteSpec.origin().get(), is( equalTo( origin ) ) );
assertThat( newRouteSpec.destination().get(), is( equalTo( destination ) ) );
assertThat( newRouteSpec.earliestDeparture().get(), is( equalTo( earliestDeparture ) ) );
assertThat( newRouteSpec.arrivalDeadline().get(), is( equalTo( deadline ) ) );
}
protected Voyage voyage( String voyageNumberStr, Schedule schedule )
{
UnitOfWork uow = module.currentUnitOfWork();
EntityBuilder<Voyage> voyage = uow.newEntityBuilder( Voyage.class, voyageNumberStr );
// VoyageNumber
ValueBuilder<VoyageNumber> voyageNumber = module.newValueBuilder( VoyageNumber.class );
voyageNumber.prototype().number().set( voyageNumberStr );
voyage.instance().voyageNumber().set( voyageNumber.newInstance() );
// Schedule
voyage.instance().schedule().set( schedule );
return voyage.newInstance();
}
private static Module findHostingModule()
{
return app.findModule( "BOOTSTRAP", "BOOTSTRAP-Bootstrap" );
}
}