Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

HADOOP-8218. RPC.closeProxy shouldn't throw error when closing a mock…

…. Contributed by Todd Lipcon.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1306164 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
commit 3f80dbb358190b07f04a0dbf27e049b404bb9303 1 parent dd58530
Todd Lipcon toddlipcon authored
3  hadoop-common-project/hadoop-common/CHANGES.txt
@@ -292,6 +292,9 @@ Release 0.23.3 - UNRELEASED
292 292 HADOOP-8202. RPC stopProxy() does not close the proxy correctly.
293 293 (Hari Mankude via suresh)
294 294
  295 + HADOOP-8218. RPC.closeProxy shouldn't throw error when closing a mock
  296 + (todd)
  297 +
295 298 BREAKDOWN OF HADOOP-7454 SUBTASKS
296 299
297 300 HADOOP-7455. HA: Introduce HA Service Protocol Interface. (suresh)
5 hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ha/HealthMonitor.java
@@ -17,7 +17,6 @@
17 17 */
18 18 package org.apache.hadoop.ha;
19 19
20   -import java.io.Closeable;
21 20 import java.io.IOException;
22 21 import java.util.Collections;
23 22 import java.util.LinkedList;
@@ -195,9 +194,7 @@ private void doHealthChecks() throws InterruptedException {
195 194 } catch (Throwable t) {
196 195 LOG.warn("Transport-level exception trying to monitor health of " +
197 196 targetToMonitor + ": " + t.getLocalizedMessage());
198   - if (proxy instanceof Closeable) {
199   - RPC.stopProxy(proxy);
200   - }
  197 + RPC.stopProxy(proxy);
201 198 proxy = null;
202 199 enterState(State.SERVICE_NOT_RESPONDING);
203 200 Thread.sleep(sleepAfterDisconnectMillis);
3  hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/RPC.java
@@ -604,6 +604,9 @@ public static void stopProxy(Object proxy) {
604 604 LOG.error("RPC.stopProxy called on non proxy.", e);
605 605 }
606 606
  607 + // If you see this error on a mock object in a unit test you're
  608 + // developing, make sure to use MockitoUtil.mockProtocol() to
  609 + // create your mock.
607 610 throw new HadoopIllegalArgumentException(
608 611 "Cannot close proxy - is not Closeable or "
609 612 + "does not provide closeable invocation handler "
96 hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ha/DummyHAService.java
@@ -17,6 +17,7 @@
17 17 */
18 18 package org.apache.hadoop.ha;
19 19
  20 +import java.io.Closeable;
20 21 import java.io.IOException;
21 22 import java.net.InetSocketAddress;
22 23 import java.util.ArrayList;
@@ -56,50 +57,7 @@
56 57 }
57 58
58 59 private HAServiceProtocol makeMock() {
59   - return Mockito.spy(new HAServiceProtocol() {
60   - @Override
61   - public void monitorHealth() throws HealthCheckFailedException,
62   - AccessControlException, IOException {
63   - checkUnreachable();
64   - if (!isHealthy) {
65   - throw new HealthCheckFailedException("not healthy");
66   - }
67   - }
68   -
69   - @Override
70   - public void transitionToActive() throws ServiceFailedException,
71   - AccessControlException, IOException {
72   - checkUnreachable();
73   - if (failToBecomeActive) {
74   - throw new ServiceFailedException("injected failure");
75   - }
76   -
77   - state = HAServiceState.ACTIVE;
78   - }
79   -
80   - @Override
81   - public void transitionToStandby() throws ServiceFailedException,
82   - AccessControlException, IOException {
83   - checkUnreachable();
84   - state = HAServiceState.STANDBY;
85   - }
86   -
87   - @Override
88   - public HAServiceStatus getServiceStatus() throws IOException {
89   - checkUnreachable();
90   - HAServiceStatus ret = new HAServiceStatus(state);
91   - if (state == HAServiceState.STANDBY) {
92   - ret.setReadyToBecomeActive();
93   - }
94   - return ret;
95   - }
96   -
97   - private void checkUnreachable() throws IOException {
98   - if (actUnreachable) {
99   - throw new IOException("Connection refused (fake)");
100   - }
101   - }
102   - });
  60 + return Mockito.spy(new MockHAProtocolImpl());
103 61 }
104 62
105 63 @Override
@@ -130,4 +88,54 @@ public String toString() {
130 88 public static HAServiceTarget getInstance(int serial) {
131 89 return instances.get(serial - 1);
132 90 }
  91 +
  92 + private class MockHAProtocolImpl implements
  93 + HAServiceProtocol, Closeable {
  94 + @Override
  95 + public void monitorHealth() throws HealthCheckFailedException,
  96 + AccessControlException, IOException {
  97 + checkUnreachable();
  98 + if (!isHealthy) {
  99 + throw new HealthCheckFailedException("not healthy");
  100 + }
  101 + }
  102 +
  103 + @Override
  104 + public void transitionToActive() throws ServiceFailedException,
  105 + AccessControlException, IOException {
  106 + checkUnreachable();
  107 + if (failToBecomeActive) {
  108 + throw new ServiceFailedException("injected failure");
  109 + }
  110 +
  111 + state = HAServiceState.ACTIVE;
  112 + }
  113 +
  114 + @Override
  115 + public void transitionToStandby() throws ServiceFailedException,
  116 + AccessControlException, IOException {
  117 + checkUnreachable();
  118 + state = HAServiceState.STANDBY;
  119 + }
  120 +
  121 + @Override
  122 + public HAServiceStatus getServiceStatus() throws IOException {
  123 + checkUnreachable();
  124 + HAServiceStatus ret = new HAServiceStatus(state);
  125 + if (state == HAServiceState.STANDBY) {
  126 + ret.setReadyToBecomeActive();
  127 + }
  128 + return ret;
  129 + }
  130 +
  131 + private void checkUnreachable() throws IOException {
  132 + if (actUnreachable) {
  133 + throw new IOException("Connection refused (fake)");
  134 + }
  135 + }
  136 +
  137 + @Override
  138 + public void close() throws IOException {
  139 + }
  140 + }
133 141 }
7 hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ha/TestFailoverController.java
@@ -17,6 +17,7 @@
17 17 */
18 18 package org.apache.hadoop.ha;
19 19
  20 +import java.io.Closeable;
20 21 import java.io.IOException;
21 22 import java.net.InetSocketAddress;
22 23
@@ -33,7 +34,6 @@
33 34 import org.junit.Test;
34 35 import org.mockito.Mockito;
35 36 import org.mockito.internal.stubbing.answers.ThrowsException;
36   -import org.mockito.stubbing.Answer;
37 37
38 38 import static org.junit.Assert.*;
39 39
@@ -228,7 +228,10 @@ public void testFailoverFromNonExistantServiceWithFencer() throws Exception {
228 228 // Getting a proxy to a dead server will throw IOException on call,
229 229 // not on creation of the proxy.
230 230 HAServiceProtocol errorThrowingProxy = Mockito.mock(HAServiceProtocol.class,
231   - new ThrowsException(new IOException("Could not connect to host")));
  231 + Mockito.withSettings()
  232 + .defaultAnswer(new ThrowsException(
  233 + new IOException("Could not connect to host")))
  234 + .extraInterfaces(Closeable.class));
232 235 Mockito.doReturn(errorThrowingProxy).when(svc1).getProxy();
233 236 DummyHAService svc2 = new DummyHAService(HAServiceState.STANDBY, svc2Addr);
234 237 svc1.fencer = svc2.fencer = setupFencer(AlwaysSucceedFencer.class.getName());
13 hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestRPC.java
@@ -50,6 +50,7 @@
50 50 import org.apache.hadoop.security.token.TokenIdentifier;
51 51 import org.apache.hadoop.security.AccessControlException;
52 52 import org.apache.hadoop.security.UserGroupInformation;
  53 +import org.apache.hadoop.test.MockitoUtil;
53 54 import org.junit.Test;
54 55 import static org.junit.Assert.*;
55 56
@@ -58,8 +59,6 @@
58 59
59 60 import static org.apache.hadoop.test.MetricsAsserts.*;
60 61
61   -import static org.mockito.Mockito.*;
62   -
63 62 /** Unit tests for RPC. */
64 63 @SuppressWarnings("deprecation")
65 64 public class TestRPC {
@@ -587,9 +586,17 @@ public void testNoPings() throws Exception {
587 586 */
588 587 @Test(expected=HadoopIllegalArgumentException.class)
589 588 public void testStopNonRegisteredProxy() throws Exception {
590   - RPC.stopProxy(mock(TestProtocol.class));
591 589 RPC.stopProxy(null);
592 590 }
  591 +
  592 + /**
  593 + * Test that the mockProtocol helper returns mock proxies that can
  594 + * be stopped without error.
  595 + */
  596 + @Test
  597 + public void testStopMockObject() throws Exception {
  598 + RPC.stopProxy(MockitoUtil.mockProtocol(TestProtocol.class));
  599 + }
593 600
594 601 @Test
595 602 public void testStopProxy() throws IOException {
36 hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/test/MockitoUtil.java
... ... @@ -0,0 +1,36 @@
  1 +/**
  2 + * Licensed to the Apache Software Foundation (ASF) under one
  3 + * or more contributor license agreements. See the NOTICE file
  4 + * distributed with this work for additional information
  5 + * regarding copyright ownership. The ASF licenses this file
  6 + * to you under the Apache License, Version 2.0 (the
  7 + * "License"); you may not use this file except in compliance
  8 + * with the License. You may obtain a copy of the License at
  9 + *
  10 + * http://www.apache.org/licenses/LICENSE-2.0
  11 + *
  12 + * Unless required by applicable law or agreed to in writing, software
  13 + * distributed under the License is distributed on an "AS IS" BASIS,
  14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15 + * See the License for the specific language governing permissions and
  16 + * limitations under the License.
  17 + */
  18 +package org.apache.hadoop.test;
  19 +
  20 +import java.io.Closeable;
  21 +
  22 +import org.mockito.Mockito;
  23 +
  24 +public abstract class MockitoUtil {
  25 +
  26 + /**
  27 + * Return a mock object for an IPC protocol. This special
  28 + * method is necessary, since the IPC proxies have to implement
  29 + * Closeable in addition to their protocol interface.
  30 + * @param clazz the protocol class
  31 + */
  32 + public static <T> T mockProtocol(Class<T> clazz) {
  33 + return Mockito.mock(clazz,
  34 + Mockito.withSettings().extraInterfaces(Closeable.class));
  35 + }
  36 +}

0 comments on commit 3f80dbb

Please sign in to comment.
Something went wrong with that request. Please try again.