Develop client ut (#11516)

* Add ut for client module auth package.

* Add ut for client module env package.

* Add ut for client module env package.

* For copyright

* Fix UT might failed problem.
This commit is contained in:
杨翊 SionYang 2023-12-18 10:20:55 +08:00 committed by GitHub
parent d84a566235
commit ab2ddac06f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 946 additions and 146 deletions

View File

@ -101,10 +101,6 @@ public final class CredentialService implements SpasCredentialLoader {
@Override
public Credentials getCredential() {
Credentials localCredential = credentials;
if (localCredential.valid()) {
return localCredential;
}
return credentials;
}

View File

@ -29,6 +29,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -59,8 +60,8 @@ public class CredentialWatcher {
this.serviceInstance = serviceInstance;
loadCredential(true);
executor = ExecutorFactory
.newSingleScheduledExecutorService(new NameThreadFactory("com.alibaba.nacos.client.auth.ram.identify.watcher"));
executor = ExecutorFactory.newSingleScheduledExecutorService(
new NameThreadFactory("com.alibaba.nacos.client.auth.ram.identify.watcher"));
executor.scheduleWithFixedDelay(new Runnable() {
private long modified = 0;
@ -107,6 +108,94 @@ public class CredentialWatcher {
}
private void loadCredential(boolean init) {
loadPropertyPath(init);
InputStream propertiesIS = loadPropertyPathToStream();
Credentials credentials = new Credentials();
boolean loadResult = Objects.isNull(propertiesIS) ? loadCredentialFromEnv(init, credentials)
: loadCredentialFromProperties(propertiesIS, init, credentials);
if (!loadResult) {
return;
}
if (!credentials.valid()) {
SPAS_LOGGER
.warn("[1] Credential file missing required property {} Credential file missing {} or {}", appName,
IdentifyConstants.ACCESS_KEY, IdentifyConstants.SECRET_KEY);
propertyPath = null;
// return;
}
serviceInstance.setCredential(credentials);
}
private boolean loadCredentialFromProperties(InputStream propertiesIS, boolean init, Credentials credentials) {
Properties properties = new Properties();
try {
properties.load(propertiesIS);
} catch (IOException e) {
SPAS_LOGGER
.error("[26] Unable to load credential file, appName:" + appName + "Unable to load credential file "
+ propertyPath, e);
propertyPath = null;
return false;
} finally {
try {
propertiesIS.close();
} catch (IOException e) {
SPAS_LOGGER.error("[27] Unable to close credential file, appName:" + appName
+ "Unable to close credential file " + propertyPath, e);
}
}
if (init) {
SPAS_LOGGER.info("[{}] Load credential file {}", appName, propertyPath);
}
String accessKey = null;
String secretKey = null;
String tenantId = null;
if (!IdentifyConstants.DOCKER_CREDENTIAL_PATH.equals(propertyPath)) {
if (properties.containsKey(IdentifyConstants.ACCESS_KEY)) {
accessKey = properties.getProperty(IdentifyConstants.ACCESS_KEY);
}
if (properties.containsKey(IdentifyConstants.SECRET_KEY)) {
secretKey = properties.getProperty(IdentifyConstants.SECRET_KEY);
}
if (properties.containsKey(IdentifyConstants.TENANT_ID)) {
tenantId = properties.getProperty(IdentifyConstants.TENANT_ID);
}
} else {
if (properties.containsKey(IdentifyConstants.DOCKER_ACCESS_KEY)) {
accessKey = properties.getProperty(IdentifyConstants.DOCKER_ACCESS_KEY);
}
if (properties.containsKey(IdentifyConstants.DOCKER_SECRET_KEY)) {
secretKey = properties.getProperty(IdentifyConstants.DOCKER_SECRET_KEY);
}
if (properties.containsKey(IdentifyConstants.DOCKER_TENANT_ID)) {
tenantId = properties.getProperty(IdentifyConstants.DOCKER_TENANT_ID);
}
}
setAccessKey(credentials, accessKey);
setSecretKey(credentials, secretKey);
setTenantId(credentials, tenantId);
return true;
}
private boolean loadCredentialFromEnv(boolean init, Credentials credentials) {
propertyPath = null;
String accessKey = NacosClientProperties.PROTOTYPE.getProperty(IdentifyConstants.ENV_ACCESS_KEY);
String secretKey = NacosClientProperties.PROTOTYPE.getProperty(IdentifyConstants.ENV_SECRET_KEY);
if (accessKey == null && secretKey == null) {
if (init) {
SPAS_LOGGER.info("{} No credential found", appName);
}
return false;
}
setAccessKey(credentials, accessKey);
setSecretKey(credentials, secretKey);
return true;
}
private void loadPropertyPath(boolean init) {
if (propertyPath == null) {
URL url = ClassLoader.getSystemResource(IdentifyConstants.PROPERTIES_FILENAME);
if (url != null) {
@ -134,7 +223,9 @@ public class CredentialWatcher {
}
}
}
}
private InputStream loadPropertyPathToStream() {
InputStream propertiesIS = null;
do {
try {
@ -152,86 +243,24 @@ public class CredentialWatcher {
}
break;
} while (true);
return propertiesIS;
}
String accessKey = null;
String secretKey = null;
String tenantId = null;
if (propertiesIS == null) {
propertyPath = null;
accessKey = NacosClientProperties.PROTOTYPE.getProperty(IdentifyConstants.ENV_ACCESS_KEY);
secretKey = NacosClientProperties.PROTOTYPE.getProperty(IdentifyConstants.ENV_SECRET_KEY);
if (accessKey == null && secretKey == null) {
if (init) {
SPAS_LOGGER.info("{} No credential found", appName);
}
return;
}
} else {
Properties properties = new Properties();
try {
properties.load(propertiesIS);
} catch (IOException e) {
SPAS_LOGGER.error("[26] Unable to load credential file, appName:" + appName
+ "Unable to load credential file " + propertyPath, e);
propertyPath = null;
return;
} finally {
try {
propertiesIS.close();
} catch (IOException e) {
SPAS_LOGGER.error("[27] Unable to close credential file, appName:" + appName
+ "Unable to close credential file " + propertyPath, e);
}
}
if (init) {
SPAS_LOGGER.info("[{}] Load credential file {}", appName, propertyPath);
}
if (!IdentifyConstants.DOCKER_CREDENTIAL_PATH.equals(propertyPath)) {
if (properties.containsKey(IdentifyConstants.ACCESS_KEY)) {
accessKey = properties.getProperty(IdentifyConstants.ACCESS_KEY);
}
if (properties.containsKey(IdentifyConstants.SECRET_KEY)) {
secretKey = properties.getProperty(IdentifyConstants.SECRET_KEY);
}
if (properties.containsKey(IdentifyConstants.TENANT_ID)) {
tenantId = properties.getProperty(IdentifyConstants.TENANT_ID);
}
} else {
if (properties.containsKey(IdentifyConstants.DOCKER_ACCESS_KEY)) {
accessKey = properties.getProperty(IdentifyConstants.DOCKER_ACCESS_KEY);
}
if (properties.containsKey(IdentifyConstants.DOCKER_SECRET_KEY)) {
secretKey = properties.getProperty(IdentifyConstants.DOCKER_SECRET_KEY);
}
if (properties.containsKey(IdentifyConstants.DOCKER_TENANT_ID)) {
tenantId = properties.getProperty(IdentifyConstants.DOCKER_TENANT_ID);
}
}
private void setAccessKey(Credentials credentials, String accessKey) {
if (!Objects.isNull(accessKey)) {
credentials.setAccessKey(accessKey.trim());
}
}
if (accessKey != null) {
accessKey = accessKey.trim();
}
if (secretKey != null) {
secretKey = secretKey.trim();
private void setSecretKey(Credentials credentials, String secretKey) {
if (!Objects.isNull(secretKey)) {
credentials.setSecretKey(secretKey.trim());
}
}
if (tenantId != null) {
tenantId = tenantId.trim();
private void setTenantId(Credentials credentials, String tenantId) {
if (!Objects.isNull(tenantId)) {
credentials.setTenantId(tenantId.trim());
}
Credentials credential = new Credentials(accessKey, secretKey, tenantId);
if (!credential.valid()) {
SPAS_LOGGER
.warn("[1] Credential file missing required property {} Credential file missing {} or {}", appName,
IdentifyConstants.ACCESS_KEY, IdentifyConstants.SECRET_KEY);
propertyPath = null;
// return;
}
serviceInstance.setCredential(credential);
}
}

View File

@ -29,16 +29,16 @@ public class Credentials implements SpasCredential {
private volatile String tenantId;
public Credentials() {
this(null, null, null);
}
public Credentials(String accessKey, String secretKey, String tenantId) {
this.accessKey = accessKey;
this.secretKey = secretKey;
this.tenantId = tenantId;
}
public Credentials() {
this(null, null, null);
}
@Override
public String getAccessKey() {
return accessKey;

View File

@ -50,7 +50,7 @@ public class SignUtil {
}
}
private static byte[] sign(byte[] data, byte[] key, SignUtil.SigningAlgorithm algorithm) throws Exception {
static byte[] sign(byte[] data, byte[] key, SignUtil.SigningAlgorithm algorithm) throws Exception {
try {
Mac mac = Mac.getInstance(algorithm.toString());
mac.init(new SecretKeySpec(key, algorithm.toString()));

View File

@ -48,6 +48,18 @@ class SearchableProperties implements NacosClientProperties {
private static final CompositeConverter CONVERTER = new CompositeConverter();
static {
SEARCH_ORDER = init();
StringBuilder orderInfo = new StringBuilder("properties search order:");
for (int i = 0; i < SEARCH_ORDER.size(); i++) {
orderInfo.append(SEARCH_ORDER.get(i).toString());
if (i < SEARCH_ORDER.size() - 1) {
orderInfo.append("->");
}
}
LOGGER.debug(orderInfo.toString());
}
private static List<SourceType> init() {
List<SourceType> initOrder = Arrays.asList(SourceType.PROPERTIES, SourceType.JVM, SourceType.ENV);
String firstEnv = JVM_ARGS_PROPERTY_SOURCE.getProperty(Constants.SysEnv.NACOS_ENV_FIRST);
@ -67,15 +79,7 @@ class SearchableProperties implements NacosClientProperties {
LOGGER.warn("first source type parse error, it will be used default order!", e);
}
}
SEARCH_ORDER = initOrder;
StringBuilder orderInfo = new StringBuilder("properties search order:");
for (int i = 0; i < SEARCH_ORDER.size(); i++) {
orderInfo.append(SEARCH_ORDER.get(i).toString());
if (i < SEARCH_ORDER.size() - 1) {
orderInfo.append("->");
}
}
LOGGER.debug(orderInfo.toString());
return initOrder;
}
static final SearchableProperties INSTANCE = new SearchableProperties();
@ -183,21 +187,11 @@ class SearchableProperties implements NacosClientProperties {
}
private <T> Optional<T> search(String key, Class<T> targetType) {
if (targetType == null) {
throw new IllegalArgumentException("target type must not be null!");
}
for (AbstractPropertySource propertySource : propertySources) {
final String value = propertySource.getProperty(key);
if (value != null) {
if (String.class.isAssignableFrom(targetType)) {
try {
return (Optional<T>) Optional.of(value);
} catch (Exception e) {
LOGGER.error("target type convert error", e);
return Optional.empty();
}
if (targetType.isAssignableFrom(String.class)) {
return (Optional<T>) Optional.of(value);
}
return Optional.ofNullable(CONVERTER.convert(value, targetType));
}

View File

@ -32,5 +32,9 @@ public enum SourceType {
/**
* get value from system environment.
*/
ENV
ENV,
/**
* get value from unknown environment, will be search in all properties by orders.
*/
UNKNOWN
}

View File

@ -0,0 +1,51 @@
/*
* Copyright 1999-2023 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.client.ability;
import com.alibaba.nacos.api.ability.constant.AbilityKey;
import com.alibaba.nacos.api.ability.constant.AbilityMode;
import org.junit.Before;
import org.junit.Test;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ClientAbilityControlManagerTest {
ClientAbilityControlManager clientAbilityControlManager;
@Before
public void setUp() {
clientAbilityControlManager = new ClientAbilityControlManager();
}
@Test
public void testInitCurrentNodeAbilities() {
Map<AbilityMode, Map<AbilityKey, Boolean>> actual = clientAbilityControlManager.initCurrentNodeAbilities();
assertEquals(1, actual.size());
assertTrue(actual.containsKey(AbilityMode.SDK_CLIENT));
// Current not define sdk ability.
assertEquals(0, actual.get(AbilityMode.SDK_CLIENT).size());
}
@Test
public void testGetPriority() {
assertEquals(0, clientAbilityControlManager.getPriority());
}
}

View File

@ -163,4 +163,70 @@ public class NacosClientAuthServiceImplTest {
Assert.assertEquals("abc", nacosClientAuthService.getLoginIdentityContext(null).getParameter(NacosAuthLoginConstant.ACCESSTOKEN));
}
@Test
public void testGetAccessEmptyToken() throws Exception {
NacosRestTemplate nacosRestTemplate = mock(NacosRestTemplate.class);
HttpRestResult<Object> result = new HttpRestResult<>();
result.setData("{\"accessToken\":\"\",\"tokenTtl\":1000}");
result.setCode(200);
when(nacosRestTemplate.postForm(any(), (Header) any(), any(), any(), any())).thenReturn(result);
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.USERNAME, "aaa");
properties.setProperty(PropertyKeyConst.PASSWORD, "123456");
List<String> serverList = new ArrayList<>();
serverList.add("localhost");
NacosClientAuthServiceImpl nacosClientAuthService = new NacosClientAuthServiceImpl();
nacosClientAuthService.setServerList(serverList);
nacosClientAuthService.setNacosRestTemplate(nacosRestTemplate);
//when
Assert.assertTrue(nacosClientAuthService.login(properties));
//then
Assert.assertEquals("", nacosClientAuthService.getLoginIdentityContext(null).getParameter(NacosAuthLoginConstant.ACCESSTOKEN));
}
@Test
public void testGetAccessTokenWithoutToken() throws Exception {
NacosRestTemplate nacosRestTemplate = mock(NacosRestTemplate.class);
HttpRestResult<Object> result = new HttpRestResult<>();
result.setData("{\"tokenTtl\":1000}");
result.setCode(200);
when(nacosRestTemplate.postForm(any(), (Header) any(), any(), any(), any())).thenReturn(result);
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.USERNAME, "aaa");
properties.setProperty(PropertyKeyConst.PASSWORD, "123456");
List<String> serverList = new ArrayList<>();
serverList.add("localhost");
NacosClientAuthServiceImpl nacosClientAuthService = new NacosClientAuthServiceImpl();
nacosClientAuthService.setServerList(serverList);
nacosClientAuthService.setNacosRestTemplate(nacosRestTemplate);
//when
Assert.assertTrue(nacosClientAuthService.login(properties));
//then
Assert.assertNull(nacosClientAuthService.getLoginIdentityContext(null).getParameter(NacosAuthLoginConstant.ACCESSTOKEN));
}
@Test
public void testGetAccessTokenWithInvalidTtl() throws Exception {
NacosRestTemplate nacosRestTemplate = mock(NacosRestTemplate.class);
HttpRestResult<Object> result = new HttpRestResult<>();
result.setData("{\"accessToken\":\"abc\",\"tokenTtl\":\"abc\"}");
result.setCode(200);
when(nacosRestTemplate.postForm(any(), (Header) any(), any(), any(), any())).thenReturn(result);
Properties properties = new Properties();
properties.setProperty(PropertyKeyConst.USERNAME, "aaa");
properties.setProperty(PropertyKeyConst.PASSWORD, "123456");
List<String> serverList = new ArrayList<>();
serverList.add("localhost");
NacosClientAuthServiceImpl nacosClientAuthService = new NacosClientAuthServiceImpl();
nacosClientAuthService.setServerList(serverList);
nacosClientAuthService.setNacosRestTemplate(nacosRestTemplate);
//when
Assert.assertFalse(nacosClientAuthService.login(properties));
}
}

View File

@ -19,7 +19,9 @@
package com.alibaba.nacos.client.auth.ram.identify;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.Field;
@ -30,6 +32,19 @@ import static org.mockito.Mockito.verify;
public class CredentialServiceTest extends TestCase {
private static final String APP_NAME = "app";
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
System.clearProperty(IdentifyConstants.PROJECT_NAME_PROPERTY);
CredentialService.freeInstance();
CredentialService.freeInstance(APP_NAME);
}
@Test
public void testGetInstance() {
CredentialService credentialService1 = CredentialService.getInstance();
@ -39,11 +54,21 @@ public class CredentialServiceTest extends TestCase {
@Test
public void testGetInstance2() {
CredentialService credentialService1 = CredentialService.getInstance("app");
CredentialService credentialService2 = CredentialService.getInstance("app");
CredentialService credentialService1 = CredentialService.getInstance(APP_NAME);
CredentialService credentialService2 = CredentialService.getInstance(APP_NAME);
Assert.assertEquals(credentialService1, credentialService2);
}
@Test
public void testGetInstance3() throws NoSuchFieldException, IllegalAccessException {
System.setProperty(IdentifyConstants.PROJECT_NAME_PROPERTY, APP_NAME);
CredentialService credentialService1 = CredentialService.getInstance();
Field appNameField = credentialService1.getClass().getDeclaredField("appName");
appNameField.setAccessible(true);
String appName = (String) appNameField.get(credentialService1);
assertEquals(APP_NAME, appName);
}
@Test
public void testFreeInstance() {
CredentialService credentialService1 = CredentialService.getInstance();
@ -104,16 +129,13 @@ public class CredentialServiceTest extends TestCase {
}
@Test
public void testRegisterCredentialListener() throws NoSuchFieldException, IllegalAccessException {
CredentialService credentialService1 = CredentialService.getInstance();
Field listenerField = CredentialService.class.getDeclaredField("listener");
listenerField.setAccessible(true);
public void testRegisterCredentialListener() {
CredentialListener expect = mock(CredentialListener.class);
//when
CredentialService credentialService1 = CredentialService.getInstance();
credentialService1.registerCredentialListener(expect);
//then
CredentialListener actual = (CredentialListener) listenerField.get(credentialService1);
Assert.assertEquals(expect, actual);
Credentials newCredentials = new Credentials();
newCredentials.setAccessKey("ak");
credentialService1.setCredential(newCredentials);
verify(expect, times(1)).onUpdateCredential();
}
}

View File

@ -16,22 +16,210 @@
package com.alibaba.nacos.client.auth.ram.identify;
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.junit.MockitoJUnitRunner;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class CredentialWatcherTest {
@Mock
private CredentialService credentialService;
private CredentialWatcher credentialWatcher;
private Method loadCredentialMethod;
private Method loadCredentialFromPropertiesMethod;
@Before
public void setUp() throws Exception {
credentialWatcher = new CredentialWatcher("testApp", credentialService);
loadCredentialMethod = CredentialWatcher.class.getDeclaredMethod("loadCredential", boolean.class);
loadCredentialMethod.setAccessible(true);
loadCredentialFromPropertiesMethod = CredentialWatcher.class
.getDeclaredMethod("loadCredentialFromProperties", InputStream.class, boolean.class, Credentials.class);
loadCredentialFromPropertiesMethod.setAccessible(true);
}
@After
public void tearDown() throws Exception {
credentialWatcher.stop();
System.clearProperty("spas.identity");
System.clearProperty(IdentifyConstants.ENV_ACCESS_KEY);
System.clearProperty(IdentifyConstants.ENV_SECRET_KEY);
CredentialService.freeInstance();
}
@Test
public void stop() throws NoSuchFieldException, IllegalAccessException {
CredentialService instance = CredentialService.getInstance();
CredentialWatcher watcher = new CredentialWatcher("app", instance);
watcher.stop();
public void testStop() throws NoSuchFieldException, IllegalAccessException {
credentialWatcher.stop();
Field executorField = CredentialWatcher.class.getDeclaredField("executor");
executorField.setAccessible(true);
ScheduledExecutorService executor = (ScheduledExecutorService) executorField.get(watcher);
ScheduledExecutorService executor = (ScheduledExecutorService) executorField.get(credentialWatcher);
Assert.assertTrue(executor.isShutdown());
}
@Test
public void testLoadCredentialByEnv() throws InvocationTargetException, IllegalAccessException {
System.setProperty(IdentifyConstants.ENV_ACCESS_KEY, "testAk");
System.setProperty(IdentifyConstants.ENV_SECRET_KEY, "testSk");
final AtomicReference<String> readAk = new AtomicReference<>("");
final AtomicReference<String> readSK = new AtomicReference<>("");
final AtomicReference<String> readTenantId = new AtomicReference<>("");
doAnswer(invocationOnMock -> {
Credentials credentials = invocationOnMock.getArgument(0, Credentials.class);
readAk.set(credentials.getAccessKey());
readSK.set(credentials.getSecretKey());
readTenantId.set(credentials.getTenantId());
return null;
}).when(credentialService).setCredential(any());
loadCredentialMethod.invoke(credentialWatcher, true);
assertEquals("testAk", readAk.get());
assertEquals("testSk", readSK.get());
assertNull(readTenantId.get());
}
@Test
public void testLoadCredentialByIdentityFile() throws InvocationTargetException, IllegalAccessException {
URL url = CredentialWatcherTest.class.getResource("/spas.identity");
System.setProperty("spas.identity", url.getPath());
final AtomicReference<String> readAk = new AtomicReference<>("");
final AtomicReference<String> readSK = new AtomicReference<>("");
final AtomicReference<String> readTenantId = new AtomicReference<>("");
doAnswer(invocationOnMock -> {
Credentials credentials = invocationOnMock.getArgument(0, Credentials.class);
readAk.set(credentials.getAccessKey());
readSK.set(credentials.getSecretKey());
readTenantId.set(credentials.getTenantId());
return null;
}).when(credentialService).setCredential(any());
loadCredentialMethod.invoke(credentialWatcher, true);
assertEquals("testAk", readAk.get());
assertEquals("testSk", readSK.get());
assertEquals("testTenantId", readTenantId.get());
}
@Test
public void testLoadCredentialByInvalidIdentityFile() throws InvocationTargetException, IllegalAccessException {
URL url = CredentialWatcherTest.class.getResource("/spas_invalid.identity");
System.setProperty("spas.identity", url.getPath());
final AtomicReference<String> readAk = new AtomicReference<>("");
final AtomicReference<String> readSK = new AtomicReference<>("");
final AtomicReference<String> readTenantId = new AtomicReference<>("");
doAnswer(invocationOnMock -> {
Credentials credentials = invocationOnMock.getArgument(0, Credentials.class);
readAk.set(credentials.getAccessKey());
readSK.set(credentials.getSecretKey());
readTenantId.set(credentials.getTenantId());
return null;
}).when(credentialService).setCredential(any());
loadCredentialMethod.invoke(credentialWatcher, true);
assertEquals("", readAk.get());
assertEquals("testSk", readSK.get());
assertEquals("testTenantId", readTenantId.get());
}
/**
* The docker file is need /etc permission, which depend environment. So use mock InputStream to test.
*/
@Test
public void testLoadCredentialByDockerFile()
throws FileNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
URL url = CredentialWatcherTest.class.getResource("/spas_docker.identity");
InputStream propertiesIS = new FileInputStream(url.getPath());
Credentials actual = new Credentials();
Field propertyPathField = CredentialWatcher.class.getDeclaredField("propertyPath");
propertyPathField.setAccessible(true);
propertyPathField.set(credentialWatcher, IdentifyConstants.DOCKER_CREDENTIAL_PATH);
loadCredentialFromPropertiesMethod.invoke(credentialWatcher, propertiesIS, true, actual);
assertEquals("testAk", actual.getAccessKey());
assertEquals("testSk", actual.getSecretKey());
assertEquals("testTenantId", actual.getTenantId());
}
@Test
public void testLoadCredentialByFileWithIoException()
throws IOException, InvocationTargetException, IllegalAccessException {
InputStream propertiesIS = mock(InputStream.class);
when(propertiesIS.read(any())).thenThrow(new IOException("test"));
doThrow(new IOException("test")).when(propertiesIS).close();
Credentials actual = new Credentials();
loadCredentialFromPropertiesMethod.invoke(credentialWatcher, propertiesIS, true, actual);
assertNull(actual.getAccessKey());
assertNull(actual.getSecretKey());
assertNull(actual.getTenantId());
}
@Test
public void testReLoadCredential()
throws InvocationTargetException, IllegalAccessException, InterruptedException {
URL url = CredentialWatcherTest.class.getResource("/spas_modified.identity");
modifiedFile(url, true);
System.setProperty("spas.identity", url.getPath());
final AtomicReference<String> readAk = new AtomicReference<>("");
final AtomicReference<String> readSK = new AtomicReference<>("");
final AtomicReference<String> readTenantId = new AtomicReference<>("");
doAnswer(invocationOnMock -> {
Credentials credentials = invocationOnMock.getArgument(0, Credentials.class);
readAk.set(credentials.getAccessKey());
readSK.set(credentials.getSecretKey());
readTenantId.set(credentials.getTenantId());
return null;
}).when(credentialService).setCredential(any());
loadCredentialMethod.invoke(credentialWatcher, true);
assertEquals("testAk", readAk.get());
assertEquals("testSk", readSK.get());
assertNull(readTenantId.get());
// waiting reload thread work
modifiedFile(url, false);
TimeUnit.MILLISECONDS.sleep(10500);
assertEquals("testAk", readAk.get());
assertEquals("testSk", readSK.get());
assertEquals("testTenantId", readTenantId.get());
}
private boolean modifiedFile(URL url, boolean init) {
File file = new File(url.getPath());
boolean result;
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
if (init) {
bw.write("accessKey=testAk\nsecretKey=testSk");
} else {
bw.write("accessKey=testAk\nsecretKey=testSk\ntenantId=testTenantId");
}
bw.flush();
result = true;
} catch (IOException ignored) {
result = false;
}
return result;
}
}

View File

@ -20,6 +20,9 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class StsConfigTest {
@After
@ -29,6 +32,11 @@ public class StsConfigTest {
StsConfig.getInstance().setCacheSecurityCredentials(true);
StsConfig.getInstance().setSecurityCredentials(null);
StsConfig.getInstance().setSecurityCredentialsUrl(null);
System.clearProperty(IdentifyConstants.RAM_ROLE_NAME_PROPERTY);
System.clearProperty(IdentifyConstants.REFRESH_TIME_PROPERTY);
System.clearProperty(IdentifyConstants.SECURITY_PROPERTY);
System.clearProperty(IdentifyConstants.SECURITY_URL_PROPERTY);
System.clearProperty(IdentifyConstants.SECURITY_CACHE_PROPERTY);
}
@Test
@ -61,6 +69,13 @@ public class StsConfigTest {
Assert.assertEquals(expect, StsConfig.getInstance().getSecurityCredentialsUrl());
}
@Test
public void testGetSecurityCredentialsUrlDefault() {
StsConfig.getInstance().setRamRoleName("test");
Assert.assertEquals("http://100.100.100.200/latest/meta-data/ram/security-credentials/test",
StsConfig.getInstance().getSecurityCredentialsUrl());
}
@Test
public void testGetSecurityCredentials() {
Assert.assertNull(StsConfig.getInstance().getSecurityCredentials());
@ -89,4 +104,22 @@ public class StsConfigTest {
Assert.assertTrue(stsOn);
}
@Test
public void testFromEnv()
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Constructor<StsConfig> constructor = StsConfig.class.getDeclaredConstructor();
constructor.setAccessible(true);
System.setProperty(IdentifyConstants.RAM_ROLE_NAME_PROPERTY, "test");
System.setProperty(IdentifyConstants.REFRESH_TIME_PROPERTY, "3000");
System.setProperty(IdentifyConstants.SECURITY_PROPERTY, "abc");
System.setProperty(IdentifyConstants.SECURITY_URL_PROPERTY, "localhost");
System.setProperty(IdentifyConstants.SECURITY_CACHE_PROPERTY, "false");
StsConfig stsConfig = constructor.newInstance();
Assert.assertEquals("test", stsConfig.getRamRoleName());
Assert.assertEquals(3000, stsConfig.getTimeToRefreshInMillisecond());
Assert.assertEquals("abc", stsConfig.getSecurityCredentials());
Assert.assertEquals("localhost", stsConfig.getSecurityCredentialsUrl());
Assert.assertFalse(stsConfig.isCacheSecurityCredentials());
}
}

View File

@ -129,6 +129,8 @@ public class StsCredentialHolderTest {
stsCredential.setAccessKeySecret("test-sts-sk");
stsCredential.setSecurityToken("test-sts-token");
stsCredential.setExpiration(new Date(System.currentTimeMillis() + 1000000));
stsCredential.setCode("200");
stsCredential.setLastUpdated(new Date());
return stsCredential;
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 1999-2023 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.client.auth.ram.injector;
import org.junit.Before;
import org.junit.Test;
public class AbstractResourceInjectorTest {
AbstractResourceInjector injector;
@Before
public void setUp() {
injector = new AbstractResourceInjector() { };
}
/**
* TODO, fill test case after AbstractResourceInjector include default logic.
*/
@Test
public void testDoInject() {
injector.doInject(null, null, null);
}
}

View File

@ -19,6 +19,8 @@ package com.alibaba.nacos.client.auth.ram.utils;
import org.junit.Assert;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
public class SignUtilTest {
@Test
@ -26,4 +28,14 @@ public class SignUtilTest {
String actual = SignUtil.sign("aaa", "b");
Assert.assertEquals("DxyaKScrqL26yXYOuHXE3OwfQ0Y=", actual);
}
@Test(expected = Exception.class)
public void testSignWithException() throws Exception {
SignUtil.sign(null, "b");
}
@Test(expected = Exception.class)
public void testSignWithException2() throws Exception {
SignUtil.sign("aaa".getBytes(StandardCharsets.UTF_8), "b".getBytes(StandardCharsets.UTF_8), null);
}
}

View File

@ -69,23 +69,20 @@ public class SpasAdapterTest {
Assert.assertEquals(2, map1.size());
Assert.assertEquals(SpasAdapter.signWithHmacSha1Encrypt("bb+aa+" + map1.get("Timestamp"), "123"),
map1.get("Spas-Signature"));
// TODO BUG fix
// Map<String, String> param2 = new HashMap<>();
// param2.put("tenant", "");
// param2.put("group", "aa");
// final Map<String, String> map2 = SpasAdapter.getSignHeaders(param2, "123");
// Assert.assertEquals(2, map2.size());
// Assert.assertEquals(SpasAdapter.signWithHmacSha1Encrypt("aa" + "+" + map2.get("Timestamp"), "123"),
// map2.get("Spas-Signature"));
// Map<String, String> param3 = new HashMap<>();
// param3.put("tenant", "bb");
// param3.put("group", "");
// final Map<String, String> map3 = SpasAdapter.getSignHeaders(param3, "123");
// Assert.assertEquals(2, map3.size());
// Assert.assertEquals(SpasAdapter.signWithHmacSha1Encrypt(map3.get("Timestamp"), "123"),
// map3.get("Spas-Signature"));
}
@Test
public void testGetSignHeadersWithoutTenant() {
Map<String, String> param1 = new HashMap<>();
param1.put("group", "aa");
final Map<String, String> map1 = SpasAdapter.getSignHeaders(param1, "123");
Assert.assertEquals(2, map1.size());
Assert.assertEquals(SpasAdapter.signWithHmacSha1Encrypt("aa+" + map1.get("Timestamp"), "123"),
map1.get("Spas-Signature"));
}
@Test(expected = Exception.class)
public void testSignWithHmacSha1EncryptWithException() {
SpasAdapter.signWithHmacSha1Encrypt(null, "123");
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright 1999-2023 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.client.env;
import com.alibaba.nacos.client.constant.Constants;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
/**
* Additional test cases for SearchableProperties.
*
* <p> Common cases see {@link NacosClientPropertiesTest}.</p>
*/
public class SearchablePropertiesTest {
Method initMethod;
@BeforeClass
public static void init() {
System.setProperty(Constants.SysEnv.NACOS_ENV_FIRST, "jvm");
}
@Before
public void setUp() throws Exception {
initMethod = SearchableProperties.class.getDeclaredMethod("init");
initMethod.setAccessible(true);
}
@After
public void tearDown() throws Exception {
init();
initMethod.invoke(null);
}
@AfterClass
public static void teardown() {
System.clearProperty(Constants.SysEnv.NACOS_ENV_FIRST);
}
@Test
public void testInitWithInvalidOrder() throws IllegalAccessException, InvocationTargetException {
System.setProperty(Constants.SysEnv.NACOS_ENV_FIRST, "invalid");
List<SourceType> order = (List<SourceType>) initMethod.invoke(null);
assertOrder(order, SourceType.PROPERTIES, SourceType.JVM, SourceType.ENV);
}
@Test
public void testInitWithoutSpecifiedOrder() throws IllegalAccessException, InvocationTargetException {
System.clearProperty(Constants.SysEnv.NACOS_ENV_FIRST);
List<SourceType> order = (List<SourceType>) initMethod.invoke(null);
assertOrder(order, SourceType.PROPERTIES, SourceType.JVM, SourceType.ENV);
}
private void assertOrder(List<SourceType> order, SourceType... sourceTypes) {
assertEquals(sourceTypes.length, order.size());
for (int i = 0; i < sourceTypes.length; i++) {
assertEquals(sourceTypes[i], order.get(i));
}
}
@Test
public void testGetPropertyFromEnv() {
System.setProperty("testFromSource", "jvm");
NacosClientProperties properties = SearchableProperties.INSTANCE.derive();
properties.setProperty("testFromSource", "properties");
assertNull(properties.getPropertyFrom(SourceType.ENV, "testFromSource"));
}
@Test
public void testGetPropertyFromUnknown() {
System.setProperty("testFromSource", "jvm");
NacosClientProperties properties = SearchableProperties.INSTANCE.derive();
properties.setProperty("testFromSource", "properties");
assertEquals(properties.getProperty("testFromSource"),
properties.getPropertyFrom(SourceType.UNKNOWN, "testFromSource"));
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 1999-2023 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.client.env;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
/**
* Additional test cases for SystemEnvPropertySource.
*
* <p> Common cases see {@link NacosClientPropertiesTest}.</p>
*/
public class SystemEnvPropertySourceTest {
SystemEnvPropertySource systemEnvPropertySource;
private Map<String, String> mockEnvMap;
@Before
public void setUp() throws Exception {
systemEnvPropertySource = new SystemEnvPropertySource();
mockEnvMap = new HashMap<>();
Field envField = SystemEnvPropertySource.class.getDeclaredField("env");
envField.setAccessible(true);
envField.set(systemEnvPropertySource, mockEnvMap);
mockEnvMap.put("testcase1", "value1");
mockEnvMap.put("test_case_2", "value2");
mockEnvMap.put("TESTCASE3", "value3");
mockEnvMap.put("TEST_CASE_4", "value4");
}
@Test
public void testGetEnvForLowerCaseKey() {
assertEquals("value1", systemEnvPropertySource.getProperty("testcase1"));
}
@Test
public void testGetEnvForLowerCaseKeyWithDot() {
assertEquals("value2", systemEnvPropertySource.getProperty("test.case.2"));
}
@Test
public void testGetEnvForLowerCaseKeyWithHyphen() {
assertEquals("value2", systemEnvPropertySource.getProperty("test-case-2"));
}
@Test
public void testGetEnvForLowerCaseKeyWithHyphenAndDot() {
assertEquals("value2", systemEnvPropertySource.getProperty("test.case-2"));
}
@Test
public void testGetEnvForUpperCaseKey() {
assertEquals("value3", systemEnvPropertySource.getProperty("TESTCASE3"));
}
@Test
public void testGetEnvForUpperCaseKeyWithDot() {
assertEquals("value4", systemEnvPropertySource.getProperty("TEST.CASE.4"));
}
@Test
public void testGetEnvForUpperCaseKeyWithHyphen() {
assertEquals("value4", systemEnvPropertySource.getProperty("TEST-CASE-4"));
}
@Test
public void testGetEnvForUpperCaseKeyWithHyphenAndDot() {
assertEquals("value4", systemEnvPropertySource.getProperty("TEST_CASE.4"));
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 1999-2023 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.client.env.convert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.MissingFormatArgumentException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class CompositeConverterTest {
CompositeConverter compositeConverter;
@Before
public void setUp() throws Exception {
compositeConverter = new CompositeConverter();
}
@After
public void tearDown() throws Exception {
}
@Test(expected = MissingFormatArgumentException.class)
public void testConvertNotSupportType() {
compositeConverter.convert("test", CompositeConverter.class);
}
@Test
public void testConvertBooleanForEmptyProperty() {
assertNull(compositeConverter.convert(null, Boolean.class));
}
@Test
public void testConvertBooleanTrue() {
assertTrue(compositeConverter.convert("true", Boolean.class));
assertTrue(compositeConverter.convert("on", Boolean.class));
assertTrue(compositeConverter.convert("yes", Boolean.class));
assertTrue(compositeConverter.convert("1", Boolean.class));
}
@Test
public void testConvertBooleanFalse() {
assertFalse(compositeConverter.convert("false", Boolean.class));
assertFalse(compositeConverter.convert("off", Boolean.class));
assertFalse(compositeConverter.convert("no", Boolean.class));
assertFalse(compositeConverter.convert("0", Boolean.class));
}
@Test(expected = IllegalArgumentException.class)
public void testConvertBooleanIllegal() {
compositeConverter.convert("aaa", Boolean.class);
}
@Test
public void testConvertIntegerForEmptyProperty() {
assertNull(compositeConverter.convert(null, Integer.class));
}
@Test
public void testConvertInteger() {
assertEquals(100, (int) compositeConverter.convert("100", Integer.class));
assertEquals(Integer.MAX_VALUE, (int) compositeConverter.convert(String.valueOf(Integer.MAX_VALUE), Integer.class));
assertEquals(Integer.MIN_VALUE, (int) compositeConverter.convert(String.valueOf(Integer.MIN_VALUE), Integer.class));
}
@Test(expected = IllegalArgumentException.class)
public void testConvertIntegerIllegal() {
compositeConverter.convert("aaa", Integer.class);
}
@Test
public void testConvertLongForEmptyProperty() {
assertNull(compositeConverter.convert(null, Long.class));
}
@Test
public void testConvertLong() {
assertEquals(100L, (long) compositeConverter.convert("100", Long.class));
assertEquals(Long.MAX_VALUE, (long) compositeConverter.convert(String.valueOf(Long.MAX_VALUE), Long.class));
assertEquals(Long.MIN_VALUE, (long) compositeConverter.convert(String.valueOf(Long.MIN_VALUE), Long.class));
}
@Test(expected = IllegalArgumentException.class)
public void testConvertLongIllegal() {
compositeConverter.convert("aaa", Long.class);
}
}

View File

@ -136,7 +136,7 @@ public class NamingGrpcClientProxyTest {
@Before
public void setUp() throws NacosException, NoSuchFieldException, IllegalAccessException {
System.setProperty(GrpcConstants.GRPC_RETRY_TIMES, "1");
System.setProperty(GrpcConstants.GRPC_SERVER_CHECK_TIMEOUT, "1000");
System.setProperty(GrpcConstants.GRPC_SERVER_CHECK_TIMEOUT, "100");
List<String> serverList = Stream.of(ORIGIN_SERVER, "anotherServer").collect(Collectors.toList());
when(factory.getServerList()).thenReturn(serverList);
when(factory.genNextServer()).thenReturn(ORIGIN_SERVER);

View File

@ -0,0 +1,18 @@
#
# Copyright 1999-2023 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.
#
accessKey=testAk
secretKey=testSk
tenantId=testTenantId

View File

@ -0,0 +1,18 @@
#
# Copyright 1999-2023 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.
#
env_spas_accessKey=testAk
env_spas_secretKey=testSk
ebv_spas_tenantId=testTenantId

View File

@ -0,0 +1,18 @@
#
# Copyright 1999-2023 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.
#
accessKey=
secretKey=testSk
tenantId=testTenantId

View File

@ -0,0 +1,15 @@
#
# Copyright 1999-2023 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.
#