// passing over REPLICATION_LIST configuration parameter, turning all the 
// addresses into canonical <ip:port> form and inserting them all, except for
// the address of local replication daemon, into 'm_replicationDaemonsList'.
void
AbstractReplicatorStateMachine::initializeReplicationList( char* buffer )
{
    StringList replicationAddressList;
    char*      replicationAddress    = NULL;
    bool       isMyAddressPresent    = false;
	Sinful     my_addr( daemonCore->InfoCommandSinfulString( ) );

    replicationAddressList.initializeFromString( buffer );
    // initializing a list unrolls it, that's why the rewind is needed to bring
    // it to the beginning
    replicationAddressList.rewind( );
    /* Passing through the REPLICATION_LIST configuration parameter, stripping
     * the optional <> brackets off, and extracting the host name out of
     * either ip:port or hostName:port entries
     */
    while( (replicationAddress = replicationAddressList.next( )) ) {
        char* sinfulAddress = utilToSinful( replicationAddress );

        if( sinfulAddress == NULL ) {
            char bufArray[BUFSIZ];

			sprintf( bufArray, 
					"AbstractReplicatorStateMachine::initializeReplicationList"
                    " invalid address %s\n", replicationAddress );
            utilCrucialError( bufArray );

            continue;
        }
        if( my_addr.addressPointsToMe( Sinful(sinfulAddress) ) ) {
            isMyAddressPresent = true;
        }
        else {
            m_replicationDaemonsList.insert( sinfulAddress );
        }
        // pay attention to release memory allocated by malloc with free and by
        // new with delete here utilToSinful returns memory allocated by malloc
        free( sinfulAddress );
    }

    if( !isMyAddressPresent ) {
        utilCrucialError( "ReplicatorStateMachine::initializeReplicationList "
                          "my address is not present in REPLICATION_LIST" );
    }
}
Example #2
0
int main( int, char ** ) {
	Sinful s;
	Sinful t;

	//
	// Test, for 0, 1, 2, and 3 condor_sockaddrs: that the vector is not NULL,
	// that the vector has the correct number of elements, that the vector's
	// elements values are correct (and in the correct order); and that the
	// string form of the sinful is correct; and that the parser correctly
	// handles the sinful string (by repeating the vector tests); and that
	// the string->sinful->string loop also works (by repeating the string
	// test).  Then repeat the 0 test after clearing the Sinful of addrs.
	//
	// We then also test adding three condor_sockaddrs in a row, just in
	// case one-at-a-time testing somehow hides a problem; this also tests
	// that adding condor_sockaddrs after clearing the Sinful works.
	//


	std::vector< condor_sockaddr > * v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 0 );
	delete v; v = NULL;

	char const * sinfulString = NULL;
	sinfulString = s.getSinful();
	REQUIRE( sinfulString == NULL );

	REQUIRE( ! s.hasAddrs() );


	condor_sockaddr sa;
	bool ok = sa.from_ip_and_port_string( "1.2.3.4:5" );
	REQUIRE( ok );
	s.addAddrToAddrs( sa );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 1 );
	REQUIRE( (*v)[0] == sa );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 1 );
	REQUIRE( (*v)[0] == sa );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	condor_sockaddr sa2;
	ok = sa2.from_ip_and_port_string( "5.6.7.8:9" );
	REQUIRE( ok );
	s.addAddrToAddrs( sa2 );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 2 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 2 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	condor_sockaddr sa3;
	ok = sa3.from_ip_and_port_string( "[1:3:5:7::a]:13" );
	REQUIRE( ok );
	s.addAddrToAddrs( sa3 );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	s.clearAddrs();
	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 0 );

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 0 );

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<>" ) == 0 );

	REQUIRE( ! s.hasAddrs() );


	s.addAddrToAddrs( sa );
	s.addAddrToAddrs( sa2 );
	s.addAddrToAddrs( sa3 );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	// In practice, all C++03 implementations are stable with respect
	// to insertion order; the  C++11 standard requires that they are.
	// This is the unit test for the former.
	std::multimap< int, condor_sockaddr > sortedByDesire;

	sortedByDesire.insert(std::make_pair( 0, sa ));
	sortedByDesire.insert(std::make_pair( 0, sa2 ));
	sortedByDesire.insert(std::make_pair( 0, sa3 ));
	int i = 0;
	std::multimap< int, condor_sockaddr >::const_iterator iter;
	for( iter = sortedByDesire.begin(); iter != sortedByDesire.end(); ++iter, ++i ) {
		switch( i ) {
			case 0:
				REQUIRE( (* iter).second == sa );
				break;
			case 1:
				REQUIRE( (* iter).second == sa2 );
				break;
			case 2:
				REQUIRE( (* iter).second == sa3 );
				break;
			default:
				REQUIRE( false );
				break;
		}
	}

	sortedByDesire.clear();
	REQUIRE( sortedByDesire.size() == 0 );
	sortedByDesire.insert(std::make_pair( 1, sa ));
	sortedByDesire.insert(std::make_pair( 0, sa2 ));
	sortedByDesire.insert(std::make_pair( 0, sa3 ));
	i = 0;
	for( iter = sortedByDesire.begin(); iter != sortedByDesire.end(); ++iter, ++i ) {
		switch( i ) {
			case 0:
				REQUIRE( (* iter).second == sa2 );
				break;
			case 1:
				REQUIRE( (* iter).second == sa3 );
				break;
			case 2:
				REQUIRE( (* iter).second == sa );
				break;
			default:
				REQUIRE( false );
				break;
		}
	}

	sortedByDesire.clear();
	REQUIRE( sortedByDesire.size() == 0 );
	sortedByDesire.insert(std::make_pair( 0, sa2 ));
	sortedByDesire.insert(std::make_pair( 1, sa ));
	sortedByDesire.insert(std::make_pair( 0, sa3 ));
	i = 0;
	for( iter = sortedByDesire.begin(); iter != sortedByDesire.end(); ++iter, ++i ) {
		switch( i ) {
			case 0:
				REQUIRE( (* iter).second == sa2 );
				break;
			case 1:
				REQUIRE( (* iter).second == sa3 );
				break;
			case 2:
				REQUIRE( (* iter).second == sa );
				break;
			default:
				REQUIRE( false );
				break;
		}
	}

	return 0;
}