Add test for GenericHelixController thread leak
Project: http://git-wip-us.apache.org/repos/asf/helix/repo Commit: http://git-wip-us.apache.org/repos/asf/helix/commit/ac39b398 Tree: http://git-wip-us.apache.org/repos/asf/helix/tree/ac39b398 Diff: http://git-wip-us.apache.org/repos/asf/helix/diff/ac39b398 Branch: refs/heads/master Commit: ac39b3984f16ce593b99c8482f7d16522dcae935 Parents: 00f8efe Author: hrzhang <[email protected]> Authored: Tue Oct 31 17:12:04 2017 -0700 Committer: Junkai Xue <[email protected]> Committed: Wed Jan 24 18:30:21 2018 -0800 ---------------------------------------------------------------------- .../TestGenericHelixControllerThreading.java | 73 ++++++++++++++++++++ 1 file changed, 73 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/helix/blob/ac39b398/helix-core/src/test/java/org/apache/helix/integration/controller/TestGenericHelixControllerThreading.java ---------------------------------------------------------------------- diff --git a/helix-core/src/test/java/org/apache/helix/integration/controller/TestGenericHelixControllerThreading.java b/helix-core/src/test/java/org/apache/helix/integration/controller/TestGenericHelixControllerThreading.java new file mode 100644 index 0000000..822e060 --- /dev/null +++ b/helix-core/src/test/java/org/apache/helix/integration/controller/TestGenericHelixControllerThreading.java @@ -0,0 +1,73 @@ +package org.apache.helix.integration.controller; + +/* + * 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. + */ + +import java.util.ArrayList; +import java.util.Set; +import org.apache.helix.controller.GenericHelixController; +import org.apache.helix.ZkUnitTestBase; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class TestGenericHelixControllerThreading extends ZkUnitTestBase { + + private static final String EVENT_PROCESS_THREAD_NAME_PREFIX = + "GerenricHelixController-event_process"; + + // Temporarily disabling the test as it's not stable when running under the entire mvn test suite. + // Some other crashed tests might cause this one to fail as controllers might not be gracefully + // shutdown + @Test(enabled = false) + public void testGenericHelixControllerThreadCount() throws Exception { + System.out.println("testGenericHelixControllerThreadCount STARTs"); + final int numControllers = 100; + ArrayList<GenericHelixController> controllers = createHelixControllers(numControllers); + Assert.assertEquals(getThreadCountByNamePrefix(EVENT_PROCESS_THREAD_NAME_PREFIX), numControllers * 2); + + int remainingExpectedEventProcessThreadsCount = numControllers * 2; + for (GenericHelixController ctrl : controllers) { + ctrl.shutdown(); + remainingExpectedEventProcessThreadsCount -= 2; + Assert.assertEquals(getThreadCountByNamePrefix(EVENT_PROCESS_THREAD_NAME_PREFIX), + remainingExpectedEventProcessThreadsCount); + } + System.out.println("testGenericHelixControllerThreadCount ENDs"); + } + + private ArrayList<GenericHelixController> createHelixControllers(int count) { + ArrayList<GenericHelixController> ret = new ArrayList<>(); + for (int i = 0; i < count; i++) { + ret.add(new GenericHelixController()); + } + return ret; + } + + private int getThreadCountByNamePrefix(String threadNamePrefix) { + Set<Thread> threadSet = Thread.getAllStackTraces().keySet(); + int eventThreadCount = 0; + for (Thread t : threadSet) { + if (t.getName().startsWith(threadNamePrefix)) { + eventThreadCount += 1; + } + } + return eventThreadCount; + } + +}
