private void stopOwnerNode(ExampleServiceState serviceState) { // find owner and stop it VerificationHost owner = null; for (VerificationHost h : this.cluster.getInProcessHostMap().values()) { if (!h.getId().equals(serviceState.documentOwner)) { peerHost = h; } else { owner = h; } } owner.log(Level.INFO, "Stopping owner node %s...", owner.getId()); // Patching the NodeGroupConfig so the stopped node get "kicked" from the group faster. NodeGroupConfig cfg = new NodeGroupConfig(); cfg.nodeRemovalDelayMicros = TimeUnit.SECONDS.toMicros(2); this.cluster.setNodeGroupConfig(cfg); this.cluster.stopHost(owner); cluster.waitForReplicatedFactoryServiceAvailable(UriUtils.buildUri(peerHost, ExampleService.FACTORY_LINK)); }
@Test public void findOwnerNode() throws Throwable { setUp(false); int nodeCount = 3; int pathVerificationCount = 3; this.host.setUpPeerHosts(nodeCount); this.host.joinNodesAndVerifyConvergence(nodeCount, true); this.host.setNodeGroupQuorum(nodeCount); // each host should say same owner for the path for (int i = 0; i < pathVerificationCount; i++) { String path = UUID.randomUUID().toString(); Map<String, String> map = new HashMap<>(); Set<String> ownerIds = new HashSet<>(); for (VerificationHost h : this.host.getInProcessHostMap().values()) { String ownerId = h.findOwnerNode(null, path).ownerNodeId; map.put(h.getId(), ownerId); ownerIds.add(ownerId); } assertThat(ownerIds).as("all peers say same owner for %s. %s", path, map).hasSize(1); } }
@Test public void findOwnerNode() throws Throwable { setUp(false); int nodeCount = 3; int pathVerificationCount = 3; this.host.setUpPeerHosts(nodeCount); this.host.joinNodesAndVerifyConvergence(nodeCount, true); this.host.setNodeGroupQuorum(nodeCount); // each host should say same owner for the path for (int i = 0; i < pathVerificationCount; i++) { String path = UUID.randomUUID().toString(); Map<String, String> map = new HashMap<>(); Set<String> ownerIds = new HashSet<>(); for (VerificationHost h : this.host.getInProcessHostMap().values()) { String ownerId = h.findOwnerNode(null, path).ownerNodeId; map.put(h.getId(), ownerId); ownerIds.add(ownerId); } assertThat(ownerIds).as("all peers say same owner for %s. %s", path, map).hasSize(1); } }
private void verifyLinks(String nextPageLink, List<URI> serviceURIs, QueryTask page) { assertEquals(QueryPageService.KIND, page.documentKind); assertNotEquals(nextPageLink, page.results.nextPageLink); assertNotEquals(nextPageLink, page.results.prevPageLink); if (serviceURIs.size() >= 1) { URI currentPageForwardUri = UriUtils.buildForwardToQueryPageUri( UriUtils.buildUri(this.host, page.documentSelfLink), this.host.getId()); String currentPageLink = currentPageForwardUri.getPath() + UriUtils.URI_QUERY_CHAR + currentPageForwardUri.getQuery(); assertEquals(serviceURIs.get(serviceURIs.size() - 1), UriUtils.buildUri(this.host, currentPageLink)); } if (serviceURIs.size() >= 2) { assertEquals(serviceURIs.get(serviceURIs.size() - 2), UriUtils.buildUri(this.host, page.results.prevPageLink)); } else { assertEquals(null, page.results.prevPageLink); } }
private void verifyLinks(String nextPageLink, List<URI> serviceURIs, QueryTask page) { assertEquals(QueryPageService.KIND, page.documentKind); assertNotEquals(nextPageLink, page.results.nextPageLink); assertNotEquals(nextPageLink, page.results.prevPageLink); if (serviceURIs.size() >= 1) { URI currentPageForwardUri = UriUtils.buildForwardToQueryPageUri( UriUtils.buildUri(this.host, page.documentSelfLink), this.host.getId()); String currentPageLink = currentPageForwardUri.getPath() + UriUtils.URI_QUERY_CHAR + currentPageForwardUri.getQuery(); assertEquals(serviceURIs.get(serviceURIs.size() - 1), UriUtils.buildUri(this.host, currentPageLink)); } if (serviceURIs.size() >= 2) { assertEquals(serviceURIs.get(serviceURIs.size() - 2), UriUtils.buildUri(this.host, page.results.prevPageLink)); } else { assertEquals(null, page.results.prevPageLink); } }
@Test public void buildChildSelfLink() throws Throwable { SomeFactoryService f = new SomeFactoryService(); f = (SomeFactoryService) this.host.startServiceAndWait(f, UUID.randomUUID().toString(), null); // this test assumes how the implementation works. If we change // the implementation, it will break, by design String idHash = Utils.computeHash(this.host.getId()); assertTrue(f.buildDefaultChildSelfLink().startsWith(idHash)); long s = System.nanoTime(); for (int i = 0; i < this.iterationCount; i++) { assertTrue(f.buildDefaultChildSelfLink() != null); } long e = System.nanoTime(); double thpt = (double) this.iterationCount / (e - s); thpt *= TimeUnit.SECONDS.toNanos(1); this.host.log("throughput (calls/sec) %f", thpt); s = System.nanoTime(); for (int i = 0; i < this.iterationCount; i++) { assertTrue(UUID.randomUUID().toString() != null); } e = System.nanoTime(); thpt = (double) this.iterationCount / (e - s); thpt *= TimeUnit.SECONDS.toNanos(1); this.host.log("UUID.randomUUID().toString() throughput (calls/sec) %f", thpt); }
@Test public void buildChildSelfLink() throws Throwable { SomeFactoryService f = new SomeFactoryService(); f = (SomeFactoryService) this.host.startServiceAndWait(f, UUID.randomUUID().toString(), null); // this test assumes how the implementation works. If we change // the implementation, it will break, by design String idHash = Utils.computeHash(this.host.getId()); assertTrue(f.buildDefaultChildSelfLink().startsWith(idHash)); long s = System.nanoTime(); for (int i = 0; i < this.iterationCount; i++) { assertTrue(f.buildDefaultChildSelfLink() != null); } long e = System.nanoTime(); double thpt = (double) this.iterationCount / (e - s); thpt *= TimeUnit.SECONDS.toNanos(1); this.host.log("throughput (calls/sec) %f", thpt); s = System.nanoTime(); for (int i = 0; i < this.iterationCount; i++) { assertTrue(UUID.randomUUID().toString() != null); } e = System.nanoTime(); thpt = (double) this.iterationCount / (e - s); thpt *= TimeUnit.SECONDS.toNanos(1); this.host.log("UUID.randomUUID().toString() throughput (calls/sec) %f", thpt); }
.filter(host -> host.getId().contentEquals(state.documentOwner)).findFirst() .orElseThrow(() -> new RuntimeException("couldn't find owner node"));
@Before public void setUp() throws Throwable { waitForServiceAvailability(ContainerDescriptionService.FACTORY_LINK); waitForServiceAvailability(CompositeDescriptionFactoryService.SELF_LINK); waitForServiceAvailability(ContainerFactoryService.SELF_LINK); state = new ContainerState(); state.id = updatedTestId; state.image = updatedTestValue; state = doPost(state, ContainerFactoryService.SELF_LINK); results = Collections.synchronizedList(new ArrayList<>()); subscriptionManager = new SubscriptionManager<>( host, host.getId(), state.documentSelfLink, ContainerState.class); waitForServiceAvailability(ServiceUriPaths.CORE_QUERY_TASKS); waitForServiceAvailability(state.documentSelfLink); }
@Test public void testSimpleServe() { String existingFile = "/serviceHostState.json"; Operation re = this.host.getTestRequestSender() .sendAndWait(Operation.createGet(this.host, SELF_LINK + existingFile)); ServiceHostState hs = re.getBody(ServiceHostState.class); assertEquals(this.host.getId(), hs.id); }
private int checkChildServicesIfStarted(Set<String> exampleTaskLinks, VerificationHost host) { this.host.setSystemAuthorizationContext(); int notStartedCount = 0; for (String s : exampleTaskLinks) { ProcessingStage st = host.getServiceStage(s); if (st == null) { notStartedCount++; } } this.host.resetAuthorizationContext(); if (notStartedCount > 0) { this.host.log("%d services not started on %s (%s)", notStartedCount, host.getPublicUri(), host.getId()); } return notStartedCount; }
@Test public void testSimpleServe() { String existingFile = "/serviceHostState.json"; Operation re = this.host.getTestRequestSender() .sendAndWait(Operation.createGet(this.host, SELF_LINK + existingFile)); ServiceHostState hs = re.getBody(ServiceHostState.class); assertEquals(this.host.getId(), hs.id); }
private int checkChildServicesIfStarted(Set<String> exampleTaskLinks, VerificationHost host) { this.host.setSystemAuthorizationContext(); int notStartedCount = 0; for (String s : exampleTaskLinks) { ProcessingStage st = host.getServiceStage(s); if (st == null) { notStartedCount++; } } this.host.resetAuthorizationContext(); if (notStartedCount > 0) { this.host.log("%d services not started on %s (%s)", notStartedCount, host.getPublicUri(), host.getId()); } return notStartedCount; }
@Test public void synchronizationRequest() throws Throwable { setUpMultiNode(); VerificationHost peer = this.host.getPeerHost(); peer.waitForReplicatedFactoryServiceAvailable(UriUtils.buildUri(peer, ExampleService.FACTORY_LINK)); List<URI> exampleServices = peer.createExampleServices(peer, this.serviceCount, null); URI serviceUri = UriUtils.buildUri(peer, SynchronizationManagementService.class); String owner = waitForStatus(peer, status -> status.equals(SynchronizationManagementState.Status.AVAILABLE)); peer = this.host.getInProcessHostMap().values().stream().filter(h -> h.getId().equals(owner)).collect(toList()).get(0); // Set factory unavailable setFactoryAvailability(peer, 0.0); waitForStatus(peer, status -> !status.equals(SynchronizationManagementState.Status.AVAILABLE)); // Call the synchronization API and verify that factory is available afterwards. SynchronizationRequest request = SynchronizationRequest.create(); request.documentSelfLink = ExampleService.FACTORY_LINK; this.sender.sendAndWait(Operation.createPatch(serviceUri).setBody(request)); waitForStatus(peer, status -> status.equals(SynchronizationManagementState.Status.AVAILABLE)); // Verify synchronization on a single child service passes. request.documentSelfLink = exampleServices.get(0).getPath(); this.sender.sendAndWait(Operation.createPatch(serviceUri).setBody(request)); // Verify calling with fake factory fails. request.documentSelfLink = "/core/fake-factory"; this.sender.sendAndWaitFailure(Operation.createPatch(serviceUri).setBody(request)); // Verify calling with fake kind fails. request.kind = "fake"; request.documentSelfLink = ExampleService.FACTORY_LINK; this.sender.sendAndWaitFailure(Operation.createPatch(serviceUri).setBody(request)); }
@Test public void synchronizationRequest() throws Throwable { setUpMultiNode(); VerificationHost peer = this.host.getPeerHost(); peer.waitForReplicatedFactoryServiceAvailable(UriUtils.buildUri(peer, ExampleService.FACTORY_LINK)); List<URI> exampleServices = peer.createExampleServices(peer, this.serviceCount, null); URI serviceUri = UriUtils.buildUri(peer, SynchronizationManagementService.class); String owner = waitForStatus(peer, status -> status.equals(SynchronizationManagementState.Status.AVAILABLE)); peer = this.host.getInProcessHostMap().values().stream().filter(h -> h.getId().equals(owner)).collect(toList()).get(0); // Set factory unavailable setFactoryAvailability(peer, 0.0); waitForStatus(peer, status -> !status.equals(SynchronizationManagementState.Status.AVAILABLE)); // Call the synchronization API and verify that factory is available afterwards. SynchronizationRequest request = SynchronizationRequest.create(); request.documentSelfLink = ExampleService.FACTORY_LINK; this.sender.sendAndWait(Operation.createPatch(serviceUri).setBody(request)); waitForStatus(peer, status -> status.equals(SynchronizationManagementState.Status.AVAILABLE)); // Verify synchronization on a single child service passes. request.documentSelfLink = exampleServices.get(0).getPath(); this.sender.sendAndWait(Operation.createPatch(serviceUri).setBody(request)); // Verify calling with fake factory fails. request.documentSelfLink = "/core/fake-factory"; this.sender.sendAndWaitFailure(Operation.createPatch(serviceUri).setBody(request)); // Verify calling with fake kind fails. request.kind = "fake"; request.documentSelfLink = ExampleService.FACTORY_LINK; this.sender.sendAndWaitFailure(Operation.createPatch(serviceUri).setBody(request)); }
private SubscriptionManager<ExampleServiceState> subscribe(ServiceHost h, ExampleServiceState serviceState, Consumer<SubscriptionNotification<ExampleServiceState>> notificationConsumer) { SubscriptionManager<ExampleServiceState> subscriptionManager = new SubscriptionManager<>( h, h.getId(), serviceState.documentSelfLink, ExampleServiceState.class); TestContext ctx = new TestContext(1, Duration.ofSeconds(SUBSCRIPTION_START_TIMEOUT_SECONDS)); String subscriptionServiceLink; // This single element array is used to extract the result from lambda. final String[] subscriptionServiceLinkResult = new String[1]; subscriptionManager.start(notificationConsumer, (subscriptionLink) -> { subscriptionServiceLinkResult[0] = subscriptionLink; ctx.completeIteration(); }); ctx.await(); subscriptionServiceLink = subscriptionServiceLinkResult[0]; cluster.log(Level.INFO, "Waiting for subscription for %s on host %s", serviceState.documentSelfLink, cluster.getId()); TestContext testCtx = new TestContext(1, Duration.ofSeconds(SUBSCRIPTION_START_TIMEOUT_SECONDS)); h.registerForServiceAvailability((o, e) -> { if (e != null) { testCtx.fail(e); } else { testCtx.complete(); } }, subscriptionServiceLink); testCtx.await(); return subscriptionManager; }
@Test public void statelessWithOwnerSelectionWithoutReplication() throws Throwable { setUpMultiNode(); TestRequestSender sender = new TestRequestSender(this.host); Operation op = Operation.createGet(this.host.getPeerHost(), StatelessOwnerSelectedTestService.SELF_LINK); ServiceDocument doc = sender.sendAndWait(op, ServiceDocument.class); VerificationHost owner = this.host.getOwnerPeer(doc.documentSelfLink, ServiceUriPaths.DEFAULT_NODE_SELECTOR); // Verify a new owner is selected after original owner stopped. this.host.stopHost(owner); op = Operation.createGet(this.host.getPeerHost(), StatelessOwnerSelectedTestService.SELF_LINK); ServiceDocument doc1 = sender.sendAndWait(op, ServiceDocument.class); assertNotEquals(doc.documentOwner, doc1.documentOwner); owner = this.host.getOwnerPeer(doc.documentSelfLink, ServiceUriPaths.DEFAULT_NODE_SELECTOR); // Create new nodes until we find a new owner for our test service. String newOwnerId = owner.getId(); while (owner.getId().equals(newOwnerId)) { VerificationHost newHost = this.host.setUpLocalPeerHost(0, VerificationHost.FAST_MAINT_INTERVAL_MILLIS, null, null); this.host.joinNodesAndVerifyConvergence(this.host.getPeerCount()); newOwnerId = this.host.getOwnerPeer(doc.documentSelfLink, ServiceUriPaths.DEFAULT_NODE_SELECTOR).getId(); newHost.startServiceAndWait(new StatelessOwnerSelectedTestService(), StatelessOwnerSelectedTestService.SELF_LINK, null); } op = Operation.createGet(this.host.getPeerHost(), StatelessOwnerSelectedTestService.SELF_LINK); ServiceDocument doc2 = sender.sendAndWait(op, ServiceDocument.class); assertNotEquals(doc1.documentOwner, doc2.documentOwner); assertEquals(newOwnerId, doc2.documentOwner); }
@Test public void statelessWithOwnerSelectionWithoutReplication() throws Throwable { setUpMultiNode(); TestRequestSender sender = new TestRequestSender(this.host); Operation op = Operation.createGet(this.host.getPeerHost(), StatelessOwnerSelectedTestService.SELF_LINK); ServiceDocument doc = sender.sendAndWait(op, ServiceDocument.class); VerificationHost owner = this.host.getOwnerPeer(doc.documentSelfLink, ServiceUriPaths.DEFAULT_NODE_SELECTOR); // Verify a new owner is selected after original owner stopped. this.host.stopHost(owner); op = Operation.createGet(this.host.getPeerHost(), StatelessOwnerSelectedTestService.SELF_LINK); ServiceDocument doc1 = sender.sendAndWait(op, ServiceDocument.class); assertNotEquals(doc.documentOwner, doc1.documentOwner); owner = this.host.getOwnerPeer(doc.documentSelfLink, ServiceUriPaths.DEFAULT_NODE_SELECTOR); // Create new nodes until we find a new owner for our test service. String newOwnerId = owner.getId(); while (owner.getId().equals(newOwnerId)) { VerificationHost newHost = this.host.setUpLocalPeerHost(0, VerificationHost.FAST_MAINT_INTERVAL_MILLIS, null, null); this.host.joinNodesAndVerifyConvergence(this.host.getPeerCount()); newOwnerId = this.host.getOwnerPeer(doc.documentSelfLink, ServiceUriPaths.DEFAULT_NODE_SELECTOR).getId(); newHost.startServiceAndWait(new StatelessOwnerSelectedTestService(), StatelessOwnerSelectedTestService.SELF_LINK, null); } op = Operation.createGet(this.host.getPeerHost(), StatelessOwnerSelectedTestService.SELF_LINK); ServiceDocument doc2 = sender.sendAndWait(op, ServiceDocument.class); assertNotEquals(doc1.documentOwner, doc2.documentOwner); assertEquals(newOwnerId, doc2.documentOwner); }