/*
* Copyright 2008-2016 MongoDB, Inc.
*
* 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 com.mongodb.connection;
import com.mongodb.ServerAddress;
import com.mongodb.Tag;
import com.mongodb.TagSet;
import org.bson.types.ObjectId;
import org.junit.Test;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
import static com.mongodb.connection.ServerConnectionState.CONNECTED;
import static com.mongodb.connection.ServerConnectionState.CONNECTING;
import static com.mongodb.connection.ServerDescription.MAX_DRIVER_WIRE_VERSION;
import static com.mongodb.connection.ServerDescription.MIN_DRIVER_WIRE_VERSION;
import static com.mongodb.connection.ServerDescription.builder;
import static com.mongodb.connection.ServerType.REPLICA_SET_PRIMARY;
import static com.mongodb.connection.ServerType.UNKNOWN;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class ServerDescriptionTest {
@Test(expected = IllegalArgumentException.class)
public void testMissingStatus() throws UnknownHostException {
builder().address(new ServerAddress()).type(REPLICA_SET_PRIMARY).build();
}
@Test(expected = IllegalArgumentException.class)
public void testMissingAddress() throws UnknownHostException {
builder().state(CONNECTED).type(REPLICA_SET_PRIMARY).build();
}
@Test
public void testDefaults() throws UnknownHostException {
long currentNanoTime = System.nanoTime();
ServerDescription serverDescription = builder().address(new ServerAddress())
.state(CONNECTED)
.build();
assertEquals(new ServerAddress(), serverDescription.getAddress());
assertFalse(serverDescription.isOk());
assertEquals(CONNECTED, serverDescription.getState());
assertEquals(UNKNOWN, serverDescription.getType());
assertFalse(serverDescription.isReplicaSetMember());
assertFalse(serverDescription.isShardRouter());
assertFalse(serverDescription.isStandAlone());
assertFalse(serverDescription.isPrimary());
assertFalse(serverDescription.isSecondary());
assertEquals(0F, serverDescription.getRoundTripTimeNanos(), 0L);
assertEquals(0x1000000, serverDescription.getMaxDocumentSize());
assertNull(serverDescription.getPrimary());
assertEquals(Collections.<String>emptySet(), serverDescription.getHosts());
assertEquals(new TagSet(), serverDescription.getTagSet());
assertNull(serverDescription.getCanonicalAddress());
assertEquals(Collections.<String>emptySet(), serverDescription.getHosts());
assertEquals(Collections.<String>emptySet(), serverDescription.getPassives());
assertNull(serverDescription.getSetName());
assertEquals(new ServerVersion(), serverDescription.getVersion());
assertEquals(0, serverDescription.getMinWireVersion());
assertEquals(0, serverDescription.getMaxWireVersion());
assertNull(serverDescription.getElectionId());
assertNull(serverDescription.getSetVersion());
assertNull(serverDescription.getLastWriteDate());
assertTrue(serverDescription.getLastUpdateTime(TimeUnit.NANOSECONDS) > currentNanoTime);
assertNull(serverDescription.getException());
}
@Test
public void testBuilder() throws UnknownHostException {
IllegalArgumentException exception = new IllegalArgumentException();
ServerDescription serverDescription = builder()
.address(new ServerAddress("localhost:27018"))
.type(ServerType.REPLICA_SET_PRIMARY)
.tagSet(new TagSet(new Tag("dc", "ny")))
.setName("test")
.maxDocumentSize(100)
.roundTripTime(50000, java.util.concurrent.TimeUnit.NANOSECONDS)
.primary("localhost:27017")
.canonicalAddress("localhost:27018")
.hosts(new HashSet<String>(asList("localhost:27017",
"localhost:27018",
"localhost:27019",
"localhost:27020")))
.arbiters(new HashSet<String>(asList("localhost:27019")))
.passives(new HashSet<String>(asList("localhost:27020")))
.ok(true)
.state(CONNECTED)
.version(new ServerVersion(asList(2, 4, 1)))
.minWireVersion(1)
.maxWireVersion(2)
.electionId(new ObjectId("123412341234123412341234"))
.setVersion(new Integer(2))
.lastWriteDate(new Date(1234L))
.lastUpdateTimeNanos(40000L)
.exception(exception)
.build();
assertEquals(new ServerAddress("localhost:27018"), serverDescription.getAddress());
assertTrue(serverDescription.isOk());
assertEquals(CONNECTED, serverDescription.getState());
assertEquals(REPLICA_SET_PRIMARY, serverDescription.getType());
assertTrue(serverDescription.isReplicaSetMember());
assertFalse(serverDescription.isShardRouter());
assertFalse(serverDescription.isStandAlone());
assertTrue(serverDescription.isPrimary());
assertFalse(serverDescription.isSecondary());
assertEquals(50000, serverDescription.getRoundTripTimeNanos(), 0L);
assertEquals(100, serverDescription.getMaxDocumentSize());
assertEquals("localhost:27017", serverDescription.getPrimary());
assertEquals("localhost:27018", serverDescription.getCanonicalAddress());
assertEquals(new HashSet<String>(asList("localhost:27017", "localhost:27018", "localhost:27019", "localhost:27020")),
serverDescription.getHosts());
assertEquals(new TagSet(new Tag("dc", "ny")), serverDescription.getTagSet());
assertEquals(new HashSet<String>(asList("localhost:27019")), serverDescription.getArbiters());
assertEquals(new HashSet<String>(asList("localhost:27020")), serverDescription.getPassives());
assertEquals("test", serverDescription.getSetName());
assertEquals(new ServerVersion(asList(2, 4, 1)), serverDescription.getVersion());
assertEquals(1, serverDescription.getMinWireVersion());
assertEquals(2, serverDescription.getMaxWireVersion());
assertEquals(new ObjectId("123412341234123412341234"), serverDescription.getElectionId());
assertEquals(new Integer(2), serverDescription.getSetVersion());
assertEquals(new Date(1234), serverDescription.getLastWriteDate());
assertEquals(40000L, serverDescription.getLastUpdateTime(TimeUnit.NANOSECONDS));
assertEquals(exception, serverDescription.getException());
}
@Test
public void testObjectOverrides() throws UnknownHostException {
ServerDescription.Builder builder = createBuilder();
ServerDescription description = builder.build();
assertEquals(description.hashCode(), builder.build().hashCode());
assertTrue(description.toString().startsWith("ServerDescription"));
assertEquals(description, description);
assertNotEquals(description, null);
assertNotEquals(description, "not a ServerDescription instance");
assertEquals(description, builder.build());
ServerDescription otherDescription = createBuilder().address(new ServerAddress("localhost:27018")).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().type(ServerType.STANDALONE).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().tagSet(null).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().setName("test2").build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().maxDocumentSize(200).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().primary("localhost:27018").build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().canonicalAddress("localhost:27018").build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().hosts(new HashSet<String>(asList("localhost:27018"))).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().arbiters(new HashSet<String>(asList("localhost:27018"))).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().passives(new HashSet<String>(asList("localhost:27018"))).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().ok(false).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().state(CONNECTING).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().version(new ServerVersion(asList(2, 6, 1))).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().minWireVersion(2).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().maxWireVersion(5).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().electionId(new ObjectId()).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().setVersion(new Integer(3)).build();
assertNotEquals(builder.build(), otherDescription);
// test exception state changes
assertNotEquals(createBuilder().exception(new IOException()).build(),
createBuilder().exception(new RuntimeException()).build());
assertNotEquals(createBuilder().exception(new IOException("message one")).build(),
createBuilder().exception(new IOException("message two")).build());
// different lastUpdateTime and lastWriteDate are considered not equal but equivalent state
otherDescription = createBuilder().lastUpdateTimeNanos(Long.MAX_VALUE).build();
assertNotEquals(builder.build(), otherDescription);
otherDescription = createBuilder().lastWriteDate(new Date()).build();
assertNotEquals(builder.build(), otherDescription);
assertNotEquals(builder.build(), otherDescription);
// roundTripTime is considered equals and equivalent state
otherDescription = createBuilder().roundTripTime(62, TimeUnit.MILLISECONDS).build();
assertEquals(builder.build(), otherDescription);
}
private ServerDescription.Builder createBuilder() {
return builder().address(new ServerAddress())
.type(ServerType.SHARD_ROUTER)
.tagSet(new TagSet(asList(new Tag("dc", "ny"))))
.setName("test")
.maxDocumentSize(100)
.roundTripTime(50000, TimeUnit.NANOSECONDS)
.primary("localhost:27017")
.canonicalAddress("localhost:27017")
.hosts(new HashSet<String>(asList("localhost:27017", "localhost:27018")))
.passives(new HashSet<String>(asList("localhost:27019")))
.arbiters(new HashSet<String>(asList("localhost:27020")))
.ok(true)
.state(CONNECTED)
.version(new ServerVersion(asList(2, 4, 1)))
.minWireVersion(1)
.lastWriteDate(new Date())
.maxWireVersion(2)
.electionId(new ObjectId("abcdabcdabcdabcdabcdabcd"))
.setVersion(new Integer(2))
.lastUpdateTimeNanos(1)
.lastWriteDate(new Date(42))
.roundTripTime(56, TimeUnit.MILLISECONDS);
}
@Test
public void testObjectOverridesWithUnequalException() throws UnknownHostException {
ServerDescription.Builder builder1 = builder()
.state(CONNECTING)
.address(new ServerAddress())
.exception(new IllegalArgumentException("This is illegal"));
ServerDescription.Builder builder2 = builder()
.state(CONNECTING)
.address(new ServerAddress())
.exception(new IllegalArgumentException("This is also illegal"));
ServerDescription.Builder builder3 = builder()
.state(CONNECTING)
.address(new ServerAddress())
.exception(new IllegalStateException("This is illegal"));
ServerDescription.Builder builder4 = builder()
.state(CONNECTING)
.address(new ServerAddress());
assertThat(builder1.build(), not(builder2.build()));
assertThat(builder1.build().hashCode(), not(builder2.build().hashCode()));
assertThat(builder1.build(), not(builder3.build()));
assertThat(builder1.build().hashCode(), not(builder3.build().hashCode()));
assertThat(builder1.build(), not(builder4.build()));
assertThat(builder1.build().hashCode(), not(builder4.build().hashCode()));
assertThat(builder4.build(), not(builder3.build()));
assertThat(builder4.build().hashCode(), not(builder3.build().hashCode()));
}
@Test
public void testShortDescription() throws UnknownHostException {
assertEquals("{address=127.0.0.1:27017, type=UNKNOWN, TagSet{[Tag{name='dc', value='ny'}, Tag{name='rack', value='1'}]}, "
+ "roundTripTime=5000.0 ms, state=CONNECTED, exception={java.lang.IllegalArgumentException: This is illegal}, "
+ "caused by {java.lang.NullPointerException: This is null}}",
builder().state(CONNECTED)
.address(new ServerAddress())
.roundTripTime(5000, TimeUnit.MILLISECONDS)
.tagSet(new TagSet(asList(new Tag("dc", "ny"), new Tag("rack", "1"))))
.exception(new IllegalArgumentException("This is illegal", new NullPointerException("This is null")))
.build()
.getShortDescription());
}
@Test
public void testIsPrimaryAndIsSecondary() throws UnknownHostException {
ServerDescription serverDescription = builder()
.address(new ServerAddress())
.type(ServerType.SHARD_ROUTER)
.ok(false)
.state(CONNECTED)
.build();
assertFalse(serverDescription.isPrimary());
assertFalse(serverDescription.isSecondary());
serverDescription = builder()
.address(new ServerAddress())
.type(ServerType.SHARD_ROUTER)
.ok(true)
.state(CONNECTED)
.build();
assertTrue(serverDescription.isPrimary());
assertTrue(serverDescription.isSecondary());
serverDescription = builder()
.address(new ServerAddress())
.type(ServerType.STANDALONE)
.ok(true)
.state(CONNECTED)
.build();
assertTrue(serverDescription.isPrimary());
assertTrue(serverDescription.isSecondary());
serverDescription = builder()
.address(new ServerAddress())
.type(REPLICA_SET_PRIMARY)
.ok(true)
.state(CONNECTED)
.build();
assertTrue(serverDescription.isPrimary());
assertFalse(serverDescription.isSecondary());
serverDescription = builder()
.address(new ServerAddress())
.type(ServerType.REPLICA_SET_SECONDARY)
.ok(true)
.state(CONNECTED)
.build();
assertFalse(serverDescription.isPrimary());
assertTrue(serverDescription.isSecondary());
}
@Test
public void testHasTags() throws UnknownHostException {
ServerDescription serverDescription = builder()
.address(new ServerAddress())
.type(ServerType.SHARD_ROUTER)
.ok(false)
.state(CONNECTED)
.build();
assertFalse(serverDescription.hasTags(new TagSet(asList(new Tag("dc", "ny")))));
serverDescription = builder()
.address(new ServerAddress())
.type(ServerType.SHARD_ROUTER)
.ok(true)
.state(CONNECTED)
.build();
assertTrue(serverDescription.hasTags(new TagSet(asList(new Tag("dc", "ny")))));
serverDescription = builder()
.address(new ServerAddress())
.type(ServerType.STANDALONE)
.ok(true)
.state(CONNECTED)
.build();
assertTrue(serverDescription.hasTags(new TagSet(asList(new Tag("dc", "ny")))));
serverDescription = builder()
.address(new ServerAddress())
.type(REPLICA_SET_PRIMARY)
.ok(true)
.state(CONNECTED)
.build();
assertTrue(serverDescription.hasTags(new TagSet()));
serverDescription = builder()
.address(new ServerAddress())
.type(REPLICA_SET_PRIMARY)
.ok(true)
.tagSet(new TagSet(asList(new Tag("dc", "ca"))))
.state(CONNECTED)
.build();
assertFalse(serverDescription.hasTags(new TagSet(asList(new Tag("dc", "ny")))));
serverDescription = builder()
.address(new ServerAddress())
.type(REPLICA_SET_PRIMARY)
.ok(true)
.tagSet(new TagSet(asList(new Tag("rack", "1"))))
.state(CONNECTED)
.build();
assertFalse(serverDescription.hasTags(new TagSet(asList(new Tag("rack", "2")))));
serverDescription = builder()
.address(new ServerAddress())
.type(REPLICA_SET_PRIMARY)
.ok(true)
.tagSet(new TagSet(asList(new Tag("rack", "1"))))
.state(CONNECTED)
.build();
assertTrue(serverDescription.hasTags(new TagSet(asList(new Tag("rack", "1")))));
}
@Test
public void notOkServerShouldBeCompatible() throws UnknownHostException {
assertTrue(builder()
.address(new ServerAddress())
.state(CONNECTING)
.ok(false)
.build()
.isCompatibleWithDriver());
}
@Test
public void serverWithMinWireVersionEqualToDriverMaxWireVersionShouldBeCompatible() throws UnknownHostException {
assertTrue(builder()
.address(new ServerAddress())
.state(CONNECTING)
.ok(true)
.minWireVersion(MAX_DRIVER_WIRE_VERSION)
.maxWireVersion(MAX_DRIVER_WIRE_VERSION + 1)
.build()
.isCompatibleWithDriver());
}
@Test
public void serverWithMaxWireVersionEqualToDriverMinWireVersionShouldBeCompatible() throws UnknownHostException {
assertTrue(builder()
.address(new ServerAddress())
.state(CONNECTING)
.ok(true)
.minWireVersion(MIN_DRIVER_WIRE_VERSION - 1)
.maxWireVersion(MIN_DRIVER_WIRE_VERSION)
.build()
.isCompatibleWithDriver());
}
@Test
public void serverWithMinWireVersionGreaterThanDriverMaxWireVersionShouldBeIncompatible() throws UnknownHostException {
assertFalse(builder()
.address(new ServerAddress())
.state(CONNECTING)
.ok(true)
.minWireVersion(MAX_DRIVER_WIRE_VERSION + 1)
.maxWireVersion(MAX_DRIVER_WIRE_VERSION + 1)
.build()
.isCompatibleWithDriver());
}
@Test
public void serverWithMaxWireVersionLessThanDriverMinWireVersionShouldBeIncompatible() throws UnknownHostException {
assertFalse(builder()
.address(new ServerAddress())
.state(CONNECTING)
.ok(true)
.minWireVersion(MIN_DRIVER_WIRE_VERSION - 1)
.maxWireVersion(MIN_DRIVER_WIRE_VERSION - 1)
.build()
.isCompatibleWithDriver());
}
}