test:add junit test to polaris-circuitbreaker.

pull/202/head
SkyeBeFreeman 3 years ago
parent 73b0dc966b
commit 5ed3b56af2

@ -10,3 +10,4 @@
- [Feature:Support near by router.](https://github.com/Tencent/spring-cloud-tencent/pull/196) - [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) - [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) - [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)

@ -107,5 +107,11 @@
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -35,8 +35,7 @@ import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
* *
* @author Haotian Zhang * @author Haotian Zhang
*/ */
public class PolarisFeignBeanPostProcessor public class PolarisFeignBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
implements BeanPostProcessor, BeanFactoryAware {
private final ConsumerAPI consumerAPI; private final ConsumerAPI consumerAPI;
@ -47,8 +46,7 @@ public class PolarisFeignBeanPostProcessor
} }
@Override @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
throws BeansException {
return wrapper(bean); return wrapper(bean);
} }

@ -27,11 +27,9 @@ import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalance
* *
* @author Haotian Zhang * @author Haotian Zhang
*/ */
public class PolarisFeignBlockingLoadBalancerClient public class PolarisFeignBlockingLoadBalancerClient extends FeignBlockingLoadBalancerClient {
extends FeignBlockingLoadBalancerClient {
public PolarisFeignBlockingLoadBalancerClient(Client delegate, public PolarisFeignBlockingLoadBalancerClient(Client delegate, BlockingLoadBalancerClient loadBalancerClient) {
BlockingLoadBalancerClient loadBalancerClient) {
super(delegate, loadBalancerClient); super(delegate, loadBalancerClient);
} }

@ -64,11 +64,13 @@ public class PolarisFeignClient implements Client {
if (response.status() >= 500) { if (response.status() >= 500) {
resultRequest.setRetStatus(RetStatus.RetFail); resultRequest.setRetStatus(RetStatus.RetFail);
} }
LOG.debug("Will report result of {}. Request=[{}]. Response=[{}].",
resultRequest.getRetStatus().name(), request, response);
return response; return response;
} }
catch (IOException origin) { catch (IOException origin) {
resultRequest.setRetStatus(RetStatus.RetFail); resultRequest.setRetStatus(RetStatus.RetFail);
LOG.debug("Will report result of {}. Request=[{}].", resultRequest.getRetStatus().name(), request, origin);
throw origin; throw origin;
} }
finally { finally {

@ -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);
});
}
}

@ -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);
});
}
}

@ -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);
}
}

@ -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);
}
}
}

@ -17,53 +17,121 @@
package com.tencent.cloud.polaris.circuitbreaker.feign; package com.tencent.cloud.polaris.circuitbreaker.feign;
import com.tencent.cloud.polaris.circuitbreaker.PolarisFeignClientAutoConfiguration; import java.io.IOException;
import com.tencent.cloud.polaris.context.PolarisContextAutoConfiguration;
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.Client;
import feign.Request;
import feign.RequestTemplate;
import feign.Response;
import feign.Target;
import org.junit.Test; import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith; 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.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner; 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}. * Test for {@link PolarisFeignClient}.
* *
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a> * @author Haotian Zhang
*/ */
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(classes = TestPolarisFeignApp.class) @SpringBootTest(classes = PolarisFeignClientTest.TestApplication.class,
@ContextConfiguration(classes = { PolarisFeignClientAutoConfiguration.class, properties = {"spring.cloud.polaris.namespace=Test", "spring.cloud.polaris.service=TestApp"})
PolarisContextAutoConfiguration.class })
public class PolarisFeignClientTest { public class PolarisFeignClientTest {
@Autowired
private ApplicationContext springCtx;
@Test @Test
public void testPolarisFeignBeanPostProcessor() { public void testConstructor() {
final PolarisFeignBeanPostProcessor postProcessor = springCtx try {
.getBean(PolarisFeignBeanPostProcessor.class); new PolarisFeignClient(null, null);
Assertions.assertNotNull(postProcessor, "PolarisFeignBeanPostProcessor"); 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 @Test
public void testFeignClient() { public void testExecute() throws IOException {
final Client client = springCtx.getBean(Client.class); // mock Client.class
if (client instanceof PolarisFeignClient) { Client delegate = mock(Client.class);
return; doAnswer(invocation -> {
} Request request = invocation.getArgument(0);
if (client instanceof PolarisLoadBalancerFeignClient) { if (request.httpMethod().equals(Request.HttpMethod.GET)) {
return; 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<Object> target = Target.EmptyTarget.create(Object.class);
// mock RequestTemplate.class
RequestTemplate requestTemplate = new RequestTemplate();
requestTemplate.feignTarget(target);
PolarisFeignClient polarisFeignClient = new PolarisFeignClient(delegate, consumerAPI);
// 200
Response response = polarisFeignClient.execute(Request.create(Request.HttpMethod.GET, "http://localhost:8080/test",
Maps.newHashMap(), null, requestTemplate), null);
assertThat(response.status()).isEqualTo(200);
// 200
response = polarisFeignClient.execute(Request.create(Request.HttpMethod.POST, "http://localhost:8080/test",
Maps.newHashMap(), null, requestTemplate), null);
assertThat(response.status()).isEqualTo(500);
// Exception
try {
polarisFeignClient.execute(Request.create(Request.HttpMethod.DELETE, "http://localhost:8080/test",
Maps.newHashMap(), null, requestTemplate), null);
fail("IOException should be thrown.");
} }
if (client instanceof PolarisFeignBlockingLoadBalancerClient) { catch (Throwable t) {
return; assertThat(t).isInstanceOf(IOException.class);
assertThat(t.getMessage()).isEqualTo("Mock exception.");
} }
throw new IllegalStateException("Polaris burying failed");
} }
@SpringBootApplication
protected static class TestApplication {
}
} }

@ -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 PolarisLoadBalancerFeignClient}.
*
* @author Haotian Zhang
*/
public class PolarisLoadBalancerFeignClientTest {
@Test
public void testConstructor() {
try {
new PolarisLoadBalancerFeignClient(null, null, null);
}
catch (Exception e) {
Assertions.fail("Exception encountered.", e);
}
}
}

@ -1,64 +0,0 @@
/*
* 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.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
/**
* Test application.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SpringBootApplication
@EnableFeignClients
public class TestPolarisFeignApp {
public static void main(String[] args) {
SpringApplication.run(TestPolarisFeignApp.class);
}
@FeignClient(name = "feign-service-polaris",
fallback = TestPolarisServiceFallback.class)
public interface TestPolarisService {
/**
* Get info of service B.
*
* @return info
*/
@GetMapping("/example/service/b/info")
String info();
}
@Component
public static class TestPolarisServiceFallback implements TestPolarisService {
@Override
public String info() {
return "trigger the refuse";
}
}
}
Loading…
Cancel
Save