diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa0e66af2..2db83e4ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,4 +6,6 @@
- [Optimize: Register the service with the ProviderAPI#registerInstance method.](https://github.com/Tencent/spring-cloud-tencent/pull/686)
- [docs:update PR template.](https://github.com/Tencent/spring-cloud-tencent/pull/690)
- [enhancement: revert default value when the field is deleted in @ConfigurationProperties bean](https://github.com/Tencent/spring-cloud-tencent/issues/681)
+- [Code optimize & add junit tests.](https://github.com/Tencent/spring-cloud-tencent/pull/701)
- [Optimize: remote deprecated method](https://github.com/Tencent/spring-cloud-tencent/pull/697)
+- [Test:support environment variable metadata test](https://github.com/Tencent/spring-cloud-tencent/pull/698)
diff --git a/spring-cloud-tencent-commons/pom.xml b/spring-cloud-tencent-commons/pom.xml
index 6cf993ed3..5e373d142 100644
--- a/spring-cloud-tencent-commons/pom.xml
+++ b/spring-cloud-tencent-commons/pom.xml
@@ -99,6 +99,11 @@
spring-boot-actuator-autoconfigure
true
-
+
+ uk.org.webcompere
+ system-stubs-junit4
+ test
+
+
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java
index 9581d8ca5..63ea080fb 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/metadata/StaticMetadataManager.java
@@ -107,7 +107,8 @@ public class StaticMetadataManager {
String value = entry.getValue();
if (StringUtils.isNotBlank(key)
&& (key.startsWith(ENV_METADATA_PREFIX) || key.equals(ENV_TRAFFIC_CONTENT_RAW_TRANSHEADERS))
- && !key.equals(ENV_METADATA_CONTENT_TRANSITIVE)) {
+ && !key.equals(ENV_METADATA_CONTENT_TRANSITIVE)
+ && !key.equals(ENV_METADATA_CONTENT_DISPOSABLE)) {
String sourceKey = "";
if (key.equals(ENV_TRAFFIC_CONTENT_RAW_TRANSHEADERS)) {
sourceKey = key;
diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/rule/ConditionUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/rule/ConditionUtils.java
index 6092c0516..c5f924d6e 100644
--- a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/rule/ConditionUtils.java
+++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/rule/ConditionUtils.java
@@ -31,7 +31,6 @@ public final class ConditionUtils {
}
public static boolean match(Map actualValues, List conditions) {
- boolean allMatched = true;
for (Condition condition : conditions) {
List expectedValues = condition.getValues();
String operation = condition.getOperation();
@@ -39,10 +38,9 @@ public final class ConditionUtils {
String actualValue = actualValues.get(key);
if (!Operation.match(expectedValues, actualValue, operation)) {
- allMatched = false;
- break;
+ return false;
}
}
- return allMatched;
+ return true;
}
}
diff --git a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java
index 64aa20bcb..4ca51fdc8 100644
--- a/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java
+++ b/spring-cloud-tencent-commons/src/test/java/com/tencent/cloud/common/metadata/StaticMetadataManagerTest.java
@@ -27,10 +27,12 @@ import java.util.Set;
import com.tencent.cloud.common.metadata.config.MetadataLocalProperties;
import com.tencent.cloud.common.spi.InstanceMetadataProvider;
import org.junit.Assert;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
+import uk.org.webcompere.systemstubs.rules.EnvironmentVariablesRule;
import org.springframework.util.CollectionUtils;
@@ -48,6 +50,12 @@ public class StaticMetadataManagerTest {
@Mock
private MetadataLocalProperties metadataLocalProperties;
+ /**
+ * EnvironmentVariablesRule.
+ */
+ @Rule
+ public EnvironmentVariablesRule rule = new EnvironmentVariablesRule();
+
@Test
public void testParseConfigMetadata() {
Map content = new HashMap<>();
@@ -134,12 +142,12 @@ public class StaticMetadataManagerTest {
Assert.assertEquals("v1", metadata.get("k1"));
Assert.assertEquals("v22", metadata.get("k2"));
- Assert.assertEquals("zone2", metadataManager.getZone());
- Assert.assertEquals("region1", metadataManager.getRegion());
-
Assert.assertTrue(CollectionUtils.isEmpty(metadataManager.getAllEnvMetadata()));
Assert.assertTrue(CollectionUtils.isEmpty(metadataManager.getEnvTransitiveMetadata()));
+ Assert.assertEquals("zone2", metadataManager.getZone());
+ Assert.assertEquals("region1", metadataManager.getRegion());
+
Map locationInfo = metadataManager.getLocationMetadata();
Assert.assertEquals("zone2", locationInfo.get("zone"));
Assert.assertEquals("region1", locationInfo.get("region"));
@@ -147,6 +155,32 @@ public class StaticMetadataManagerTest {
}
+ @Test
+ public void testEnvMetadata() {
+ // set env
+ rule.set("SCT_METADATA_CONTENT_TRANSITIVE", "transitiveKey");
+ rule.set("SCT_METADATA_CONTENT_DISPOSABLE", "disposableKey");
+ rule.set("SCT_METADATA_CONTENT_transitiveKey", "transitiveValue");
+ rule.set("SCT_METADATA_CONTENT_disposableKey", "disposableValue");
+ rule.set("SCT_TRAFFIC_CONTENT_RAW_TRANSHEADERS", "header1,header2,header3");
+
+ StaticMetadataManager metadataManager = new StaticMetadataManager(metadataLocalProperties, null);
+ Map allEnvMetadata = metadataManager.getAllEnvMetadata();
+ Assert.assertTrue(allEnvMetadata.containsKey("transitiveKey"));
+ Assert.assertTrue(allEnvMetadata.containsKey("disposableKey"));
+
+ Map envDisposableMetadata = metadataManager.getEnvDisposableMetadata();
+ Assert.assertTrue(envDisposableMetadata.containsKey("disposableKey"));
+ Assert.assertEquals(envDisposableMetadata.get("disposableKey"), "disposableValue");
+
+ Map envTransitiveMetadata = metadataManager.getEnvTransitiveMetadata();
+ Assert.assertTrue(envTransitiveMetadata.containsKey("transitiveKey"));
+ Assert.assertEquals(envTransitiveMetadata.get("transitiveKey"), "transitiveValue");
+
+ String transHeaderFromEnv = metadataManager.getTransHeaderFromEnv();
+ Assert.assertEquals(transHeaderFromEnv, "header1,header2,header3");
+ }
+
static class MockedMetadataProvider implements InstanceMetadataProvider {
@Override
diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml
index 8126a44b3..3c89b07cf 100644
--- a/spring-cloud-tencent-dependencies/pom.xml
+++ b/spring-cloud-tencent-dependencies/pom.xml
@@ -80,6 +80,7 @@
1.12.10
3.16.1
1.69
+ 2.0.1
3.2.0
@@ -248,6 +249,13 @@
${mocktio.version}
test
+
+
+ uk.org.webcompere
+ system-stubs-junit4
+ ${system-stubs-junit4.version}
+ test
+
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/pom.xml b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/pom.xml
index 06a9c65e0..863f6fc9a 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/pom.xml
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/pom.xml
@@ -30,5 +30,11 @@
spring-boot-starter-test
test
+
+
+ org.mockito
+ mockito-inline
+ test
+
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfiguration.java
index 1d33cfb49..16ca5303b 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfiguration.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfiguration.java
@@ -20,7 +20,6 @@ package com.tencent.cloud.plugin.gateway;
import java.util.List;
-import com.tencent.cloud.plugin.gateway.staining.StainingProperties;
import com.tencent.cloud.plugin.gateway.staining.TrafficStainer;
import com.tencent.cloud.plugin.gateway.staining.TrafficStainingGatewayFilter;
import com.tencent.cloud.plugin.gateway.staining.rule.RuleStainingExecutor;
@@ -45,44 +44,33 @@ import org.springframework.context.annotation.Configuration;
public class SCGPluginsAutoConfiguration {
@Configuration
- @ConditionalOnProperty("spring.cloud.tencent.plugin.scg.staining.enabled")
- public static class StainingPluginConfiguration {
+ @ConditionalOnProperty("spring.cloud.tencent.plugin.scg.staining.rule-staining.enabled")
+ @ConditionalOnPolarisConfigEnabled
+ public static class RuleStainingPluginConfiguration {
@Bean
- public StainingProperties stainingProperties() {
- return new StainingProperties();
+ public RuleStainingProperties ruleStainingProperties() {
+ return new RuleStainingProperties();
}
- @Configuration
- @ConditionalOnProperty(value = "spring.cloud.tencent.plugin.scg.staining.rule-staining.enabled", matchIfMissing = true)
- @ConditionalOnPolarisConfigEnabled
- public static class RuleStainingPluginConfiguration {
-
- @Bean
- public RuleStainingProperties ruleStainingProperties() {
- return new RuleStainingProperties();
- }
-
- @Bean
- public StainingRuleManager stainingRuleManager(RuleStainingProperties stainingProperties, ConfigFileService configFileService) {
- return new StainingRuleManager(stainingProperties, configFileService);
- }
+ @Bean
+ public StainingRuleManager stainingRuleManager(RuleStainingProperties stainingProperties, ConfigFileService configFileService) {
+ return new StainingRuleManager(stainingProperties, configFileService);
+ }
- @Bean
- public TrafficStainingGatewayFilter trafficStainingGatewayFilter(List trafficStainer) {
- return new TrafficStainingGatewayFilter(trafficStainer);
- }
+ @Bean
+ public TrafficStainingGatewayFilter trafficStainingGatewayFilter(List trafficStainer) {
+ return new TrafficStainingGatewayFilter(trafficStainer);
+ }
- @Bean
- public RuleStainingExecutor ruleStainingExecutor() {
- return new RuleStainingExecutor();
- }
+ @Bean
+ public RuleStainingExecutor ruleStainingExecutor() {
+ return new RuleStainingExecutor();
+ }
- @Bean
- public RuleTrafficStainer ruleTrafficStainer(StainingRuleManager stainingRuleManager,
- RuleStainingExecutor ruleStainingExecutor) {
- return new RuleTrafficStainer(stainingRuleManager, ruleStainingExecutor);
- }
+ @Bean
+ public RuleTrafficStainer ruleTrafficStainer(StainingRuleManager stainingRuleManager, RuleStainingExecutor ruleStainingExecutor) {
+ return new RuleTrafficStainer(stainingRuleManager, ruleStainingExecutor);
}
}
}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/staining/StainingProperties.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/staining/StainingProperties.java
deleted file mode 100644
index 226563bb9..000000000
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/main/java/com/tencent/cloud/plugin/gateway/staining/StainingProperties.java
+++ /dev/null
@@ -1,39 +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.plugin.gateway.staining;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * The properties for traffic staining.
- * @author lepdou 2022-07-07
- */
-@ConfigurationProperties("spring.cloud.tencent.plugin.scg.staining")
-public class StainingProperties {
-
- private boolean enabled;
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfigurationTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfigurationTest.java
new file mode 100644
index 000000000..21314544d
--- /dev/null
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/SCGPluginsAutoConfigurationTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.plugin.gateway;
+
+import com.tencent.cloud.plugin.gateway.staining.TrafficStainingGatewayFilter;
+import com.tencent.cloud.plugin.gateway.staining.rule.RuleStainingExecutor;
+import com.tencent.cloud.plugin.gateway.staining.rule.RuleStainingProperties;
+import com.tencent.cloud.plugin.gateway.staining.rule.RuleTrafficStainer;
+import com.tencent.cloud.plugin.gateway.staining.rule.StainingRuleManager;
+import com.tencent.polaris.client.api.SDKContext;
+import com.tencent.polaris.configuration.api.core.ConfigFileService;
+import com.tencent.polaris.configuration.factory.ConfigFileServiceFactory;
+import org.junit.Assert;
+import org.junit.Test;
+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.context.annotation.Bean;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
+
+/**
+ * Test for {@link SCGPluginsAutoConfiguration}.
+ * @author derek.yi 2022-11-03
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = DEFINED_PORT, classes = SCGPluginsAutoConfigurationTest.TestApplication.class,
+ properties = {"server.port=8081", "spring.config.location = classpath:application-test.yml",
+ "spring.cloud.tencent.plugin.scg.staining.rule-staining.enabled = true"})
+public class SCGPluginsAutoConfigurationTest {
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Test
+ public void testAutoConfiguration() {
+ Assert.assertEquals(1, applicationContext.getBeansOfType(RuleStainingProperties.class).size());
+ Assert.assertEquals(1, applicationContext.getBeansOfType(StainingRuleManager.class).size());
+ Assert.assertEquals(1, applicationContext.getBeansOfType(TrafficStainingGatewayFilter.class).size());
+ Assert.assertEquals(1, applicationContext.getBeansOfType(RuleStainingExecutor.class).size());
+ Assert.assertEquals(1, applicationContext.getBeansOfType(RuleTrafficStainer.class).size());
+ }
+
+ @SpringBootApplication
+ public static class TestApplication {
+
+ @Bean
+ public ConfigFileService configFileService(SDKContext sdkContext) {
+ return ConfigFileServiceFactory.createConfigFileService(sdkContext);
+ }
+ }
+}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/TrafficStainerGatewayFilterTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/TrafficStainerGatewayFilterTest.java
deleted file mode 100644
index 6339691db..000000000
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/TrafficStainerGatewayFilterTest.java
+++ /dev/null
@@ -1,89 +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.plugin.gateway.staining;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.junit.MockitoJUnitRunner;
-import reactor.core.publisher.Mono;
-
-import org.springframework.cloud.gateway.filter.GatewayFilterChain;
-import org.springframework.util.CollectionUtils;
-import org.springframework.web.server.ServerWebExchange;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * Test for {@link TrafficStainingGatewayFilter}.
- * @author lepdou 2022-07-12
- */
-@RunWith(MockitoJUnitRunner.class)
-public class TrafficStainerGatewayFilterTest {
-
- @Mock
- private GatewayFilterChain chain;
- @Mock
- private ServerWebExchange exchange;
-
- @Test
- public void testNoneTrafficStainingImplement() {
- TrafficStainingGatewayFilter filter = new TrafficStainingGatewayFilter(null);
-
- when(chain.filter(exchange)).thenReturn(Mono.empty());
-
- filter.filter(exchange, chain);
-
- verify(chain).filter(exchange);
- }
-
- @Test
- public void testMultiStaining() {
- TrafficStainer trafficStainer1 = Mockito.mock(TrafficStainer.class);
- TrafficStainer trafficStainer2 = Mockito.mock(TrafficStainer.class);
-
- when(trafficStainer1.getOrder()).thenReturn(1);
- when(trafficStainer2.getOrder()).thenReturn(2);
-
- Map labels1 = new HashMap<>();
- labels1.put("k1", "v1");
- labels1.put("k2", "v2");
- when(trafficStainer1.apply(exchange)).thenReturn(labels1);
-
- Map labels2 = new HashMap<>();
- labels2.put("k1", "v11");
- labels2.put("k3", "v3");
- when(trafficStainer2.apply(exchange)).thenReturn(labels2);
-
- TrafficStainingGatewayFilter filter = new TrafficStainingGatewayFilter(Arrays.asList(trafficStainer1, trafficStainer2));
- Map result = filter.getStainedLabels(exchange);
-
- Assert.assertFalse(CollectionUtils.isEmpty(result));
- Assert.assertEquals("v1", result.get("k1"));
- Assert.assertEquals("v2", result.get("k2"));
- Assert.assertEquals("v3", result.get("k3"));
- }
-}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/TrafficStainingGatewayFilterTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/TrafficStainingGatewayFilterTest.java
new file mode 100644
index 000000000..9178161a3
--- /dev/null
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/TrafficStainingGatewayFilterTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.plugin.gateway.staining;
+
+import java.util.Arrays;
+import java.util.Collections;
+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.plugin.gateway.staining.rule.RuleStainingExecutor;
+import com.tencent.cloud.plugin.gateway.staining.rule.RuleStainingProperties;
+import com.tencent.cloud.plugin.gateway.staining.rule.RuleTrafficStainer;
+import com.tencent.cloud.plugin.gateway.staining.rule.StainingRuleManager;
+import com.tencent.polaris.configuration.api.core.ConfigFile;
+import com.tencent.polaris.configuration.api.core.ConfigFileService;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import reactor.core.publisher.Mono;
+
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import org.springframework.mock.web.server.MockServerWebExchange;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.server.ServerWebExchange;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test for {@link TrafficStainingGatewayFilter}.
+ * @author lepdou 2022-07-12
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class TrafficStainingGatewayFilterTest {
+
+ @Mock
+ private GatewayFilterChain chain;
+ @Mock
+ private ServerWebExchange exchange;
+ @Mock
+ private ConfigFileService configFileService;
+
+ private final String testNamespace = "testNamespace";
+ private final String testGroup = "testGroup";
+ private final String testFileName = "rule.json";
+
+ @BeforeClass
+ public static void before() {
+ Mockito.mockStatic(ApplicationContextAwareUtils.class);
+ when(ApplicationContextAwareUtils
+ .getProperties(any())).thenReturn("fooBar");
+ }
+
+ @Test
+ public void testNoneTrafficStainingImplement() {
+ TrafficStainingGatewayFilter filter = new TrafficStainingGatewayFilter(null);
+
+ when(chain.filter(exchange)).thenReturn(Mono.empty());
+
+ filter.filter(exchange, chain);
+
+ verify(chain).filter(exchange);
+ }
+
+ @Test
+ public void testMultiStaining() {
+ TrafficStainer trafficStainer1 = Mockito.mock(TrafficStainer.class);
+ TrafficStainer trafficStainer2 = Mockito.mock(TrafficStainer.class);
+
+ when(trafficStainer1.getOrder()).thenReturn(1);
+ when(trafficStainer2.getOrder()).thenReturn(2);
+
+ Map labels1 = new HashMap<>();
+ labels1.put("k1", "v1");
+ labels1.put("k2", "v2");
+ when(trafficStainer1.apply(exchange)).thenReturn(labels1);
+
+ Map labels2 = new HashMap<>();
+ labels2.put("k1", "v11");
+ labels2.put("k3", "v3");
+ when(trafficStainer2.apply(exchange)).thenReturn(labels2);
+
+ TrafficStainingGatewayFilter filter = new TrafficStainingGatewayFilter(Arrays.asList(trafficStainer1, trafficStainer2));
+ Map result = filter.getStainedLabels(exchange);
+
+ Assert.assertFalse(CollectionUtils.isEmpty(result));
+ Assert.assertEquals("v1", result.get("k1"));
+ Assert.assertEquals("v2", result.get("k2"));
+ Assert.assertEquals("v3", result.get("k3"));
+ }
+
+ @Test
+ public void testNoTrafficStainers() {
+ MetadataContext metadataContext = new MetadataContext();
+ MetadataContextHolder.set(metadataContext);
+
+ TrafficStainingGatewayFilter filter = new TrafficStainingGatewayFilter(null);
+ filter.filter(exchange, chain);
+ Map map = metadataContext.getTransitiveMetadata();
+ Assert.assertTrue(CollectionUtils.isEmpty(map));
+ }
+
+ @Test
+ public void testWithTrafficStainers() {
+ MetadataContext metadataContext = new MetadataContext();
+ MetadataContextHolder.set(metadataContext);
+
+ RuleStainingProperties ruleStainingProperties = new RuleStainingProperties();
+ ruleStainingProperties.setNamespace(testNamespace);
+ ruleStainingProperties.setGroup(testGroup);
+ ruleStainingProperties.setFileName(testFileName);
+
+ ConfigFile configFile = Mockito.mock(ConfigFile.class);
+ when(configFile.getContent()).thenReturn("{\n"
+ + " \"rules\":[\n"
+ + " {\n"
+ + " \"conditions\":[\n"
+ + " {\n"
+ + " \"key\":\"${http.query.uid}\",\n"
+ + " \"values\":[\"1000\"],\n"
+ + " \"operation\":\"EQUALS\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"labels\":[\n"
+ + " {\n"
+ + " \"key\":\"env\",\n"
+ + " \"value\":\"blue\"\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + " ]\n"
+ + "}");
+ when(configFileService.getConfigFile(testNamespace, testGroup, testFileName)).thenReturn(configFile);
+
+ StainingRuleManager stainingRuleManager = new StainingRuleManager(ruleStainingProperties, configFileService);
+ RuleStainingExecutor ruleStainingExecutor = new RuleStainingExecutor();
+ RuleTrafficStainer ruleTrafficStainer = new RuleTrafficStainer(stainingRuleManager, ruleStainingExecutor);
+
+ TrafficStainingGatewayFilter filter = new TrafficStainingGatewayFilter(Collections.singletonList(ruleTrafficStainer));
+
+ MockServerHttpRequest request = MockServerHttpRequest.get("/users")
+ .queryParam("uid", "1000").build();
+ MockServerWebExchange exchange = new MockServerWebExchange.Builder(request).build();
+
+ filter.filter(exchange, chain);
+ Map map = metadataContext.getTransitiveMetadata();
+ Assert.assertNotNull(map);
+ Assert.assertEquals(1, map.size());
+ Assert.assertEquals("blue", map.get("env"));
+ }
+}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/RuleStainingExecutorTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/RuleStainingExecutorTest.java
index 91c0c42d8..c320c0ca6 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/RuleStainingExecutorTest.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/RuleStainingExecutorTest.java
@@ -32,6 +32,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
+import org.springframework.util.CollectionUtils;
/**
* Test for {@link RuleStainingExecutor}.
@@ -178,4 +179,11 @@ public class RuleStainingExecutorTest {
Assert.assertEquals("value1", stainedLabels.get("label1"));
Assert.assertEquals("value2", stainedLabels.get("label2"));
}
+
+ @Test
+ public void testNoStainingRule() {
+ RuleStainingExecutor executor = new RuleStainingExecutor();
+ Assert.assertTrue(CollectionUtils.isEmpty(executor.execute(null, null)));
+ Assert.assertTrue(CollectionUtils.isEmpty(executor.execute(null, new StainingRule())));
+ }
}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/RuleTrafficStainerTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/RuleTrafficStainerTest.java
new file mode 100644
index 000000000..d8e678750
--- /dev/null
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/RuleTrafficStainerTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.plugin.gateway.staining.rule;
+
+import java.util.Map;
+
+import com.tencent.polaris.configuration.api.core.ConfigFile;
+import com.tencent.polaris.configuration.api.core.ConfigFileService;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import org.springframework.mock.web.server.MockServerWebExchange;
+import org.springframework.util.CollectionUtils;
+
+import static org.mockito.Mockito.when;
+
+/**
+ * Test for {@link RuleTrafficStainer}.
+ * @author derek.yi 2022-11-03
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class RuleTrafficStainerTest {
+
+ @Mock
+ private ConfigFileService configFileService;
+
+ private final String testNamespace = "testNamespace";
+ private final String testGroup = "testGroup";
+ private final String testFileName = "rule.json";
+
+ @Test
+ public void testNoStainingRule() {
+ RuleStainingProperties ruleStainingProperties = new RuleStainingProperties();
+ ruleStainingProperties.setNamespace(testNamespace);
+ ruleStainingProperties.setGroup(testGroup);
+ ruleStainingProperties.setFileName(testFileName);
+
+ ConfigFile configFile = Mockito.mock(ConfigFile.class);
+ when(configFile.getContent()).thenReturn("");
+ when(configFileService.getConfigFile(testNamespace, testGroup, testFileName)).thenReturn(configFile);
+
+ StainingRuleManager stainingRuleManager = new StainingRuleManager(ruleStainingProperties, configFileService);
+ RuleStainingExecutor ruleStainingExecutor = new RuleStainingExecutor();
+ RuleTrafficStainer ruleTrafficStainer = new RuleTrafficStainer(stainingRuleManager, ruleStainingExecutor);
+ Map map = ruleTrafficStainer.apply(null);
+ Assert.assertTrue(CollectionUtils.isEmpty(map));
+ }
+
+ @Test
+ public void testWithStainingRule() {
+ RuleStainingProperties ruleStainingProperties = new RuleStainingProperties();
+ ruleStainingProperties.setNamespace(testNamespace);
+ ruleStainingProperties.setGroup(testGroup);
+ ruleStainingProperties.setFileName(testFileName);
+
+ ConfigFile configFile = Mockito.mock(ConfigFile.class);
+ when(configFile.getContent()).thenReturn("{\n"
+ + " \"rules\":[\n"
+ + " {\n"
+ + " \"conditions\":[\n"
+ + " {\n"
+ + " \"key\":\"${http.query.uid}\",\n"
+ + " \"values\":[\"1000\"],\n"
+ + " \"operation\":\"EQUALS\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"labels\":[\n"
+ + " {\n"
+ + " \"key\":\"env\",\n"
+ + " \"value\":\"blue\"\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + " ]\n"
+ + "}");
+ when(configFileService.getConfigFile(testNamespace, testGroup, testFileName)).thenReturn(configFile);
+
+ StainingRuleManager stainingRuleManager = new StainingRuleManager(ruleStainingProperties, configFileService);
+ RuleStainingExecutor ruleStainingExecutor = new RuleStainingExecutor();
+ RuleTrafficStainer ruleTrafficStainer = new RuleTrafficStainer(stainingRuleManager, ruleStainingExecutor);
+
+ MockServerHttpRequest request = MockServerHttpRequest.get("/users")
+ .queryParam("uid", "1000").build();
+ MockServerWebExchange exchange = new MockServerWebExchange.Builder(request).build();
+
+ Map map = ruleTrafficStainer.apply(exchange);
+ Assert.assertNotNull(map);
+ Assert.assertEquals(1, map.size());
+ Assert.assertEquals("blue", map.get("env"));
+ }
+}
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/StainingRuleManagerTest.java b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/StainingRuleManagerTest.java
index 1ac88e3c8..2972d0d84 100644
--- a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/StainingRuleManagerTest.java
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/java/com/tencent/cloud/plugin/gateway/staining/rule/StainingRuleManagerTest.java
@@ -59,7 +59,7 @@ public class StainingRuleManagerTest {
+ " {\n"
+ " \"key\":\"${http.query.uid}\",\n"
+ " \"values\":[\"1000\"],\n"
- + " \"operation\":\"EQUAL\"\n"
+ + " \"operation\":\"EQUALS\"\n"
+ " }\n"
+ " ],\n"
+ " \"labels\":[\n"
@@ -99,7 +99,7 @@ public class StainingRuleManagerTest {
+ " {\n"
+ " \"key\":\"${http.query.uid}\",\n"
+ " \"values\":[\"1000\"],\n"
- + " \"operation\":\"EQUAL\"\n"
+ + " \"operation\":\"EQUALS\"\n"
+ " }\n"
+ " ],\n"
+ " \"labels\":[\n"
diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/resources/application-test.yml b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/resources/application-test.yml
new file mode 100644
index 000000000..48a51f7a9
--- /dev/null
+++ b/spring-cloud-tencent-plugin-starters/spring-cloud-tencent-gateway-plugin/src/test/resources/application-test.yml
@@ -0,0 +1,14 @@
+spring:
+ application:
+ name: test
+ cloud:
+ polaris:
+ address: grpc://127.0.0.1:8091
+ namespace: default
+ config:
+ connect-remote-server: false
+ shutdown-if-connect-to-config-server-failed: false
+ # auto-refresh: true
+ config:
+ import:
+ - optional:polaris