/*
* Copyright (c) 2002-2017 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* 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.neo4j.driver.internal.cluster;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.neo4j.driver.internal.InternalRecord;
import org.neo4j.driver.internal.net.BoltServerAddress;
import org.neo4j.driver.v1.Record;
import org.neo4j.driver.v1.Value;
import static java.util.Arrays.asList;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.A;
import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.B;
import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.C;
import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.D;
import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.E;
import static org.neo4j.driver.internal.cluster.ClusterCompositionUtil.F;
import static org.neo4j.driver.v1.Values.value;
public class ClusterCompositionTest
{
@Test
public void hasWritersReturnsFalseWhenNoWriters()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses(), addresses( C, D ) );
assertFalse( composition.hasWriters() );
}
@Test
public void hasWritersReturnsTrueWhenSomeWriters()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) );
assertTrue( composition.hasWriters() );
}
@Test
public void hasRoutersAndReadersReturnsFalseWhenNoRouters()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses() );
assertFalse( composition.hasRoutersAndReaders() );
}
@Test
public void hasRoutersAndReadersReturnsFalseWhenNoReaders()
{
ClusterComposition composition = newComposition( 1, addresses(), addresses( A, B ), addresses( C, D ) );
assertFalse( composition.hasRoutersAndReaders() );
}
@Test
public void hasRoutersAndReadersWhenSomeReadersAndRouters()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) );
assertTrue( composition.hasRoutersAndReaders() );
}
@Test
public void readersWhenEmpty()
{
ClusterComposition composition = newComposition( 1, addresses(), addresses( A, B ), addresses( C, D ) );
assertEquals( 0, composition.readers().size() );
}
@Test
public void writersWhenEmpty()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses(), addresses( C, D ) );
assertEquals( 0, composition.writers().size() );
}
@Test
public void routersWhenEmpty()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses() );
assertEquals( 0, composition.routers().size() );
}
@Test
public void readersWhenNonEmpty()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) );
assertEquals( addresses( A, B ), composition.readers() );
}
@Test
public void writersWhenNonEmpty()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) );
assertEquals( addresses( C, D ), composition.writers() );
}
@Test
public void routersWhenNonEmpty()
{
ClusterComposition composition = newComposition( 1, addresses( A, B ), addresses( C, D ), addresses( E, F ) );
assertEquals( addresses( E, F ), composition.routers() );
}
@Test
public void expirationTimestamp()
{
ClusterComposition composition = newComposition( 42, addresses( A, B ), addresses( C, D ), addresses( E, F ) );
assertEquals( 42, composition.expirationTimestamp() );
}
@Test
public void parseCorrectRecord()
{
Value[] values = {
value( 42L ),
value( asList( serversEntry( "READ", A, B ),
serversEntry( "WRITE", C, D ),
serversEntry( "ROUTE", E, F ) ) )
};
Record record = new InternalRecord( asList( "ttl", "servers" ), values );
ClusterComposition composition = ClusterComposition.parse( record, 0 );
// TTL is received in seconds and is converted to millis
assertEquals( 42_000, composition.expirationTimestamp() );
assertEquals( addresses( A, B ), composition.readers() );
assertEquals( addresses( C, D ), composition.writers() );
assertEquals( addresses( E, F ), composition.routers() );
}
@Test
public void parsePreservesOrderOfReaders()
{
Value[] values = {
value( 42L ),
value( asList( serversEntry( "READ", A, C, E, B, F, D ),
serversEntry( "WRITE" ),
serversEntry( "ROUTE" ) ) )
};
Record record = new InternalRecord( asList( "ttl", "servers" ), values );
ClusterComposition composition = ClusterComposition.parse( record, 0 );
assertThat( composition.readers(), contains( A, C, E, B, F, D ) );
assertEquals( 0, composition.writers().size() );
assertEquals( 0, composition.routers().size() );
}
@Test
public void parsePreservesOrderOfWriters()
{
Value[] values = {
value( 42L ),
value( asList( serversEntry( "READ" ),
serversEntry( "WRITE", C, F, D, A, B, E ),
serversEntry( "ROUTE" ) ) )
};
Record record = new InternalRecord( asList( "ttl", "servers" ), values );
ClusterComposition composition = ClusterComposition.parse( record, 0 );
assertEquals( 0, composition.readers().size() );
assertThat( composition.writers(), contains( C, F, D, A, B, E ) );
assertEquals( 0, composition.routers().size() );
}
@Test
public void parsePreservesOrderOfRouters()
{
Value[] values = {
value( 42L ),
value( asList( serversEntry( "READ" ),
serversEntry( "WRITE" ),
serversEntry( "ROUTE", F, D, A, B, C, E ) ) )
};
Record record = new InternalRecord( asList( "ttl", "servers" ), values );
ClusterComposition composition = ClusterComposition.parse( record, 0 );
assertEquals( 0, composition.readers().size() );
assertEquals( 0, composition.writers().size() );
assertThat( composition.routers(), contains( F, D, A, B, C, E ) );
}
private static ClusterComposition newComposition( long expirationTimestamp, Set<BoltServerAddress> readers,
Set<BoltServerAddress> writers, Set<BoltServerAddress> routers )
{
return new ClusterComposition( expirationTimestamp, readers, writers, routers );
}
private static Set<BoltServerAddress> addresses( BoltServerAddress... elements )
{
return new LinkedHashSet<>( asList( elements ) );
}
private static Map<String,Object> serversEntry( String role, BoltServerAddress... addresses )
{
Map<String,Object> map = new HashMap<>();
map.put( "role", role );
List<String> addressStrings = new ArrayList<>();
for ( BoltServerAddress address : addresses )
{
addressStrings.add( address.toString() );
}
map.put( "addresses", addressStrings );
return map;
}
}