package org.dcache.services.info.base;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
/**
* This class provides a set of tests to check the behaviour of
* {@link TestStateExhibitor}. Some of the tests involve the
* {@link MalleableStateTransition} which, in turn, is tested using a
* TestStateExhibitor, so not all tests are completely independent.
*/
public class TestStateExhibitorTests {
TestStateExhibitor _exhibitor;
static final StatePath METRIC_PATH =
StatePath.parsePath( "aa.bb.metric value");
@Before
public void setUp()
{
_exhibitor = new TestStateExhibitor();
}
@Test
public void testEmptyExhibitor() {
VerifyingVisitor visitor = new VerifyingVisitor();
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testSingleStringMetricExhibitor() {
assertSingleMetricOk( new StringStateValue( "a typical string value"));
}
@Test
public void testSingleIntegerMetricExhibitor() {
assertSingleMetricOk( new IntegerStateValue( 42));
}
@Test
public void testSingleFloatingPointMetricExhibitor() {
assertSingleMetricOk( new FloatingPointStateValue( 42.3));
}
@Test
public void testSingleBooleanMetricExhibitor() {
assertSingleMetricOk( new BooleanStateValue( true));
}
@Test
public void testMultipleSiblingMetricExhibitor() {
VerifyingVisitor visitor = new VerifyingVisitor();
StatePath metricBranch = StatePath.parsePath( "aa.bb");
StatePath metricPath1 = metricBranch.newChild( "metric 1");
StatePath metricPath2 = metricBranch.newChild( "metric 2");
StateValue metricValue1 =
new StringStateValue( "a typical string value");
StateValue metricValue2 = new IntegerStateValue( 42);
_exhibitor.addMetric( metricPath1, metricValue1);
_exhibitor.addMetric( metricPath2, metricValue2);
visitor.addExpectedMetric( metricPath1, metricValue1);
visitor.addExpectedMetric( metricPath2, metricValue2);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testSingleBranch() {
StatePath branchPath = StatePath.parsePath( "aa.bb.cc");
_exhibitor.addBranch( branchPath);
VerifyingVisitor visitor = new VerifyingVisitor();
visitor.addExpectedBranch( branchPath);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testTwoSiblingBranches() {
StatePath branchPath1 = StatePath.parsePath( "aa.bb.cc.branch1");
StatePath branchPath2 = StatePath.parsePath( "aa.bb.cc.branch2");
_exhibitor.addBranch( branchPath1);
_exhibitor.addBranch( branchPath2);
VerifyingVisitor visitor = new VerifyingVisitor();
visitor.addExpectedBranch( branchPath1);
visitor.addExpectedBranch( branchPath2);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testThreeSiblingBranches() {
StatePath branchPath1 = StatePath.parsePath( "aa.bb.cc.branch1");
StatePath branchPath2 = StatePath.parsePath( "aa.bb.cc.branch2");
StatePath branchPath3 = StatePath.parsePath( "aa.bb.cc.branch3");
_exhibitor.addBranch( branchPath1);
_exhibitor.addBranch( branchPath2);
_exhibitor.addBranch( branchPath3);
VerifyingVisitor visitor = new VerifyingVisitor();
visitor.addExpectedBranch( branchPath1);
visitor.addExpectedBranch( branchPath2);
visitor.addExpectedBranch( branchPath3);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testFourSiblingBranches() {
StatePath branchPath1 = StatePath.parsePath( "aa.bb.cc.branch1");
StatePath branchPath2 = StatePath.parsePath( "aa.bb.cc.branch2");
StatePath branchPath3 = StatePath.parsePath( "aa.bb.cc.branch3");
StatePath branchPath4 = StatePath.parsePath( "aa.bb.cc.branch4");
_exhibitor.addBranch( branchPath1);
_exhibitor.addBranch( branchPath2);
_exhibitor.addBranch( branchPath3);
_exhibitor.addBranch( branchPath4);
VerifyingVisitor visitor = new VerifyingVisitor();
visitor.addExpectedBranch( branchPath1);
visitor.addExpectedBranch( branchPath2);
visitor.addExpectedBranch( branchPath3);
visitor.addExpectedBranch( branchPath4);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testFourSiblingBranchesWithSubbranches() {
StatePath branchPath1 = StatePath.parsePath( "aa.bb.cc.branch1");
StatePath branchPath2a = StatePath.parsePath( "aa.bb.cc.branch2.a");
StatePath branchPath2b = StatePath.parsePath( "aa.bb.cc.branch2.b");
StatePath branchPath3 = StatePath.parsePath( "aa.bb.cc.branch3");
StatePath branchPath3a = StatePath.parsePath( "aa.bb.cc.branch3.a");
StatePath branchPath3b = StatePath.parsePath( "aa.bb.cc.branch3.b");
StatePath branchPath3c = StatePath.parsePath( "aa.bb.cc.branch3.c");
StatePath branchPath4 = StatePath.parsePath( "aa.bb.cc.branch4");
_exhibitor.addBranch( branchPath1);
_exhibitor.addBranch( branchPath2a);
_exhibitor.addBranch( branchPath2b);
_exhibitor.addBranch( branchPath3);
_exhibitor.addBranch( branchPath3a);
_exhibitor.addBranch( branchPath3b);
_exhibitor.addBranch( branchPath3c);
_exhibitor.addBranch( branchPath4);
VerifyingVisitor visitor = new VerifyingVisitor();
visitor.addExpectedBranch( branchPath1);
visitor.addExpectedBranch( branchPath2a);
visitor.addExpectedBranch( branchPath2b);
visitor.addExpectedBranch( branchPath3);
visitor.addExpectedBranch( branchPath3a);
visitor.addExpectedBranch( branchPath3b);
visitor.addExpectedBranch( branchPath3c);
visitor.addExpectedBranch( branchPath4);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testRealisticExample() {
StatePath link1Pool1 = StatePath.parsePath( "links.link-1.pools.pool1");
StatePath link1Pool2 = StatePath.parsePath( "links.link-1.pools.pool2");
StatePath link1ReadPrefPath =
StatePath.parsePath( "links.link-1.prefs.read");
StateValue link1ReadPrefMetric = new IntegerStateValue( 5);
StatePath link1WritePrefPath =
StatePath.parsePath( "links.link-1.prefs.write");
StateValue link1WritePrefMetric = new IntegerStateValue( 7);
StatePath link1P2pPrefPath =
StatePath.parsePath( "links.link-1.prefs.p2p");
StateValue link1P2pPrefMetric = new IntegerStateValue( 11);
StatePath link1CachePrefPath =
StatePath.parsePath( "links.link-1.prefs.cache");
StateValue link1CachePrefMetric = new IntegerStateValue( 13);
_exhibitor.addBranch( link1Pool1);
_exhibitor.addBranch( link1Pool2);
_exhibitor.addMetric( link1ReadPrefPath, link1ReadPrefMetric);
_exhibitor.addMetric( link1WritePrefPath, link1WritePrefMetric);
_exhibitor.addMetric( link1P2pPrefPath, link1P2pPrefMetric);
_exhibitor.addMetric( link1CachePrefPath, link1CachePrefMetric);
VerifyingVisitor visitor = new VerifyingVisitor();
visitor.addExpectedBranch( link1Pool1);
visitor.addExpectedBranch( link1Pool2);
visitor.addExpectedMetric( link1ReadPrefPath, link1ReadPrefMetric);
visitor.addExpectedMetric( link1WritePrefPath, link1WritePrefMetric);
visitor.addExpectedMetric( link1P2pPrefPath, link1P2pPrefMetric);
visitor.addExpectedMetric( link1CachePrefPath, link1CachePrefMetric);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
@Test
public void testListItemExhibitor() {
StatePath path = StatePath.parsePath( "SimpleWidget");
String type = "widget";
String idName = "id";
_exhibitor.addListItem( path, type, idName);
AssertableMetadataCapturingVisitor visitor =
new AssertableMetadataCapturingVisitor();
_exhibitor.visitState( visitor);
visitor.assertListMetadata( path, type, idName);
}
@Test
public void testTwoListItemExhibitor() {
StatePath path1 = StatePath.parsePath( "SimpleWidget");
String type1 = "widget";
String idName1 = "id";
StatePath path2 = StatePath.parsePath( "bobble");
String type2 = "bibble";
String idName2 = "name";
_exhibitor.addListItem( path1, type1, idName1);
_exhibitor.addListItem( path2, type2, idName2);
AssertableMetadataCapturingVisitor visitor =
new AssertableMetadataCapturingVisitor();
_exhibitor.visitState( visitor);
visitor.assertListMetadata( path1, type1, idName1);
visitor.assertListMetadata( path2, type2, idName2);
}
@Test
public void testSingleDepthSingleListItemExhibitor() {
StatePath path = StatePath.parsePath( "widgets.SimpleWidget");
String type = "widget";
String idName = "id";
_exhibitor.addListItem( path, type, idName);
AssertableMetadataCapturingVisitor visitor =
new AssertableMetadataCapturingVisitor();
_exhibitor.visitState( visitor);
visitor.assertListMetadata( path, type, idName);
}
@Test
public void testSingleDepthTwoListItemsExhibitor() {
StatePath path1 = StatePath.parsePath( "widgets.SimpleWidget");
StatePath path2 = StatePath.parsePath( "widgets.ComplexWidget");
String type = "widget";
String idName = "id";
_exhibitor.addListItem( path1, type, idName);
_exhibitor.addListItem( path2, type, idName);
AssertableMetadataCapturingVisitor visitor =
new AssertableMetadataCapturingVisitor();
_exhibitor.visitState( visitor);
visitor.assertListMetadata( path1, type, idName);
visitor.assertListMetadata( path2, type, idName);
}
@Test
public void testTwoDeepSingleListItemExhibitor() {
StatePath path =
StatePath.parsePath( "widgets.boringWidgets.SimpleWidget");
String type = "widget";
String idName = "id";
_exhibitor.addListItem( path, type, idName);
AssertableMetadataCapturingVisitor visitor =
new AssertableMetadataCapturingVisitor();
_exhibitor.visitState( visitor);
visitor.assertListMetadata( path, type, idName);
}
/*
* TESTS INVOLVING SKIPPING
*/
@Test
public void testSingleMetricSkipNull() {
StatePath metricPath = StatePath.parsePath( "aa.bb.metric");
StateValue metricValue = new StringStateValue( "some string");
_exhibitor.addMetric( metricPath, metricValue);
VerifyingVisitor visitor = new VerifyingVisitor();
visitor.addExpectedMetric( metricPath, metricValue);
_exhibitor.visitState( visitor);
assertTrue( "visitor is satisfied", visitor.satisfied());
}
/*
* PRIVATE SUPPORT METHODS.
*/
/**
* Add a single metric to the {@link TestStateExhibitor} and configure
* the {@link VerifyingVisitor} so it expects this metric at the same
* location.
*/
private void addSingleMetricAndUpdateVisitor( VerifyingVisitor visitor,
StateValue metricValue) {
_exhibitor.addMetric( METRIC_PATH, metricValue);
visitor.addExpectedMetric( METRIC_PATH, metricValue);
}
/**
* Add a single metric to an empty {@link TestStateExhibitor}. An empty
* {@link VerifyingVisitor} is created and told to expect a metric at the
* same location. The state is visited using
* {@link TestStateExhibitor#visitState(StateVisitor)} and the
* VerifyingVisitor is checked to see whether it is satisfied with the
* result.
*
* @param metricValue the metric value to check.
* @param useClone if true then visitClonedState() is used instead of
* visitState()
*/
private void assertSingleMetricOk( StateValue metricValue) {
VerifyingVisitor visitor = new VerifyingVisitor();
addSingleMetricAndUpdateVisitor( visitor, metricValue);
_exhibitor.visitState( visitor);
assertTrue( "VerifyingVisitor is satisfied", visitor.satisfied());
}
/**
* Visitor that visits all the state, collects metadata and allows
* list-assertions to be made about collected data.
*/
private static class AssertableMetadataCapturingVisitor implements
StateVisitor {
private static final StatePath ROOT_PATH = null;
Map<StatePath, Map<String, String>> _collectedMetadata =
new HashMap<>();
private Map<String, String> getMetadataForPath( StatePath path) {
return _collectedMetadata.get( path);
}
private void assertListItemMetadata( StatePath path,
String expectedType,
String expectedIdName) {
Map<String, String> pathMetadata = getMetadataForPath( path);
String discoveredType =
pathMetadata.get( State.METADATA_BRANCH_CLASS_KEY);
String discoveredIdName =
pathMetadata.get( State.METADATA_BRANCH_IDNAME_KEY);
assertEquals( "class mismatch: " + path, expectedType,
discoveredType);
assertEquals( "idName mismatch: " + path, expectedIdName,
discoveredIdName);
}
private void assertBranchHasNoMetadata( StatePath path) {
Map<String, String> pathMetadata = getMetadataForPath( path);
String pathLabel = path != ROOT_PATH ? path.toString() : "(root)";
assertNull( "checking branch has no metadata: " + pathLabel,
pathMetadata);
}
private void assertBranchAndParentsHaveNoMetadata( final StatePath path) {
StatePath currentPath = path;
while (!currentPath.isSimplePath()) {
assertBranchHasNoMetadata( currentPath);
currentPath = currentPath.parentPath();
}
assertBranchHasNoMetadata( currentPath);
}
private void assertParentBranchesHaveNoMetadata( StatePath listItemPath) {
if( !listItemPath.isSimplePath()) {
StatePath parentPath = listItemPath.parentPath();
assertBranchAndParentsHaveNoMetadata( parentPath);
}
assertBranchHasNoMetadata( ROOT_PATH);
}
public void assertListMetadata( StatePath path, String type,
String idName) {
assertListItemMetadata( path, type, idName);
assertParentBranchesHaveNoMetadata( path);
}
@Override
public void visitBoolean( StatePath path, BooleanStateValue value) {
}
@Override
public void visitCompositePostDescend( StatePath path,
Map<String, String> metadata) {
}
@Override
public void visitCompositePreDescend( StatePath path,
Map<String, String> metadata) {
if( metadata != null) {
_collectedMetadata.put(path, metadata);
}
}
@Override
public void visitFloatingPoint( StatePath path,
FloatingPointStateValue value) {
}
@Override
public void visitInteger( StatePath path, IntegerStateValue value) {
}
@Override
public void visitString( StatePath path, StringStateValue value) {
}
@Override
public boolean isVisitable( StatePath path) {
return true;
}
}
}