GEODE-393: GetRegionFunction uses the cache in the FunctionContext
Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/5551b3fe Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/5551b3fe Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/5551b3fe Branch: refs/heads/feature/GEM-1483 Commit: 5551b3feb1e85d1c7eae207583e505f11ed26720 Parents: 564a94b Author: Jinmei Liao <jil...@pivotal.io> Authored: Thu Jul 20 10:39:54 2017 -0700 Committer: Jinmei Liao <jil...@pivotal.io> Committed: Fri Jul 21 13:08:49 2017 -0700 ---------------------------------------------------------------------- .../cli/functions/GetRegionsFunction.java | 3 +- .../cli/functions/GetRegionsFunctionTest.java | 88 ++++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/5551b3fe/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunction.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunction.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunction.java index d524924..6571dca 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunction.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunction.java @@ -18,7 +18,6 @@ import java.util.HashSet; import java.util.Set; import org.apache.geode.cache.Cache; -import org.apache.geode.cache.CacheFactory; import org.apache.geode.cache.Region; import org.apache.geode.cache.execute.Function; import org.apache.geode.cache.execute.FunctionContext; @@ -41,7 +40,7 @@ public class GetRegionsFunction implements Function, InternalEntity { @Override public void execute(FunctionContext functionContext) { try { - Cache cache = CacheFactory.getAnyInstance(); + Cache cache = functionContext.getCache(); Set<Region<?, ?>> regions = cache.rootRegions(); // should never return a null if (regions == null || regions.isEmpty()) { http://git-wip-us.apache.org/repos/asf/geode/blob/5551b3fe/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunctionTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunctionTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunctionTest.java new file mode 100644 index 0000000..77db7cd --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/functions/GetRegionsFunctionTest.java @@ -0,0 +1,88 @@ +/* + * 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.geode.management.internal.cli.functions; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.awaitility.core.ConditionTimeoutException; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.cache.execute.FunctionContext; +import org.apache.geode.cache.execute.ResultSender; +import org.apache.geode.test.junit.categories.UnitTest; + +@Category(UnitTest.class) +public class GetRegionsFunctionTest { + + private enum STATE { + INITIAL, BLOCKING, FINISHED + }; + + private static GetRegionsFunctionTest.STATE lockingThreadState = + GetRegionsFunctionTest.STATE.INITIAL; + private static AtomicBoolean lockAquired = new AtomicBoolean(false); + private static AtomicBoolean functionExecuted = new AtomicBoolean(false); + + private GetRegionsFunction getRegionsFunction; + private FunctionContext functionContext; + + @Before + public void before() { + getRegionsFunction = new GetRegionsFunction(); + functionContext = mock(FunctionContext.class); + } + + @Test + public void doNotUseCacheFacotryToGetCache() throws Exception { + // start a thread that would hold on to the CacheFactory's class lock + new Thread(() -> { + synchronized (CacheFactory.class) { + lockAquired.set(true); + lockingThreadState = GetRegionsFunctionTest.STATE.BLOCKING; + try { + await().atMost(10, TimeUnit.SECONDS).untilTrue(functionExecuted); + } catch (ConditionTimeoutException e) { + e.printStackTrace(); + lockingThreadState = GetRegionsFunctionTest.STATE.FINISHED; + } + } + }).start(); + + // wait till the blocking thread aquired the lock on CacheFactory + await().atMost(1, TimeUnit.SECONDS).untilTrue(lockAquired); + when(functionContext.getCache()).thenReturn(mock(Cache.class)); + when(functionContext.getResultSender()).thenReturn(mock(ResultSender.class)); + + // execute a function that would get the cache, make sure that's not waiting on the lock + // of CacheFactory + getRegionsFunction.execute(functionContext); + assertThat(lockingThreadState).isEqualTo(lockingThreadState.BLOCKING); + + + // this will make the awaitility call in the thread return + functionExecuted.set(true); + } +}