diff --git a/CHANGELOG.md b/CHANGELOG.md
index d010c25bb..4d65d2a39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,3 +10,4 @@
- [Feature:Support near by router.](https://github.com/Tencent/spring-cloud-tencent/pull/196)
- [Feature: Load application.yml and application-${profile}.yml from polaris server.](https://github.com/Tencent/spring-cloud-tencent/pull/199)
- [feat:add rate limit of unirate.](https://github.com/Tencent/spring-cloud-tencent/pull/197)
+- [test:add junit test to polaris-circuitbreaker.](https://github.com/Tencent/spring-cloud-tencent/pull/202)
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml
index c55bb3d78..5c8c0d957 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/pom.xml
@@ -107,5 +107,11 @@
spring-boot-starter-test
test
+
+
+ org.mockito
+ mockito-inline
+ test
+
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java
index da6726481..619815795 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessor.java
@@ -35,8 +35,7 @@
*
* @author Haotian Zhang
*/
-public class PolarisFeignBeanPostProcessor
- implements BeanPostProcessor, BeanFactoryAware {
+public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
private final ConsumerAPI consumerAPI;
@@ -47,8 +46,7 @@ public PolarisFeignBeanPostProcessor(ConsumerAPI consumerAPI) {
}
@Override
- public Object postProcessBeforeInitialization(Object bean, String beanName)
- throws BeansException {
+ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return wrapper(bean);
}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java
index 9adaa6bfe..4cf8780c1 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClient.java
@@ -27,11 +27,9 @@
*
* @author Haotian Zhang
*/
-public class PolarisFeignBlockingLoadBalancerClient
- extends FeignBlockingLoadBalancerClient {
+public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient {
- public PolarisFeignBlockingLoadBalancerClient(Client delegate,
- BlockingLoadBalancerClient loadBalancerClient) {
+ public PolarisFeignBlockingLoadBalancerClient(Client delegate, BlockingLoadBalancerClient loadBalancerClient) {
super(delegate, loadBalancerClient);
}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java
index 54ab9a53e..dc49566f2 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/main/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClient.java
@@ -64,11 +64,13 @@ public Response execute(Request request, Options options) throws IOException {
if (response.status() >= 500) {
resultRequest.setRetStatus(RetStatus.RetFail);
}
+ LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].",
+ resultRequest.getRetStatus().name(), request, response);
return response;
}
catch (IOException origin) {
resultRequest.setRetStatus(RetStatus.RetFail);
-
+ LOG.debug("Will report result of {}. Request=[{}].", resultRequest.getRetStatus().name(), request, origin);
throw origin;
}
finally {
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java
new file mode 100644
index 000000000..42777a3b6
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisCircuitBreakerBootstrapConfigurationTest.java
@@ -0,0 +1,44 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.cloud.polaris.circuitbreaker;
+
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test for {@link PolarisCircuitBreakerBootstrapConfiguration}.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisCircuitBreakerBootstrapConfigurationTest {
+ private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(
+ AutoConfigurations.of(PolarisCircuitBreakerBootstrapConfiguration.class))
+ .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
+
+ @Test
+ public void testDefaultInitialization() {
+ this.contextRunner.run(context -> {
+ assertThat(context).hasSingleBean(PolarisCircuitBreakerBootstrapConfiguration.CircuitBreakerConfigModifier.class);
+ });
+ }
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java
new file mode 100644
index 000000000..c83608478
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/PolarisFeignClientAutoConfigurationTest.java
@@ -0,0 +1,52 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.cloud.polaris.circuitbreaker;
+
+import com.tencent.cloud.polaris.circuitbreaker.feign.PolarisFeignBeanPostProcessor;
+import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test for {@link PolarisFeignClientAutoConfiguration}.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisFeignClientAutoConfigurationTest {
+
+ private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(
+ AutoConfigurations.of(
+ PolarisContextAutoConfiguration.class,
+ PolarisFeignClientAutoConfiguration.class))
+ .withPropertyValues("spring.cloud.polaris.circuitbreaker.enabled=true");
+
+ @Test
+ public void testDefaultInitialization() {
+ this.contextRunner.run(context -> {
+ assertThat(context).hasSingleBean(ConsumerAPI.class);
+ assertThat(context).hasSingleBean(PolarisFeignBeanPostProcessor.class);
+ });
+ }
+
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessorTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessorTest.java
new file mode 100644
index 000000000..252dcc021
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBeanPostProcessorTest.java
@@ -0,0 +1,97 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.cloud.polaris.circuitbreaker.feign;
+
+import com.tencent.polaris.api.core.ConsumerAPI;
+import feign.Client;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
+import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
+import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
+import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
+import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Test for {@link PolarisFeignBeanPostProcessor}.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisFeignBeanPostProcessorTest {
+
+ private PolarisFeignBeanPostProcessor polarisFeignBeanPostProcessor;
+
+ @Before
+ public void setUp() {
+ ConsumerAPI consumerAPI = mock(ConsumerAPI.class);
+
+ polarisFeignBeanPostProcessor = new PolarisFeignBeanPostProcessor(consumerAPI);
+ }
+
+ @Test
+ public void testPostProcessBeforeInitialization() {
+ BeanFactory beanFactory = mock(BeanFactory.class);
+ doAnswer(invocation -> {
+ Class> clazz = invocation.getArgument(0);
+ if (clazz.equals(BlockingLoadBalancerClient.class)) {
+ return mock(BlockingLoadBalancerClient.class);
+ }
+ if (clazz.equals(CachingSpringLoadBalancerFactory.class)) {
+ return mock(CachingSpringLoadBalancerFactory.class);
+ }
+ if (clazz.equals(SpringClientFactory.class)) {
+ return mock(SpringClientFactory.class);
+ }
+ return null;
+ }).when(beanFactory).getBean(any(Class.class));
+ polarisFeignBeanPostProcessor.setBeanFactory(beanFactory);
+
+ // isNeedWrap(bean) == false
+ Object bean1 = new Object();
+ Object bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean1, "bean1");
+ assertThat(bean).isNotInstanceOfAny(
+ PolarisFeignClient.class,
+ PolarisLoadBalancerFeignClient.class,
+ PolarisFeignBlockingLoadBalancerClient.class);
+
+ // bean instanceOf Client.class
+ Client bean2 = mock(Client.class);
+ bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean2, "bean2");
+ assertThat(bean).isInstanceOf(PolarisFeignClient.class);
+
+ // bean instanceOf LoadBalancerFeignClient.class
+ LoadBalancerFeignClient bean3 = mock(LoadBalancerFeignClient.class);
+ doReturn(mock(Client.class)).when(bean3).getDelegate();
+ bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean3, "bean3");
+ assertThat(bean).isInstanceOf(PolarisLoadBalancerFeignClient.class);
+
+ // bean instanceOf FeignBlockingLoadBalancerClient.class
+ FeignBlockingLoadBalancerClient bean4 = mock(FeignBlockingLoadBalancerClient.class);
+ doReturn(mock(Client.class)).when(bean4).getDelegate();
+ bean = polarisFeignBeanPostProcessor.postProcessBeforeInitialization(bean4, "bean4");
+ assertThat(bean).isInstanceOf(PolarisFeignBlockingLoadBalancerClient.class);
+ }
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClientTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClientTest.java
new file mode 100644
index 000000000..5be8111bc
--- /dev/null
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignBlockingLoadBalancerClientTest.java
@@ -0,0 +1,39 @@
+/*
+ * Tencent is pleased to support the open source community by making Spring Cloud Tencent available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.cloud.polaris.circuitbreaker.feign;
+
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+/**
+ * Test for {@link PolarisFeignBlockingLoadBalancerClient}.
+ *
+ * @author Haotian Zhang
+ */
+public class PolarisFeignBlockingLoadBalancerClientTest {
+
+ @Test
+ public void testConstructor() {
+ try {
+ new PolarisFeignBlockingLoadBalancerClient(null, null);
+ }
+ catch (Exception e) {
+ Assertions.fail("Exception encountered.", e);
+ }
+ }
+}
diff --git a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java
index 9005ec591..993eedc58 100644
--- a/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java
+++ b/spring-cloud-starter-tencent-polaris-circuitbreaker/src/test/java/com/tencent/cloud/polaris/circuitbreaker/feign/PolarisFeignClientTest.java
@@ -17,53 +17,121 @@
package com.tencent.cloud.polaris.circuitbreaker.feign;
-import com.tencent.cloud.polaris.circuitbreaker.PolarisFeignClientAutoConfiguration;
-import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration;
+import java.io.IOException;
+
+import com.google.common.collect.Maps;
+import com.tencent.polaris.api.core.ConsumerAPI;
+import com.tencent.polaris.api.rpc.ServiceCallResult;
import feign.Client;
+import feign.Request;
+import feign.RequestTemplate;
+import feign.Response;
+import feign.Target;
import org.junit.Test;
-import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.ApplicationContext;
-import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+
/**
* Test for {@link PolarisFeignClient}.
*
- * @author liaochuntao
+ * @author Haotian Zhang
*/
@RunWith(SpringRunner.class)
-@SpringBootTest(classes = TestPolarisFeignApp.class)
-@ContextConfiguration(classes = { PolarisFeignClientAutoConfiguration.class,
- PolarisContextAutoConfiguration.class })
+@SpringBootTest(classes = PolarisFeignClientTest.TestApplication.class,
+ properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"})
public class PolarisFeignClientTest {
- @Autowired
- private ApplicationContext springCtx;
-
@Test
- public void testPolarisFeignBeanPostProcessor() {
- final PolarisFeignBeanPostProcessor postProcessor = springCtx
- .getBean(PolarisFeignBeanPostProcessor.class);
- Assertions.assertNotNull(postProcessor, "PolarisFeignBeanPostProcessor");
+ public void testConstructor() {
+ try {
+ new PolarisFeignClient(null, null);
+ fail("NullPointerException should be thrown.");
+ }
+ catch (Throwable e) {
+ assertThat(e).isInstanceOf(NullPointerException.class);
+ assertThat(e.getMessage()).isEqualTo("target");
+ }
+
+ try {
+ new PolarisFeignClient(mock(Client.class), null);
+ fail("NullPointerException should be thrown.");
+ }
+ catch (Throwable e) {
+ assertThat(e).isInstanceOf(NullPointerException.class);
+ assertThat(e.getMessage()).isEqualTo("CircuitBreakAPI");
+ }
+
+ try {
+ assertThat(new PolarisFeignClient(mock(Client.class), mock(ConsumerAPI.class))).isInstanceOf(PolarisFeignClient.class);
+ }
+ catch (Throwable e) {
+ fail("Exception encountered.", e);
+ }
}
@Test
- public void testFeignClient() {
- final Client client = springCtx.getBean(Client.class);
- if (client instanceof PolarisFeignClient) {
- return;
- }
- if (client instanceof PolarisLoadBalancerFeignClient) {
- return;
+ public void testExecute() throws IOException {
+ // mock Client.class
+ Client delegate = mock(Client.class);
+ doAnswer(invocation -> {
+ Request request = invocation.getArgument(0);
+ if (request.httpMethod().equals(Request.HttpMethod.GET)) {
+ return Response.builder().request(request).status(200).build();
+ }
+ else if (request.httpMethod().equals(Request.HttpMethod.POST)) {
+ return Response.builder().request(request).status(500).build();
+ }
+ throw new IOException("Mock exception.");
+ }).when(delegate).execute(any(Request.class), nullable(Request.Options.class));
+
+ // mock ConsumerAPI.class
+ ConsumerAPI consumerAPI = mock(ConsumerAPI.class);
+ doNothing().when(consumerAPI).updateServiceCallResult(any(ServiceCallResult.class));
+
+ // mock target
+ Target