/** * Copyright (C) 2010 BonitaSoft S.A. * BonitaSoft, 31 rue Gustave Eiffel - 38000 Grenoble * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2.0 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.bonitasoft.simulation; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; import junit.framework.TestCase; import org.bonitasoft.simulation.engine.ResourceInstanceAvailability; import org.bonitasoft.simulation.engine.ResourcePool; import org.bonitasoft.simulation.model.Period; import org.bonitasoft.simulation.model.TimeUnit; import org.bonitasoft.simulation.model.calendar.SimCalendar; import org.bonitasoft.simulation.model.calendar.SimCalendarInstance; import org.bonitasoft.simulation.model.calendar.SimCalendarPeriod; import org.bonitasoft.simulation.model.calendar.SimCalendarTime; import org.bonitasoft.simulation.model.instance.ResourceInstance; import org.bonitasoft.simulation.model.resource.Resource; /** * @author Romain Bioteau * */ public class TestSimulationCalendar extends TestCase{ @SuppressWarnings("deprecation") public void testFindAvailablePeriodWhenTaskCanBeDoneImmediatly() throws Exception { long start = new Date(2010, 06, 18, 9, 0).getTime(); ResourcePool.getInstance().addResource(SimulationTestUtil.createProcessDefinition(),SimulationTestUtil.createResources().get(0),start,SimulationTestUtil.getHoursIntoMilliseconds(24)) ; SimCalendarInstance planning = ResourcePool.getInstance().getResourceInstances(SimulationTestUtil.createResources().get(0)).get(0).getPlanning(); long available = planning.getFirstAvailableDate(start, SimulationTestUtil.getHoursIntoMilliseconds(1), true); assertEquals("This calendar should allow the task to be done immediatly", start, available); //$NON-NLS-1$ } public void testWorkingDuration() throws Exception{ List<Resource> ressources = SimulationTestUtil.createResources() ; Resource r = ressources.get(0) ; Calendar cal = GregorianCalendar.getInstance() ; cal.set(2010,5,1,8,0,0); cal.set(Calendar.MILLISECOND , 0) ; long start = cal.getTimeInMillis(); cal.add(Calendar.DAY_OF_WEEK, 4) ; cal.set(Calendar.SECOND, 0) ; cal.set(Calendar.MILLISECOND , 0) ; long end = cal.getTimeInMillis(); long duration = r.getPlanning().getWorkingPlanningDuration(start, end) ; assertEquals(4*SimulationTestUtil.getHoursIntoMilliseconds(10), duration) ; cal.set(2010,5,5,8,0,0);//Saturday cal.set(Calendar.MILLISECOND , 0) ; start = cal.getTimeInMillis(); cal.add(Calendar.DAY_OF_WEEK, 1) ; cal.set(Calendar.SECOND, 0) ; cal.set(Calendar.MILLISECOND , 0) ; end = cal.getTimeInMillis(); duration = r.getPlanning().getWorkingPlanningDuration(start, end) ; assertEquals(0, duration) ; cal.set(2010,5,5,4,0,0); cal.set(Calendar.MILLISECOND , 0) ; start = cal.getTimeInMillis(); cal.add(Calendar.HOUR_OF_DAY, 1) ; cal.set(Calendar.SECOND, 0) ; cal.set(Calendar.MILLISECOND , 0) ; end = cal.getTimeInMillis(); duration = r.getPlanning().getWorkingPlanningDuration(start, end) ; assertEquals(0, duration) ; } public void testFindAvailablePeriod() throws Exception{ List<Resource> ressources = SimulationTestUtil.createResources() ; Resource r = ressources.get(0) ; Calendar myInstance = GregorianCalendar.getInstance() ; myInstance.set(2010, 6, 1, 9,0); long start = myInstance.getTimeInMillis() ; ResourcePool.getInstance().addResource(null,r,start,SimulationTestUtil.getHoursIntoMilliseconds(24)); ResourceInstance ri = ResourcePool.getInstance().getResourceInstances(ressources.get(0)).get(0); myInstance.add(Calendar.HOUR, 2) ; long end = myInstance.getTimeInMillis() ; Period p = new Period(start, end) ; ri.getPlanning().addBusyPeriod(p,false) ; myInstance.add(Calendar.HOUR, -1); long nextTaskToStart = myInstance.getTimeInMillis() ; long executionTime = 60000 * 60 * 4 ; // 4 Hours List<ResourceInstanceAvailability> result = ResourcePool.getInstance().findAvailableResource(1,r, nextTaskToStart, executionTime,false); Period per = new Period(result.get(0).getTime(),result.get(0).getTime()+executionTime); List<Period> periods = result.get(0).getResource().getPlanning().split(per); assertEquals(2, periods.size()); long total = 0 ; for(Period period : periods){ total = total + period.getDuration(); } assertEquals(60000 * 60 * 4,total) ; result = ResourcePool.getInstance().findAvailableResource(1,r, nextTaskToStart, executionTime,true); per = new Period(result.get(0).getTime(),result.get(0).getTime()+executionTime); periods = result.get(0).getResource().getPlanning().split(per); assertEquals(1, periods.size()); total = 0 ; for(Period period : periods){ total = total + period.getDuration(); } assertEquals(60000 * 60 * 4,total) ; } public void testSpliPeriod() throws Exception{ List<Resource> ressources = SimulationTestUtil.createResources() ; Resource r = ressources.get(0) ; Calendar myInstance = GregorianCalendar.getInstance() ; myInstance.set(2010, 6, 1, 9,0); myInstance.set(Calendar.MILLISECOND, 0); myInstance.set(Calendar.SECOND, 0); long start = myInstance.getTimeInMillis() ; ResourcePool.getInstance().addResource(null,r,start,SimulationTestUtil.getHoursIntoMilliseconds(24)); myInstance.add(Calendar.HOUR, 4) ; long end = myInstance.getTimeInMillis() ; Period p = new Period(start, end) ; List<ResourceInstance> riList = ResourcePool.getInstance().getResourceInstances(r) ; List<Period> periods = riList.get(0).getPlanning().split(p) ; long total = 0 ; for(Period per : periods){ total = total + per.getDuration(); } assertEquals(60000 * 60 * 4,total) ; SimCalendar c = new SimCalendar(); Set<SimCalendarPeriod> workingDay = new HashSet<SimCalendarPeriod>() ; SimCalendarPeriod morning = new SimCalendarPeriod(new SimCalendarTime(0,0),new SimCalendarTime(0,0)); workingDay.add(morning) ; c.addSimCalendarDay(Calendar.MONDAY, new TreeSet<SimCalendarPeriod>()); c.addSimCalendarDay(Calendar.TUESDAY, new TreeSet<SimCalendarPeriod>()); c.addSimCalendarDay(Calendar.WEDNESDAY, new TreeSet<SimCalendarPeriod>()); c.addSimCalendarDay(Calendar.THURSDAY, new TreeSet<SimCalendarPeriod>()); c.addSimCalendarDay(Calendar.FRIDAY, new TreeSet<SimCalendarPeriod>()); c.addSimCalendarDay(Calendar.SATURDAY, workingDay); c.addSimCalendarDay(Calendar.SUNDAY, workingDay); Resource res = new Resource("R&D Team","Developer",5,5,c,"$",TimeUnit.HOUR,0,20); ResourcePool.getInstance().addResource(null,res,start,SimulationTestUtil.getHoursIntoMilliseconds(24)); List<ResourceInstance> riList2 = ResourcePool.getInstance().getResourceInstances(res) ; periods = riList2.get(0).getPlanning().split(p) ; assertEquals(1,periods.size()); } public void testGetFirstAvailableDate() throws Exception{ List<Resource> ressources = SimulationTestUtil.createResources() ; Resource r = ressources.get(0) ; Calendar myInstance = GregorianCalendar.getInstance() ; myInstance.set(2010, 6, 1, 11,0); myInstance.set(Calendar.MILLISECOND, 0); myInstance.set(Calendar.SECOND, 0); long start = myInstance.getTimeInMillis() ; ResourcePool.getInstance().addResource(null,r,start,SimulationTestUtil.getHoursIntoMilliseconds(24)); myInstance.add(Calendar.HOUR, 4) ; long end = myInstance.getTimeInMillis() ; Period p = new Period(start, end) ; myInstance.add(Calendar.HOUR, -1) ; long wStart = myInstance.getTimeInMillis() ; myInstance.add(Calendar.HOUR, 3) ; long wEnd = myInstance.getTimeInMillis() ; List<ResourceInstance> riList = ResourcePool.getInstance().getResourceInstances(r) ; Period wp = new Period(wStart,wEnd); riList.get(0).getPlanning().addBusyPeriod(wp,false); assertTrue(riList.get(0).getPlanning().isWorkingDuring(wp)) ; long startDate = riList.get(0).getPlanning().getFirstAvailableDate(start, p.getDuration(), false); assertTrue(startDate >= wp.getEnd()) ; startDate = riList.get(0).getPlanning().getNextPlanningUnavailable(startDate) ; assertTrue(riList.get(0).getPlanning().isPlanningAvailable(riList.get(0).getPlanning().getFirstAvailableDate(startDate,10,true))) ; } public void testPeriodOverlap() throws Exception{ Calendar myInstance = GregorianCalendar.getInstance() ; myInstance.set(2010, 6, 1, 11,0); myInstance.set(Calendar.MILLISECOND, 0); myInstance.set(Calendar.SECOND, 0); long start = myInstance.getTimeInMillis() ; myInstance.add(Calendar.HOUR, 4) ; long end = myInstance.getTimeInMillis() ; Period p11_15 = new Period(start, end) ; myInstance.add(Calendar.HOUR, -5) ; start = myInstance.getTimeInMillis() ; myInstance.add(Calendar.HOUR, 2) ; end = myInstance.getTimeInMillis() ; Period p10_12 = new Period(start, end) ; myInstance.add(Calendar.HOUR, 2) ; start = myInstance.getTimeInMillis() ; myInstance.add(Calendar.HOUR, 2) ; end = myInstance.getTimeInMillis() ; Period p14_16 = new Period(start, end) ; start = end ; myInstance.add(Calendar.HOUR, 1) ; end = myInstance.getTimeInMillis() ; Period p16_17 = new Period(start, end) ; assertTrue(p11_15.overlaps(p11_15)) ; assertTrue(p11_15.overlaps(p10_12)) ; assertTrue(p10_12.overlaps(p11_15)) ; assertTrue(p14_16.overlaps(p11_15)) ; assertTrue(p11_15.overlaps(p14_16)) ; assertFalse(p10_12.overlaps(p14_16)) ; assertFalse(p14_16.overlaps(p10_12)) ; assertFalse(p16_17.overlaps(p14_16)) ; } public void testNextPlanningAvailableDate() throws Exception{ List<Resource> ressources = SimulationTestUtil.createResources() ; Resource r = ressources.get(0) ; Calendar cal = GregorianCalendar.getInstance(); cal.set(2010, 1, 1, 7,0); ResourcePool.getInstance().addResource(null,r,cal.getTimeInMillis(),SimulationTestUtil.getHoursIntoMilliseconds(24)); List<ResourceInstance> riList = ResourcePool.getInstance().getResourceInstances(r) ; long nextAvailable = riList.get(0).getPlanning().getNextPlanningAvailable(cal.getTimeInMillis()); assertTrue( riList.get(0).getPlanning().isPlanningAvailable(nextAvailable)) ; cal.setTimeInMillis(nextAvailable) ; assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 8); cal.setTimeInMillis(nextAvailable+51000); nextAvailable = riList.get(0).getPlanning().getNextPlanningAvailable(cal.getTimeInMillis()); assertTrue( riList.get(0).getPlanning().isPlanningAvailable(nextAvailable)) ; assertEquals(cal.getTimeInMillis(),nextAvailable); cal.set(2010, 1, 1, 13,10); nextAvailable = riList.get(0).getPlanning().getNextPlanningAvailable(cal.getTimeInMillis()); cal.setTimeInMillis(nextAvailable) ; assertTrue( riList.get(0).getPlanning().isPlanningAvailable(nextAvailable)) ; assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 13 && cal.get(Calendar.MINUTE) == 30); cal.set(2010, 1, 1, 20,0); nextAvailable = riList.get(0).getPlanning().getNextPlanningAvailable(cal.getTimeInMillis()); cal.setTimeInMillis(nextAvailable) ; assertTrue( riList.get(0).getPlanning().isPlanningAvailable(nextAvailable)) ; assertTrue(cal.get(Calendar.DAY_OF_WEEK) == 3 && cal.get(Calendar.HOUR_OF_DAY) == 8); } public void testNextPlanningUnavailableDate() throws Exception{ List<Resource> ressources = SimulationTestUtil.createResources() ; Resource r = ressources.get(0) ; Calendar cal = GregorianCalendar.getInstance(); cal.set(2010, 1, 1, 7,0); ResourcePool.getInstance().addResource(null,r,cal.getTimeInMillis(),SimulationTestUtil.getHoursIntoMilliseconds(24)); List<ResourceInstance> riList = ResourcePool.getInstance().getResourceInstances(r) ; long nextUnAvailable = riList.get(0).getPlanning().getNextPlanningUnavailable(cal.getTimeInMillis()); assertFalse( riList.get(0).getPlanning().isPlanningAvailable(nextUnAvailable)) ; cal.setTimeInMillis(nextUnAvailable); assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 7); cal.add(Calendar.HOUR_OF_DAY, 2); nextUnAvailable = riList.get(0).getPlanning().getNextPlanningUnavailable(cal.getTimeInMillis()); assertFalse( riList.get(0).getPlanning().isPlanningAvailable(nextUnAvailable)) ; cal.setTimeInMillis(nextUnAvailable); assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 12); SimCalendar calendar = new SimCalendar(); Set<SimCalendarPeriod> workingDay = new HashSet<SimCalendarPeriod>() ; SimCalendarPeriod allDay = new SimCalendarPeriod(new SimCalendarTime(0,0),new SimCalendarTime(0,0)); workingDay.add(allDay) ; calendar.addSimCalendarDay(Calendar.MONDAY, workingDay); calendar.addSimCalendarDay(Calendar.TUESDAY, workingDay); calendar.addSimCalendarDay(Calendar.WEDNESDAY, workingDay); calendar.addSimCalendarDay(Calendar.THURSDAY, workingDay); calendar.addSimCalendarDay(Calendar.FRIDAY, workingDay); calendar.addSimCalendarDay(Calendar.SATURDAY, workingDay); calendar.addSimCalendarDay(Calendar.SUNDAY, workingDay); Resource res = new Resource("name", "type", 1,1, calendar,"kudos", TimeUnit.DAY,0.0,0.0); assertTrue(res.getPlanning().getNextPlanningAvailable(cal.getTimeInMillis()) == cal.getTimeInMillis()) ; assertTrue(res.getPlanning().getNextPlanningUnavailable(cal.getTimeInMillis()) == -1); calendar = new SimCalendar(); Set<SimCalendarPeriod> workingDay2 = new HashSet<SimCalendarPeriod>() ; SimCalendarPeriod notAllDay = new SimCalendarPeriod(new SimCalendarTime(0,0),new SimCalendarTime(2,0)); workingDay2.add(notAllDay) ; calendar.addSimCalendarDay(Calendar.MONDAY, workingDay); calendar.addSimCalendarDay(Calendar.TUESDAY, workingDay2); calendar.addSimCalendarDay(Calendar.WEDNESDAY, workingDay); calendar.addSimCalendarDay(Calendar.THURSDAY, workingDay2); calendar.addSimCalendarDay(Calendar.FRIDAY, workingDay); calendar.addSimCalendarDay(Calendar.SATURDAY, workingDay2); calendar.addSimCalendarDay(Calendar.SUNDAY, workingDay); res = new Resource("name", "type", 1,1, calendar,"kudos", TimeUnit.DAY,0.0,0.0); cal.set(2010, 6, 26, 15, 0) ; assertTrue(cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) ; assertTrue(res.getPlanning().getNextPlanningAvailable(cal.getTimeInMillis()) == cal.getTimeInMillis()) ; System.out.println(new Date(cal.getTimeInMillis())); cal.setTimeInMillis(res.getPlanning().getNextPlanningUnavailable(cal.getTimeInMillis())); System.out.println(new Date(cal.getTimeInMillis())); assertTrue(cal.get(Calendar.HOUR_OF_DAY) == 2); } public void testSimCalendarPeriod() throws Exception{ SimCalendarPeriod p = new SimCalendarPeriod(new SimCalendarTime(0, 0), new SimCalendarTime(0, 0)) ; assertTrue(p.contains(new Date().getTime())); } public void testContigousGetFirstAvailableDate() throws Exception{ List<Resource> ressources = SimulationTestUtil.createResources() ; Resource r = ressources.get(0) ; Calendar myInstance = GregorianCalendar.getInstance() ; myInstance.set(2010, 6, 2, 11,0); myInstance.set(Calendar.MILLISECOND, 0); myInstance.set(Calendar.SECOND, 0); long start = myInstance.getTimeInMillis() ; ResourcePool.getInstance().addResource(null,r,start,SimulationTestUtil.getHoursIntoMilliseconds(24)); myInstance.add(Calendar.HOUR, 4) ; long end = myInstance.getTimeInMillis() ; Period p = new Period(start, end) ; myInstance.add(Calendar.HOUR, -1) ; long wStart = myInstance.getTimeInMillis() ; myInstance.add(Calendar.HOUR, 3) ; long wEnd = myInstance.getTimeInMillis() ; List<ResourceInstance> riList = ResourcePool.getInstance().getResourceInstances(r) ; Period wp = new Period(wStart,wEnd); riList.get(0).getPlanning().addBusyPeriod(wp,false); long startDate = riList.get(0).getPlanning().getFirstAvailableDate(start, p.getDuration(), true); assertTrue(riList.get(0).getPlanning().isPlanningAvailable(new Period(startDate,startDate + p.getDuration()))); startDate = riList.get(0).getPlanning().getNextPlanningUnavailable(startDate) ; assertTrue(riList.get(0).getPlanning().isPlanningAvailable(riList.get(0).getPlanning().getFirstAvailableDate(startDate,10,true))) ; } }