Package org.nimbustools.ctxbroker.blackboard

Source Code of org.nimbustools.ctxbroker.blackboard.BlackboardTest

/*
* Copyright 1999-2009 University of Chicago
*
* 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.nimbustools.ctxbroker.blackboard;

import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import static org.testng.Assert.*;
import static org.testng.Assert.assertEquals;
import org.nimbustools.ctxbroker.ContextBrokerException;
import org.nimbustools.ctxbroker.Identity;

import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.UUID;

public class BlackboardTest {

    final static String ID = "test-Blackboard";

    int nextWorkspaceID = 0;

    private synchronized Integer getWorkspaceID() {
        return nextWorkspaceID++;
    }
    private Identity getIdentity(int workspaceID) {
        return new Identity("publicnic",
                "192.168.0."+workspaceID,
                "id-"+workspaceID,
                "asdfghjk");
    }

    private static void assertDataPairs(List<DataPair> actual, List<DataPair> expected) {
        assertEquals(actual.size(), expected.size());
        for (DataPair expectedPair : expected) {
            boolean found = false;
            for (DataPair actualPair : actual) {
                if (expectedPair.getName().equals(actualPair.getName()) &&
                        expectedPair.getValue().equals(expectedPair.getValue())) {
                    found = true;
                    break;
                }
            }
            assertTrue(found, "Data pair: "+expectedPair.toString() +
                    " was not found in actual data pair list");
        }
    }

    private static void assertIdentitiesEqual(Identity actual, Identity expected) {
        assertNotNull(actual);
        assertNotNull(expected);

        assertEquals(actual.getIface(), expected.getIface());
        assertEquals(actual.getIp(), expected.getIp());
        assertEquals(actual.getPubkey(), expected.getPubkey());
        assertEquals(actual.getHostname(), expected.getHostname());
    }


    @Test
    public void testNodeCountChange() throws ContextBrokerException {
        Blackboard bb = new Blackboard(ID);

        Integer workspaceId = getWorkspaceID();
        Identity[] ids = new Identity[] {getIdentity(workspaceId)};

        bb.addWorkspace(workspaceId, ids, true, null, null, null, 3);

        boolean failed = false;
        try {
            bb.addWorkspace(workspaceId, ids, true, null, null, null, 4);
        } catch (ContextBrokerException e) {
            failed = true;
        }

        assertTrue(failed, "Mismatched node counts did not cause failure");
    }

    @Test
    public void testTooManyNodes() {
        Blackboard bb = new Blackboard(ID);

        final int nodeCount = 3;

        boolean failed = false;
        // we try to add one more node than we advertise
        for (int i=0; i<=nodeCount; i++) {

            Integer workspaceId = getWorkspaceID();
            Identity[] ids = new Identity[] {getIdentity(workspaceId)};
            try {
                bb.addWorkspace(workspaceId, ids, true, null,
                        null, null, nodeCount);
            } catch (ContextBrokerException e) {
                assertEquals(i, nodeCount, "addWorkspace() failed on an " +
                        "earlier node than expected");
                failed = true;
            }
        }
        assertTrue(failed, "Adding one too many nodes did not cause failure");
    }

    @Test
    public void testDuplicateNodeId() throws ContextBrokerException {
        Blackboard bb = new Blackboard(ID);
        Integer workspaceId = getWorkspaceID();
        Identity[] ids = new Identity[] {getIdentity(workspaceId)};

        bb.addWorkspace(workspaceId, ids, true, null, null, null, 3);

        boolean failed = false;
        try {
            bb.addWorkspace(workspaceId, ids, true, null, null, null, 3);
        } catch (ContextBrokerException e) {
            failed = true;
        }
        assertTrue(failed, "Adding node with duplicate ID did not cause failure");

    }



    @DataProvider(name="allofthebools")
    private Object[][] generateBooleans() {
        // seems a little silly
        return new Object[][] {
                new Object[] {true},
                new Object[] {false}
        };
    }

    @Test(dataProvider = "allofthebools")
    public void testSingleNode(boolean reportOk) throws ContextBrokerException {
        Blackboard bb = new Blackboard(ID);
        Integer workspaceId = getWorkspaceID();
        Identity[] ids = new Identity[] {getIdentity(workspaceId)};

        DataPair[] data = new DataPair[] {
                new DataPair("foo", "bar"),
                new DataPair("billy", "anyteen")
        };

        CtxStatus ctxStatus = bb.getStatus();
        assertFalse(ctxStatus.isAllOk());
        assertFalse(ctxStatus.isErrorOccurred());
        assertFalse(ctxStatus.isComplete());

        bb.addWorkspace(workspaceId, ids, true, null, data, null, 1);

        final NodeManifest nodeManifest = bb.retrieve(workspaceId);
        assertDataPairs(nodeManifest.getData(), Arrays.asList(data));
        assertEquals(nodeManifest.getRequiredRoles().size(), 0);
        assertEquals(nodeManifest.getIdentities().size(), 1);


        // node has retrieved its data but not reported in yet
        ctxStatus = bb.getStatus();
        assertFalse(ctxStatus.isAllOk());
        assertFalse(ctxStatus.isErrorOccurred());
        assertTrue(ctxStatus.isComplete());


        if (reportOk) {
            bb.okExit(workspaceId);

            ctxStatus = bb.getStatus();
            assertTrue(ctxStatus.isAllOk());
            assertFalse(ctxStatus.isErrorOccurred());
            assertTrue(ctxStatus.isComplete());

            final List<NodeStatus> list = bb.identities(true, null, null);
            assertEquals(list.size(), 1);
            final NodeStatus nodeStatus = list.get(0);

            assertEquals(nodeStatus.getIdentities().size(), 1);
            assertIdentitiesEqual(nodeStatus.getIdentities().get(0), ids[0]);

            assertEquals(nodeStatus.getErrorCode(),0);
            assertNull(nodeStatus.getErrorMessage());
            assertFalse(nodeStatus.isErrorOccurred());
            assertTrue(nodeStatus.isOkOccurred());
        } else {

            final short exitCode = 1;
            final String errorMsg = "this isn't really an error";
            bb.errorExit(workspaceId, exitCode, errorMsg);

            ctxStatus = bb.getStatus();
            assertFalse(ctxStatus.isAllOk());
            assertTrue(ctxStatus.isErrorOccurred());
            assertTrue(ctxStatus.isComplete());

            final List<NodeStatus> list = bb.identities(true, null, null);
            assertEquals(list.size(), 1);
            final NodeStatus nodeStatus = list.get(0);

            assertEquals(nodeStatus.getIdentities().size(), 1);
            assertIdentitiesEqual(nodeStatus.getIdentities().get(0), ids[0]);

            assertEquals(nodeStatus.getErrorCode(), exitCode);
            assertEquals(nodeStatus.getErrorMessage(), errorMsg);
            assertTrue(nodeStatus.isErrorOccurred());
            assertFalse(nodeStatus.isOkOccurred());
        }


    }

    @Test(dataProvider = "allofthebools")
    public void testMasterWorker(boolean requireAllIdentities)
            throws ContextBrokerException {

        // one-way dependency: a master role that depends on nothing but is required by multiple workers

        // requireAllIdentities affects whether nodes want information for every node, or just
        // those that they depend on. This affects two things:
        //      * Whether nodes can be retrieve()d once they have dependencies satisfied but not all
        //        nodes have checked in
        //      * How many Identities nodes get back from retrieve()


        Blackboard bb = new Blackboard(ID);

        final String masterRole ="mastermaster";
        final int workerCount = 2;
        final int nodeCount = workerCount+1;

        final Integer masterId = getWorkspaceID();
        final Identity[] masterIdentities = new Identity[] { getIdentity(masterId)};
        final ProvidedRoleDescription[] masterProvidedRoles = new ProvidedRoleDescription[] {
                new ProvidedRoleDescription(masterRole, null)
        };
        final RequiredRole[] masterRequiredRoles = null;

        bb.addWorkspace(masterId, masterIdentities, requireAllIdentities,
                masterRequiredRoles, null, masterProvidedRoles, nodeCount);

        List<Integer> workerIds = new ArrayList<Integer>(workerCount);
        for (int i=0; i< workerCount; i++) {

            // context should not be complete and retrieve should fail until workers check in
            assertFalse(bb.isComplete());

            if (requireAllIdentities) {
                assertTrue(bb.retrieve(masterId) == null);
                for (Integer id : workerIds) {
                    assertTrue(bb.retrieve(id) == null);
                }
            } else {
                assertTrue(bb.retrieve(masterId) != null);
                for (Integer id : workerIds) {
                    assertTrue(bb.retrieve(id) != null);
                }
            }

            final Integer workerId = getWorkspaceID();
            workerIds.add(workerId);
            final Identity[] workerIdentities = new Identity[] { getIdentity(workerId)};
            final ProvidedRoleDescription[] workerProvidedRoles = null;
            final RequiredRole[] workerRequiredRoles = new RequiredRole[] {
                    new RequiredRole(masterRole, true, true)
            };

            bb.addWorkspace(workerId, workerIdentities, requireAllIdentities,
                    workerRequiredRoles, null, workerProvidedRoles, nodeCount);
        }

        // okay now everyone is checked in.
        assertTrue(bb.isComplete());
        for (Integer workerId : workerIds) {
            final NodeManifest man = bb.retrieve(workerId);

            assertTrue(man.getData().isEmpty());
            assertEquals(man.getRequiredRoles().size(), 1);
            RoleIdentityPair rolePair = man.getRequiredRoles().get(0);
            assertIdentitiesEqual(rolePair.getIdentity(), masterIdentities[0]);
            assertEquals(rolePair.getRole(), masterRole);

            if (requireAllIdentities) {
                assertEquals(man.getIdentities().size(), nodeCount);
            } else {
                // just the master
                assertEquals(man.getIdentities().size(), 1);
                assertIdentitiesEqual(man.getIdentities().get(0), masterIdentities[0]);
            }
        }

        final NodeManifest masterManifest = bb.retrieve(masterId);
        assertTrue(masterManifest.getData().isEmpty());
        assertTrue(masterManifest.getRequiredRoles().isEmpty());

        // if we don't require all identities, master will get 0 identities
        assertEquals(masterManifest.getIdentities().size(),
                requireAllIdentities ? nodeCount : 0);
    }

    @Test
    public void testFindIdentities() throws ContextBrokerException {

        final Blackboard bb = new Blackboard(ID);
        final int nodeCount = 3;

        Identity[] ids = new Identity[nodeCount];
        for (int i=0; i< nodeCount; i++) {
            Integer workspaceId = getWorkspaceID();
            ids[i] = getIdentity(workspaceId);

            bb.addWorkspace(workspaceId, new Identity[] {ids[i]},
                    true, null, null, null, nodeCount);
        }

        // find all identities
        final List<NodeStatus> allNodes = bb.identities(true, null, null);
        assertEquals(allNodes.size(), nodeCount);

        // find by IP
        for (Identity id : ids) {
            final List<NodeStatus> list = bb.identities(false, null, id.getIp());
            assertEquals(list.size(), 1);
            final List<Identity> nodeIdentities = list.get(0).getIdentities();
            assertEquals(list.size(), 1);
            assertIdentitiesEqual(nodeIdentities.get(0), id);
        }

        // and a nonexistent IP
        assertEquals(bb.identities(false, null, "10.10.10.10").size(), 0);


        // find by hostname
        for (Identity id : ids) {
            final List<NodeStatus> list = bb.identities(false, id.getHostname(), null);
            assertEquals(list.size(), 1);
            final List<Identity> nodeIdentities = list.get(0).getIdentities();
            assertEquals(list.size(), 1);
            assertIdentitiesEqual(nodeIdentities.get(0), id);
        }

        // and a nonexistent hostname
        assertEquals(bb.identities(false, "google.com", null).size(), 0);

    }

    @Test
    public void testInjectData() throws ContextBrokerException {
        final Blackboard bb = new Blackboard(ID);

        final String dataName = "OMGDATA";
        final String[] dataValues = new String[] {"VALUE1", "VALUE2"};
       

        // add a node that requires a data but provides no value

        DataPair dataNoValue = new DataPair(dataName);
        DataPair dataWithValue = new DataPair(dataName, dataValues[0]);


        Integer workspaceNoValueId = getWorkspaceID();
        bb.addWorkspace(workspaceNoValueId, new Identity[] {getIdentity(workspaceNoValueId)},
                true, null, new DataPair[] {dataNoValue}, null, 2);

        Integer workspaceWithValueId = getWorkspaceID();
        bb.addWorkspace(workspaceWithValueId, new Identity[] {getIdentity(workspaceWithValueId)},
                true, null, new DataPair[] {dataWithValue}, null, 2);

        bb.injectData(dataName, dataValues[1]);

        NodeManifest node1 = bb.retrieve(workspaceNoValueId);
        assertNotNull(node1);
        final List<DataPair> node1Data = node1.getData();
        assertEquals(node1Data.size(), dataValues.length);
        for (DataPair dp : node1Data) {
            assertEquals(dp.getName(), dataName);
            final String value = dp.getValue();
            assertNotNull(value);

            int matchCount = 0;
            for (String dataValue : dataValues) {
                if (value.equals(dataValue)) {
                    matchCount++;
                }
            }
            assertEquals(matchCount, 1);
        }

        NodeManifest node2 = bb.retrieve(workspaceWithValueId);
        assertNotNull(node2);
        final List<DataPair> node2Data = node2.getData();
        assertEquals(node2Data.size(), dataValues.length);
        for (DataPair dp : node2Data) {
            assertEquals(dp.getName(), dataName);
            final String value = dp.getValue();
            assertNotNull(value);

            int matchCount = 0;
            for (String dataValue : dataValues) {
                if (value.equals(dataValue)) {
                    matchCount++;
                }
            }
            assertEquals(matchCount, 1);
        }

    }

    @Test
    public void testStaticBlackboardFactory() {
        final String id = UUID.randomUUID().toString();

        final Blackboard blackboard = Blackboard.createOrGetBlackboard(id);

        assertSame(Blackboard.createOrGetBlackboard(id), blackboard);

        final String anotherId = UUID.randomUUID().toString();
        assertNotSame(Blackboard.createOrGetBlackboard(anotherId), blackboard);
    }

}
TOP

Related Classes of org.nimbustools.ctxbroker.blackboard.BlackboardTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.