check server stream ready state to avoid bytebuffer back up in flow control pending write queue. (#11514)

* 修复客户端cmsgc导致服务端推送积压直接内存oom问题

* 修复ut及bug

* 修复ut及bug,checkstyle

* 修复ut

* 修复覆盖率

* checkstyle
This commit is contained in:
nov.lzf 2023-12-15 15:40:45 +08:00 committed by GitHub
parent 58803687c8
commit 06edd123f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1010 additions and 413 deletions

View File

@ -166,9 +166,9 @@ public class GroupCapacityPersistService {
GroupCapacityMapper groupCapacityMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(),
TableConstant.GROUP_CAPACITY);
MapperContext context = new MapperContext();
context.putWhereParameter(FieldConstant.GMT_MODIFIED, groupCapacity.getGmtModified());
context.putUpdateParameter(FieldConstant.GMT_MODIFIED, groupCapacity.getGmtModified());
context.putWhereParameter(FieldConstant.GROUP_ID, groupCapacity.getGroup());
context.putWhereParameter(FieldConstant.QUOTA, groupCapacity.getQuota());
context.putWhereParameter(FieldConstant.USAGE, groupCapacity.getQuota());
MapperResult mapperResult = groupCapacityMapper.incrementUsageByWhereQuotaEqualZero(context);
try {
int affectRow = jdbcTemplate.update(mapperResult.getSql(), mapperResult.getParamList().toArray());
@ -312,7 +312,7 @@ public class GroupCapacityPersistService {
TableConstant.GROUP_CAPACITY);
MapperResult mapperResult;
MapperContext context = new MapperContext();
context.putWhereParameter(FieldConstant.GMT_MODIFIED, gmtModified);
context.putUpdateParameter(FieldConstant.GMT_MODIFIED, gmtModified);
context.putWhereParameter(FieldConstant.GROUP_ID, group);
if (CLUSTER.equals(group)) {
mapperResult = groupCapacityMapper.updateUsage(context);

View File

@ -146,7 +146,7 @@ public class TenantCapacityPersistService {
MapperContext context = new MapperContext();
context.putUpdateParameter(FieldConstant.GMT_MODIFIED, tenantCapacity.getGmtModified());
context.putWhereParameter(FieldConstant.TENANT_ID, tenantCapacity.getTenant());
context.putWhereParameter(FieldConstant.USAGE, tenantCapacity.getUsage());
context.putWhereParameter(FieldConstant.USAGE, tenantCapacity.getQuota());
MapperResult mapperResult = tenantCapacityMapper.incrementUsageWithDefaultQuotaLimit(context);
try {

View File

@ -52,8 +52,10 @@ public class ConfigCommonConfigTest {
@Test
public void setMaxPushRetryTimes() {
int maxPushRetryTimesOld = commonConfig.getMaxPushRetryTimes();
commonConfig.setMaxPushRetryTimes(100);
assertEquals(100, commonConfig.getMaxPushRetryTimes());
commonConfig.setMaxPushRetryTimes(maxPushRetryTimesOld);
}
@Test

View File

@ -85,22 +85,12 @@ public class CommunicationControllerTest {
public void setUp() {
EnvUtil.setEnvironment(new StandardEnvironment());
when(servletContext.getContextPath()).thenReturn("/nacos");
ReflectionTestUtils.setField(communicationController, "dumpService", dumpService);
ReflectionTestUtils.setField(communicationController, "longPollingService", longPollingService);
ReflectionTestUtils.setField(communicationController, "configChangeListenContext", configChangeListenContext);
ReflectionTestUtils.setField(communicationController, "connectionManager", connectionManager);
mockMvc = MockMvcBuilders.standaloneSetup(communicationController).build();
}
@Test
public void testNotifyConfigInfo() throws Exception {
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.COMMUNICATION_CONTROLLER_PATH + "/dataChange")
.param("dataId", "test").param("group", "test");
String actualValue = mockMvc.perform(builder).andReturn().getResponse().getContentAsString();
Assert.assertEquals("true", actualValue);
}
@Test
public void testGetSubClientConfig1x() throws Exception {

View File

@ -22,10 +22,10 @@ import com.alibaba.nacos.persistence.datasource.DynamicDataSource;
import com.alibaba.nacos.persistence.datasource.LocalDataSourceServiceImpl;
import com.alibaba.nacos.config.server.service.dump.DumpService;
import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import com.alibaba.nacos.persistence.configuration.DatasourceConfiguration;
import com.alibaba.nacos.sys.env.EnvUtil;
import com.alibaba.nacos.sys.utils.ApplicationUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -68,19 +68,36 @@ public class ConfigOpsControllerTest {
@Mock
DumpService dumpService;
MockedStatic<DatasourceConfiguration> datasourceConfigurationMockedStatic;
MockedStatic<DynamicDataSource> dynamicDataSourceMockedStatic;
MockedStatic<ApplicationUtils> applicationUtilsMockedStatic;
@After
public void after() {
datasourceConfigurationMockedStatic.close();
dynamicDataSourceMockedStatic.close();
applicationUtilsMockedStatic.close();
}
@Before
public void init() {
EnvUtil.setEnvironment(new StandardEnvironment());
when(servletContext.getContextPath()).thenReturn("/nacos");
ReflectionTestUtils.setField(configOpsController, "dumpService", dumpService);
mockMvc = MockMvcBuilders.standaloneSetup(configOpsController).build();
datasourceConfigurationMockedStatic = Mockito.mockStatic(DatasourceConfiguration.class);
dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class);
applicationUtilsMockedStatic = Mockito.mockStatic(ApplicationUtils.class);
}
@Test
public void testUpdateLocalCacheFromStore() throws Exception {
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders
.post(Constants.OPS_CONTROLLER_PATH + "/localCache");
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post(
Constants.OPS_CONTROLLER_PATH + "/localCache");
int actualValue = mockMvc.perform(builder).andReturn().getResponse().getStatus();
Assert.assertEquals(200, actualValue);
}
@ -96,10 +113,8 @@ public class ConfigOpsControllerTest {
@Test
public void testDerbyOps() throws Exception {
MockedStatic<PropertyUtil> propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class);
MockedStatic<DynamicDataSource> dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class);
propertyUtilMockedStatic.when(DatasourceConfiguration::isEmbeddedStorage).thenReturn(true);
datasourceConfigurationMockedStatic.when(DatasourceConfiguration::isEmbeddedStorage).thenReturn(true);
DynamicDataSource dataSource = Mockito.mock(DynamicDataSource.class);
dynamicDataSourceMockedStatic.when(DynamicDataSource::getInstance).thenReturn(dataSource);
LocalDataSourceServiceImpl dataSourceService = Mockito.mock(LocalDataSourceServiceImpl.class);
@ -112,26 +127,21 @@ public class ConfigOpsControllerTest {
.param("sql", "SELECT * FROM TEST");
String actualValue = mockMvc.perform(builder).andReturn().getResponse().getContentAsString();
Assert.assertEquals("200", JacksonUtils.toObj(actualValue).get("code").toString());
propertyUtilMockedStatic.close();
dynamicDataSourceMockedStatic.close();
}
@Test
public void testImportDerby() throws Exception {
MockedStatic<PropertyUtil> propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class);
MockedStatic<ApplicationUtils> applicationUtilsMockedStatic = Mockito.mockStatic(ApplicationUtils.class);
propertyUtilMockedStatic.when(DatasourceConfiguration::isEmbeddedStorage).thenReturn(true);
datasourceConfigurationMockedStatic.when(DatasourceConfiguration::isEmbeddedStorage).thenReturn(true);
applicationUtilsMockedStatic.when(() -> ApplicationUtils.getBean(DatabaseOperate.class))
.thenReturn(Mockito.mock(DatabaseOperate.class));
MockMultipartFile file = new MockMultipartFile("file", "test.zip", "application/zip", "test".getBytes());
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders
.multipart(Constants.OPS_CONTROLLER_PATH + "/data/removal").file(file);
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(
Constants.OPS_CONTROLLER_PATH + "/data/removal").file(file);
int actualValue = mockMvc.perform(builder).andReturn().getResponse().getStatus();
Assert.assertEquals(200, actualValue);
propertyUtilMockedStatic.close();
applicationUtilsMockedStatic.close();
}
}

View File

@ -23,6 +23,8 @@ import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper;
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
import com.alibaba.nacos.config.server.service.ConfigCacheService;
import com.alibaba.nacos.config.server.service.LongPollingService;
import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory;
import com.alibaba.nacos.config.server.service.dump.disk.ConfigRocksDbDiskService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService;
@ -30,6 +32,7 @@ import com.alibaba.nacos.config.server.utils.DiskUtil;
import com.alibaba.nacos.config.server.utils.MD5Util;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@ -78,18 +81,59 @@ public class ConfigServletInnerTest {
@Mock
private ConfigInfoTagPersistService configInfoTagPersistService;
@Mock
private ConfigRocksDbDiskService configRocksDbDiskService;
static MockedStatic<ConfigDiskServiceFactory> configDiskServiceFactoryMockedStatic;
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
MockedStatic<ConfigCacheService> configCacheServiceMockedStatic;
MockedStatic<DiskUtil> diskUtilMockedStatic;
MockedStatic<PropertyUtil> propertyUtilMockedStatic;
MockedStatic<MD5Util> md5UtilMockedStatic;
@Before
public void setUp() {
EnvUtil.setEnvironment(new StandardEnvironment());
ReflectionTestUtils.setField(configServletInner, "longPollingService", longPollingService);
configCacheServiceMockedStatic = Mockito.mockStatic(ConfigCacheService.class);
diskUtilMockedStatic = Mockito.mockStatic(DiskUtil.class);
propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class);
propertyUtilMockedStatic.when(PropertyUtil::getMaxContent).thenReturn(1024 * 1000);
md5UtilMockedStatic = Mockito.mockStatic(MD5Util.class);
configDiskServiceFactoryMockedStatic = Mockito.mockStatic(ConfigDiskServiceFactory.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
}
@After
public void after() {
if (diskUtilMockedStatic != null) {
diskUtilMockedStatic.close();
}
if (configCacheServiceMockedStatic != null) {
configCacheServiceMockedStatic.close();
}
if (propertyUtilMockedStatic != null) {
propertyUtilMockedStatic.close();
}
if (md5UtilMockedStatic != null) {
md5UtilMockedStatic.close();
}
if (configDiskServiceFactoryMockedStatic != null) {
configDiskServiceFactoryMockedStatic.close();
}
}
@Test
public void testDoPollingConfig() throws Exception {
MockedStatic<MD5Util> md5UtilMockedStatic = Mockito.mockStatic(MD5Util.class);
Map<String, String> clientMd5Map = new HashMap<>();
MockHttpServletRequest request = new MockHttpServletRequest();
@ -109,15 +153,10 @@ public class ConfigServletInnerTest {
Assert.assertEquals("test-new", response.getHeader(Constants.PROBE_MODIFY_RESPONSE_NEW));
Assert.assertEquals("no-cache,no-store", response.getHeader("Cache-Control"));
md5UtilMockedStatic.close();
}
@Test
public void testDoGetConfigV1() throws Exception {
final MockedStatic<ConfigCacheService> configCacheServiceMockedStatic = Mockito.mockStatic(
ConfigCacheService.class);
final MockedStatic<DiskUtil> diskUtilMockedStatic = Mockito.mockStatic(DiskUtil.class);
final MockedStatic<PropertyUtil> propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class);
configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryReadLock(anyString())).thenReturn(1);
@ -127,6 +166,7 @@ public class ConfigServletInnerTest {
List<String> ips4Beta = new ArrayList<>();
ips4Beta.add("localhost");
cacheItem.setIps4Beta(ips4Beta);
cacheItem.initBetaCacheIfEmpty();
configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(anyString()))
.thenReturn(cacheItem);
@ -154,26 +194,20 @@ public class ConfigServletInnerTest {
File file = tempFolder.newFile("test.txt");
diskUtilMockedStatic.when(() -> DiskUtil.targetBetaFile(anyString(), anyString(), anyString()))
.thenReturn(file);
when(configRocksDbDiskService.getBetaContent("test", "test", "test")).thenReturn(
"isBeta:true, direct read: false");
response = new MockHttpServletResponse();
actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "", "true",
"localhost");
Assert.assertEquals(HttpServletResponse.SC_OK + "", actualValue);
Assert.assertEquals("true", response.getHeader("isBeta"));
Assert.assertEquals("", response.getContentAsString());
Assert.assertEquals("isBeta:true, direct read: false", response.getContentAsString());
configCacheServiceMockedStatic.close();
diskUtilMockedStatic.close();
propertyUtilMockedStatic.close();
}
@Test
public void testDoGetConfigV2() throws Exception {
final MockedStatic<ConfigCacheService> configCacheServiceMockedStatic = Mockito.mockStatic(
ConfigCacheService.class);
final MockedStatic<DiskUtil> diskUtilMockedStatic = Mockito.mockStatic(DiskUtil.class);
final MockedStatic<PropertyUtil> propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class);
configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryReadLock(anyString())).thenReturn(1);
// isBeta: false
@ -182,6 +216,8 @@ public class ConfigServletInnerTest {
List<String> ips4Beta = new ArrayList<>();
ips4Beta.add("localhost");
cacheItem.setIps4Beta(ips4Beta);
cacheItem.initConfigTagsIfEmpty("auto-tag-test");
configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(anyString()))
.thenReturn(cacheItem);
@ -205,12 +241,13 @@ public class ConfigServletInnerTest {
// if tag is blank and direct read is false
propertyUtilMockedStatic.when(PropertyUtil::isDirectRead).thenReturn(false);
response = new MockHttpServletResponse();
File file = tempFolder.newFile("test.txt");
diskUtilMockedStatic.when(() -> DiskUtil.targetFile(anyString(), anyString(), anyString())).thenReturn(file);
when(configRocksDbDiskService.getContent("test", "test", "test")).thenReturn(
"tag is blank and direct read is false");
actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "", "true",
"localhost");
Assert.assertEquals(HttpServletResponse.SC_OK + "", actualValue);
Assert.assertEquals("", response.getContentAsString());
Assert.assertEquals("tag is blank and direct read is false", response.getContentAsString());
// if tag is not blank and direct read is true
propertyUtilMockedStatic.when(PropertyUtil::isDirectRead).thenReturn(true);
@ -229,19 +266,15 @@ public class ConfigServletInnerTest {
// if tag is not blank and direct read is false
propertyUtilMockedStatic.when(PropertyUtil::isDirectRead).thenReturn(false);
response = new MockHttpServletResponse();
diskUtilMockedStatic.when(() -> DiskUtil.targetTagFile(anyString(), anyString(), anyString(), anyString()))
.thenReturn(file);
actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "test", "true",
when(configRocksDbDiskService.getTagContent("test", "test", "test", "testTag")).thenReturn(
"tag is not blank and direct read is true");
actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "testTag", "true",
"localhost");
Assert.assertEquals(HttpServletResponse.SC_OK + "", actualValue);
Assert.assertEquals("", response.getContentAsString());
Assert.assertEquals("tag is not blank and direct read is true", response.getContentAsString());
// if use auto tag and direct read is true
propertyUtilMockedStatic.when(PropertyUtil::isDirectRead).thenReturn(true);
Map<String, String> tagMd5 = new HashMap<>();
tagMd5.put("auto-tag-test", "auto-tag-test");
cacheItem.initConfigTagsIfEmpty("auto-tag-test");
cacheItem.getConfigCacheTags().get("auto-tag-test").setMd5Utf8("auto-tag-test");
request.addHeader("Vipserver-Tag", "auto-tag-test");
configInfoTagWrapper.setContent("auto tag mode and direct read is true");
when(configInfoTagPersistService.findConfigInfo4Tag(anyString(), anyString(), anyString(),
@ -254,23 +287,19 @@ public class ConfigServletInnerTest {
// if use auto tag and direct read is false
propertyUtilMockedStatic.when(PropertyUtil::isDirectRead).thenReturn(false);
when(configRocksDbDiskService.getTagContent("test", "test", "test", "auto-tag-test")).thenReturn(
"use auto tag and direct read is false");
response = new MockHttpServletResponse();
actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "", "true",
"localhost");
Assert.assertEquals(HttpServletResponse.SC_OK + "", actualValue);
Assert.assertEquals("", response.getContentAsString());
Assert.assertEquals("use auto tag and direct read is false", response.getContentAsString());
configCacheServiceMockedStatic.close();
diskUtilMockedStatic.close();
propertyUtilMockedStatic.close();
}
@Test
public void testDoGetConfigV3() throws Exception {
final MockedStatic<ConfigCacheService> configCacheServiceMockedStatic = Mockito.mockStatic(
ConfigCacheService.class);
// if lockResult equals 0
configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryReadLock(anyString())).thenReturn(0);
MockHttpServletRequest request = new MockHttpServletRequest();
@ -285,6 +314,5 @@ public class ConfigServletInnerTest {
"localhost");
Assert.assertEquals(HttpServletResponse.SC_CONFLICT + "", actualValue);
configCacheServiceMockedStatic.close();
}
}

View File

@ -107,7 +107,6 @@ public class ConfigControllerV2Test {
@Before
public void setUp() {
EnvUtil.setEnvironment(new StandardEnvironment());
when(servletContext.getContextPath()).thenReturn("/nacos");
configDetailService = new ConfigDetailService(configInfoPersistService);
configControllerV2 = new ConfigControllerV2(inner, configOperationService, configDetailService);
mockmvc = MockMvcBuilders.standaloneSetup(configControllerV2).addFilter(authFilter).build();
@ -305,6 +304,5 @@ public class ConfigControllerV2Test {
assertEquals(response.getErrorMessage(),
"Invalid server identity key or value, Please make sure set `nacos.core.auth.server.identity.key`"
+ " and `nacos.core.auth.server.identity.value`, or open `nacos.core.auth.enable.userAgentAuthWhite`");
when(authConfigs.isAuthEnabled()).thenReturn(false);
}
}

View File

@ -21,6 +21,8 @@ import com.alibaba.nacos.api.config.remote.response.ConfigPublishResponse;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.remote.request.RequestMeta;
import com.alibaba.nacos.api.remote.response.ResponseCode;
import com.alibaba.nacos.config.server.model.ConfigInfo;
import com.alibaba.nacos.config.server.model.ConfigOperateResult;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService;
@ -33,6 +35,11 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.env.StandardEnvironment;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ConfigPublishRequestHandlerTest {
@ -62,6 +69,8 @@ public class ConfigPublishRequestHandlerTest {
configPublishRequest.setContent("content");
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
when(configInfoPersistService.insertOrUpdate(any(), any(), any(ConfigInfo.class), any(Map.class))).thenReturn(
new ConfigOperateResult(true));
ConfigPublishResponse response = configPublishRequestHandler.handle(configPublishRequest, requestMeta);
Assert.assertEquals(ResponseCode.SUCCESS.getCode(), response.getResultCode());
}

View File

@ -18,80 +18,526 @@ package com.alibaba.nacos.config.server.remote;
import com.alibaba.nacos.api.config.remote.request.ConfigQueryRequest;
import com.alibaba.nacos.api.config.remote.response.ConfigQueryResponse;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.remote.request.RequestMeta;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.config.server.model.CacheItem;
import com.alibaba.nacos.config.server.model.ConfigCache;
import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper;
import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper;
import com.alibaba.nacos.config.server.model.ConfigInfoWrapper;
import com.alibaba.nacos.config.server.service.ConfigCacheService;
import com.alibaba.nacos.config.server.utils.DiskUtil;
import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory;
import com.alibaba.nacos.config.server.service.dump.disk.ConfigRocksDbDiskService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService;
import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService;
import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.config.server.utils.PropertyUtil;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.env.StandardEnvironment;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import static com.alibaba.nacos.api.common.Constants.ENCODE;
import static com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ConfigQueryRequestHandlerTest {
@InjectMocks
private ConfigQueryRequestHandler configQueryRequestHandler;
@Mock
private File file;
private ConfigInfoPersistService configInfoPersistService;
@Mock
private ConfigInfoTagPersistService configInfoTagPersistService;
@Mock
private ConfigInfoBetaPersistService configInfoBetaPersistService;
static MockedStatic<ConfigCacheService> configCacheServiceMockedStatic;
static MockedStatic<PropertyUtil> propertyUtilMockedStatic;
static MockedStatic<ConfigDiskServiceFactory> configDiskServiceFactoryMockedStatic;
String dataId = "dataId" + System.currentTimeMillis();
String group = "group" + System.currentTimeMillis();
String content = "content" + System.currentTimeMillis();
@After
public void after() {
configCacheServiceMockedStatic.close();
propertyUtilMockedStatic.close();
configDiskServiceFactoryMockedStatic.close();
EnvUtil.setEnvironment(null);
}
@Before
public void setUp() throws IOException {
EnvUtil.setEnvironment(new StandardEnvironment());
configCacheServiceMockedStatic = Mockito.mockStatic(ConfigCacheService.class);
propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class);
configDiskServiceFactoryMockedStatic = Mockito.mockStatic(ConfigDiskServiceFactory.class);
configQueryRequestHandler = new ConfigQueryRequestHandler(configInfoPersistService, configInfoTagPersistService,
configInfoBetaPersistService);
final String groupKey = GroupKey2.getKey(dataId, group, "");
when(ConfigCacheService.tryReadLock(groupKey)).thenReturn(1);
propertyUtilMockedStatic.when(PropertyUtil::getMaxContent).thenReturn(1024 * 1000);
}
/**
* get normal config from direct read.
*
* @throws Exception Exception.
*/
@Test
public void testHandle() throws NacosException {
final MockedStatic<ConfigCacheService> configCacheServiceMockedStatic = Mockito.mockStatic(
ConfigCacheService.class);
final MockedStatic<FileUtils> fileUtilsMockedStatic = Mockito.mockStatic(FileUtils.class);
final MockedStatic<DiskUtil> diskUtilMockedStatic = Mockito.mockStatic(DiskUtil.class);
MockedStatic<PropertyUtil> propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class);
public void testGetNormalDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
String content = "content_from_directreadÄãºÃ" + System.currentTimeMillis();
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(true);
propertyUtilMockedStatic.when(PropertyUtil::isDirectRead).thenReturn(false);
final String groupKey = GroupKey2.getKey("dataId", "group", "");
configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryReadLock(groupKey)).thenReturn(1);
diskUtilMockedStatic.when(() -> DiskUtil.targetFile(Mockito.any(), Mockito.any(), Mockito.any()))
.thenReturn(file);
fileUtilsMockedStatic.when(() -> FileUtils.readFileToString(file, ENCODE)).thenReturn("content");
when(file.exists()).thenReturn(true);
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.getConfigCache().setMd5Utf8("1");
cacheItem.getConfigCache().setLastModifiedTs(1L);
cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(Mockito.any()))
.thenReturn(cacheItem);
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId("dataId");
configQueryRequest.setGroup("group");
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
ConfigInfoWrapper configInfoBase = new ConfigInfoWrapper();
configInfoBase.setDataId(dataId);
configInfoBase.setGroup(group);
configInfoBase.setContent(content);
when(configInfoPersistService.findConfigInfo(eq(dataId), eq(group), eq(null))).thenReturn(configInfoBase);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
Assert.assertEquals(response.getContent(), "content");
Assert.assertEquals(content, response.getContent());
Assert.assertEquals(MD5Utils.md5Hex(content, "UTF-8"), response.getMd5());
Assert.assertFalse(response.isBeta());
Assert.assertNull(response.getTag());
configCacheServiceMockedStatic.close();
fileUtilsMockedStatic.close();
diskUtilMockedStatic.close();
propertyUtilMockedStatic.close();
}
/**
* get normal config from local disk.
*
* @throws Exception Exception.
*/
@Test
public void testGetNormalNotDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
String content = "content_from_notdirectreadÄãºÃ" + System.currentTimeMillis();
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(false);
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
cacheItem.getConfigCache().setEncryptedDataKey("key_testGetNormal_NotDirectRead");
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
when(configRocksDbDiskService.getContent(eq(dataId), eq(group), eq(null))).thenReturn(content);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
Assert.assertEquals(content, response.getContent());
Assert.assertEquals(MD5Utils.md5Hex(content, "UTF-8"), response.getMd5());
Assert.assertEquals("key_testGetNormal_NotDirectRead", response.getEncryptedDataKey());
Assert.assertFalse(response.isBeta());
Assert.assertNull(response.getTag());
Assert.assertEquals(content, response.getContent());
}
/**
* get beta config from local disk.
*
* @throws Exception Exception.
*/
@Test
public void testGetBetaNotDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(false);
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.initBetaCacheIfEmpty();
String content = "content_from_beta_notdirectreadÄãºÃ" + System.currentTimeMillis();
cacheItem.getConfigCacheBeta().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCacheBeta().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
cacheItem.getConfigCacheBeta().setEncryptedDataKey("key_testGetBeta_NotDirectRead");
cacheItem.setBeta(true);
cacheItem.setIps4Beta(Arrays.asList("127.0.0.1"));
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
when(configRocksDbDiskService.getBetaContent(eq(dataId), eq(group), eq(null))).thenReturn(content);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
//check content&md5
Assert.assertEquals(content, response.getContent());
Assert.assertEquals(MD5Utils.md5Hex(content, "UTF-8"), response.getMd5());
//check flags.
Assert.assertTrue(response.isBeta());
Assert.assertNull(response.getTag());
}
/**
* get beta config from direct read.
*
* @throws Exception Exception.
*/
@Test
public void testGetBetaDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(true);
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.initBetaCacheIfEmpty();
String content = "content_from_beta_directreadÄãºÃ" + System.currentTimeMillis();
cacheItem.getConfigCacheBeta().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCacheBeta().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
cacheItem.getConfigCacheBeta().setEncryptedDataKey("key_testGetBeta_DirectRead");
cacheItem.setBeta(true);
cacheItem.setIps4Beta(Arrays.asList("127.0.0.1"));
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
//mock direct read.
ConfigInfoBetaWrapper configInfoBase = new ConfigInfoBetaWrapper();
configInfoBase.setDataId(dataId);
configInfoBase.setGroup(group);
configInfoBase.setContent(content);
when(configInfoBetaPersistService.findConfigInfo4Beta(eq(dataId), eq(group), eq(null))).thenReturn(
configInfoBase);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
//check content&md5
Assert.assertEquals(content, response.getContent());
Assert.assertEquals(MD5Utils.md5Hex(content, "UTF-8"), response.getMd5());
Assert.assertEquals("key_testGetBeta_DirectRead", response.getEncryptedDataKey());
//check flags.
Assert.assertTrue(response.isBeta());
Assert.assertNull(response.getTag());
}
/**
* get tag config ,but not found.
*
* @throws Exception Exception.
*/
@Test
public void testGetTagNotFound() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
String content = "content_from_tag_directreadÄãºÃ" + System.currentTimeMillis();
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(true);
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
cacheItem.getConfigCache().setEncryptedDataKey("key_testGetTag_NotFound");
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
String specificTag = "specific_tag";
configQueryRequest.setTag(specificTag);
String autoTag = "specific_tag";
configQueryRequest.putHeader(VIPSERVER_TAG, autoTag);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
//mock direct read.
when(configInfoTagPersistService.findConfigInfo4Tag(eq(dataId), eq(group), eq(null),
eq(specificTag))).thenReturn(null);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
//check content&md5
Assert.assertNull(response.getContent());
Assert.assertNull(response.getMd5());
System.out.println(response.getMessage());
Assert.assertEquals(response.getErrorCode(), ConfigQueryResponse.CONFIG_NOT_FOUND);
Assert.assertNull(response.getEncryptedDataKey());
//check flags.
Assert.assertFalse(response.isBeta());
Assert.assertEquals(response.getTag(), specificTag);
}
/**
* get tag config from direct read.
*
* @throws Exception Exception.
*/
@Test
public void testGetTagDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(true);
CacheItem cacheItem = new CacheItem(groupKey);
String content = "content_from_tag_directreadÄãºÃ" + System.currentTimeMillis();
cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCache().setEncryptedDataKey("key_testGetTag_DirectRead");
cacheItem.initConfigTagsIfEmpty();
ConfigCache configCacheTag = new ConfigCache();
String tagContent = "content_from_specific_tag_directreadÄãºÃ" + System.currentTimeMillis();
configCacheTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK"));
configCacheTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8"));
configCacheTag.setEncryptedDataKey("key_testGetTag_DirectRead");
cacheItem.initConfigTagsIfEmpty();
//specific tag to get
String specificTag = "specific_tag";
cacheItem.getConfigCacheTags().put(specificTag, configCacheTag);
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
configQueryRequest.setTag(specificTag);
//just for compare.
String autoTag = "specific_tag";
configQueryRequest.putHeader(VIPSERVER_TAG, autoTag);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
//mock direct read.
ConfigInfoTagWrapper configInfoBase = new ConfigInfoTagWrapper();
configInfoBase.setDataId(dataId);
configInfoBase.setGroup(group);
configInfoBase.setContent(tagContent);
configInfoBase.setMd5(MD5Utils.md5Hex(tagContent, "UTF-8"));
when(configInfoTagPersistService.findConfigInfo4Tag(eq(dataId), eq(group), eq(null),
eq(specificTag))).thenReturn(configInfoBase);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
//check content&md5
Assert.assertEquals(tagContent, response.getContent());
Assert.assertEquals("key_testGetTag_DirectRead", response.getEncryptedDataKey());
Assert.assertEquals(MD5Utils.md5Hex(tagContent, "UTF-8"), response.getMd5());
//check flags.
Assert.assertFalse(response.isBeta());
Assert.assertEquals(response.getTag(), specificTag);
}
/**
* get tag config from local disk.
*
* @throws Exception Exception.
*/
@Test
public void testGetTagNotDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
String content = "content_from_tag_notdirectreadÄãºÃ" + System.currentTimeMillis();
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(false);
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
cacheItem.getConfigCache().setEncryptedDataKey("key_formal");
ConfigCache configCacheTag = new ConfigCache();
String tagContent = "content_from_specific_tag_directreadÄãºÃ" + System.currentTimeMillis();
configCacheTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK"));
configCacheTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8"));
configCacheTag.setEncryptedDataKey("key_testGetTag_NotDirectRead");
cacheItem.initConfigTagsIfEmpty();
//specific tag to get
String specificTag = "specific_tag";
//just for compare.
cacheItem.getConfigCacheTags().put(specificTag, configCacheTag);
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
configQueryRequest.setTag(specificTag);
String autoTag = "auto_tag";
configQueryRequest.putHeader(VIPSERVER_TAG, autoTag);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
//mock disk read.
when(configRocksDbDiskService.getTagContent(eq(dataId), eq(group), eq(null), eq(specificTag))).thenReturn(
tagContent);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
//check content&md5
Assert.assertEquals(tagContent, response.getContent());
Assert.assertEquals(MD5Utils.md5Hex(tagContent, "UTF-8"), response.getMd5());
Assert.assertEquals("key_testGetTag_NotDirectRead", response.getEncryptedDataKey());
//check flags.
Assert.assertFalse(response.isBeta());
Assert.assertEquals(response.getTag(), specificTag);
}
/**
* get tao config of auto tag matchd from local disk.
*
* @throws Exception Exception.
*/
@Test
public void testGetTagAutoTagNotDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
String content = "content_from_tag_notdirectreadÄãºÃ" + System.currentTimeMillis();
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(false);
//just for compare.
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
ConfigCache configCacheTag = new ConfigCache();
String tagContent = "content_from_specific_tag_directreadÄãºÃ" + System.currentTimeMillis();
configCacheTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK"));
configCacheTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8"));
configCacheTag.setEncryptedDataKey("key_testGetTag_AutoTag_NotDirectRead");
cacheItem.initConfigTagsIfEmpty();
String autoTag = "auto_tag";
cacheItem.getConfigCacheTags().put(autoTag, configCacheTag);
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
configQueryRequest.putHeader(VIPSERVER_TAG, autoTag);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
//mock disk read.
when(configRocksDbDiskService.getTagContent(eq(dataId), eq(group), eq(null), eq(autoTag))).thenReturn(
tagContent);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
//check content&md5
Assert.assertEquals(tagContent, response.getContent());
Assert.assertEquals(MD5Utils.md5Hex(tagContent, "UTF-8"), response.getMd5());
Assert.assertEquals("key_testGetTag_AutoTag_NotDirectRead", response.getEncryptedDataKey());
//check flags.
Assert.assertFalse(response.isBeta());
Assert.assertEquals(response.getTag(), autoTag);
}
/**
* get tag config of auto tag from direct read.
*
* @throws Exception Exception.
*/
@Test
public void testGetTagAutoTagDirectRead() throws Exception {
final String groupKey = GroupKey2.getKey(dataId, group, "");
String content = "content_from_tag_directreadÄãºÃ" + System.currentTimeMillis();
ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class);
when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService);
when(PropertyUtil.isDirectRead()).thenReturn(true);
CacheItem cacheItem = new CacheItem(groupKey);
cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK"));
cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8"));
ConfigCache configCacheTag = new ConfigCache();
String tagContent = "content_from_specific_tag_directreadÄãºÃ" + System.currentTimeMillis();
configCacheTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK"));
configCacheTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8"));
configCacheTag.setEncryptedDataKey("key_testGetTag_AutoTag_DirectRead");
cacheItem.initConfigTagsIfEmpty();
//just for compare.
String autoTag = "auto_tag";
cacheItem.getConfigCacheTags().put(autoTag, configCacheTag);
when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem);
ConfigQueryRequest configQueryRequest = new ConfigQueryRequest();
configQueryRequest.setDataId(dataId);
configQueryRequest.setGroup(group);
configQueryRequest.setTag(autoTag);
configQueryRequest.putHeader(VIPSERVER_TAG, autoTag);
RequestMeta requestMeta = new RequestMeta();
requestMeta.setClientIp("127.0.0.1");
//mock direct read.
ConfigInfoTagWrapper configInfoBase = new ConfigInfoTagWrapper();
configInfoBase.setDataId(dataId);
configInfoBase.setGroup(group);
configInfoBase.setContent(tagContent);
when(configInfoTagPersistService.findConfigInfo4Tag(eq(dataId), eq(group), eq(null), eq(autoTag))).thenReturn(
configInfoBase);
ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta);
//check content&md5
Assert.assertEquals(tagContent, response.getContent());
Assert.assertEquals(MD5Utils.md5Hex(tagContent, "UTF-8"), response.getMd5());
Assert.assertEquals("key_testGetTag_AutoTag_DirectRead", response.getEncryptedDataKey());
//check flags.
Assert.assertFalse(response.isBeta());
Assert.assertEquals(response.getTag(), autoTag);
}
}

