Skip to content

Commit

Permalink
fix: unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
dyx1234 committed Sep 13, 2024
1 parent 562b325 commit 8705ba1
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,49 +43,77 @@ public void initClient() {
coreV1Api = new CoreV1Api(client);

} catch (Exception e) {
throw new RuntimeException("k8s client init failed");
String errorMessage = "Failed to initialize Kubernetes client: " + e.getMessage();
log.error(errorMessage, e);
throw new RuntimeException(errorMessage, e);
}
}

/**
* Creates a Kubernetes ConfigMap.
*
* @param configMapNamespace the namespace of the ConfigMap
* @param name the name of the ConfigMap
* @param data the data to be stored in the ConfigMap
* @return the name of the created ConfigMap
* @throws RuntimeException if an error occurs while creating the ConfigMap
*/
public String createConfigMap(String configMapNamespace, String name, Map<String, String> data) {
if (configMapNamespace == null || configMapNamespace == "" || name == null || name == "") {
log.error("create config map failed due to null parameter");
return null;
throw new RuntimeException("ConfigMap namespace and name cannot be null or empty");
}
V1ConfigMap configMap = new V1ConfigMap().metadata(new V1ObjectMeta().name(name).namespace(configMapNamespace)).data(data);
try {
coreV1Api.createNamespacedConfigMap(configMapNamespace, configMap, null, null, null,null);
return name;
} catch (Exception e) {
log.error("create config map failed", e);
return null;
throw new RuntimeException("Failed to create ConfigMap: " + e.getMessage(), e);
}
}

/**
* get value from config map
* @param configMapNamespace
* @param name config map name (appId)
* @return configMap data(all key-value pairs in config map)
*/
public String loadFromConfigMap(String configMapNamespace, String name) {
if (configMapNamespace == null || configMapNamespace.isEmpty() || name == null || name.isEmpty() || name == null || name.isEmpty()) {
log.error("参数不能为空");
return null;
throw new RuntimeException(String
.format("参数不能为空, configMapNamespace: %s, name: %s", configMapNamespace, name));
}
try {
V1ConfigMap configMap = coreV1Api.readNamespacedConfigMap(name, configMapNamespace, null);
if (configMap == null) {
log.error("ConfigMap不存在");
return null;
throw new RuntimeException(String
.format("ConfigMap不存在, configMapNamespace: %s, name: %s", configMapNamespace, name));
}
Map<String, String> data = configMap.getData();
if (data != null && data.containsKey(name)) {
return data.get(name);
} else {
log.error("在ConfigMap中未找到指定的键: " + name);
return null;
throw new RuntimeException(String
.format("在ConfigMap中未找到指定的键: %s, configMapNamespace: %s, name: %s", name, configMapNamespace, name));
}
} catch (Exception e) {
log.error("get config map failed", e);
return null;
throw new RuntimeException(String
.format("get config map failed, configMapNamespace: %s, name: %s", configMapNamespace, name));
}
}

