package org.dcache.services.info.secondaryInfoProviders; import org.junit.Before; import org.junit.Test; import java.util.HashSet; import java.util.Set; import org.dcache.services.info.base.IntegerStateValue; import org.dcache.services.info.base.MalleableStateTransition; import org.dcache.services.info.base.PostTransitionStateExhibitor; import org.dcache.services.info.base.QueuingStateUpdateManager; import org.dcache.services.info.base.StateComposite; import org.dcache.services.info.base.StateExhibitor; import org.dcache.services.info.base.StatePath; import org.dcache.services.info.base.StateUpdate; import org.dcache.services.info.base.StateWatcher; import org.dcache.services.info.base.StringStateValue; import org.dcache.services.info.base.TestStateExhibitor; import org.dcache.services.info.stateInfo.ReservationInfo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class ReservationByDescMaintainerTests { static final StatePath SUMMARY_RESERVATIONS_BY_VO = StatePath.parsePath( "summary.reservations.by-VO"); StateWatcher _watcher; QueuingStateUpdateManager _sum; TestStateExhibitor _exhibitor; StateUpdate _update; MalleableStateTransition _transition; @Before public void setUp() { _exhibitor = new TestStateExhibitor(); _watcher = new ReservationByDescMaintainer(); _sum = new QueuingStateUpdateManager(); _update = new StateUpdate(); _transition = new MalleableStateTransition(); } /** * State is empty. We add a reservation. */ @Test public void testEmptyNewReservationId() { String id = "id"; StateLocation.transitionAddsReservation( _transition, id, 0); triggerWatcher(); assertEquals( "Check number of purges", 0, _update.countPurges()); assertEquals( "Check number of updates", 0, _update.count()); } /** * State is empty. We add a complete reservation. */ @Test public void testEmptyNewReservation() { String id = "id"; String vo = "atlas"; String group = "/" + vo; String role = ""; String FQAN = group; String description = "MCDISK"; long total = 10; long used = 2; long allocated = 1; long free = 7; StateLocation.transitionAddsReservation( _transition, id, 0); StateLocation.transitionAddsReservationDescription( _transition, 2, id, description); StateLocation.transitionAddsReservationAuth( _transition, 2, id, FQAN, group, role); StateLocation.transitionAddsReservationSpace( _transition, 2, id, total, used, allocated, free); StateLocation.transitionAddsReservationState( _transition, 2, id, ReservationInfo.State.RESERVED); triggerWatcher(); assertEquals( "Check number of purges", 0, _update.countPurges()); StatePath expectedSummary = SUMMARY_RESERVATIONS_BY_VO.newChild( vo).newChild( "by-description").newChild( description); assertStringMetric( "vo metric", expectedSummary.newChild("vo"), vo); StatePath expectedSummarySpace = expectedSummary.newChild( "space"); assertIntegerMetric( "total metric", expectedSummarySpace.newChild("total"), total); assertIntegerMetric( "used metric", expectedSummarySpace.newChild("used"), used); assertIntegerMetric( "free metric", expectedSummarySpace.newChild("free"), free); assertIntegerMetric( "allocated metric", expectedSummarySpace.newChild("allocated"), allocated); Set<String> ids = new HashSet<>(); ids.add( id); assertList( "reservations list", expectedSummary.newChild( "reservations"), ids); } @Test public void testReservationTransitionUpdatesVo() { String id = "id"; String oldVo = "atlas"; String oldGroup = "/" + oldVo; String oldRole = ""; String oldFQAN = oldGroup; String description = "SCRATCH"; long total = 10; long used = 2; long allocated = 1; long free = 7; StateLocation.putReservationAuth( _exhibitor, id, oldFQAN, oldGroup, oldRole); StateLocation.putReservationDescription( _exhibitor, id, description); StateLocation.putReservationSpace( _exhibitor, id, total, used, allocated, free); StateLocation.putReservationState( _exhibitor, id, ReservationInfo.State.RESERVED); String newVo = "cms"; String newGroup = "/" + newVo; String newFQAN = newGroup; String newRole = ""; StateLocation.transitionAddsReservationAuth( _transition, 4, id, newFQAN, newGroup, newRole); triggerWatcher(); // SIP should purge the old atlas information assertEquals( "Check number of purges", 1, _update.countPurges()); // Check that new summary is created with the new VO. StatePath expectedSummaryBase = SUMMARY_RESERVATIONS_BY_VO.newChild( newVo).newChild( "by-description").newChild( description); assertStringMetric( "checking new vo summary", expectedSummaryBase.newChild( "vo"), newVo); StatePath expectedSummarySpace = expectedSummaryBase.newChild( "space"); assertIntegerMetric( "checking total", expectedSummarySpace.newChild( "total"), total); assertIntegerMetric( "checking used", expectedSummarySpace.newChild( "used"), used); assertIntegerMetric( "checking allocated", expectedSummarySpace.newChild( "allocated"), allocated); assertIntegerMetric( "checking free", expectedSummarySpace.newChild( "free"), free); } @Test public void testReservationTransitionUpdatesSpaceMetric() { String id = "id"; String vo = "atlas"; String group = "/" + vo; String role = ""; String FQAN = group; String description = "SCRATCH"; long oldTotal = 10; long newTotal = 20; long used = 2; long allocated = 1; long free = 7; StateLocation.putReservationAuth( _exhibitor, id, FQAN, group, role); StateLocation.putReservationDescription( _exhibitor, id, description); StateLocation.putReservationSpace( _exhibitor, id, oldTotal, used, allocated, free); StateLocation.putReservationState( _exhibitor, id, ReservationInfo.State.RESERVED); StateLocation.transitionAddsReservationSpaceTotal( _transition, 4, id, newTotal); triggerWatcher(); assertEquals( "Check number of purges", 0, _update.countPurges()); StatePath expectedSummarySpace = SUMMARY_RESERVATIONS_BY_VO.newChild( vo).newChild( "by-description").newChild( description).newChild( "space"); assertIntegerMetric( "total metric", expectedSummarySpace.newChild("total"), newTotal); } @Test public void testReservationTransitionAddsReservationWithSameDescription() { /* Common info */ String resvDesc = "MCDISK"; String vo = "atlas"; String group = "/" + vo; String role = ""; String FQAN = group; String resv1Id = "id-1"; int resv1Total = 10; int resv1Used = 1; int resv1Allocated = 1; int resv1Free = 8; String resv2Id = "id-2"; int resv2Total = 20; int resv2Used = 2; int resv2Allocated = 3; int resv2Free = 15; StateLocation.putReservationDescription( _exhibitor, resv1Id, resvDesc); StateLocation.putReservationAuth( _exhibitor, resv1Id, FQAN, group, role); StateLocation.putReservationSpace( _exhibitor, resv1Id, resv1Total, resv1Used, resv1Allocated, resv1Free); StateLocation.putReservationState( _exhibitor, resv1Id, ReservationInfo.State.RESERVED); StateLocation.transitionAddsReservation( _transition, resv2Id, 1); StateLocation.transitionAddsReservationDescription( _transition, 2, resv2Id, resvDesc); StateLocation.transitionAddsReservationAuth( _transition, 2, resv2Id, FQAN, group, role); StateLocation.transitionAddsReservationSpace( _transition, 2, resv2Id, resv2Total, resv2Used, resv2Allocated, resv2Free); StateLocation.transitionAddsReservationState( _transition, 2, resv2Id, ReservationInfo.State.RESERVED); triggerWatcher(); assertEquals( "Check number of purges", 0, _update.countPurges()); StatePath expectedSummary = SUMMARY_RESERVATIONS_BY_VO.newChild( vo).newChild( "by-description").newChild( resvDesc); StatePath expectedSummarySpace = expectedSummary.newChild( "space"); assertIntegerMetric( "total metric", expectedSummarySpace.newChild("total"), resv1Total + resv2Total); assertIntegerMetric( "used metric", expectedSummarySpace.newChild("used"), resv1Used + resv2Used); assertIntegerMetric( "free metric", expectedSummarySpace.newChild("free"), resv1Free + resv2Free); assertIntegerMetric( "allocated metric", expectedSummarySpace.newChild("allocated"), resv1Allocated + resv2Allocated); Set<String> ids = new HashSet<>(); ids.add( resv2Id); assertList( "reservations list", expectedSummary.newChild( "reservations"), ids); } @Test public void testReservationTransitionAddsReservationWithDifferentDescription() { /* Common info */ String vo = "atlas"; String group = "/" + vo; String role = ""; String FQAN = group; String resv1Desc = "MCDISK"; String resv1Id = "id-1"; int resv1Total = 10; int resv1Used = 1; int resv1Allocated = 1; int resv1Free = 8; String resv2Desc = "SCRATCH"; String resv2Id = "id-2"; int resv2Total = 20; int resv2Used = 2; int resv2Allocated = 3; int resv2Free = 15; StateLocation.putReservationDescription( _exhibitor, resv1Id, resv1Desc); StateLocation.putReservationAuth( _exhibitor, resv1Id, FQAN, group, role); StateLocation.putReservationSpace( _exhibitor, resv1Id, resv1Total, resv1Used, resv1Allocated, resv1Free); StateLocation.putReservationState( _exhibitor, resv1Id, ReservationInfo.State.RESERVED); StateLocation.transitionAddsReservation( _transition, resv2Id, 1); StateLocation.transitionAddsReservationDescription( _transition, 2, resv2Id, resv2Desc); StateLocation.transitionAddsReservationAuth( _transition, 2, resv2Id, FQAN, group, role); StateLocation.transitionAddsReservationSpace( _transition, 2, resv2Id, resv2Total, resv2Used, resv2Allocated, resv2Free); StateLocation.transitionAddsReservationState( _transition, 2, resv2Id, ReservationInfo.State.RESERVED); triggerWatcher(); assertEquals( "Check number of purges", 0, _update.countPurges()); StatePath expectedSummary = SUMMARY_RESERVATIONS_BY_VO.newChild( vo).newChild( "by-description").newChild( resv2Desc); StatePath expectedSummarySpace = expectedSummary.newChild( "space"); assertIntegerMetric( "total metric", expectedSummarySpace.newChild("total"), resv2Total); assertIntegerMetric( "used metric", expectedSummarySpace.newChild("used"), resv2Used); assertIntegerMetric( "free metric", expectedSummarySpace.newChild("free"), resv2Free); assertIntegerMetric( "allocated metric", expectedSummarySpace.newChild("allocated"), resv2Allocated); Set<String> ids = new HashSet<>(); ids.add( resv2Id); assertList( "reservations list", expectedSummary.newChild( "reservations"), ids); } @Test public void testReservationTransitionAddsReservationWithSameDescriptionDifferentVO() { /* Common info */ String resvDesc = "MCDISK"; String role = ""; String resv1Id = "id-1"; String resv1Vo = "atlas"; String resv1Group = "/" + resv1Vo; String resv1FQAN = resv1Group; int resv1Total = 10; int resv1Used = 1; int resv1Allocated = 1; int resv1Free = 8; String resv2Id = "id-2"; String resv2Vo = "cms"; String resv2Group = "/" + resv2Vo; String resv2FQAN = resv2Group; int resv2Total = 20; int resv2Used = 2; int resv2Allocated = 3; int resv2Free = 15; StateLocation.putReservationDescription( _exhibitor, resv1Id, resvDesc); StateLocation.putReservationAuth( _exhibitor, resv1Id, resv1FQAN, resv1Group, role); StateLocation.putReservationSpace( _exhibitor, resv1Id, resv1Total, resv1Used, resv1Allocated, resv1Free); StateLocation.putReservationState( _exhibitor, resv1Id, ReservationInfo.State.RESERVED); StateLocation.transitionAddsReservation( _transition, resv2Id, 1); StateLocation.transitionAddsReservationDescription( _transition, 2, resv2Id, resvDesc); StateLocation.transitionAddsReservationAuth( _transition, 2, resv2Id, resv2FQAN, resv2Group, role); StateLocation.transitionAddsReservationSpace( _transition, 2, resv2Id, resv2Total, resv2Used, resv2Allocated, resv2Free); StateLocation.transitionAddsReservationState( _transition, 2, resv2Id, ReservationInfo.State.RESERVED); triggerWatcher(); assertEquals( "Check number of purges", 0, _update.countPurges()); StatePath expectedSummary = SUMMARY_RESERVATIONS_BY_VO.newChild( resv2Vo).newChild( "by-description").newChild( resvDesc); StatePath expectedSummarySpace = expectedSummary.newChild( "space"); assertIntegerMetric( "total metric", expectedSummarySpace.newChild("total"), resv2Total); assertIntegerMetric( "used metric", expectedSummarySpace.newChild("used"), resv2Used); assertIntegerMetric( "free metric", expectedSummarySpace.newChild("free"), resv2Free); assertIntegerMetric( "allocated metric", expectedSummarySpace.newChild("allocated"), resv2Allocated); Set<String> ids = new HashSet<>(); ids.add( resv2Id); assertList( "reservations list", expectedSummary.newChild( "reservations"), ids); } @Test public void testTwoReservationsSameVoTransitionRemovesReservation() { /* Common info */ String role = ""; String vo = "atlas"; String group = "/" + vo; String FQAN = group; String resv1Desc = "MCDISK"; String resv1Id = "id-1"; int resv1Total = 10; int resv1Used = 1; int resv1Allocated = 1; int resv1Free = 8; String resv2Desc = "SCRATCH"; String resv2Id = "id-2"; int resv2Total = 20; int resv2Used = 2; int resv2Allocated = 3; int resv2Free = 15; StateLocation.putReservationDescription( _exhibitor, resv1Id, resv1Desc); StateLocation.putReservationAuth( _exhibitor, resv1Id, FQAN, group, role); StateLocation.putReservationSpace( _exhibitor, resv1Id, resv1Total, resv1Used, resv1Allocated, resv1Free); StateLocation.putReservationState( _exhibitor, resv1Id, ReservationInfo.State.RESERVED); StateLocation.putReservationDescription( _exhibitor, resv2Id, resv2Desc); StateLocation.putReservationAuth( _exhibitor, resv2Id, FQAN, group, role); StateLocation.putReservationSpace( _exhibitor, resv2Id, resv2Total, resv2Used, resv2Allocated, resv2Free); StateLocation.putReservationState( _exhibitor, resv2Id, ReservationInfo.State.RESERVED); StateLocation.transitionRemovesReservation( _transition, resv2Id); triggerWatcher(); StatePath expectedSummary = SUMMARY_RESERVATIONS_BY_VO.newChild( vo); assertPurge( "check all of reservation-2 is removed", expectedSummary.newChild( "by-description").newChild( resv2Desc)); } @Test public void testTwoReservationsSameVoAndDescriptionTransitionRemovesReservation() { /* Common info */ String resvDesc = "MCDISK"; String role = ""; String vo = "atlas"; String group = "/" + vo; String FQAN = group; String resv1Id = "id-1"; int resv1Total = 10; int resv1Used = 1; int resv1Allocated = 1; int resv1Free = 8; String resv2Id = "id-2"; int resv2Total = 20; int resv2Used = 2; int resv2Allocated = 3; int resv2Free = 15; StateLocation.putReservationDescription( _exhibitor, resv1Id, resvDesc); StateLocation.putReservationAuth( _exhibitor, resv1Id, FQAN, group, role); StateLocation.putReservationSpace( _exhibitor, resv1Id, resv1Total, resv1Used, resv1Allocated, resv1Free); StateLocation.putReservationState( _exhibitor, resv1Id, ReservationInfo.State.RESERVED); StateLocation.putReservationDescription( _exhibitor, resv2Id, resvDesc); StateLocation.putReservationAuth( _exhibitor, resv2Id, FQAN, group, role); StateLocation.putReservationSpace( _exhibitor, resv2Id, resv2Total, resv2Used, resv2Allocated, resv2Free); StateLocation.putReservationState( _exhibitor, resv2Id, ReservationInfo.State.RESERVED); StateLocation.transitionRemovesReservation( _transition, resv2Id); triggerWatcher(); StatePath expectedSummary = SUMMARY_RESERVATIONS_BY_VO.newChild( vo).newChild( "by-description").newChild( resvDesc); StatePath expectedReservations = expectedSummary.newChild( "reservations"); assertPurge( "check reservation 2 is removed", expectedReservations.newChild( resv2Id)); /* Should update to reflect new space info */ StatePath expectedSummarySpace = expectedSummary.newChild( "space"); assertIntegerMetric( "total metric", expectedSummarySpace.newChild("total"), resv1Total); assertIntegerMetric( "used metric", expectedSummarySpace.newChild("used"), resv1Used); assertIntegerMetric( "free metric", expectedSummarySpace.newChild("free"), resv1Free); assertIntegerMetric( "allocated metric", expectedSummarySpace.newChild("allocated"), resv1Allocated); } @Test public void testTwoReservationsTransitionRemovesReservation() { /* Common info */ String role = ""; String resv1Desc = "MCDISK"; String resv1Id = "id-1"; String resv1Vo = "atlas"; String resv1Group = "/" + resv1Vo; String resv1FQAN = resv1Group; int resv1Total = 10; int resv1Used = 1; int resv1Allocated = 1; int resv1Free = 8; String resv2Desc = "SCRATCH"; String resv2Id = "id-2"; String resv2Vo = "cms"; String resv2Group = "/" + resv2Vo; String resv2FQAN = resv2Group; int resv2Total = 20; int resv2Used = 2; int resv2Allocated = 3; int resv2Free = 15; StateLocation.putReservationDescription( _exhibitor, resv1Id, resv1Desc); StateLocation.putReservationAuth( _exhibitor, resv1Id, resv1FQAN, resv1Group, role); StateLocation.putReservationSpace( _exhibitor, resv1Id, resv1Total, resv1Used, resv1Allocated, resv1Free); StateLocation.putReservationState( _exhibitor, resv1Id, ReservationInfo.State.RESERVED); StateLocation.putReservationDescription( _exhibitor, resv2Id, resv2Desc); StateLocation.putReservationAuth( _exhibitor, resv2Id, resv2FQAN, resv2Group, role); StateLocation.putReservationSpace( _exhibitor, resv2Id, resv2Total, resv2Used, resv2Allocated, resv2Free); StateLocation.putReservationState( _exhibitor, resv2Id, ReservationInfo.State.RESERVED); StateLocation.transitionRemovesReservation( _transition, resv2Id); triggerWatcher(); StatePath vo2BasePath = SUMMARY_RESERVATIONS_BY_VO.newChild( resv2Vo); assertPurge( "check all of VO-2 is removed", vo2BasePath); } private void assertStringMetric( String msg, StatePath path, String value) { assertTrue( msg, _update.hasUpdate( path, new StringStateValue(value))); } private void assertIntegerMetric( String msg, StatePath path, long value) { assertTrue( msg, _update.hasUpdate( path, new IntegerStateValue( value))); } private void assertList( String msg, StatePath path, Set<String> items) { for( String item : items) { assertTrue(msg, _update .hasUpdate(path.newChild(item), new StateComposite(true))); } } private void assertPurge( String msg, StatePath path) { assertTrue( msg + " [" + path.toString() + "]", _update.hasPurge( path)); } private void triggerWatcher() { StateExhibitor futureState = new PostTransitionStateExhibitor( _exhibitor, _transition); _watcher.trigger( _update, _exhibitor, futureState); } }