From bb43644e4f1331489510721bdd2ecf003fd5ee55 Mon Sep 17 00:00:00 2001 From: seanyu Date: Tue, 11 Apr 2023 12:34:40 +0800 Subject: [PATCH] fix ut --- .../RpcEnhancementAutoConfiguration.java | 1 - .../EnhancedPolarisRestTemplateReporter.java | 2 +- .../BlockingLoadBalancerClientAspectTest.java | 92 +++++++ ...hancedPolarisRestTemplateReporterTest.java | 137 +++++++++++ .../EnhancedRestTemplateReporterTest.java | 231 ------------------ .../EnhancedWebClientReporterTest.java | 97 +++++--- ...dBalancerClientRequestTransformerTest.java | 90 +++++++ 7 files changed, 385 insertions(+), 265 deletions(-) create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java delete mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java create mode 100644 spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java index 521271b09..304e86a76 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/config/RpcEnhancementAutoConfiguration.java @@ -29,7 +29,6 @@ import com.tencent.cloud.rpc.enhancement.feign.plugin.EnhancedFeignPlugin; import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.ExceptionPolarisReporter; import com.tencent.cloud.rpc.enhancement.feign.plugin.reporter.SuccessPolarisReporter; import com.tencent.cloud.rpc.enhancement.resttemplate.BlockingLoadBalancerClientAspect; -import com.tencent.cloud.rpc.enhancement.scg.RecordRequestStartTimeGlobalFilter; import com.tencent.cloud.rpc.enhancement.webclient.PolarisLoadBalancerClientRequestTransformer; import com.tencent.cloud.rpc.enhancement.scg.EnhancedPolarisGatewayReporter; import com.tencent.cloud.rpc.enhancement.resttemplate.EnhancedPolarisRestTemplateReporter; diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java index 7a3cbaa4f..0fc20200a 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporter.java @@ -93,7 +93,7 @@ public class EnhancedPolarisRestTemplateReporter extends AbstractPolarisReporter Map loadBalancerContext = MetadataContextHolder.get().getLoadbalancerMetadata(); String targetHost = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST); - Integer targetPort = Integer.valueOf(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)); + Integer targetPort = loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT) != null ? Integer.valueOf(loadBalancerContext.get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)) : null; long delay = System.currentTimeMillis() - startTime; ServiceCallResult resultRequest = createServiceCallResult( diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java new file mode 100644 index 000000000..82bf173ba --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/BlockingLoadBalancerClientAspectTest.java @@ -0,0 +1,92 @@ +/* + * 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.rpc.enhancement.resttemplate; + +import com.tencent.cloud.common.constant.HeaderConstant; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.context.ApplicationContext; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +@ExtendWith(MockitoExtension.class) +public class BlockingLoadBalancerClientAspectTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + @Mock + private ProceedingJoinPoint proceedingJoinPoint; + + private BlockingLoadBalancerClientAspect aspect = new BlockingLoadBalancerClientAspect(); + + @BeforeAll + static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class); + StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class); + doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class); + doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext); + } + + @AfterAll + static void afterAll() { + mockedApplicationContextAwareUtils.close(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + @Test + public void test() throws Throwable { + ServiceInstance serviceInstance = mock(ServiceInstance.class); + doReturn("0.0.0.0").when(serviceInstance).getHost(); + doReturn(80).when(serviceInstance).getPort(); + doReturn(new Object[]{ serviceInstance }).when(proceedingJoinPoint).getArgs(); + aspect.invoke(proceedingJoinPoint); + aspect.pointcut(); + assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_HOST)).isEqualTo("0.0.0.0"); + assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_INSTANCE_PORT)).isEqualTo("80"); + } + +} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporterTest.java index 7a6d20b5d..f41d15002 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedPolarisRestTemplateReporterTest.java @@ -1,5 +1,142 @@ +/* + * 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.rpc.enhancement.resttemplate; +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.net.URI; +import java.net.URISyntaxException; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.polaris.api.config.Configuration; +import com.tencent.polaris.api.config.global.APIConfig; +import com.tencent.polaris.api.config.global.GlobalConfig; +import com.tencent.polaris.api.core.ConsumerAPI; +import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.polaris.client.api.SDKContext; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.context.ApplicationContext; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpResponse; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; + +@ExtendWith(MockitoExtension.class) public class EnhancedPolarisRestTemplateReporterTest { + private static MockedStatic mockedApplicationContextAwareUtils; + @Mock + private RpcEnhancementReporterProperties reporterProperties; + @Mock + private SDKContext sdkContext; + @Mock + private ConsumerAPI consumerAPI; + @Mock + private CircuitBreakAPI circuitBreakAPI; + @Mock + private ClientHttpRequestExecution mockClientHttpRequestExecution; + @Mock + private ClientHttpResponse mockClientHttpResponse; + @Mock + private HttpRequest mockHttpRequest; + @Mock + private HttpHeaders mockHttpHeaders; + + @BeforeAll + static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class); + StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class); + doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class); + doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext); + } + + @AfterAll + static void afterAll() { + mockedApplicationContextAwareUtils.close(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + @Test + public void testRun() throws IOException, URISyntaxException { + + APIConfig apiConfig = mock(APIConfig.class); + doReturn("0.0.0.0").when(apiConfig).getBindIP(); + + GlobalConfig globalConfig = mock(GlobalConfig.class); + doReturn(apiConfig).when(globalConfig).getAPI(); + + Configuration configuration = mock(Configuration.class); + doReturn(globalConfig).when(configuration).getGlobal(); + + doReturn(configuration).when(sdkContext).getConfig(); + + ClientHttpResponse actualResult; + final byte[] inputBody = null; + + URI uri = new URI("http://0.0.0.0/"); + doReturn(uri).when(mockHttpRequest).getURI(); + doReturn(HttpMethod.GET).when(mockHttpRequest).getMethod(); + doReturn(mockHttpHeaders).when(mockHttpRequest).getHeaders(); + doReturn(mockClientHttpResponse).when(mockClientHttpRequestExecution).execute(mockHttpRequest, inputBody); + + EnhancedPolarisRestTemplateReporter reporter = new EnhancedPolarisRestTemplateReporter(reporterProperties, sdkContext, consumerAPI, circuitBreakAPI); + actualResult = reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution); + assertSame(mockClientHttpResponse, actualResult); + + doReturn(true).when(reporterProperties).isEnabled(); + actualResult = reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution); + assertSame(mockClientHttpResponse, actualResult); + + doThrow(new SocketTimeoutException()).when(mockClientHttpRequestExecution).execute(mockHttpRequest, inputBody); + assertThrows(SocketTimeoutException.class, () -> reporter.intercept(mockHttpRequest, inputBody, mockClientHttpRequestExecution)); + } + } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java deleted file mode 100644 index 92db4f0ac..000000000 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/resttemplate/EnhancedRestTemplateReporterTest.java +++ /dev/null @@ -1,231 +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.rpc.enhancement.resttemplate; -// -//import java.io.IOException; -//import java.io.InputStream; -//import java.net.URI; -//import java.util.HashMap; -//import java.util.Map; -// -//import com.tencent.cloud.common.metadata.MetadataContext; -//import com.tencent.cloud.common.metadata.MetadataContextHolder; -//import com.tencent.cloud.common.util.ApplicationContextAwareUtils; -//import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; -//import com.tencent.polaris.api.core.ConsumerAPI; -//import org.checkerframework.checker.nullness.qual.NonNull; -//import org.junit.jupiter.api.AfterAll; -//import org.junit.jupiter.api.BeforeAll; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.mockito.InjectMocks; -//import org.mockito.Mock; -//import org.mockito.MockedStatic; -//import org.mockito.Mockito; -//import org.mockito.junit.jupiter.MockitoExtension; -// -//import org.springframework.context.ApplicationContext; -//import org.springframework.http.HttpHeaders; -//import org.springframework.http.HttpMethod; -//import org.springframework.http.HttpStatus; -//import org.springframework.http.client.AbstractClientHttpResponse; -//import org.springframework.http.client.ClientHttpResponse; -//import org.springframework.web.client.DefaultResponseErrorHandler; -//import org.springframework.web.client.ResponseErrorHandler; -// -//import static org.assertj.core.api.Assertions.assertThat; -//import static org.mockito.ArgumentMatchers.any; -//import static org.mockito.ArgumentMatchers.anyString; -//import static org.mockito.Mockito.mock; -//import static org.mockito.Mockito.times; -//import static org.mockito.Mockito.verify; -//import static org.mockito.Mockito.when; -// -///** -// * Test for {@link EnhancedRestTemplateReporter}. -// * -// * @author lepdou 2022-09-06 -// */ -//@ExtendWith(MockitoExtension.class) -//public class EnhancedRestTemplateReporterTest { -// -// private static MockedStatic mockedMetadataContextHolder; -// private static MockedStatic mockedApplicationContextAwareUtils; -// @Mock -// private ConsumerAPI consumerAPI; -// @Mock -// private RpcEnhancementReporterProperties reporterProperties; -// @Mock -// private ResponseErrorHandler delegate; -// @InjectMocks -// private EnhancedRestTemplateReporter enhancedRestTemplateReporter; -// -// @InjectMocks -// private EnhancedRestTemplateReporter enhancedRestTemplateReporter2; -// -// @BeforeAll -// static void beforeAll() { -// mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); -// mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) -// .thenReturn("caller"); -// MetadataContext metadataContext = Mockito.mock(MetadataContext.class); -// -// // mock transitive metadata -// Map loadBalancerContext = new HashMap<>(); -// loadBalancerContext.put("host", "1.1.1.1"); -// loadBalancerContext.put("port", "8080"); -// loadBalancerContext.put("startMillis", String.valueOf(System.currentTimeMillis())); -// when(metadataContext.getLoadbalancerMetadata()).thenReturn(loadBalancerContext); -// -// mockedMetadataContextHolder = Mockito.mockStatic(MetadataContextHolder.class); -// mockedMetadataContextHolder.when(MetadataContextHolder::get).thenReturn(metadataContext); -// } -// -// @AfterAll -// static void afterAll() { -// mockedApplicationContextAwareUtils.close(); -// mockedMetadataContextHolder.close(); -// } -// -// @BeforeEach -// void setUp() { -// enhancedRestTemplateReporter.setDelegateHandler(delegate); -// } -// -// @Test -// public void testSetApplicationContext() { -// ApplicationContext applicationContext = mock(ApplicationContext.class); -// -// // test no ResponseErrorHandler -// when(applicationContext.getBeanNamesForType(any(Class.class))) -// .thenReturn(new String[] {"enhancedRestTemplateReporter"}); -// enhancedRestTemplateReporter2.setApplicationContext(applicationContext); -// assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(DefaultResponseErrorHandler.class); -// -// // test one other ResponseErrorHandler -// when(applicationContext.getBeanNamesForType(any(Class.class))) -// .thenReturn(new String[] {"enhancedRestTemplateReporter", "mockedResponseErrorHandler"}); -// when(applicationContext.getBean(anyString())).thenReturn(mock(MockedResponseErrorHandler.class)); -// enhancedRestTemplateReporter2.setApplicationContext(applicationContext); -// assertThat(enhancedRestTemplateReporter2.getDelegateHandler()).isInstanceOf(MockedResponseErrorHandler.class); -// } -// -// @Test -// public void testHasError() throws IOException { -// when(delegate.hasError(any())).thenReturn(true); -// -// MockedClientHttpResponse response = new MockedClientHttpResponse(); -// assertThat(enhancedRestTemplateReporter.hasError(response)).isTrue(); -// -// String realHasError = response.getHeaders().getFirst(EnhancedRestTemplateReporter.HEADER_HAS_ERROR); -// assertThat(realHasError).isEqualTo("true"); -// } -// -// @Test -// public void testHandleHasError() throws IOException { -// when(reporterProperties.isEnabled()).thenReturn(true); -// when(delegate.hasError(any())).thenReturn(true); -// -// MockedClientHttpResponse response = new MockedClientHttpResponse(); -// enhancedRestTemplateReporter.hasError(response); -// -// URI uri = mock(URI.class); -// enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response); -// -// verify(consumerAPI, times(1)).updateServiceCallResult(any()); -// verify(delegate).handleError(uri, HttpMethod.GET, response); -// } -// -// @Test -// public void testHandleHasNotError() throws IOException { -// when(reporterProperties.isEnabled()).thenReturn(true); -// when(delegate.hasError(any())).thenReturn(false); -// -// MockedClientHttpResponse response = new MockedClientHttpResponse(); -// enhancedRestTemplateReporter.hasError(response); -// -// URI uri = mock(URI.class); -// enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response); -// -// verify(consumerAPI, times(1)).updateServiceCallResult(any()); -// verify(delegate, times(0)).handleError(uri, HttpMethod.GET, response); -// } -// -// @Test -// public void testReportSwitchOff() throws IOException { -// when(reporterProperties.isEnabled()).thenReturn(false); -// when(delegate.hasError(any())).thenReturn(true); -// -// MockedClientHttpResponse response = new MockedClientHttpResponse(); -// enhancedRestTemplateReporter.hasError(response); -// -// URI uri = mock(URI.class); -// enhancedRestTemplateReporter.handleError(uri, HttpMethod.GET, response); -// -// verify(consumerAPI, times(0)).updateServiceCallResult(any()); -// verify(delegate).handleError(uri, HttpMethod.GET, response); -// } -// -// static class MockedClientHttpResponse extends AbstractClientHttpResponse { -// -// private final HttpHeaders headers; -// -// MockedClientHttpResponse() { -// this.headers = new HttpHeaders(); -// } -// -// @Override -// public int getRawStatusCode() { -// return 0; -// } -// -// @Override -// public String getStatusText() { -// return null; -// } -// -// @Override -// public void close() { -// -// } -// -// @Override -// public InputStream getBody() throws IOException { -// return null; -// } -// -// @Override -// public HttpHeaders getHeaders() { -// return headers; -// } -// -// @Override -// public HttpStatus getStatusCode() throws IOException { -// return HttpStatus.OK; -// } -// } -// -// private static class MockedResponseErrorHandler extends DefaultResponseErrorHandler { -// -// @Override -// public void handleError(@NonNull ClientHttpResponse response) { -// } -// -// } -//} diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java index 8cb5c8ab5..a3e702c32 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/EnhancedWebClientReporterTest.java @@ -18,41 +18,75 @@ package com.tencent.cloud.rpc.enhancement.webclient; import java.net.URI; +import java.net.URISyntaxException; import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; import com.tencent.cloud.common.util.ApplicationContextAwareUtils; import com.tencent.cloud.rpc.enhancement.config.RpcEnhancementReporterProperties; +import com.tencent.polaris.api.config.Configuration; +import com.tencent.polaris.api.config.global.APIConfig; +import com.tencent.polaris.api.config.global.GlobalConfig; import com.tencent.polaris.api.core.ConsumerAPI; -import com.tencent.polaris.api.rpc.ServiceCallResult; +import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI; +import com.tencent.polaris.client.api.SDKContext; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Mono; +import org.springframework.context.ApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.ExchangeFunction; import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +@ExtendWith(MockitoExtension.class) public class EnhancedWebClientReporterTest { - private static final String URI_TEMPLATE_ATTRIBUTE = EnhancedWebClientReporterTest.class.getName() + ".uriTemplate"; - private static MockedStatic mockedApplicationContextAwareUtils; + @Mock + private RpcEnhancementReporterProperties reporterProperties; + @Mock + private SDKContext sdkContext; + @Mock + private ConsumerAPI consumerAPI; + @Mock + private CircuitBreakAPI circuitBreakAPI; + @Mock + private ClientRequest clientRequest; + @Mock + private ExchangeFunction exchangeFunction; + @Mock + private ClientResponse clientResponse; @BeforeAll static void beforeAll() { mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class); + StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class); + doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class); + doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext); } @AfterAll @@ -65,35 +99,34 @@ public class EnhancedWebClientReporterTest { MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; } - @Test - public void testInstrumentResponse() { - ClientResponse response = Mockito.mock(ClientResponse.class); - ClientResponse.Headers headers = Mockito.mock(ClientResponse.Headers.class); - Mockito.doReturn(headers).when(response).headers(); - Mockito.doReturn(new HttpHeaders()).when(headers).asHttpHeaders(); - Mono responseMono = Mono.just(response); - ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot")) - .attribute(URI_TEMPLATE_ATTRIBUTE, "https://example.org/projects/{project}") - .build(); - - ConsumerAPI consumerAPI = Mockito.mock(ConsumerAPI.class); - Mockito.doAnswer(invocationOnMock -> { - ServiceCallResult result = invocationOnMock.getArgument(0, ServiceCallResult.class); - Assertions.assertTrue(result.getDelay() > 0); - return null; - }).when(consumerAPI) - .updateServiceCallResult(Mockito.any(ServiceCallResult.class)); - - RpcEnhancementReporterProperties properties = new RpcEnhancementReporterProperties(); - properties.setEnabled(true); - properties.getStatuses().clear(); - properties.getSeries().clear(); -// EnhancedWebClientReporter reporter = new EnhancedWebClientReporter(properties, null, consumerAPI); -// -// reporter.instrumentResponse(request, responseMono) -// .contextWrite(context -> context.put(METRICS_WEBCLIENT_START_TIME, System.currentTimeMillis())) -// .subscribe(); + public void testRun() throws URISyntaxException { + APIConfig apiConfig = mock(APIConfig.class); + doReturn("0.0.0.0").when(apiConfig).getBindIP(); + + GlobalConfig globalConfig = mock(GlobalConfig.class); + doReturn(apiConfig).when(globalConfig).getAPI(); + + Configuration configuration = mock(Configuration.class); + doReturn(globalConfig).when(configuration).getGlobal(); + + doReturn(configuration).when(sdkContext).getConfig(); + + doReturn(new URI("http://0.0.0.0/")).when(clientRequest).url(); + doReturn(new HttpHeaders()).when(clientRequest).headers(); + doReturn(HttpMethod.GET).when(clientRequest).method(); + ClientResponse.Headers headers = mock(ClientResponse.Headers.class); + doReturn(headers).when(clientResponse).headers(); + doReturn(Mono.just(clientResponse)).when(exchangeFunction).exchange(any()); + + EnhancedWebClientReporter reporter = new EnhancedWebClientReporter(reporterProperties, sdkContext, consumerAPI, circuitBreakAPI); + ClientResponse clientResponse1 = reporter.filter(clientRequest, exchangeFunction).block(); + assertSame(clientResponse, clientResponse1); + + doReturn(true).when(reporterProperties).isEnabled(); + ClientResponse clientResponse2 = reporter.filter(clientRequest, exchangeFunction).block(); + assertSame(clientResponse, clientResponse2); + } } diff --git a/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java new file mode 100644 index 000000000..811b7c5eb --- /dev/null +++ b/spring-cloud-tencent-rpc-enhancement/src/test/java/com/tencent/cloud/rpc/enhancement/webclient/PolarisLoadBalancerClientRequestTransformerTest.java @@ -0,0 +1,90 @@ +/* + * 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.rpc.enhancement.webclient; + +import com.tencent.cloud.common.constant.HeaderConstant; +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.common.metadata.StaticMetadataManager; +import com.tencent.cloud.common.metadata.config.MetadataLocalProperties; +import com.tencent.cloud.common.util.ApplicationContextAwareUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.context.ApplicationContext; +import org.springframework.web.reactive.function.client.ClientRequest; + +import static com.tencent.polaris.test.common.Consts.NAMESPACE_TEST; +import static com.tencent.polaris.test.common.Consts.SERVICE_PROVIDER; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +@ExtendWith(MockitoExtension.class) +public class PolarisLoadBalancerClientRequestTransformerTest { + + private static MockedStatic mockedApplicationContextAwareUtils; + + private PolarisLoadBalancerClientRequestTransformer transformer = new PolarisLoadBalancerClientRequestTransformer(); + + @Mock + private ClientRequest clientRequest; + + @Mock + private ServiceInstance serviceInstance; + + @BeforeAll + static void beforeAll() { + mockedApplicationContextAwareUtils = Mockito.mockStatic(ApplicationContextAwareUtils.class); + mockedApplicationContextAwareUtils.when(() -> ApplicationContextAwareUtils.getProperties(anyString())) + .thenReturn("unit-test"); + ApplicationContext applicationContext = mock(ApplicationContext.class); + MetadataLocalProperties metadataLocalProperties = mock(MetadataLocalProperties.class); + StaticMetadataManager staticMetadataManager = mock(StaticMetadataManager.class); + doReturn(metadataLocalProperties).when(applicationContext).getBean(MetadataLocalProperties.class); + doReturn(staticMetadataManager).when(applicationContext).getBean(StaticMetadataManager.class); + mockedApplicationContextAwareUtils.when(ApplicationContextAwareUtils::getApplicationContext).thenReturn(applicationContext); + } + + @AfterAll + static void afterAll() { + mockedApplicationContextAwareUtils.close(); + } + + @BeforeEach + void setUp() { + MetadataContext.LOCAL_NAMESPACE = NAMESPACE_TEST; + MetadataContext.LOCAL_SERVICE = SERVICE_PROVIDER; + } + + @Test + public void test() throws Throwable { + doReturn("test").when(serviceInstance).getServiceId(); + transformer.transformRequest(clientRequest, serviceInstance); + assertThat(MetadataContextHolder.get().getLoadbalancerMetadata().get(HeaderConstant.INTERNAL_CALLEE_SERVICE_ID)).isEqualTo("test"); + } +}