/**
* get value from config map
* @param configMapNamespace configMapNamespace
* @param name config map name (appId)
* @param key config map key (cluster+namespace)
* @return value(json string)
*/
public String getValueFromConfigMap(String configMapNamespace, String name, String key) {
if (configMapNamespace == null || configMapNamespace.isEmpty() || name == null || name.isEmpty() || key == null || key.isEmpty()) {
log.error("参数不能为空");
Expand All @@ -108,6 +136,13 @@ public String getValueFromConfigMap(String configMapNamespace, String name, Stri
}
}

/**
* update config map
* @param configMapNamespace
* @param name config map name (appId)
* @param data new data
* @return config map name
*/
public String updateConfigMap(String configMapNamespace, String name, Map<String, String> data) {
if (configMapNamespace == null || configMapNamespace.isEmpty() || name == null || name.isEmpty() || data == null || data.isEmpty()) {
log.error("参数不能为空");
Expand All @@ -123,6 +158,12 @@ public String updateConfigMap(String configMapNamespace, String name, Map<String
}
}

/**
* check config map exist
* @param configMapNamespace config map namespace
* @param configMapName config map name
* @return true if config map exist, false otherwise
*/
public boolean checkConfigMapExist(String configMapNamespace, String configMapName) {
if (configMapNamespace == null || configMapNamespace.isEmpty() || configMapName == null || configMapName.isEmpty()) {
log.error("参数不能为空");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ public class K8sConfigMapConfigRepository extends AbstractConfigRepository
* configmap-value 配置文件信息的json串
*/

// TODO Properties和appConfig格式的兼容
// TODO 初次时configMap的创建
// TODO configUtil和k8sManager单测已完成
// TODO Properties和appConfig格式的兼容(go客户端存的格式是封装过的ApolloConfig,不是单纯的配置信息json)

/**
* Constructor
Expand Down Expand Up @@ -208,6 +206,10 @@ public Properties loadFromK8sConfigMap() throws IOException {
try {
// 从ConfigMap获取整个配置信息的JSON字符串
String jsonConfig = kubernetesManager.getValueFromConfigMap(configMapNamespace, configUtil.getAppId(), configMapKey);
if (jsonConfig == null) {
// TODO 待修改,重试访问保底configmap
jsonConfig = kubernetesManager.getValueFromConfigMap(configMapNamespace, configMapName, Joiner.on(ConfigConsts.CLUSTER_NAMESPACE_SEPARATOR).join("default", namespace));
}

// 确保获取到的配置信息不为空
if (jsonConfig != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/*
* Copyright 2022 Apollo Authors
*
* 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.ctrip.framework.apollo.internals;

import com.ctrip.framework.apollo.Kubernetes.KubernetesManager;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.util.ConfigUtil;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Properties;

import static org.mockito.Mockito.*;

/**
* TODO (未完成)K8sConfigMapConfigRepository单元测试
*/
public class K8sConfigMapConfigRepositoryTest {

private String someNamespace;
private ConfigRepository upstreamRepo;
private Properties someProperties;
private static String someAppId = "someApp";
private static String someCluster = "someCluster";
private String defaultKey;
private String defaultValue;
private ConfigSourceType someSourceType;

@Mock
private KubernetesManager kubernetesManager;
@Mock
private ConfigUtil configUtil;

private K8sConfigMapConfigRepository k8sConfigMapConfigRepository;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(configUtil.getAppId()).thenReturn("testAppId");
when(configUtil.getCluster()).thenReturn("default");
when(configUtil.getConfigMapNamespace()).thenReturn("default");

someProperties = new Properties();
defaultKey = "defaultKey";
defaultValue = "defaultValue";
someProperties.setProperty(defaultKey, defaultValue);


k8sConfigMapConfigRepository = new K8sConfigMapConfigRepository("namespace", null);
}

/**
* 测试sync方法成功从上游数据源同步
*/
@Test
public void testSyncSuccessFromUpstream() throws Throwable {
// arrange
ConfigRepository upstream = mock(ConfigRepository.class);
Properties upstreamProperties = new Properties();
upstreamProperties.setProperty("key", "value");
when(upstream.getConfig()).thenReturn(upstreamProperties);
when(upstream.getSourceType()).thenReturn(ConfigSourceType.REMOTE);
k8sConfigMapConfigRepository.setUpstreamRepository(upstream);

// act
k8sConfigMapConfigRepository.sync();

// assert
verify(upstream, times(1)).getConfig();
}

/**
* 测试sync方法从上游数据源同步失败,成功从Kubernetes的ConfigMap中加载
*/
@Test
public void testSyncFailFromUpstreamSuccessFromConfigMap() throws Throwable {
// arrange
ConfigRepository upstream = mock(ConfigRepository.class);
when(upstream.getConfig()).thenThrow(new RuntimeException("Upstream sync failed"));
k8sConfigMapConfigRepository.setUpstreamRepository(upstream);
when(kubernetesManager.getValueFromConfigMap(anyString(), anyString(), anyString())).thenReturn("encodedConfig");

// act
k8sConfigMapConfigRepository.sync();

// assert
verify(kubernetesManager, times(1)).getValueFromConfigMap(anyString(), anyString(), anyString());
}

/**
* 测试loadFromK8sConfigMap方法成功加载配置信息
*/
@Test
public void testLoadFromK8sConfigMapSuccess() throws Throwable {
// arrange
when(kubernetesManager.getValueFromConfigMap(anyString(), anyString(), anyString())).thenReturn("encodedConfig");

// act
Properties properties = k8sConfigMapConfigRepository.loadFromK8sConfigMap();

// assert
verify(kubernetesManager, times(1)).getValueFromConfigMap(anyString(), anyString(), anyString());
// 这里应该有更具体的断言来验证properties的内容,但由于编码和解码逻辑未给出,此处省略
}

/**
* 测试loadFromK8sConfigMap方法在加载配置信息时发生异常
*/
@Test(expected = ApolloConfigException.class)
public void testLoadFromK8sConfigMapException() throws Throwable {
// arrange
when(kubernetesManager.getValueFromConfigMap(anyString(), anyString(), anyString())).thenThrow(new RuntimeException("Load failed"));

// act
k8sConfigMapConfigRepository.loadFromK8sConfigMap();

// assert
// 预期抛出ApolloConfigException
}

/**
* 测试persistConfigMap方法成功持久化配置信息
*/
@Test
public void testPersistConfigMapSuccess() throws Throwable {
// arrange
Properties properties = new Properties();
properties.setProperty("key", "value");

// act
k8sConfigMapConfigRepository.persistConfigMap(properties);

// assert
verify(kubernetesManager, times(1)).updateConfigMap(anyString(), anyString(), anyMap());
}

/**
* 测试persistConfigMap方法在持久化配置信息时发生异常
*/
@Test(expected = ApolloConfigException.class)
public void testPersistConfigMapException() throws Throwable {
// arrange
Properties properties = new Properties();
properties.setProperty("key", "value");
doThrow(new RuntimeException("Persist failed")).when(kubernetesManager).updateConfigMap(anyString(), anyString(), anyMap());

// act
k8sConfigMapConfigRepository.persistConfigMap(properties);

// assert
// 预期抛出ApolloConfigException
}
}

0 comments on commit 8705ba1

Please sign in to comment.