public MockPartitionServerHandler(ByteBuffer result) { this.response = HankResponse.value(result); List<HankResponse> responses = new ArrayList<HankResponse>(); responses.add(HankResponse.value(result)); this.bulkResponse = HankBulkResponse.responses(responses); }
@Test public void testIt() throws Exception { int server1Port = 12345; int server2Port = 12346; int server3Port = 12347; // launch server 1 final MockPartitionServerHandler iface1 = new MockPartitionServerHandler(VALUE_1); TNonblockingServerTransport transport1 = createPartitionServerTransport(server1Port); final TServer server1 = createPartitionServer(transport1, iface1); Thread thread1 = new Thread(new ServerRunnable(server1), "mock partition server thread 1"); thread1.start(); // launch server 2; final MockPartitionServerHandler iface2 = new MockPartitionServerHandler(VALUE_2); TNonblockingServerTransport transport2 = createPartitionServerTransport(server2Port); final TServer server2 = createPartitionServer(transport2, iface2); Thread thread2 = new Thread(new ServerRunnable(server2), "mock partition server thread 2"); thread2.start(); // launch server 3; final MockPartitionServerHandler iface3 = new MockPartitionServerHandler(VALUE_3); TNonblockingServerTransport transport3 = createPartitionServerTransport(server3Port); final TServer server3 = createPartitionServer(transport3, iface3); Thread thread3 = new Thread(new ServerRunnable(server3), "mock partition server thread 3"); thread3.start(); final MockDomain existentDomain = new MockDomain( "existent_domain", 0, 2, new MapPartitioner(KEY_1, 0, KEY_2, 1, KEY_NOT_FOUND, 0), null, null, null); final MockDomain newDomain = new MockDomain("new_domain", 1, 1, new MapPartitioner(KEY_3, 0), null, null, null); final Host host1 = getHost(existentDomain, new PartitionServerAddress("localhost", server1Port), 0); final Host host2 = getHost(existentDomain, new PartitionServerAddress("localhost", server2Port), 1); final Host host3 = getHost(newDomain, new PartitionServerAddress("localhost", server3Port), 0); final Set<Host> mockRingHosts = new HashSet<Host>(); mockRingHosts.add(host1); mockRingHosts.add(host2); final MockRing mockRing = new MockRing(null, null, 1) { @Override public Set<Host> getHosts() { return mockRingHosts; } }; MockDomainGroup mockDomainGroup = new MockDomainGroup("myDomainGroup") { @Override public Set<DomainAndVersion> getDomainVersions() { return new HashSet<DomainAndVersion>( Arrays.asList(new DomainAndVersion(existentDomain, 1))); } }; final MockRingGroup mockRingGroup = new MockRingGroup(mockDomainGroup, "myRingGroup", null) { @Override public Set<Ring> getRings() { return Collections.singleton((Ring) mockRing); } }; Coordinator mockCoord = new MockCoordinator() { @Override public RingGroup getRingGroup(String ringGroupName) { return mockRingGroup; } @Override public Domain getDomain(String domainName) { if (domainName.equals("existent_domain")) { return existentDomain; } else if (domainName.equals("new_domain")) { return newDomain; } else { return null; } } }; WaitUntil.orDie( new Condition() { @Override public boolean test() { return server1.isServing() && server2.isServing() && server3.isServing(); } }); try { final HankSmartClient client = new HankSmartClient( mockCoord, "myRingGroup", new HankSmartClientOptions().setQueryTimeoutMs(1000)); final HankSmartClient cachingClient = new HankSmartClient( mockCoord, "myRingGroup", new HankSmartClientOptions() .setResponseCacheEnabled(true) .setResponseCacheNumItemsCapacity(1) .setResponseCacheNumBytesCapacity(-1) .setResponseCacheExpirationSeconds(1)); // Test invalid get assertEquals( HankResponse.xception(HankException.no_such_domain(true)), client.get("nonexistent_domain", null)); // Test get assertEquals(HankResponse.value(VALUE_1), client.get("existent_domain", KEY_1)); assertEquals(HankResponse.value(VALUE_2), client.get("existent_domain", KEY_2)); // Test invalid getBulk assertEquals( HankBulkResponse.xception(HankException.no_such_domain(true)), client.getBulk("nonexistent_domain", null)); // Test getBulk HankBulkResponse bulkResponse1 = HankBulkResponse.responses(new ArrayList<HankResponse>()); bulkResponse1.get_responses().add(HankResponse.value(VALUE_1)); bulkResponse1.get_responses().add(HankResponse.value(VALUE_2)); List<ByteBuffer> bulkRequest1 = new ArrayList<ByteBuffer>(); bulkRequest1.add(KEY_1); bulkRequest1.add(KEY_2); assertEquals(bulkResponse1, client.getBulk("existent_domain", bulkRequest1)); // Test get with null key try { client.get("existent_domain", null); fail("Should throw an exception."); } catch (NullKeyException e) { // Good } // Test get with empty key try { client.get("existent_domain", ByteBuffer.wrap(new byte[0])); fail("Should throw an exception."); } catch (EmptyKeyException e) { // Good } // Host is not available host1.setState(HostState.UPDATING); assertEquals( HankResponse.xception(HankException.no_connection_available(true)), client.get("existent_domain", KEY_1)); // Host is offline but it's the only one, use it opportunistically host2.setState(HostState.OFFLINE); assertEquals(HankResponse.value(VALUE_2), client.get("existent_domain", KEY_2)); host1.setState(HostState.SERVING); host2.setState(HostState.SERVING); // Test location changes // Add new host that has new domain mockRingHosts.add(host3); // Should not be able to query new domain assertTrue(client.get("new_domain", KEY_3).get_xception().is_set_no_replica()); // Notify client of data location change client.onDataLocationChange(mockCoord.getRingGroup("myRingGroup")); // Should be able to query new domain when the client has done updating its cache WaitUntil.orDie( new Condition() { @Override public boolean test() { return HankResponse.value(VALUE_3).equals(client.get("new_domain", KEY_3)); } }); assertEquals(HankResponse.value(VALUE_3), client.get("new_domain", KEY_3)); // TODO: Test not querying deletable partitions // Simulate servers that fail to perform gets iface1.setMode(MockPartitionServerHandler.Mode.FAILING); iface2.setMode(MockPartitionServerHandler.Mode.FAILING); assertTrue(client.get("existent_domain", KEY_1).get_xception().get_failed_retries() > 0); assertTrue(client.get("existent_domain", KEY_2).get_xception().get_failed_retries() > 0); // Simulate servers that throws an error iface1.setMode(MockPartitionServerHandler.Mode.THROWING_ERROR); iface2.setMode(MockPartitionServerHandler.Mode.THROWING_ERROR); assertTrue(client.get("existent_domain", KEY_1).get_xception().get_failed_retries() > 0); assertTrue(client.get("existent_domain", KEY_2).get_xception().get_failed_retries() > 0); // Simulate servers that hangs iface1.setMode(MockPartitionServerHandler.Mode.HANGING); iface2.setMode(MockPartitionServerHandler.Mode.HANGING); assertTrue(client.get("existent_domain", KEY_1).get_xception().get_failed_retries() > 0); assertTrue(client.get("existent_domain", KEY_2).get_xception().get_failed_retries() > 0); // Test caching iface1.setMode(MockPartitionServerHandler.Mode.NORMAL); iface2.setMode(MockPartitionServerHandler.Mode.NORMAL); iface3.setMode(MockPartitionServerHandler.Mode.NORMAL); iface1.clearNumRequests(); // One request assertEquals(HankResponse.value(VALUE_1), cachingClient.get("existent_domain", KEY_1)); assertEquals(1, iface1.getNumRequests()); // One cached request assertEquals(HankResponse.value(VALUE_1), cachingClient.get("existent_domain", KEY_1)); assertEquals(1, iface1.getNumRequests()); iface1.clearNumRequests(); // One not found request assertEquals( HankResponse.not_found(true), cachingClient.get("existent_domain", KEY_NOT_FOUND)); assertEquals(1, iface1.getNumRequests()); // One not found cached request assertEquals( HankResponse.not_found(true), cachingClient.get("existent_domain", KEY_NOT_FOUND)); assertEquals(1, iface1.getNumRequests()); // Wait for cache to expire Thread.sleep(2000); // Should not be in cache anymore assertEquals( HankResponse.not_found(true), cachingClient.get("existent_domain", KEY_NOT_FOUND)); assertEquals(2, iface1.getNumRequests()); } finally { server1.stop(); server2.stop(); thread1.join(); thread2.join(); transport1.close(); transport2.close(); } }