| /*========================================================================= |
| * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. |
| * This product is protected by U.S. and international copyright |
| * and intellectual property laws. Pivotal products are covered by |
| * one or more patents listed at http://www.pivotal.io/patents. |
| *========================================================================= |
| */ |
| |
| #include "fw_dunit.hpp" |
| #include "ThinClientHelper.hpp" |
| |
| /* Testing Parameters Param's Value |
| Server notify-by-subscription: true |
| |
| Descripton: This is to test the receiveValues flag |
| in register interest APIs. Client events |
| delivered should include creates/updates or not include them (converted into invalidates). |
| */ |
| |
| #define CLIENT_NBS_TRUE s1p1 |
| /* |
| #define CLIENT_NBS_FALSE s1p2 |
| #define CLIENT_NBS_DEFAULT s2p1 |
| */ |
| #define SERVER_AND_FEEDER s2p2 |
| #define SERVER1 s2p2 // duplicate definition required for a helper file |
| |
| class EventListener : public CacheListener |
| { |
| public: |
| |
| int m_creates; |
| int m_updates; |
| int m_invalidates; |
| int m_destroys; |
| std::string m_name; |
| |
| void check(const EntryEvent& event, const char * eventType) |
| { |
| char buf[256] = {'\0'}; |
| |
| try |
| { |
| CacheableStringPtr keyPtr = dynCast<CacheableStringPtr>(event.getKey()); |
| CacheableInt32Ptr valuePtr = dynCast<CacheableInt32Ptr>(event.getNewValue()); |
| |
| sprintf(buf,"%s: %s: Key = %s, NewValue = %s", m_name.c_str(), eventType, keyPtr->asChar(), |
| (valuePtr == NULLPTR ? "NULLPTR" : valuePtr->toString()->asChar())); |
| LOG(buf); |
| } |
| catch (const Exception & excp) |
| { |
| sprintf(buf,"%s: %s: %s: %s", m_name.c_str(), eventType, excp.getName(), excp.getMessage()); |
| LOG(buf); |
| } |
| catch (...) |
| { |
| sprintf(buf,"%s: %s: unknown exception", m_name.c_str(), eventType); |
| LOG(buf); |
| } |
| } |
| |
| public: |
| |
| EventListener(const char * name):m_name(name), |
| m_creates(0),m_updates(0),m_invalidates(0),m_destroys(0) {} |
| |
| ~EventListener() {} |
| |
| virtual void afterCreate( const EntryEvent& event ) |
| { |
| check(event, "afterCreate"); |
| m_creates++; |
| } |
| |
| virtual void afterUpdate( const EntryEvent& event ) |
| { |
| check(event, "afterUpdate"); |
| m_updates++; |
| } |
| |
| virtual void afterInvalidate( const EntryEvent& event ) |
| { |
| check(event, "afterInvalidate"); |
| m_invalidates++; |
| } |
| |
| virtual void afterDestroy( const EntryEvent& event ) |
| { |
| check(event, "afterDestroy"); |
| m_destroys++; |
| } |
| |
| void reset() |
| { |
| m_creates = 0; |
| m_updates = 0; |
| m_invalidates = 0; |
| m_destroys = 0; |
| } |
| |
| // validate expected event counts |
| void validate(int creates, int updates, int invalidates, int destroys ) |
| { |
| char logmsg[256] = {'\0'}; |
| sprintf(logmsg, "VALIDATE CALLED for %s", m_name.c_str()); |
| LOG(logmsg); |
| sprintf(logmsg, "creates: expected = %d, actual = %d", creates, m_creates); |
| LOG(logmsg); |
| ASSERT(m_creates == creates, logmsg); |
| sprintf(logmsg, "updates: expected = %d, actual = %d", updates, m_updates); |
| LOG(logmsg); |
| ASSERT(m_updates == updates, logmsg); |
| sprintf(logmsg, "invalidates: expected = %d, actual = %d", invalidates, m_invalidates); |
| LOG(logmsg); |
| ASSERT(m_invalidates == invalidates, logmsg); |
| sprintf(logmsg, "destroys: expected = %d, actual = %d", destroys, m_destroys); |
| LOG(logmsg); |
| ASSERT(m_destroys == destroys, logmsg); |
| } |
| }; |
| typedef SharedPtr<EventListener> EventListenerPtr; |
| |
| void setCacheListener(const char *regName, EventListenerPtr monitor) |
| { |
| RegionPtr reg = getHelper()->getRegion(regName); |
| AttributesMutatorPtr attrMutator = reg->getAttributesMutator(); |
| attrMutator->setCacheListener(monitor); |
| } |
| |
| // clientXXRegionYY where XX is NBS setting and YY is receiveValue setting in RegisterInterest API calls, |
| // RegionOther means no interest registered so no events should arrive except invalidates when NBS == false. |
| |
| EventListenerPtr clientTrueRegionTrue = NULLPTR; |
| EventListenerPtr clientTrueRegionFalse = NULLPTR; |
| EventListenerPtr clientTrueRegionOther = NULLPTR; |
| /* |
| EventListenerPtr clientFalseRegionTrue = NULLPTR; |
| EventListenerPtr clientFalseRegionFalse = NULLPTR; |
| EventListenerPtr clientFalseRegionOther = NULLPTR; |
| EventListenerPtr clientDefaultRegionTrue = NULLPTR; |
| EventListenerPtr clientDefaultRegionFalse = NULLPTR; |
| EventListenerPtr clientDefaultRegionOther = NULLPTR; |
| */ |
| |
| const char * regions[] = { "RegionTrue", "RegionFalse", "RegionOther" }; |
| const char * keysForRegex[] = { "key-regex-1", "key-regex-2", "key-regex-3" }; |
| |
| #include "ThinClientDurableInit.hpp" |
| #include "ThinClientTasks_C2S2.hpp" |
| #include "LocatorHelper.hpp" |
| |
| void initClientForInterestNotify( EventListenerPtr& mon1, EventListenerPtr& mon2, |
| EventListenerPtr& mon3, const char* nbs, const char * clientName) |
| { |
| PropertiesPtr props = Properties::create(); |
| //props->insert( "notify-by-subscription-override", nbs ); |
| |
| const char *ep = CacheHelper::getTcrEndpoints( isLocalServer, 1 ); |
| |
| if ( g_poolConfig ) { |
| initClient( true, props ); |
| if ( g_poolLocators ) { |
| LOG( "CLIENT: Setting pool with locator."); |
| getHelper()->createPoolWithLocators( "__TESTPOOL1_", locatorsG, true, 0, 1 ); |
| } |
| else { |
| LOG( "CLIENT: Setting pool endpoint to:"); |
| LOG( ep ); |
| getHelper()->createPoolWithEPs( "__TESTPOOL1_", ep, true, 0, 1 ); |
| } |
| createRegionAndAttachPool( regions[0], USE_ACK, "__TESTPOOL1_", true ); |
| createRegionAndAttachPool( regions[1], USE_ACK, "__TESTPOOL1_", true ); |
| createRegionAndAttachPool( regions[2], USE_ACK, "__TESTPOOL1_", true ); |
| } |
| else { |
| LOG( "CLIENT: Setting region endpoint to:"); |
| LOG( ep ); |
| props->insert( "notify-ack-interval", 1 ); |
| initClient( ep, 0, props ); |
| createRegion( regions[0], USE_ACK, endPoint, true ); |
| createRegion( regions[1], USE_ACK, endPoint, true ); |
| createRegion( regions[2], USE_ACK, endPoint, true ); |
| } |
| |
| std::string name1 = clientName; |
| name1 += "_"; |
| name1 += regions[0]; |
| std::string name2 = clientName; |
| name2 += "_"; |
| name2 += regions[1]; |
| std::string name3 = clientName; |
| name3 += "_"; |
| name3 += regions[2]; |
| |
| // Recreate listeners |
| mon1 = new EventListener(name1.c_str()); |
| mon2 = new EventListener(name2.c_str()); |
| mon3 = new EventListener(name3.c_str()); |
| |
| setCacheListener( regions[0], mon1 ); |
| setCacheListener( regions[1], mon2 ); |
| setCacheListener( regions[2], mon3 ); |
| |
| LOG( "initClientForInterestNotify complete." ); |
| } |
| |
| void feederPuts(int count) |
| { |
| for (int region = 0; region < 3; region++) |
| { |
| for (int key = 0; key < 3; key++) |
| { |
| // if you create entry with value == 0 it does check for |
| // value not exist and fails so start the entry count from 1. |
| for (int entry = 1; entry <= count; entry++) |
| { |
| createIntEntry( regions[region], keys[key], entry ); |
| createIntEntry( regions[region], keysForRegex[key], entry ); |
| } |
| } |
| } |
| } |
| |
| void feederInvalidates() |
| { |
| for (int region = 0; region < 3; region++) |
| { |
| for (int key = 0; key < 3; key++) |
| { |
| invalidateEntry( regions[region], keys[key] ); |
| invalidateEntry( regions[region], keysForRegex[key] ); |
| } |
| } |
| } |
| |
| void feederDestroys() |
| { |
| for (int region = 0; region < 3; region++) |
| { |
| for (int key = 0; key < 3; key++) |
| { |
| destroyEntry( regions[region], keys[key] ); |
| destroyEntry( regions[region], keysForRegex[key] ); |
| } |
| } |
| } |
| |
| void registerInterests(const char * region, bool durable, bool receiveValues) |
| { |
| RegionPtr regionPtr = getHelper()->getRegion(region); |
| |
| VectorOfCacheableKey keysVector; |
| |
| keysVector.push_back(CacheableKey::create(keys[0])); |
| keysVector.push_back(CacheableKey::create(keys[1])); |
| keysVector.push_back(CacheableKey::create(keys[2])); |
| |
| regionPtr->registerKeys(keysVector, durable, true, receiveValues); |
| |
| regionPtr->registerRegex("key-regex.*", durable, NULLPTR, true, receiveValues); |
| } |
| |
| void unregisterInterests(const char * region) |
| { |
| RegionPtr regionPtr = getHelper()->getRegion(region); |
| |
| VectorOfCacheableKey keysVector; |
| |
| keysVector.push_back(CacheableKey::create(keys[0])); |
| keysVector.push_back(CacheableKey::create(keys[1])); |
| keysVector.push_back(CacheableKey::create(keys[2])); |
| |
| regionPtr->unregisterKeys(keysVector); |
| |
| regionPtr->unregisterRegex("key-regex.*"); |
| } |
| |
| void closeClient() |
| { |
| getHelper()->disconnect(); |
| cleanProc(); |
| LOG( "CLIENT CLOSED" ); |
| } |
| |
| DUNIT_TASK_DEFINITION(SERVER_AND_FEEDER, StartServer_NBS) |
| { |
| if ( isLocalServer ) |
| CacheHelper::initServer( 1 , "cacheserver_interest_notify.xml"); |
| LOG("SERVER with NBS=false started without locator"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(SERVER_AND_FEEDER, StartServerWithLocator_NBS ) |
| { |
| if ( isLocalServer ) { |
| CacheHelper::initServer( 1, "cacheserver_interest_notify.xml", locatorsG ); |
| } |
| LOG("SERVER with NBS=false started with locator"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(SERVER_AND_FEEDER, FeederUpAndFeed) |
| { |
| initClient(true); |
| |
| createRegion( regions[0], USE_ACK, endPoint); |
| createRegion( regions[1], USE_ACK, endPoint); |
| createRegion( regions[2], USE_ACK, endPoint); |
| |
| feederPuts(1); |
| |
| LOG( "FeederUpAndFeed complete." ); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_TRUE, ClientNbsTrue_Up) |
| { |
| initClientForInterestNotify( clientTrueRegionTrue , |
| clientTrueRegionFalse, clientTrueRegionOther, "true", "clientNbsTrue" ); |
| LOG("ClientNbsTrue_Up complete"); |
| } |
| END_TASK_DEFINITION |
| |
| /* |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_FALSE, ClientNbsFalse_Up) |
| { |
| initClientForInterestNotify( clientFalseRegionTrue , |
| clientFalseRegionFalse, clientFalseRegionOther, "false", "clientNbsFalse" ); |
| LOG("ClientNbsFalse_Up complete"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_DEFAULT, ClientNbsDefault_Up) |
| { |
| initClientForInterestNotify( clientDefaultRegionTrue , |
| clientDefaultRegionFalse, clientDefaultRegionOther, "server", "clientNbsDefault" ); |
| LOG("ClientNbsDefault_Up complete"); |
| } |
| END_TASK_DEFINITION |
| */ |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_TRUE, ClientNbsTrue_Register) |
| { |
| registerInterests(regions[0], false, true); |
| registerInterests(regions[1], false, false); |
| |
| // We intentionally DO NOT register interest in the third region to |
| // check that we don't get unexpected events based on the NBS setting. |
| //registerInterests(regions[2], false, true); |
| |
| LOG("ClientNbsTrue_Register complete"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_TRUE, ClientNbsTrue_Unregister) |
| { |
| unregisterInterests(regions[0]); |
| unregisterInterests(regions[1]); |
| //unregisterInterests(regions[2]); |
| LOG("ClientNbsTrue_Unregister complete"); |
| } |
| END_TASK_DEFINITION |
| |
| /* |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_FALSE, ClientNbsFalse_Register) |
| { |
| registerInterests(regions[0], false, true); |
| registerInterests(regions[1], false, false); |
| |
| // We intentionally DO NOT register interest in the third region to |
| // check that we don't get unexpected events based on the NBS setting. |
| //registerInterests(regions[2], false, true); |
| |
| LOG("ClientNbsFalse_Register complete"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_FALSE, ClientNbsFalse_Unregister) |
| { |
| unregisterInterests(regions[0]); |
| unregisterInterests(regions[1]); |
| //unregisterInterests(regions[2]); |
| LOG("ClientNbsFalse_Unregister complete"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_DEFAULT, ClientNbsDefault_Register) |
| { |
| registerInterests(regions[0], false, true); |
| registerInterests(regions[1], false, false); |
| |
| // We intentionally DO NOT register interest in the third region to |
| // check that we don't get unexpected events based on the NBS setting. |
| //registerInterests(regions[2], false, true); |
| |
| LOG("ClientNbsDefault_Register complete"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_DEFAULT, ClientNbsDefault_Unregister) |
| { |
| unregisterInterests(regions[0]); |
| unregisterInterests(regions[1]); |
| //unregisterInterests(regions[2]); |
| LOG("ClientNbsDefault_Unregister complete"); |
| } |
| END_TASK_DEFINITION |
| */ |
| |
| DUNIT_TASK_DEFINITION(SERVER_AND_FEEDER, FeederDoOps) |
| { |
| // Do 3 puts, 1 invalidate and 1 destroy for each of the 6 keys |
| feederPuts(3); |
| feederInvalidates(); |
| feederDestroys(); |
| LOG( "FeederDoOps complete." ); |
| } |
| END_TASK_DEFINITION |
| |
| // VERIFICATION COUNTS: |
| // Each regon has 6 keys, for each key feeder does: |
| // 3 puts, 1 invalidate, 1 destroy. |
| // Invalidate operations from the feeder are not sent to the server so |
| // registered clients do not receive those invalidates only those |
| // that are registered interest or due to notify-by-subscription=false. |
| // Feeder does the above steps 3 times, once when clients have registered |
| // interest, then when clients unregister interest, then again when clients |
| // re-register interest. |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_TRUE, ClientNbsTrue_Verify) |
| { |
| //validate expected creates, updates, invalidates and destroys in that order |
| // Verify only events received while client had registered interest |
| clientTrueRegionTrue->validate(6, 30, 0, 12); |
| clientTrueRegionFalse->validate(0, 0, 36, 12); |
| clientTrueRegionOther->validate(0, 0, 0, 0); |
| LOG("ClientNbsTrue_Verify complete"); |
| } |
| END_TASK_DEFINITION |
| |
| /* |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_FALSE, ClientNbsFalse_Verify) |
| { |
| //validate expected creates, updates, invalidates and destroys in that order |
| // Verify only events received while client had registered interest |
| clientFalseRegionTrue->validate(0, 0, 54, 18); |
| clientFalseRegionFalse->validate(0, 0, 54, 18); |
| clientFalseRegionOther->validate(0, 0, 54, 18); |
| LOG("ClientNbsFalse_Verify complete"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_DEFAULT, ClientNbsDefault_Verify) |
| { |
| //validate expected creates, updates, invalidates and destroys in that order |
| // Verify only events received while client had registered interest |
| clientDefaultRegionTrue->validate(0, 0, 54, 18); |
| clientDefaultRegionFalse->validate(0, 0, 54, 18); |
| clientDefaultRegionOther->validate(0, 0, 54, 18); |
| LOG("ClientNbsDefault_Verify complete"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_DEFAULT, ClientNbsDefault_Close) |
| { |
| cleanProc(); |
| LOG("ClientNbsDefault_Close complete"); |
| } |
| END_TASK_DEFINITION |
| */ |
| |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_TRUE, ClientNbsTrue_Close) |
| { |
| cleanProc(); |
| LOG("ClientNbsTrue_Close complete"); |
| } |
| END_TASK_DEFINITION |
| |
| /* |
| DUNIT_TASK_DEFINITION(CLIENT_NBS_FALSE, ClientNbsFalse_Close) |
| { |
| cleanProc(); |
| LOG("ClientNbsFalse_Close complete"); |
| } |
| END_TASK_DEFINITION |
| */ |
| |
| DUNIT_TASK_DEFINITION(SERVER_AND_FEEDER,CloseFeeder) |
| { |
| cleanProc(); |
| LOG("FEEDER closed"); |
| } |
| END_TASK_DEFINITION |
| |
| DUNIT_TASK_DEFINITION(SERVER_AND_FEEDER , CloseServer) |
| { |
| CacheHelper::closeServer( 1 ); |
| LOG("SERVER closed"); |
| } |
| END_TASK_DEFINITION |
| |
| void doThinClientInterestNotify( bool poolConfig = false, bool poolLocators = false ) |
| { |
| initLocatorSettings( poolConfig, poolLocators ); |
| |
| if ( poolConfig && poolLocators ) { |
| CALL_TASK( StartLocator ); |
| CALL_TASK( StartServerWithLocator_NBS ); |
| } |
| else { |
| CALL_TASK( StartServer_NBS ); |
| } |
| |
| CALL_TASK( FeederUpAndFeed ); |
| |
| CALL_TASK( ClientNbsTrue_Up ); |
| /* |
| CALL_TASK( ClientNbsFalse_Up ); |
| CALL_TASK( ClientNbsDefault_Up ); |
| */ |
| |
| CALL_TASK( ClientNbsTrue_Register ); |
| /* |
| CALL_TASK( ClientNbsFalse_Register ); |
| CALL_TASK( ClientNbsDefault_Register ); |
| */ |
| |
| // Do 3 puts, 1 invalidate and 1 destroy for |
| // each of the 6 keys while client has registered interest |
| CALL_TASK( FeederDoOps ); |
| |
| // wait for queues to drain |
| SLEEP(10000); |
| |
| CALL_TASK( ClientNbsTrue_Unregister ); |
| /* |
| CALL_TASK( ClientNbsFalse_Unregister ); |
| CALL_TASK( ClientNbsDefault_Unregister ); |
| */ |
| |
| // Do 3 puts, 1 invalidate and 1 destroy for |
| // each of the 6 keys while client has UN-registered interest |
| CALL_TASK( FeederDoOps ); |
| |
| CALL_TASK( ClientNbsTrue_Register ); |
| /* |
| CALL_TASK( ClientNbsFalse_Register ); |
| CALL_TASK( ClientNbsDefault_Register ); |
| */ |
| |
| // Do 3 puts, 1 invalidate and 1 destroy for |
| // each of the 6 keys while client has RE-registered interest |
| CALL_TASK( FeederDoOps ); |
| |
| // wait for queues to drain |
| SLEEP(10000); |
| |
| // Verify only events received while client had registered interest |
| CALL_TASK( ClientNbsTrue_Verify ); |
| /* |
| CALL_TASK( ClientNbsFalse_Verify ); |
| CALL_TASK( ClientNbsDefault_Verify ); |
| */ |
| |
| CALL_TASK( ClientNbsTrue_Close ); |
| /* |
| CALL_TASK( ClientNbsFalse_Close ); |
| CALL_TASK( ClientNbsDefault_Close ); |
| */ |
| |
| CALL_TASK( CloseFeeder); |
| |
| CALL_TASK( CloseServer); |
| |
| closeLocator( ); |
| } |
| |
| DUNIT_MAIN |
| { |
| // nbs true/false without pools |
| doThinClientInterestNotify(); |
| |
| // nbs true/false with pool with endpoints |
| doThinClientInterestNotify(true); |
| |
| // nbs true/false with pool with locator |
| doThinClientInterestNotify(true, true); |
| } |
| END_MAIN |