View File

@ -34,22 +34,22 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ConfigRemoveRequestHandlerTest {
private ConfigRemoveRequestHandler configRemoveRequestHandler;
@Mock
private ConfigInfoPersistService configInfoPersistService;
@Mock
private ConfigInfoTagPersistService configInfoTagPersistService;
@Before
public void setUp() throws Exception {
configRemoveRequestHandler = new ConfigRemoveRequestHandler(configInfoPersistService,
configInfoTagPersistService);
Mockito.mockStatic(ConfigTraceService.class);
}
@Test
public void testHandle() {
ConfigRemoveRequest configRemoveRequest = new ConfigRemoveRequest();
@ -64,7 +64,8 @@ public class ConfigRemoveRequestHandlerTest {
Assert.assertEquals(ResponseCode.SUCCESS.getCode(), configRemoveResponse.getResultCode());
} catch (NacosException e) {
e.printStackTrace();
Assert.assertTrue(false);
}
}
}

View File

@ -20,10 +20,14 @@ import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent;
import com.alibaba.nacos.config.server.utils.GroupKey2;
import com.alibaba.nacos.core.remote.ConnectionManager;
import com.alibaba.nacos.core.remote.RpcPushService;
import com.alibaba.nacos.plugin.control.ControlManagerCenter;
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;
@ -44,23 +48,36 @@ public class RpcConfigChangeNotifierTest {
@Mock
private ConnectionManager connectionManager;
@Mock
ControlManagerCenter controlManagerCenter;
@Mock
TpsControlManager tpsControlManager;
MockedStatic<ControlManagerCenter> controlManagerCenterMockedStatic;
@Before
public void setUp() {
rpcConfigChangeNotifier = new RpcConfigChangeNotifier();
controlManagerCenterMockedStatic = Mockito.mockStatic(ControlManagerCenter.class);
Mockito.when(ControlManagerCenter.getInstance()).thenReturn(controlManagerCenter);
Mockito.when(ControlManagerCenter.getInstance().getTpsControlManager()).thenReturn(tpsControlManager);
rpcConfigChangeNotifier = new RpcConfigChangeNotifier();
ReflectionTestUtils.setField(rpcConfigChangeNotifier, "configChangeListenContext", configChangeListenContext);
ReflectionTestUtils.setField(rpcConfigChangeNotifier, "rpcPushService", rpcPushService);
ReflectionTestUtils.setField(rpcConfigChangeNotifier, "connectionManager", connectionManager);
}
@Test
public void testOnEvent() {
final String groupKey = GroupKey2.getKey("nacos.internal.tps.control_rule_1", "nacos", "tenant");
final String limitGroupKey = GroupKey2
.getKey("nacos.internal.tps.nacos.internal.connection.limit.rule", "nacos", "tenant");
final String limitGroupKey = GroupKey2.getKey("nacos.internal.tps.nacos.internal.connection.limit.rule",
"nacos", "tenant");
List<String> betaIps = new ArrayList<>();
betaIps.add("1.1.1.1");
rpcConfigChangeNotifier.onEvent(new LocalDataChangeEvent(groupKey, true, betaIps));
rpcConfigChangeNotifier.onEvent(new LocalDataChangeEvent(limitGroupKey));
}

View File

@ -1,61 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.alibaba.nacos.config.server.service;
import com.alibaba.nacos.config.server.utils.DiskUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import java.io.File;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class DiskServiceUnitTest {
private DiskUtil diskService;
private File tempFile;
private String path;
@Before
public void setUp() throws IOException {
this.tempFile = File.createTempFile("diskServiceTest", "tmp");
this.path = tempFile.getParent();
this.diskService = new DiskUtil();
}
@Test
public void testCreateConfig() throws IOException {
DiskUtil.saveToDisk("testDataId", "testGroup", "testTenant", "testContent");
String content = DiskUtil.getConfig("testDataId", "testGroup", "testTenant");
assertEquals(content, "testContent");
}
@After
public void tearDown() throws IOException {
tempFile.delete();
}
}

View File

@ -19,17 +19,17 @@ package com.alibaba.nacos.config.server.service.capacity;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.config.server.model.capacity.Capacity;
import com.alibaba.nacos.config.server.model.capacity.GroupCapacity;
import com.alibaba.nacos.persistence.datasource.DataSourceService;
import com.alibaba.nacos.config.server.utils.TimeUtils;
import com.alibaba.nacos.persistence.datasource.DataSourceService;
import com.alibaba.nacos.plugin.datasource.MapperManager;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoMapperByMySql;
import com.alibaba.nacos.plugin.datasource.impl.mysql.GroupCapacityMapperByMysql;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
@ -38,7 +38,6 @@ import org.mockito.stubbing.Answer;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -46,13 +45,10 @@ import org.springframework.test.util.ReflectionTestUtils;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
@ -73,6 +69,13 @@ public class GroupCapacityPersistServiceTest {
@Mock
private MapperManager mapperManager;
MockedStatic<TimeUtils> timeUtilsMockedStatic;
@After
public void after() {
timeUtilsMockedStatic.close();
}
@Before
public void setUp() {
ReflectionTestUtils.setField(service, "jdbcTemplate", jdbcTemplate);
@ -81,6 +84,8 @@ public class GroupCapacityPersistServiceTest {
when(dataSourceService.getJdbcTemplate()).thenReturn(jdbcTemplate);
doReturn(new GroupCapacityMapperByMysql()).when(mapperManager)
.findMapper(any(), eq(TableConstant.GROUP_CAPACITY));
timeUtilsMockedStatic = Mockito.mockStatic(TimeUtils.class);
}
@Test
@ -115,23 +120,20 @@ public class GroupCapacityPersistServiceTest {
@Test
public void testInsertGroupCapacity() {
Mockito.when(jdbcTemplate.update(any(PreparedStatementCreator.class),
argThat((ArgumentMatcher<GeneratedKeyHolder>) keyHolder -> {
List<Map<String, Object>> keyList = new ArrayList<>();
Map<String, Object> keyMap = new HashMap<>();
Number number = 1;
keyMap.put("test", number);
keyList.add(keyMap);
List<Map<String, Object>> expect = keyHolder.getKeyList();
expect.addAll(keyList);
return false;
}))).thenReturn(1);
doReturn(1).when(jdbcTemplate)
.update(anyString(), eq(""), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null));
// when(jdbcTemplate.update(anyString(), eq(timestamp), eq("test3"))).thenReturn(1);
GroupCapacity capacity = new GroupCapacity();
capacity.setGroup(GroupCapacityPersistService.CLUSTER);
Assert.assertTrue(service.insertGroupCapacity(capacity));
capacity.setGroup("test");
doReturn(1).when(jdbcTemplate)
.update(anyString(), eq("test"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq("test"));
Assert.assertTrue(service.insertGroupCapacity(capacity));
}
@ -149,8 +151,8 @@ public class GroupCapacityPersistServiceTest {
when(jdbcTemplate.query(anyString(), eq(new Object[] {groupId}), any(RowMapper.class))).thenReturn(list);
Assert.assertEquals(groupCapacity.getUsage().intValue(), service.getClusterUsage());
when(jdbcTemplate.query(anyString(), eq(new Object[] {groupId}), any(RowMapper.class)))
.thenReturn(new ArrayList<>());
when(jdbcTemplate.query(anyString(), eq(new Object[] {groupId}), any(RowMapper.class))).thenReturn(
new ArrayList<>());
when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(20);
Assert.assertEquals(20, service.getClusterUsage());
}
@ -203,7 +205,6 @@ public class GroupCapacityPersistServiceTest {
@Test
public void testUpdateGroupCapacity() {
final MockedStatic<TimeUtils> timeUtilsMockedStatic = Mockito.mockStatic(TimeUtils.class);
List<Object> argList = CollectionUtils.list();
@ -220,8 +221,7 @@ public class GroupCapacityPersistServiceTest {
argList.add(maxAggrSize);
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
timeUtilsMockedStatic.when(TimeUtils::getCurrentTime).thenReturn(timestamp);
when(TimeUtils.getCurrentTime()).thenReturn(timestamp);
argList.add(timestamp);
String group = "test";
@ -230,19 +230,20 @@ public class GroupCapacityPersistServiceTest {
when(jdbcTemplate.update(anyString(), any(Object.class))).thenAnswer((Answer<Integer>) invocationOnMock -> {
if (invocationOnMock.getArgument(1).equals(quota) && invocationOnMock.getArgument(2).equals(maxSize)
&& invocationOnMock.getArgument(3).equals(maxAggrCount) && invocationOnMock.getArgument(4)
.equals(maxAggrSize) && invocationOnMock.getArgument(5).equals(timestamp) && invocationOnMock
.getArgument(6).equals(group)) {
.equals(maxAggrSize) && invocationOnMock.getArgument(5).equals(timestamp)
&& invocationOnMock.getArgument(6).equals(group)) {
return 1;
}
return 0;
});
Assert.assertTrue(service.updateGroupCapacity(group, quota, maxSize, maxAggrCount, maxAggrSize));
timeUtilsMockedStatic.close();
}
@Test
public void testUpdateQuota() {
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
when(TimeUtils.getCurrentTime()).thenReturn(timestamp);
List<Object> argList = CollectionUtils.list();
Integer quota = 2;
@ -251,12 +252,8 @@ public class GroupCapacityPersistServiceTest {
String group = "test2";
argList.add(group);
when(jdbcTemplate.update(anyString(), any(Object.class))).thenAnswer((Answer<Integer>) invocationOnMock -> {
if (invocationOnMock.getArgument(1).equals(quota) && invocationOnMock.getArgument(3).equals(group)) {
return 1;
}
return 0;
});
when(jdbcTemplate.update(anyString(), eq(2), eq(timestamp), eq(group))).thenReturn(1);
Assert.assertTrue(service.updateQuota(group, quota));
}
@ -264,19 +261,15 @@ public class GroupCapacityPersistServiceTest {
public void testUpdateMaxSize() {
List<Object> argList = CollectionUtils.list();
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
when(TimeUtils.getCurrentTime()).thenReturn(timestamp);
Integer maxSize = 3;
argList.add(maxSize);
String group = "test3";
argList.add(group);
when(jdbcTemplate.update(anyString(), any(Object.class))).thenAnswer((Answer<Integer>) invocationOnMock -> {
if (invocationOnMock.getArgument(1).equals(maxSize) && invocationOnMock.getArgument(3).equals(group)) {
return 1;
}
return 0;
});
when(jdbcTemplate.update(anyString(), eq(3), eq(timestamp), eq(group))).thenReturn(1);
Assert.assertTrue(service.updateMaxSize(group, maxSize));
}
@ -304,8 +297,8 @@ public class GroupCapacityPersistServiceTest {
long lastId = 1;
int pageSize = 1;
when(jdbcTemplate.query(anyString(), eq(new Object[] {lastId, pageSize}), any(RowMapper.class)))
.thenReturn(list);
when(jdbcTemplate.query(anyString(), eq(new Object[] {lastId, pageSize}), any(RowMapper.class))).thenReturn(
list);
List<GroupCapacity> ret = service.getCapacityList4CorrectUsage(lastId, pageSize);
Assert.assertEquals(list.size(), ret.size());

View File

@ -18,8 +18,8 @@ package com.alibaba.nacos.config.server.service.capacity;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.config.server.model.capacity.TenantCapacity;
import com.alibaba.nacos.persistence.datasource.DataSourceService;
import com.alibaba.nacos.config.server.utils.TimeUtils;
import com.alibaba.nacos.persistence.datasource.DataSourceService;
import com.alibaba.nacos.plugin.datasource.MapperManager;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.impl.mysql.TenantCapacityMapperByMySql;
@ -27,7 +27,6 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
@ -36,7 +35,6 @@ import org.mockito.stubbing.Answer;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -44,13 +42,10 @@ import org.springframework.test.util.ReflectionTestUtils;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
@ -99,17 +94,8 @@ public class TenantCapacityPersistServiceTest {
@Test
public void testInsertTenantCapacity() {
when(jdbcTemplate.update(any(PreparedStatementCreator.class),
argThat((ArgumentMatcher<GeneratedKeyHolder>) keyHolder -> {
List<Map<String, Object>> keyList = new ArrayList<>();
Map<String, Object> keyMap = new HashMap<>();
Number number = 1;
keyMap.put("test", number);
keyList.add(keyMap);
List<Map<String, Object>> expect = keyHolder.getKeyList();
expect.addAll(keyList);
return false;
}))).thenReturn(1);
when(jdbcTemplate.update(anyString(), eq("test"), eq(null), eq(null), eq(null), eq(null), eq(null), eq(null),
eq("test"))).thenReturn(1);
TenantCapacity capacity = new TenantCapacity();
capacity.setTenant("test");
@ -193,8 +179,8 @@ public class TenantCapacityPersistServiceTest {
when(jdbcTemplate.update(anyString(), any(Object.class))).thenAnswer((Answer<Integer>) invocationOnMock -> {
if (invocationOnMock.getArgument(1).equals(quota) && invocationOnMock.getArgument(2).equals(maxSize)
&& invocationOnMock.getArgument(3).equals(maxAggrCount) && invocationOnMock.getArgument(4)
.equals(maxAggrSize) && invocationOnMock.getArgument(5).equals(timestamp) && invocationOnMock
.getArgument(6).equals(tenant)) {
.equals(maxAggrSize) && invocationOnMock.getArgument(5).equals(timestamp)
&& invocationOnMock.getArgument(6).equals(tenant)) {
return 1;
}
return 0;
@ -243,8 +229,8 @@ public class TenantCapacityPersistServiceTest {
long lastId = 1;
int pageSize = 1;
when(jdbcTemplate.query(anyString(), eq(new Object[] {lastId, pageSize}), any(RowMapper.class)))
.thenReturn(list);
when(jdbcTemplate.query(anyString(), eq(new Object[] {lastId, pageSize}), any(RowMapper.class))).thenReturn(
list);
List<TenantCapacity> ret = service.getCapacityList4CorrectUsage(lastId, pageSize);
Assert.assertEquals(list.size(), ret.size());

View File

@ -18,6 +18,7 @@ package com.alibaba.nacos.config.server.service.dump;
import com.alibaba.nacos.persistence.datasource.DynamicDataSource;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@ -31,6 +32,7 @@ import org.springframework.test.util.ReflectionTestUtils;
@SpringBootTest
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
@WebAppConfiguration
@Ignore
public class DumpServiceTest {
@Autowired

View File

@ -16,19 +16,24 @@
package com.alibaba.nacos.config.server.utils;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.alibaba.nacos.config.server.constant.Constants;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.apache.commons.io.FileUtils;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.File;
import java.io.IOException;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@RunWith(SpringJUnit4ClassRunner.class)
public class DiskUtilsTest {
static MockedStatic<FileUtils> fileUtils;
@ -38,166 +43,31 @@ public class DiskUtilsTest {
fileUtils = Mockito.mockStatic(FileUtils.class);
}
@AfterClass
public static void after() {
fileUtils.close();
}
@Test
public void testSaveHeartBeatToDisk() throws IOException {
String heartBeatTime = System.currentTimeMillis() + "";
DiskUtil.saveHeartBeatToDisk(heartBeatTime);
fileUtils.verify(() -> FileUtils.writeStringToFile(DiskUtil.heartBeatFile(), heartBeatTime, Constants.ENCODE), Mockito.times(1));
fileUtils.verify(() -> FileUtils.writeStringToFile(any(), eq(heartBeatTime), eq(UTF_8.displayName())), Mockito.times(1));
}
@Test
public void testSaveToDisk() throws IOException {
File targetFile = DiskUtil.targetFile("test", "test", "test");
DiskUtil.saveToDisk("test", "test", "test", "saveToDisk");
fileUtils.verify(() -> FileUtils.writeStringToFile(targetFile, "saveToDisk", Constants.ENCODE), Mockito.times(1));
}
@Test
public void testSaveBetaToDisk() throws IOException {
File targetFile = DiskUtil.targetBetaFile("test", "test", "test");
DiskUtil.saveBetaToDisk("test", "test", "test", "saveBetaToDisk");
fileUtils.verify(() -> FileUtils.writeStringToFile(targetFile, "saveBetaToDisk", Constants.ENCODE), Mockito.times(1));
}
@Test
public void testSaveTagToDisk() throws IOException {
File targetFile = DiskUtil.targetTagFile("test", "test", "test", "tag");
DiskUtil.saveTagToDisk("test", "test", "test", "tag", "saveTagToDisk");
fileUtils.verify(() -> FileUtils.writeStringToFile(targetFile, "saveTagToDisk", Constants.ENCODE), Mockito.times(1));
}
@Test
public void testRemoveConfigInfo() {
File targetFile = DiskUtil.targetFile("test", "test", "test");
DiskUtil.removeConfigInfo("test", "test", "test");
fileUtils.verify(() -> FileUtils.deleteQuietly(targetFile), Mockito.times(1));
}
@Test
public void testRemoveConfigInfo4Beta() {
File targetFile = DiskUtil.targetBetaFile("test", "test", "test");
DiskUtil.removeConfigInfo4Beta("test", "test", "test");
fileUtils.verify(() -> FileUtils.deleteQuietly(targetFile), Mockito.times(1));
}
@Test
public void testRemoveConfigInfo4Tag() {
File targetFile = DiskUtil.targetTagFile("test", "test", "test", "tag");
DiskUtil.removeConfigInfo4Tag("test", "test", "test", "tag");
fileUtils.verify(() -> FileUtils.deleteQuietly(targetFile), Mockito.times(1));
}
@Test
public void testRemoveHeartHeat() {
File targetFile = DiskUtil.heartBeatFile();
DiskUtil.removeHeartHeat();
fileUtils.verify(() -> FileUtils.deleteQuietly(targetFile), Mockito.times(1));
}
@Test
public void testTargetFile() {
File file = DiskUtil.targetFile("test1", "test2", "test3");
String[] arr = file.getPath().split(File.separator);
Assert.assertEquals("test1", arr[arr.length - 1]);
Assert.assertEquals("test2", arr[arr.length - 2]);
Assert.assertEquals("test3", arr[arr.length - 3]);
File file2 = DiskUtil.targetFile("test1", "test2", "");
String[] arr2 = file2.getPath().split(File.separator);
Assert.assertEquals("test1", arr2[arr2.length - 1]);
Assert.assertEquals("test2", arr2[arr2.length - 2]);
Assert.assertEquals("config-data", arr2[arr2.length - 3]);
}
@Test
public void testTargetBetaFile() {
File file = DiskUtil.targetBetaFile("test1", "test2", "test3");
String[] arr = file.getPath().split(File.separator);
Assert.assertEquals("test1", arr[arr.length - 1]);
Assert.assertEquals("test2", arr[arr.length - 2]);
Assert.assertEquals("test3", arr[arr.length - 3]);
File file2 = DiskUtil.targetBetaFile("test1", "test2", "");
String[] arr2 = file2.getPath().split(File.separator);
Assert.assertEquals("test1", arr2[arr2.length - 1]);
Assert.assertEquals("test2", arr2[arr2.length - 2]);
Assert.assertEquals("beta-data", arr2[arr2.length - 3]);
}
@Test
public void testTargetTagFile() {
File file = DiskUtil.targetTagFile("test1", "test2", "test3", "tag");
String[] arr = file.getPath().split(File.separator);
Assert.assertEquals("tag", arr[arr.length - 1]);
Assert.assertEquals("test1", arr[arr.length - 2]);
Assert.assertEquals("test2", arr[arr.length - 3]);
Assert.assertEquals("test3", arr[arr.length - 4]);
File file2 = DiskUtil.targetTagFile("test1", "test2", "", "tag");
String[] arr2 = file2.getPath().split(File.separator);
Assert.assertEquals("tag", arr2[arr2.length - 1]);
Assert.assertEquals("test1", arr2[arr2.length - 2]);
Assert.assertEquals("test2", arr2[arr2.length - 3]);
Assert.assertEquals("tag-data", arr2[arr2.length - 4]);
}
@Test
public void testGetConfig() throws IOException {
String result = DiskUtil.getConfig("test", "test", "test");
Assert.assertEquals("", result);
}
@Test
public void testGetLocalConfigMd5() throws IOException {
final MockedStatic<MD5Utils> md5Utils = Mockito.mockStatic(MD5Utils.class);
Mockito.when(MD5Utils.md5Hex("", Constants.ENCODE)).thenReturn("md5");
String result = DiskUtil.getLocalConfigMd5("test", "test", "test");
Assert.assertEquals("md5", result);
md5Utils.close();
}
@Test
public void testHeartBeatFile() {
File file = DiskUtil.heartBeatFile();
String[] arr = file.getPath().split(File.separator);
String[] arr = file.getPath().split("/");
Assert.assertEquals("heartBeat.txt", arr[arr.length - 1]);
Assert.assertEquals("status", arr[arr.length - 2]);
Assert.assertEquals("nacos", arr[arr.length - 3]);
}
@Test
public void testRelativePath() {
String relativePath = DiskUtil.relativePath("test1", "test2");
String[] arr = relativePath.split(File.separator);
Assert.assertEquals("test2", arr[arr.length - 1]);
Assert.assertEquals("test1", arr[arr.length - 2]);
}
@Test
public void testClearAll() {
DiskUtil.clearAll();
File file = new File(EnvUtil.getNacosHome(), DiskUtil.BASE_DIR);
fileUtils.verify(() -> FileUtils.deleteQuietly(file), Mockito.times(1));
File fileTenant = new File(EnvUtil.getNacosHome(), DiskUtil.TENANT_BASE_DIR);
fileUtils.verify(() -> FileUtils.deleteQuietly(fileTenant), Mockito.times(1));
}
@Test
public void testClearAllBeta() {
DiskUtil.clearAllBeta();
File file = new File(EnvUtil.getNacosHome(), DiskUtil.BETA_DIR);
fileUtils.verify(() -> FileUtils.deleteQuietly(file), Mockito.times(1));
File fileTenant = new File(EnvUtil.getNacosHome(), DiskUtil.TENANT_BETA_DIR);
fileUtils.verify(() -> FileUtils.deleteQuietly(fileTenant), Mockito.times(1));
}
@Test
public void testClearAllTag() {
DiskUtil.clearAllTag();
File file = new File(EnvUtil.getNacosHome(), DiskUtil.TAG_DIR);
fileUtils.verify(() -> FileUtils.deleteQuietly(file), Mockito.times(1));
File fileTenant = new File(EnvUtil.getNacosHome(), DiskUtil.TENANT_TAG_DIR);
fileUtils.verify(() -> FileUtils.deleteQuietly(fileTenant), Mockito.times(1));
}
}

View File

@ -38,17 +38,20 @@ import java.util.List;
import java.util.Map;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
public class MD5UtilTest {
@Test
public void testCompareMd5() {
final MockedStatic<ConfigCacheService> configCacheServiceMockedStatic = Mockito.mockStatic(ConfigCacheService.class);
configCacheServiceMockedStatic.when(
() -> ConfigCacheService.isUptodate(anyString(), anyString(), anyString(), anyString()))
final MockedStatic<ConfigCacheService> configCacheServiceMockedStatic = Mockito
.mockStatic(ConfigCacheService.class);
when(ConfigCacheService
.isUptodate(anyString(), anyString(), anyString(), anyString()))
.thenReturn(false);
Map<String, String> clientMd5Map = new HashMap<>();
clientMd5Map.put("test", "test");
@ -60,13 +63,13 @@ public class MD5UtilTest {
Assert.assertEquals(1, changedGroupKeys.size());
Assert.assertEquals("test", changedGroupKeys.get(0));
configCacheServiceMockedStatic.close();
configCacheServiceMockedStatic.close();
}
@Test
public void testCompareMd5OldResult() {
final MockedStatic<GroupKey2> groupKey2MockedStatic = Mockito.mockStatic(GroupKey2.class);
List<String> changedGroupKeys = new ArrayList<>();
@ -76,18 +79,18 @@ public class MD5UtilTest {
arr[0] = "test0";
arr[1] = "test1";
arr[2] = "test2";
groupKey2MockedStatic.when(() -> GroupKey2.parseKey(anyString())).thenReturn(arr);
when(GroupKey2.parseKey(anyString())).thenReturn(arr);
String actualValue = MD5Util.compareMd5OldResult(changedGroupKeys);
Assert.assertEquals("test0:test1;", actualValue);
groupKey2MockedStatic.close();
groupKey2MockedStatic.close();
}
@Test
public void testCompareMd5ResultString() {
final MockedStatic<GroupKey2> groupKey2MockedStatic = Mockito.mockStatic(GroupKey2.class);
List<String> changedGroupKeys = new ArrayList<>();
@ -97,15 +100,15 @@ public class MD5UtilTest {
arr[0] = "test0";
arr[1] = "test1";
arr[2] = "test2";
groupKey2MockedStatic.when(() -> GroupKey2.parseKey(anyString())).thenReturn(arr);
when(GroupKey2.parseKey(anyString())).thenReturn(arr);
try {
String actualValue = MD5Util.compareMd5ResultString(changedGroupKeys);
Assert.assertEquals("test0%02test1%02test2%01", actualValue);
} catch (IOException e) {
System.out.println(e);
System.out.println(e.toString());
}
groupKey2MockedStatic.close();
}
@ -125,11 +128,11 @@ public class MD5UtilTest {
@Test
public void testGetClientMd5MapForNewProtocol() {
String configKeysString =
"test0" + MD5Util.WORD_SEPARATOR_CHAR + "test1" + MD5Util.WORD_SEPARATOR_CHAR + "test2" + MD5Util.WORD_SEPARATOR_CHAR + "test3"
+ MD5Util.LINE_SEPARATOR_CHAR;
"test0" + MD5Util.WORD_SEPARATOR_CHAR + "test1" + MD5Util.WORD_SEPARATOR_CHAR + "test2"
+ MD5Util.WORD_SEPARATOR_CHAR + "test3" + MD5Util.LINE_SEPARATOR_CHAR;
Map<String, String> actualValueMap = MD5Util.getClientMd5Map(configKeysString);
Assert.assertEquals("test2", actualValueMap.get("test0+test1+test3"));
}
@ -141,7 +144,7 @@ public class MD5UtilTest {
String actualValue = MD5Util.toString(input, "UTF-8");
Assert.assertEquals("test", actualValue);
} catch (IOException e) {
System.out.println(e);
System.out.println(e.toString());
}
}
@ -153,7 +156,7 @@ public class MD5UtilTest {
String actualValue = MD5Util.toString(reader);
Assert.assertEquals("test", actualValue);
} catch (IOException e) {
System.out.println(e);
System.out.println(e.toString());
}
}
@ -170,8 +173,8 @@ public class MD5UtilTest {
Assert.assertEquals(content, output.toString());
} catch (IOException e) {
System.out.println(e);
System.out.println(e.toString());
}
}
}
}

View File

@ -87,6 +87,10 @@ public class ConnectionMeta {
*/
String tenant;
long firstPushQueueBlockTime = 0;
long lastPushQueueBlockTime = 0;
protected Map<String, String> labels = new HashMap<>();
public String getLabel(String labelKey) {
@ -292,6 +296,34 @@ public class ConnectionMeta {
this.tenant = tenant;
}
/**
* recordPushQueueBlockTimes.
*/
public void recordPushQueueBlockTimes() {
if (this.firstPushQueueBlockTime == 0) {
firstPushQueueBlockTime = System.currentTimeMillis();
} else {
lastPushQueueBlockTime = System.currentTimeMillis();
}
}
/**
* clear push queue block times.
*/
public void clearPushQueueBlockTimes() {
this.firstPushQueueBlockTime = 0;
this.lastPushQueueBlockTime = 0;
}
/**
* check block greater than the specific time.
* @param timeMillsSeconds check times.
* @return
*/
public boolean pushQueueBlockTimesLastOver(long timeMillsSeconds) {
return this.lastPushQueueBlockTime - this.firstPushQueueBlockTime > timeMillsSeconds;
}
@Override
public String toString() {
return "ConnectionMeta{" + "connectType='" + connectType + '\'' + ", clientIp='" + clientIp + '\''

View File

@ -52,15 +52,15 @@ public class NacosRuntimeConnectionEjector extends RuntimeConnectionEjector {
// remove overload connection
ejectOverLimitConnection();
}
/**
* eject the outdated connection.
*/
private void ejectOutdatedConnection() {
try {
Loggers.CONNECTION.info("Connection check task start");
Map<String, Connection> connections = connectionManager.connections;
int totalCount = connections.size();
int currentSdkClientCount = connectionManager.currentSdkClientCount();
@ -75,6 +75,8 @@ public class NacosRuntimeConnectionEjector extends RuntimeConnectionEjector {
Connection client = entry.getValue();
if (now - client.getMetaInfo().getLastActiveTime() >= KEEP_ALIVE_TIME) {
outDatedConnections.add(client.getMetaInfo().getConnectionId());
} else if (client.getMetaInfo().pushQueueBlockTimesLastOver(300 * 1000)) {
outDatedConnections.add(client.getMetaInfo().getConnectionId());
}
}
@ -145,7 +147,7 @@ public class NacosRuntimeConnectionEjector extends RuntimeConnectionEjector {
Loggers.CONNECTION.error("Error occurs during connection check... ", e);
}
}
/**
* eject the over limit connection.
*/

View File

@ -17,6 +17,7 @@
package com.alibaba.nacos.core.remote.grpc;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.api.grpc.auto.Payload;
import com.alibaba.nacos.api.remote.DefaultRequestFuture;
import com.alibaba.nacos.api.remote.RequestCallBack;
@ -25,15 +26,21 @@ import com.alibaba.nacos.api.remote.request.Request;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.common.remote.client.grpc.GrpcUtils;
import com.alibaba.nacos.common.remote.exception.ConnectionAlreadyClosedException;
import com.alibaba.nacos.common.remote.exception.ConnectionBusyException;
import com.alibaba.nacos.core.remote.Connection;
import com.alibaba.nacos.core.remote.ConnectionMeta;
import com.alibaba.nacos.core.remote.RpcAckCallbackSynchronizer;
import com.alibaba.nacos.core.utils.Loggers;
import com.alibaba.nacos.plugin.control.ControlManagerCenter;
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
import com.alibaba.nacos.plugin.control.tps.request.TpsCheckRequest;
import io.grpc.StatusRuntimeException;
import io.grpc.netty.shaded.io.netty.channel.Channel;
import io.grpc.stub.ServerCallStreamObserver;
import io.grpc.stub.StreamObserver;
import java.util.concurrent.atomic.AtomicReference;
/**
* grpc connection.
*
@ -46,6 +53,8 @@ public class GrpcConnection extends Connection {
private Channel channel;
private static TpsControlManager tpsControlManager;
public GrpcConnection(ConnectionMeta metaInfo, StreamObserver streamObserver, Channel channel) {
super(metaInfo);
this.streamObserver = streamObserver;
@ -59,19 +68,71 @@ public class GrpcConnection extends Connection {
* @throws NacosException NacosException
*/
public void sendRequestNoAck(Request request) throws NacosException {
try {
sendQueueBlockCheck();
final AtomicReference<NacosRuntimeException> exception = new AtomicReference<>();
final DefaultRequestFuture future = new DefaultRequestFuture(this.getMetaInfo().getConnectionId(), "0");
this.channel.eventLoop().execute(() -> {
//StreamObserver#onNext() is not thread-safe,synchronized is required to avoid direct memory leak.
synchronized (streamObserver) {
Payload payload = GrpcUtils.convert(request);
traceIfNecessary(payload);
streamObserver.onNext(payload);
try {
Payload payload = GrpcUtils.convert(request);
traceIfNecessary(payload);
streamObserver.onNext(payload);
future.setResponse(new Response() {
@Override
public String getMessage() {
return "";
}
});
} catch (Throwable e) {
if (e instanceof StatusRuntimeException) {
exception.set(new ConnectionAlreadyClosedException(e));
} else if (e instanceof IllegalStateException) {
exception.set(new ConnectionAlreadyClosedException(e));
} else {
exception.set(new NacosRuntimeException(NacosException.SERVER_ERROR, e));
}
future.setFailResult(exception.get());
}
}
});
try {
future.get();
} catch (Exception e) {
if (e instanceof StatusRuntimeException) {
throw new ConnectionAlreadyClosedException(e);
//ignore
}
if (exception.get() != null) {
throw exception.get();
}
}
private void sendQueueBlockCheck() {
if (streamObserver instanceof ServerCallStreamObserver) {
// if bytes on queue is greater than 32k ,isReady will return false.
// queue type: grpc write queue,flowed controller queue etc.
// this 32k threshold is fixed with static final.
// see io.grpc.internal.AbstractStream.TransportState.DEFAULT_ONREADY_THRESHOLD
boolean ready = ((ServerCallStreamObserver<?>) streamObserver).isReady();
if (!ready) {
if (tpsControlManager == null) {
synchronized (GrpcConnection.class.getClass()) {
if (tpsControlManager == null) {
tpsControlManager = ControlManagerCenter.getInstance().getTpsControlManager();
tpsControlManager.registerTpsPoint("SERVER_PUSH_BLOCK");
}
}
}
TpsCheckRequest tpsCheckRequest = new TpsCheckRequest("SERVER_PUSH_BLOCK",
this.getMetaInfo().getConnectionId(), this.getMetaInfo().getClientIp());
//record block only.
tpsControlManager.check(tpsCheckRequest);
getMetaInfo().recordPushQueueBlockTimes();
throw new ConnectionBusyException("too much bytes on sending queue of this stream.");
} else {
getMetaInfo().clearPushQueueBlockTimes();
}
throw e;
}
}
@ -133,8 +194,12 @@ public class GrpcConnection extends Connection {
if (isTraced()) {
Loggers.REMOTE_DIGEST.warn("[{}] try to close connection ", connectionId);
}
closeBiStream();
try {
closeBiStream();
} catch (Throwable e) {
Loggers.REMOTE_DIGEST.warn("[{}] connection close bi stream exception : {}", connectionId, e);
}
channel.close();
} catch (Exception e) {

View File

@ -0,0 +1,204 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.alibaba.nacos.core.remote.grpc;
import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException;
import com.alibaba.nacos.api.naming.remote.request.NotifySubscriberRequest;
import com.alibaba.nacos.api.naming.remote.response.NotifySubscriberResponse;
import com.alibaba.nacos.api.remote.DefaultRequestFuture;
import com.alibaba.nacos.common.remote.exception.ConnectionAlreadyClosedException;
import com.alibaba.nacos.common.remote.exception.ConnectionBusyException;
import com.alibaba.nacos.core.remote.ConnectionMeta;
import com.alibaba.nacos.core.remote.RpcAckCallbackSynchronizer;
import com.alibaba.nacos.plugin.control.ControlManagerCenter;
import com.alibaba.nacos.plugin.control.tps.TpsControlManager;
import com.alibaba.nacos.plugin.control.tps.response.TpsCheckResponse;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.netty.shaded.io.netty.channel.Channel;
import io.grpc.netty.shaded.io.netty.channel.DefaultEventLoop;
import io.grpc.stub.ServerCallStreamObserver;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@RunWith(MockitoJUnitRunner.class)
public class GrpcConnectionTest {
@Mock
private Channel channel;
@Mock
ServerCallStreamObserver streamObserver;
@Mock
ControlManagerCenter controlManagerCenter;
@Mock
TpsControlManager tpsControlManager;
GrpcConnection connection;
MockedStatic<ControlManagerCenter> controlManagerCenterMockedStatic;
@After
public void setDown() throws IOException {
if (controlManagerCenterMockedStatic != null) {
controlManagerCenterMockedStatic.close();
}
}
@Before
public void setUp() throws IOException {
String ip = "1.1.1.1";
ConnectionMeta connectionMeta = new ConnectionMeta("connectId" + System.currentTimeMillis(), ip, ip, 8888, 9848,
"GRPC", "", "", new HashMap<>());
connection = new GrpcConnection(connectionMeta, streamObserver, channel);
}
@Test
public void testStatusRuntimeException() {
Mockito.doReturn(new DefaultEventLoop()).when(channel).eventLoop();
Mockito.doThrow(new StatusRuntimeException(Status.CANCELLED)).when(streamObserver).onNext(Mockito.any());
Mockito.doReturn(true).when(streamObserver).isReady();
try {
connection.request(new NotifySubscriberRequest(), 3000L);
Assert.assertTrue(false);
} catch (Exception e) {
Assert.assertTrue(e instanceof ConnectionAlreadyClosedException);
Assert.assertTrue(e.getCause() instanceof StatusRuntimeException);
}
}
@Test
public void testIllegalStateException() {
Mockito.doReturn(new DefaultEventLoop()).when(channel).eventLoop();
Mockito.doThrow(new IllegalStateException()).when(streamObserver).onNext(Mockito.any());
Mockito.doReturn(true).when(streamObserver).isReady();
try {
connection.request(new NotifySubscriberRequest(), 3000L);
Assert.assertTrue(false);
} catch (Exception e) {
Assert.assertTrue(e instanceof ConnectionAlreadyClosedException);
Assert.assertTrue(e.getCause() instanceof IllegalStateException);
}
}
@Test
public void testOtherException() {
Mockito.doReturn(new DefaultEventLoop()).when(channel).eventLoop();
Mockito.doThrow(new Error("OOM")).when(streamObserver).onNext(Mockito.any());
Mockito.doReturn(true).when(streamObserver).isReady();
try {
connection.request(new NotifySubscriberRequest(), 3000L);
Assert.assertTrue(false);
} catch (Throwable e) {
Assert.assertTrue(e instanceof NacosRuntimeException);
Assert.assertTrue(e.getCause() instanceof Error);
}
}
@Test
public void testNormal() {
Mockito.doReturn(new DefaultEventLoop()).when(channel).eventLoop();
Mockito.doReturn(true).when(streamObserver).isReady();
try {
new Thread(new Runnable() {
@Override
public void run() {
long start = System.currentTimeMillis();
while ((System.currentTimeMillis() - start < 3000L)) {
Map<String, DefaultRequestFuture> stringDefaultRequestFutureMap = RpcAckCallbackSynchronizer.initContextIfNecessary(
connection.getMetaInfo().getConnectionId());
if (!stringDefaultRequestFutureMap.entrySet().iterator().hasNext()) {
try {
Thread.sleep(100L);
continue;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Map.Entry<String, DefaultRequestFuture> next = stringDefaultRequestFutureMap.entrySet()
.iterator().next();
NotifySubscriberResponse notifySubscriberResponse = new NotifySubscriberResponse();
notifySubscriberResponse.setRequestId(next.getValue().getRequestId());
try {
RpcAckCallbackSynchronizer.ackNotify(connection.getMetaInfo().getConnectionId(),
notifySubscriberResponse);
} catch (Exception e) {
//ignore
}
}
}
}).start();
connection.request(new NotifySubscriberRequest(), 3000L);
Assert.assertTrue(true);
} catch (Throwable e) {
e.printStackTrace();
Assert.assertFalse(true);
}
}
@Test
public void testBusy() {
controlManagerCenterMockedStatic = Mockito.mockStatic(ControlManagerCenter.class);
Mockito.when(ControlManagerCenter.getInstance()).thenReturn(controlManagerCenter);
Mockito.when(ControlManagerCenter.getInstance().getTpsControlManager()).thenReturn(tpsControlManager);
Mockito.when(tpsControlManager.check(Mockito.any())).thenReturn(new TpsCheckResponse(true, 200, ""));
Mockito.doReturn(false).when(streamObserver).isReady();
try {
connection.request(new NotifySubscriberRequest(), 3000L);
Assert.assertTrue(false);
} catch (Exception e) {
Assert.assertTrue(e instanceof ConnectionBusyException);
}
try {
Thread.sleep(3001);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
connection.request(new NotifySubscriberRequest(), 3000L);
Assert.assertTrue(false);
} catch (Exception e) {
Assert.assertTrue(e instanceof ConnectionBusyException);
}
Assert.assertTrue(connection.getMetaInfo().pushQueueBlockTimesLastOver(3000));
}
}

View File

@ -195,7 +195,7 @@ public interface GroupCapacityMapper extends Mapper {
"UPDATE group_capacity SET usage = (SELECT count(*) FROM config_info WHERE group_id=? AND tenant_id = '"
+ NamespaceUtil.getNamespaceDefaultId() + "')," + " gmt_modified = ? WHERE group_id= ?",
CollectionUtils.list(context.getWhereParameter(FieldConstant.GROUP_ID),
context.getWhereParameter(FieldConstant.GMT_MODIFIED),
context.getUpdateParameter(FieldConstant.GMT_MODIFIED),
context.getWhereParameter(FieldConstant.GROUP_ID)));
}