Repository: incubator-slider Updated Branches: refs/heads/develop 2c4ceb6ba -> 313f9eea7
SLIDER-1199 Blacklist nodes that exceed the node failure threshold for a role Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/313f9eea Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/313f9eea Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/313f9eea Branch: refs/heads/develop Commit: 313f9eea75e8ae09d7267434dd48dd6456bc068b Parents: 2c4ceb6 Author: Billie Rinaldi <bil...@apache.org> Authored: Wed Feb 8 19:28:27 2017 -0800 Committer: Billie Rinaldi <bil...@apache.org> Committed: Wed Feb 8 20:04:46 2017 -0800 ---------------------------------------------------------------------- .../providers/AbstractProviderService.java | 6 ++ .../server/appmaster/SliderAppMaster.java | 8 +- .../appmaster/actions/ResetFailureWindow.java | 14 ++- .../operations/AsyncRMOperationHandler.java | 6 ++ .../ProviderNotifyingOperationHandler.java | 8 ++ .../operations/RMOperationHandlerActions.java | 8 ++ .../operations/UpdateBlacklistOperation.java | 42 ++++++++ .../slider/server/appmaster/state/AppState.java | 19 ++++ .../server/appmaster/state/NodeInstance.java | 10 ++ .../server/appmaster/state/RoleHistory.java | 34 +++++++ .../TestMockAppStateContainerFailure.groovy | 22 ++-- .../TestRoleHistoryUpdateBlacklist.groovy | 101 +++++++++++++++++++ .../server/appmaster/model/mock/MockAM.groovy | 23 +++++ .../appmaster/model/mock/MockFactory.groovy | 12 ++- .../model/mock/MockProviderService.groovy | 6 ++ .../model/mock/MockRMOperationHandler.groovy | 9 ++ 16 files changed, 311 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java index 92766f5..030fe1a 100644 --- a/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java +++ b/slider-core/src/main/java/org/apache/slider/providers/AbstractProviderService.java @@ -410,6 +410,12 @@ public abstract class AbstractProviderService } @Override + public void updateBlacklist(List<String> blacklistAdditions, + List<String> blacklistRemovals) { + // no-op + } + + @Override public void execute(List<AbstractRMOperation> operations) { for (AbstractRMOperation operation : operations) { operation.execute(this); http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java index bb9e418..8e45fe4 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java @@ -1874,7 +1874,7 @@ public class SliderAppMaster extends AbstractSliderLaunchedService */ private void scheduleFailureWindowResets(ConfTree resources) throws BadConfigException { - ResetFailureWindow reset = new ResetFailureWindow(); + ResetFailureWindow reset = new ResetFailureWindow(rmOperationHandler); ConfTreeOperations ops = new ConfTreeOperations(resources); MapOperations globals = ops.getGlobalOptions(); long seconds = globals.getTimeRange(ResourceKeys.CONTAINER_FAILURE_WINDOW, @@ -2112,6 +2112,12 @@ public class SliderAppMaster extends AbstractSliderLaunchedService rmOperationHandler.cancelSingleRequest(request); } + @Override + public void updateBlacklist(List<String> blacklistAdditions, + List<String> blacklistRemovals) { + rmOperationHandler.updateBlacklist(blacklistAdditions, blacklistRemovals); + } + /* =================================================================== */ /* END */ /* =================================================================== */ http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ResetFailureWindow.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ResetFailureWindow.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ResetFailureWindow.java index 28bcf55..36f58dd 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ResetFailureWindow.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ResetFailureWindow.java @@ -19,21 +19,31 @@ package org.apache.slider.server.appmaster.actions; import org.apache.slider.server.appmaster.SliderAppMaster; +import org.apache.slider.server.appmaster.operations.AbstractRMOperation; +import org.apache.slider.server.appmaster.operations.RMOperationHandlerActions; import org.apache.slider.server.appmaster.state.AppState; /** * Requests the AM to reset the failure window */ public class ResetFailureWindow extends AsyncAction { + private final RMOperationHandlerActions operationHandler; - public ResetFailureWindow() { + public ResetFailureWindow(RMOperationHandlerActions operationHandler) { super("ResetFailureWindow"); + this.operationHandler = operationHandler; } @Override public void execute(SliderAppMaster appMaster, QueueAccess queueService, AppState appState) throws Exception { - appState.resetFailureCounts(); + synchronized (appMaster) { + appState.resetFailureCounts(); + AbstractRMOperation blacklistOperation = appState.updateBlacklist(); + if (blacklistOperation != null) { + blacklistOperation.execute(operationHandler); + } + } } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java index 03231ef..7173354 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/AsyncRMOperationHandler.java @@ -107,4 +107,10 @@ public class AsyncRMOperationHandler extends RMOperationHandler { public void addContainerRequest(AMRMClient.ContainerRequest req) { client.addContainerRequest(req); } + + @Override + public void updateBlacklist(List<String> blacklistAdditions, + List<String> blacklistRemovals) { + client.updateBlacklist(blacklistAdditions, blacklistRemovals); + } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ProviderNotifyingOperationHandler.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ProviderNotifyingOperationHandler.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ProviderNotifyingOperationHandler.java index 184a36a..972cc30 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ProviderNotifyingOperationHandler.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/ProviderNotifyingOperationHandler.java @@ -23,6 +23,8 @@ import org.apache.hadoop.yarn.api.records.Priority; import org.apache.hadoop.yarn.client.api.AMRMClient; import org.apache.slider.providers.ProviderService; +import java.util.List; + public class ProviderNotifyingOperationHandler extends RMOperationHandler { private final ProviderService providerService; @@ -52,4 +54,10 @@ public class ProviderNotifyingOperationHandler extends RMOperationHandler { public void cancelSingleRequest(AMRMClient.ContainerRequest request) { providerService.cancelSingleRequest(request); } + + @Override + public void updateBlacklist(List<String> blacklistAdditions, + List<String> blacklistRemovals) { + providerService.updateBlacklist(blacklistAdditions, blacklistRemovals); + } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java index b7794ed..b8566d8 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/RMOperationHandlerActions.java @@ -53,6 +53,14 @@ public interface RMOperationHandlerActions { int cancelContainerRequests(Priority priority1, Priority priority2, int count); /** + * Blacklist resources + * @param blacklistAdditions resources to add to the blacklist + * @param blacklistRemovals resources to remove from the blacklist + */ + void updateBlacklist(List<String> blacklistAdditions, + List<String> blacklistRemovals); + + /** * Execute an entire list of operations * @param operations ops */ http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/UpdateBlacklistOperation.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/UpdateBlacklistOperation.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/UpdateBlacklistOperation.java new file mode 100644 index 0000000..7bc060d --- /dev/null +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/operations/UpdateBlacklistOperation.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.slider.server.appmaster.operations; + +import java.util.List; + +public class UpdateBlacklistOperation extends AbstractRMOperation { + private final List<String> blacklistAdditions; + private final List<String> blacklistRemovals; + + public UpdateBlacklistOperation(List<String> blacklistAdditions, + List<String> blacklistRemovals) { + this.blacklistAdditions = blacklistAdditions; + this.blacklistRemovals = blacklistRemovals; + } + + @Override + public void execute(RMOperationHandlerActions handler) { + handler.updateBlacklist(blacklistAdditions, blacklistRemovals); + } + + @Override + public String toString() { + return "blacklist additions: " + blacklistAdditions + + ", blacklist removals: " + blacklistRemovals; + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java index 3db9388..0ca9f78 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java @@ -75,6 +75,7 @@ import org.apache.slider.server.appmaster.management.MetricsConstants; import org.apache.slider.server.appmaster.operations.AbstractRMOperation; import org.apache.slider.server.appmaster.operations.ContainerReleaseOperation; import org.apache.slider.server.appmaster.operations.ContainerRequestOperation; +import org.apache.slider.server.appmaster.operations.UpdateBlacklistOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -449,6 +450,11 @@ public class AppState { return roleHistory; } + @VisibleForTesting + public void setRoleHistory(RoleHistory roleHistory) { + this.roleHistory = roleHistory; + } + /** * Get the path used for history files * @return the directory used for history files @@ -1976,6 +1982,15 @@ public class AppState { return results; } + public synchronized AbstractRMOperation updateBlacklist() { + UpdateBlacklistOperation blacklistOperation = + roleHistory.updateBlacklist(getRoleStatusMap().values()); + if (blacklistOperation != null) { + log.info("Updating {}", blacklistOperation); + } + return blacklistOperation; + } + /** * Look at where the current node state is -and whether it should be changed */ @@ -1983,6 +1998,10 @@ public class AppState { throws SliderInternalStateException, TriggerClusterTeardownException { log.debug("in reviewRequestAndReleaseNodes()"); List<AbstractRMOperation> allOperations = new ArrayList<>(); + AbstractRMOperation blacklistOperation = updateBlacklist(); + if (blacklistOperation != null) { + allOperations.add(blacklistOperation); + } for (RoleStatus roleStatus : getRoleStatusMap().values()) { if (!roleStatus.isExcludeFromFlexing()) { List<AbstractRMOperation> operations = reviewOneRole(roleStatus); http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/state/NodeInstance.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/NodeInstance.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/NodeInstance.java index cc17cf0..ea07698 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/NodeInstance.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/NodeInstance.java @@ -42,6 +42,8 @@ public class NodeInstance { public final String hostname; + private boolean blacklisted = false; + /** * last state of node. Starts off as {@link NodeState#RUNNING}, * on the assumption that it is live. @@ -81,6 +83,14 @@ public class NodeInstance { nodeEntries = new ArrayList<>(roles); } + public synchronized void setBlacklisted(boolean blacklisted) { + this.blacklisted = blacklisted; + } + + public boolean isBlacklisted() { + return blacklisted; + } + /** * Update the node status. * The return code is true if the node state changed enough to http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleHistory.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleHistory.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleHistory.java index 4e8a4d7..38c70f3 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleHistory.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleHistory.java @@ -34,6 +34,7 @@ import org.apache.slider.server.appmaster.management.BoolMetric; import org.apache.slider.server.appmaster.management.MetricsAndMonitoring; import org.apache.slider.server.appmaster.management.Timestamp; import org.apache.slider.server.appmaster.operations.AbstractRMOperation; +import org.apache.slider.server.appmaster.operations.UpdateBlacklistOperation; import org.apache.slider.server.avro.LoadedRoleHistory; import org.apache.slider.server.avro.NodeEntryRecord; import org.apache.slider.server.avro.RoleHistoryHeader; @@ -49,6 +50,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; /** @@ -546,6 +548,38 @@ public class RoleHistory { } } + public synchronized UpdateBlacklistOperation updateBlacklist( + Collection<RoleStatus> roleStatuses) { + List<String> blacklistAdditions = new ArrayList<>(); + List<String> blacklistRemovals = new ArrayList<>(); + for (Entry<String, NodeInstance> nodeInstanceEntry : nodemap.entrySet()) { + boolean shouldBeBlacklisted = false; + String nodeHost = nodeInstanceEntry.getKey(); + NodeInstance nodeInstance = nodeInstanceEntry.getValue(); + for (RoleStatus roleStatus : roleStatuses) { + if (nodeInstance.exceedsFailureThreshold(roleStatus)) { + shouldBeBlacklisted = true; + break; + } + } + if (shouldBeBlacklisted) { + if (!nodeInstance.isBlacklisted()) { + blacklistAdditions.add(nodeHost); + nodeInstance.setBlacklisted(true); + } + } else { + if (nodeInstance.isBlacklisted()) { + blacklistRemovals.add(nodeHost); + nodeInstance.setBlacklisted(false); + } + } + } + if (blacklistAdditions.isEmpty() && blacklistRemovals.isEmpty()) { + return null; + } + return new UpdateBlacklistOperation(blacklistAdditions, blacklistRemovals); + } + /** * Find a node for use * @param role role http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateContainerFailure.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateContainerFailure.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateContainerFailure.groovy index 0eb5456..f1a4027 100644 --- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateContainerFailure.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/appstate/TestMockAppStateContainerFailure.groovy @@ -27,7 +27,9 @@ import org.apache.slider.core.exceptions.SliderException import org.apache.slider.core.exceptions.TriggerClusterTeardownException import org.apache.slider.server.appmaster.actions.ResetFailureWindow import org.apache.slider.server.appmaster.model.mock.BaseMockAppStateTest +import org.apache.slider.server.appmaster.model.mock.MockAM import org.apache.slider.server.appmaster.model.mock.MockAppState +import org.apache.slider.server.appmaster.model.mock.MockRMOperationHandler import org.apache.slider.server.appmaster.model.mock.MockRoles import org.apache.slider.server.appmaster.model.mock.MockYarnEngine import org.apache.slider.server.appmaster.state.AppState @@ -46,6 +48,8 @@ import org.junit.Test @Slf4j class TestMockAppStateContainerFailure extends BaseMockAppStateTest implements MockRoles { + MockRMOperationHandler operationHandler = new MockRMOperationHandler() + MockAM mockAM = new MockAM() @Override String getTestName() { @@ -214,14 +218,14 @@ class TestMockAppStateContainerFailure extends BaseMockAppStateTest @Test public void testRoleStatusFailureWindow() throws Throwable { - ResetFailureWindow resetter = new ResetFailureWindow(); + ResetFailureWindow resetter = new ResetFailureWindow(operationHandler); // initial reset - resetter.execute(null, null, appState) + resetter.execute(mockAM, null, appState) role0Status.desired = 1 for (int i = 0; i < 100; i++) { - resetter.execute(null, null, appState) + resetter.execute(mockAM, null, appState) List<RoleInstance> instances = createAndSubmitNodes() assert instances.size() == 1 @@ -250,8 +254,8 @@ class TestMockAppStateContainerFailure extends BaseMockAppStateTest assert 0L == status.preempted assert 0L == status.nodeFailed - ResetFailureWindow resetter = new ResetFailureWindow(); - resetter.execute(null, null, appState) + ResetFailureWindow resetter = new ResetFailureWindow(operationHandler); + resetter.execute(mockAM, null, appState) assert 1 == status.failed assert 0L == status.failedRecently } @@ -267,8 +271,8 @@ class TestMockAppStateContainerFailure extends BaseMockAppStateTest assert 0L == status.preempted assert 0L == status.nodeFailed - ResetFailureWindow resetter = new ResetFailureWindow(); - resetter.execute(null, null, appState) + ResetFailureWindow resetter = new ResetFailureWindow(operationHandler); + resetter.execute(mockAM, null, appState) assert 1 == status.failed assert 0L == status.failedRecently assert 1L == status.limitsExceeded @@ -285,8 +289,8 @@ class TestMockAppStateContainerFailure extends BaseMockAppStateTest assert 0L == status.failedRecently assert 0L == status.nodeFailed - ResetFailureWindow resetter = new ResetFailureWindow(); - resetter.execute(null, null, appState) + ResetFailureWindow resetter = new ResetFailureWindow(operationHandler); + resetter.execute(mockAM, null, appState) assert 1L == status.preempted } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/history/TestRoleHistoryUpdateBlacklist.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/history/TestRoleHistoryUpdateBlacklist.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/history/TestRoleHistoryUpdateBlacklist.groovy new file mode 100644 index 0000000..8e26003 --- /dev/null +++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/history/TestRoleHistoryUpdateBlacklist.groovy @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.slider.server.appmaster.model.history + +import org.apache.slider.server.appmaster.actions.ResetFailureWindow +import org.apache.slider.server.appmaster.model.mock.BaseMockAppStateTest +import org.apache.slider.server.appmaster.model.mock.MockAM +import org.apache.slider.server.appmaster.model.mock.MockFactory +import org.apache.slider.server.appmaster.model.mock.MockRMOperationHandler +import org.apache.slider.server.appmaster.model.mock.MockRoleHistory +import org.apache.slider.server.appmaster.operations.AbstractRMOperation +import org.apache.slider.server.appmaster.operations.UpdateBlacklistOperation +import org.apache.slider.server.appmaster.state.NodeInstance +import org.apache.slider.server.appmaster.state.RoleHistory +import org.apache.slider.server.appmaster.state.RoleStatus +import org.junit.Before +import org.junit.Test + +class TestRoleHistoryUpdateBlacklist extends BaseMockAppStateTest { + RoleHistory roleHistory = new MockRoleHistory(MockFactory.ROLES) + Collection<RoleStatus> roleStatuses = [new RoleStatus(MockFactory.PROVIDER_ROLE0)] + NodeInstance ni = nodeInstance(1, 0, 0, 0) + List<NodeInstance> nodes = [ni] + + @Override + String getTestName() { + return "TestUpdateBlacklist" + } + + @Before + public void setupNodeMap() { + roleHistory.insert(nodes) + roleHistory.buildRecentNodeLists(); + appState.roleHistory = roleHistory + } + + @Test + public void testUpdateBlacklist() { + assert !ni.isBlacklisted() + + // at threshold, blacklist is unmodified + recordAsFailed(ni, 0, MockFactory.NODE_FAILURE_THRESHOLD) + def op = roleHistory.updateBlacklist(roleStatuses) + assert null == op + assert !ni.isBlacklisted() + + // threshold is reached, node goes on blacklist + recordAsFailed(ni, 0, 1) + op = roleHistory.updateBlacklist(roleStatuses) + assert null != op + assert ni.isBlacklisted() + + // blacklist remains unmodified + op = roleHistory.updateBlacklist(roleStatuses) + assert null == op + assert ni.isBlacklisted() + + // failure threshold reset, node goes off blacklist + ni.resetFailedRecently() + op = roleHistory.updateBlacklist(roleStatuses) + assert null != op + assert !ni.isBlacklisted() + } + + @Test + public void testBlacklistOperations() { + recordAsFailed(ni, 0, MockFactory.NODE_FAILURE_THRESHOLD + 1) + + List<AbstractRMOperation> ops = appState.reviewRequestAndReleaseNodes() + assertListLength(ops, 1) + AbstractRMOperation op = ops[0] + assert op instanceof UpdateBlacklistOperation + assert ni.isBlacklisted() + + MockRMOperationHandler handler = new MockRMOperationHandler() + assert 0 == handler.blacklisted + handler.execute(ops) + assert 1 == handler.blacklisted + + ResetFailureWindow resetter = new ResetFailureWindow(handler); + resetter.execute(new MockAM(), null, appState) + assert 0 == handler.blacklisted + assert !ni.isBlacklisted() + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockAM.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockAM.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockAM.groovy new file mode 100644 index 0000000..e24c6b3 --- /dev/null +++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockAM.groovy @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.slider.server.appmaster.model.mock + +import org.apache.slider.server.appmaster.SliderAppMaster + +class MockAM extends SliderAppMaster { +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockFactory.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockFactory.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockFactory.groovy index 3ba6e31..bad44c6 100644 --- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockFactory.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockFactory.groovy @@ -45,6 +45,8 @@ import org.apache.slider.providers.ProviderRole @Slf4j class MockFactory implements MockRoles { + public static final NODE_FAILURE_THRESHOLD = 2; + public static MockFactory instance = new MockFactory(); /* @@ -58,7 +60,7 @@ class MockFactory implements MockRoles { MockRoles.ROLE0, 0, PlacementPolicy.DEFAULT, - 2, + NODE_FAILURE_THRESHOLD, 1, ResourceKeys.DEF_YARN_LABEL_EXPRESSION) /** @@ -68,7 +70,7 @@ class MockFactory implements MockRoles { MockRoles.ROLE1, 1, PlacementPolicy.STRICT, - 2, + NODE_FAILURE_THRESHOLD, 1, ResourceKeys.DEF_YARN_LABEL_EXPRESSION) @@ -79,7 +81,7 @@ class MockFactory implements MockRoles { MockRoles.ROLE2, 2, PlacementPolicy.ANYWHERE, - 2, + NODE_FAILURE_THRESHOLD, 2, ResourceKeys.DEF_YARN_LABEL_EXPRESSION) @@ -90,7 +92,7 @@ class MockFactory implements MockRoles { MockRoles.ROLE2, 2, PlacementPolicy.ANTI_AFFINITY_REQUIRED, - 2, + NODE_FAILURE_THRESHOLD, 2, null) @@ -101,7 +103,7 @@ class MockFactory implements MockRoles { MockRoles.ROLE1, 1, PlacementPolicy.ANTI_AFFINITY_REQUIRED, - 2, + NODE_FAILURE_THRESHOLD, 1, MockRoles.LABEL_GPU) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy index 1ea2277..1580787 100644 --- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockProviderService.groovy @@ -283,6 +283,12 @@ class MockProviderService implements ProviderService { } @Override + void updateBlacklist(List<String> blacklistAdditions, + List<String> blacklistRemovals) { + + } + + @Override void execute(List<AbstractRMOperation> operations) { } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/313f9eea/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRMOperationHandler.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRMOperationHandler.groovy b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRMOperationHandler.groovy index c803b54..921c283 100644 --- a/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRMOperationHandler.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/server/appmaster/model/mock/MockRMOperationHandler.groovy @@ -35,6 +35,8 @@ class MockRMOperationHandler extends RMOperationHandler { int availableToCancel = 0; // count of cancelled values. This must be explicitly set int cancelled + // number blacklisted + int blacklisted = 0 @Override public void releaseAssignedContainer(ContainerId containerId) { @@ -70,6 +72,13 @@ class MockRMOperationHandler extends RMOperationHandler { } } + @Override + void updateBlacklist(List<String> blacklistAdditions, List<String> + blacklistRemovals) { + blacklisted += blacklistAdditions.size() + blacklisted -= blacklistRemovals.size() + } + /** * clear the history */