This is an automated email from the ASF dual-hosted git repository.
wuzhiguo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git
The following commit(s) were added to refs/heads/main by this push:
new 5b61ee74 BIGTOP-4363: Add some unit tests for stack core module (#178)
5b61ee74 is described below
commit 5b61ee74f5cf8b02e2f709b4941c11f9122af28d
Author: xianrenzw <[email protected]>
AuthorDate: Tue Feb 18 14:41:58 2025 +0800
BIGTOP-4363: Add some unit tests for stack core module (#178)
---
.../manager/stack/core/spi/hook/AddHook.java | 2 +-
.../manager/stack/core/utils/LocalSettings.java | 16 +-
.../stack/core/utils/linux/LinuxAccountUtils.java | 2 +-
.../manager/stack/core/spi/hook/AddHookTest.java | 97 +++++++++
.../stack/core/spi/hook/RestartHookTest.java | 62 ++++++
.../manager/stack/core/spi/hook/StartHookTest.java | 62 ++++++
.../manager/stack/core/spi/hook/StopHookTest.java | 62 ++++++
.../stack/core/spi/param/BaseParamsTest.java | 186 +++++++++++++++++
.../stack/core/spi/repo/AptPackageManagerTest.java | 97 +++++++++
.../stack/core/spi/repo/DnfPackageManagerTest.java | 97 +++++++++
.../stack/core/spi/repo/YumPackageManagerTest.java | 97 +++++++++
.../core/spi/script/AbstractClientScriptTest.java | 81 ++++++++
.../stack/core/tarball/ChecksumValidatorTest.java | 110 ++++++++++
.../stack/core/utils/LocalSettingsTest.java | 224 ++++++++++++++++++++
.../manager/stack/core/utils/PackageUtilsTest.java | 91 ++++++++
.../stack/core/utils/PropertiesUtilsTest.java | 101 +++++++++
.../core/utils/linux/LinuxAccountUtilsTest.java | 228 +++++++++++++++++++++
.../stack/core/utils/linux/LinuxOSUtilsTest.java | 174 ++++++++++++++++
.../core/utils/template/TemplateUtilsTest.java | 109 ++++++++++
19 files changed, 1890 insertions(+), 8 deletions(-)
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/spi/hook/AddHook.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/spi/hook/AddHook.java
index 8e9da6e9..14633910 100644
---
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/spi/hook/AddHook.java
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/spi/hook/AddHook.java
@@ -46,7 +46,7 @@ public class AddHook extends AbstractHook {
return NAME;
}
- private void addUserAndGroup(Params params) {
+ protected void addUserAndGroup(Params params) {
String user = params.user();
String group = params.group();
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/LocalSettings.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/LocalSettings.java
index 1c1f230f..ba0b7363 100644
---
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/LocalSettings.java
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/LocalSettings.java
@@ -43,7 +43,7 @@ public class LocalSettings {
public static Map<String, Object> configurations(String service, String
type) {
Map<String, Object> configDataMap = new HashMap<>();
- File file = new File(ProjectPathUtils.getAgentCachePath() +
CacheFiles.CONFIGURATIONS_INFO);
+ File file = createFile(ProjectPathUtils.getAgentCachePath() +
CacheFiles.CONFIGURATIONS_INFO);
try {
if (file.exists()) {
Map<String, Map<String, Object>> configJson =
JsonUtils.readFromFile(file, new TypeReference<>() {});
@@ -67,7 +67,7 @@ public class LocalSettings {
public static Map<String, List<String>> hosts() {
Map<String, List<String>> hostJson = new HashMap<>();
- File file = new File(ProjectPathUtils.getAgentCachePath() +
CacheFiles.HOSTS_INFO);
+ File file = createFile(ProjectPathUtils.getAgentCachePath() +
CacheFiles.HOSTS_INFO);
if (file.exists()) {
hostJson = JsonUtils.readFromFile(file, new TypeReference<>() {});
}
@@ -77,7 +77,7 @@ public class LocalSettings {
public static Map<String, Object> basicInfo() {
Map<String, Object> settings = new HashMap<>();
- File file = new File(ProjectPathUtils.getAgentCachePath() +
CacheFiles.SETTINGS_INFO);
+ File file = createFile(ProjectPathUtils.getAgentCachePath() +
CacheFiles.SETTINGS_INFO);
if (file.exists()) {
settings = JsonUtils.readFromFile(file, new TypeReference<>() {});
}
@@ -87,7 +87,7 @@ public class LocalSettings {
public static Map<String, String> users() {
Map<String, String> userMap = new HashMap<>();
- File file = new File(ProjectPathUtils.getAgentCachePath() +
CacheFiles.USERS_INFO);
+ File file = createFile(ProjectPathUtils.getAgentCachePath() +
CacheFiles.USERS_INFO);
if (file.exists()) {
userMap = JsonUtils.readFromFile(file, new TypeReference<>() {});
}
@@ -101,7 +101,7 @@ public class LocalSettings {
public static List<RepoInfo> repos() {
List<RepoInfo> repoInfoList = List.of();
- File file = new File(ProjectPathUtils.getAgentCachePath() +
CacheFiles.REPOS_INFO);
+ File file = createFile(ProjectPathUtils.getAgentCachePath() +
CacheFiles.REPOS_INFO);
if (file.exists()) {
repoInfoList = JsonUtils.readFromFile(file, new TypeReference<>()
{});
}
@@ -111,10 +111,14 @@ public class LocalSettings {
public static ClusterInfo cluster() {
ClusterInfo clusterInfo = new ClusterInfo();
- File file = new File(ProjectPathUtils.getAgentCachePath() +
CacheFiles.CLUSTER_INFO);
+ File file = createFile(ProjectPathUtils.getAgentCachePath() +
CacheFiles.CLUSTER_INFO);
if (file.exists()) {
clusterInfo = JsonUtils.readFromFile(file, new TypeReference<>()
{});
}
return clusterInfo;
}
+
+ protected static File createFile(String fileName) {
+ return new File(fileName);
+ }
}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxAccountUtils.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxAccountUtils.java
index 91bd67c8..0a4139dc 100644
---
a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxAccountUtils.java
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxAccountUtils.java
@@ -328,7 +328,7 @@ public class LinuxAccountUtils {
return null;
}
- private static ShellResult sudoExecCmd(List<String> params) throws
IOException {
+ protected static ShellResult sudoExecCmd(List<String> params) throws
IOException {
if ("root".equals(System.getProperty("user.name"))) {
return ShellExecutor.execCommand(params);
} else {
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/AddHookTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/AddHookTest.java
new file mode 100644
index 00000000..d53493d2
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/AddHookTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.hook;
+
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+import org.apache.bigtop.manager.stack.core.utils.linux.LinuxAccountUtils;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class AddHookTest {
+
+ @Mock
+ private AddHook addHook;
+
+ @Mock
+ private Params params;
+
+ @Test
+ public void testDoBefore() {
+ doNothing().when(addHook).addUserAndGroup(any());
+ doCallRealMethod().when(addHook).doBefore(any());
+ addHook.doBefore(params);
+ verify(addHook, times(1)).addUserAndGroup(params);
+ }
+
+ @Test
+ public void testDoAfter() {
+ doCallRealMethod().when(addHook).doAfter(any());
+ addHook.doAfter(params);
+ verify(addHook, never()).addUserAndGroup(params);
+ }
+
+ @Test
+ public void testGetName() {
+ doCallRealMethod().when(addHook).getName();
+ String name = addHook.getName();
+ assert name.equals("add");
+ }
+
+ @Test
+ public void testAddUserAndGroup() {
+ try (MockedStatic<LinuxAccountUtils> linuxAccountUtilsMockedStatic =
mockStatic(LinuxAccountUtils.class)) {
+ when(params.user()).thenReturn("testUser");
+ when(params.group()).thenReturn("testGroup1");
+ doCallRealMethod().when(addHook).addUserAndGroup(any());
+
+ linuxAccountUtilsMockedStatic
+ .when(() -> LinuxAccountUtils.userAdd(any(), any()))
+ .thenAnswer(invocation -> null);
+ linuxAccountUtilsMockedStatic
+ .when(() -> LinuxAccountUtils.groupAdd(any()))
+ .thenAnswer(invocation -> null);
+
+ linuxAccountUtilsMockedStatic
+ .when(() -> LinuxAccountUtils.getUserPrimaryGroup(any()))
+ .thenReturn("testGroup1");
+ addHook.addUserAndGroup(params);
+ linuxAccountUtilsMockedStatic.verify(() ->
LinuxAccountUtils.userAdd(any(), any()), never());
+
+ linuxAccountUtilsMockedStatic
+ .when(() -> LinuxAccountUtils.getUserPrimaryGroup(any()))
+ .thenReturn("testGroup2");
+ addHook.addUserAndGroup(params);
+ linuxAccountUtilsMockedStatic.verify(() ->
LinuxAccountUtils.userAdd(any(), any()), times(1));
+ }
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/RestartHookTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/RestartHookTest.java
new file mode 100644
index 00000000..d450fb0c
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/RestartHookTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.hook;
+
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@ExtendWith(MockitoExtension.class)
+public class RestartHookTest {
+
+ @Mock
+ private RestartHook restartHook;
+
+ @Mock
+ private Params params;
+
+ @Test
+ public void testDoBefore() {
+ doCallRealMethod().when(restartHook).doBefore(any());
+ restartHook.doBefore(params);
+ verify(restartHook, times(1)).doBefore(params);
+ }
+
+ @Test
+ public void testDoAfter() {
+ doCallRealMethod().when(restartHook).doAfter(any());
+ restartHook.doAfter(params);
+ verify(restartHook, times(1)).doAfter(params);
+ }
+
+ @Test
+ public void testGetName() {
+ doCallRealMethod().when(restartHook).getName();
+ String name = restartHook.getName();
+ assert name.equals("restart");
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/StartHookTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/StartHookTest.java
new file mode 100644
index 00000000..1cdf5089
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/StartHookTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.hook;
+
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@ExtendWith(MockitoExtension.class)
+public class StartHookTest {
+
+ @Mock
+ private StartHook startHook;
+
+ @Mock
+ private Params params;
+
+ @Test
+ public void testDoBefore() {
+ doCallRealMethod().when(startHook).doBefore(any());
+ startHook.doBefore(params);
+ verify(startHook, times(1)).doBefore(params);
+ }
+
+ @Test
+ public void testDoAfter() {
+ doCallRealMethod().when(startHook).doAfter(any());
+ startHook.doAfter(params);
+ verify(startHook, times(1)).doAfter(params);
+ }
+
+ @Test
+ public void testGetName() {
+ doCallRealMethod().when(startHook).getName();
+ String name = startHook.getName();
+ assert name.equals("start");
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/StopHookTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/StopHookTest.java
new file mode 100644
index 00000000..43597de3
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/hook/StopHookTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.hook;
+
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+@ExtendWith(MockitoExtension.class)
+public class StopHookTest {
+
+ @Mock
+ private StopHook stopHook;
+
+ @Mock
+ private Params params;
+
+ @Test
+ public void testDoBefore() {
+ doCallRealMethod().when(stopHook).doBefore(any());
+ stopHook.doBefore(params);
+ verify(stopHook, times(1)).doBefore(params);
+ }
+
+ @Test
+ public void testDoAfter() {
+ doCallRealMethod().when(stopHook).doAfter(any());
+ stopHook.doAfter(params);
+ verify(stopHook, times(1)).doAfter(params);
+ }
+
+ @Test
+ public void testGetName() {
+ doCallRealMethod().when(stopHook).getName();
+ String name = stopHook.getName();
+ assert name.equals("stop");
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/param/BaseParamsTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/param/BaseParamsTest.java
new file mode 100644
index 00000000..eeed94b1
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/param/BaseParamsTest.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.param;
+
+import org.apache.bigtop.manager.common.utils.NetUtils;
+import org.apache.bigtop.manager.common.utils.os.OSDetection;
+import org.apache.bigtop.manager.grpc.payload.ComponentCommandPayload;
+import org.apache.bigtop.manager.grpc.pojo.ClusterInfo;
+import org.apache.bigtop.manager.grpc.pojo.PackageInfo;
+import org.apache.bigtop.manager.grpc.pojo.PackageSpecificInfo;
+import org.apache.bigtop.manager.grpc.pojo.RepoInfo;
+import org.apache.bigtop.manager.grpc.pojo.TemplateInfo;
+import org.apache.bigtop.manager.stack.core.utils.LocalSettings;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.MockedStatic;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mockStatic;
+
+@ExtendWith(MockitoExtension.class)
+public class BaseParamsTest {
+
+ private MockedStatic<LocalSettings> localSettingsMockedStatic;
+ private MockedStatic<OSDetection> osDetectionMockedStatic;
+ private MockedStatic<NetUtils> netUtilsMockedStatic;
+
+ private final ClusterInfo clusterInfo = new ClusterInfo();
+
+ private final ComponentCommandPayload payload = new
ComponentCommandPayload();
+
+ private MockBaseParams mockBaseParams;
+
+ @BeforeEach
+ public void setUp() {
+ List<RepoInfo> repos = new ArrayList<>();
+ repos.add(new RepoInfo("repo1", "mockArch", "testURL", 2));
+ repos.add(new RepoInfo("repo2", "mockArch", "testURL", 1));
+ repos.add(new RepoInfo("repo3", "mockArch", "testURL", 1));
+
+ List<String> arch = new ArrayList<>();
+ arch.add("mockArch");
+
+ List<PackageInfo> packages = new ArrayList<>();
+ packages.add(new PackageInfo("package1", "testChecksum1"));
+ packages.add(new PackageInfo("package2", "testChecksum2"));
+
+ List<PackageSpecificInfo> packageSpecifics = new ArrayList<>();
+ PackageSpecificInfo packageSpecific = new PackageSpecificInfo();
+ packageSpecific.setArch(arch);
+ packageSpecific.setPackages(packages);
+ packageSpecifics.add(packageSpecific);
+
+ List<TemplateInfo> templates = new ArrayList<>();
+ TemplateInfo template = new TemplateInfo();
+ template.setSrc("mockSrc");
+ template.setDest("mockDest");
+ template.setContent("mockContent");
+ templates.add(template);
+
+ payload.setServiceUser("mockUser");
+ payload.setPackageSpecifics(packageSpecifics);
+ payload.setTemplates(templates);
+
+ clusterInfo.setRootDir("/mockRoot");
+ clusterInfo.setUserGroup("mockGroup");
+
+ mockBaseParams = new MockBaseParams(payload);
+
+ localSettingsMockedStatic = mockStatic(LocalSettings.class);
+ osDetectionMockedStatic = mockStatic(OSDetection.class);
+ netUtilsMockedStatic = mockStatic(NetUtils.class);
+
netUtilsMockedStatic.when(NetUtils::getHostname).thenReturn("mockHostname");
+ localSettingsMockedStatic.when(LocalSettings::repos).thenReturn(repos);
+
localSettingsMockedStatic.when(LocalSettings::cluster).thenReturn(clusterInfo);
+
osDetectionMockedStatic.when(OSDetection::getArch).thenReturn("mockArch");
+ }
+
+ @AfterEach
+ public void tearDown() {
+ localSettingsMockedStatic.close();
+ osDetectionMockedStatic.close();
+ netUtilsMockedStatic.close();
+ }
+
+ @Test
+ public void testHostname() {
+ String hostname = mockBaseParams.hostname();
+ assertEquals("mockHostname", hostname);
+ }
+
+ @Test
+ public void testConfDir() {
+ String confDir = mockBaseParams.confDir();
+ assertEquals("/mockRoot/services/mockService/conf", confDir);
+ }
+
+ @Test
+ public void testUser() {
+ String user = mockBaseParams.user();
+ assertEquals("mockUser", user);
+ }
+
+ @Test
+ public void testGroup() {
+ String group = mockBaseParams.group();
+ assertEquals("mockGroup", group);
+ }
+
+ @Test
+ public void testRepo() {
+ RepoInfo repo = mockBaseParams.repo();
+ assertEquals(1, repo.getType());
+ assertEquals("repo2", repo.getName());
+ assertEquals("mockArch", repo.getArch());
+ }
+
+ @Test
+ public void testPackages() {
+ List<PackageInfo> packages = mockBaseParams.packages();
+ assertEquals(2, packages.size());
+ assertEquals("package1", packages.get(0).getName());
+ assertEquals("package2", packages.get(1).getName());
+ }
+
+ @Test
+ public void testTemplates() {
+ List<TemplateInfo> templates = mockBaseParams.templates();
+ assertEquals(1, templates.size());
+ assertEquals("mockSrc", templates.get(0).getSrc());
+ assertEquals("mockDest", templates.get(0).getDest());
+ assertEquals("mockContent", templates.get(0).getContent());
+ }
+
+ @Test
+ public void testJavaHome() {
+ String javaHome = mockBaseParams.javaHome();
+ assertEquals("/mockRoot/tools/jdk", javaHome);
+ }
+
+ @Test
+ public void testStackHome() {
+ String stackHome = mockBaseParams.stackHome();
+ assertEquals("/mockRoot/services", stackHome);
+ }
+
+ @Test
+ public void testServiceHome() {
+ String serviceHome = mockBaseParams.serviceHome();
+ assertEquals("/mockRoot/services/mockService", serviceHome);
+ }
+
+ private static class MockBaseParams extends BaseParams {
+ public MockBaseParams(ComponentCommandPayload payload) {
+ this.payload = payload;
+ }
+
+ @Override
+ public String getServiceName() {
+ return "mockService";
+ }
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/AptPackageManagerTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/AptPackageManagerTest.java
new file mode 100644
index 00000000..42290801
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/AptPackageManagerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.repo;
+
+import org.apache.bigtop.manager.common.shell.ShellExecutor;
+import org.apache.bigtop.manager.common.shell.ShellResult;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.mockStatic;
+
+public class AptPackageManagerTest {
+
+ private MockedStatic<ShellExecutor> mockStatic;
+
+ private final AptPackageManager aptPackageManager = new
AptPackageManager();
+
+ @BeforeEach
+ public void setUp() {
+ mockStatic = mockStatic(ShellExecutor.class);
+ mockStatic
+ .when(() -> ShellExecutor.execCommand(anyList(), anyBoolean()))
+ .thenAnswer(invocation -> {
+ List<String> cmd = invocation.getArgument(0);
+ return ShellResult.success(cmd.toString());
+ });
+ }
+
+ @AfterEach
+ public void tearDown() {
+ mockStatic.close();
+ }
+
+ @Test
+ public void testInstallPackage() {
+ String packageToInstall = "testPackage";
+ ShellResult result =
aptPackageManager.installPackage(List.of(packageToInstall));
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList(),
anyBoolean()));
+ assertEquals("[/usr/bin/apt-get, install, -y, testPackage]",
result.getOutput());
+ }
+
+ @Test
+ public void testUninstallPackage() {
+ String packageToInstall = "testPackage";
+ ShellResult result =
aptPackageManager.uninstallPackage(List.of(packageToInstall));
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList(),
anyBoolean()));
+ assertEquals("[/usr/bin/apt-get, remove, -y, testPackage]",
result.getOutput());
+ }
+
+ @Test
+ public void testListPackages() {
+
+ mockStatic.when(() ->
ShellExecutor.execCommand(anyList())).thenAnswer(invocation -> {
+ List<String> mockOutput = List.of(
+ "Listing... Done",
+ "package1/now 1.2.3-1 amd64 [installed,local]",
+ "package2/stable 4.5.6-1 amd64 [installed]",
+ "package3/stable 7.8.9-1 amd64 [installed]");
+ return ShellResult.success(String.join("\n", mockOutput));
+ });
+ List<String> packagesResult = aptPackageManager.listPackages();
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList()));
+ assertEquals(3, packagesResult.size());
+ assertEquals("package1", packagesResult.get(0));
+ assertEquals("package2", packagesResult.get(1));
+ assertEquals("package3", packagesResult.get(2));
+ }
+
+ @Test
+ public void testGetName() {
+ assertEquals("APT", aptPackageManager.getName());
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/DnfPackageManagerTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/DnfPackageManagerTest.java
new file mode 100644
index 00000000..594752bf
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/DnfPackageManagerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.repo;
+
+import org.apache.bigtop.manager.common.shell.ShellExecutor;
+import org.apache.bigtop.manager.common.shell.ShellResult;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.Mockito.mockStatic;
+
+public class DnfPackageManagerTest {
+
+ private MockedStatic<ShellExecutor> mockStatic;
+
+ private final DnfPackageManager dnfPackageManager = new
DnfPackageManager();
+
+ @BeforeEach
+ public void setUp() {
+ mockStatic = mockStatic(ShellExecutor.class);
+ mockStatic
+ .when(() -> ShellExecutor.execCommand(anyList(), anyBoolean()))
+ .thenAnswer(invocation -> {
+ List<String> cmd = invocation.getArgument(0);
+ return ShellResult.success(cmd.toString());
+ });
+ }
+
+ @AfterEach
+ public void tearDown() {
+ mockStatic.close();
+ }
+
+ @Test
+ public void testInstallPackage() {
+ String packageToInstall = "testPackage";
+ ShellResult result =
dnfPackageManager.installPackage(List.of(packageToInstall));
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList(),
anyBoolean()));
+ assertEquals("[/usr/bin/dnf, install, -y, testPackage]",
result.getOutput());
+ }
+
+ @Test
+ public void testUninstallPackage() {
+ String packageToRemove = "testPackage";
+ ShellResult result =
dnfPackageManager.uninstallPackage(List.of(packageToRemove));
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList(),
anyBoolean()));
+ assertEquals("[/usr/bin/dnf, remove, -y, testPackage]",
result.getOutput());
+ }
+
+ @Test
+ public void testListPackages() {
+ mockStatic.when(() ->
ShellExecutor.execCommand(anyList())).thenAnswer(invocation -> {
+ List<String> mockOutput = List.of(
+ "Listing... Done",
+ "package1.x86_64 1.2.3-1 @updates",
+ "package2.noarch 4.5.6-1 @fedora",
+ "package3.i686 7.8.9-1 @fedora");
+ return ShellResult.success(String.join("\n", mockOutput));
+ });
+
+ List<String> packagesResult = dnfPackageManager.listPackages();
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList()));
+ assertEquals(3, packagesResult.size());
+ assertEquals("package1", packagesResult.get(0));
+ assertEquals("package2", packagesResult.get(1));
+ assertEquals("package3", packagesResult.get(2));
+ }
+
+ @Test
+ public void testGetName() {
+ assertEquals("DNF", dnfPackageManager.getName());
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/YumPackageManagerTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/YumPackageManagerTest.java
new file mode 100644
index 00000000..8c545de2
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/repo/YumPackageManagerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.repo;
+
+import org.apache.bigtop.manager.common.shell.ShellExecutor;
+import org.apache.bigtop.manager.common.shell.ShellResult;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.mockStatic;
+
+public class YumPackageManagerTest {
+
+ private MockedStatic<ShellExecutor> mockStatic;
+
+ private final YumPackageManager yumPackageManager = new
YumPackageManager();
+
+ @BeforeEach
+ public void setUp() {
+ mockStatic = mockStatic(ShellExecutor.class);
+ mockStatic
+ .when(() -> ShellExecutor.execCommand(anyList(), anyBoolean()))
+ .thenAnswer(invocation -> {
+ List<String> cmd = invocation.getArgument(0);
+ return ShellResult.success(cmd.toString());
+ });
+ }
+
+ @AfterEach
+ public void tearDown() {
+ mockStatic.close();
+ }
+
+ @Test
+ public void testInstallPackage() {
+ String packageToInstall = "testPackage";
+ ShellResult result =
yumPackageManager.installPackage(List.of(packageToInstall));
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList(),
anyBoolean()));
+ assertEquals("[/usr/bin/yum, install, -y, testPackage]",
result.getOutput());
+ }
+
+ @Test
+ public void testUninstallPackage() {
+ String packageToRemove = "testPackage";
+ ShellResult result =
yumPackageManager.uninstallPackage(List.of(packageToRemove));
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList(),
anyBoolean()));
+ assertEquals("[/usr/bin/yum, remove, -y, testPackage]",
result.getOutput());
+ }
+
+ @Test
+ public void testListPackages() {
+ mockStatic.when(() ->
ShellExecutor.execCommand(anyList())).thenAnswer(invocation -> {
+ List<String> mockOutput = List.of(
+ "Installed Packages",
+ "package1.x86_64 1.2.3-1",
+ "package2.noarch 4.5.6-1",
+ "package3.i686 7.8.9-1");
+ return ShellResult.success(String.join("\n", mockOutput));
+ });
+
+ List<String> packagesResult = yumPackageManager.listPackages();
+ mockStatic.verify(() -> ShellExecutor.execCommand(anyList()));
+ assertEquals(3, packagesResult.size());
+ assertEquals("package1", packagesResult.get(0));
+ assertEquals("package2", packagesResult.get(1));
+ assertEquals("package3", packagesResult.get(2));
+ }
+
+ @Test
+ public void testGetName() {
+ assertEquals("YUM", yumPackageManager.getName());
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/script/AbstractClientScriptTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/script/AbstractClientScriptTest.java
new file mode 100644
index 00000000..e2a2a6f1
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/spi/script/AbstractClientScriptTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.spi.script;
+
+import org.apache.bigtop.manager.common.constants.MessageConstants;
+import org.apache.bigtop.manager.common.shell.ShellResult;
+import org.apache.bigtop.manager.stack.core.spi.param.Params;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+@ExtendWith(MockitoExtension.class)
+public class AbstractClientScriptTest {
+
+ @Mock
+ private Params params;
+
+ @Test
+ public void testStart() {
+ MockClientScript clientScript = new MockClientScript();
+ ShellResult result = clientScript.start(params);
+ assertEquals(MessageConstants.SUCCESS_CODE, result.getExitCode());
+ }
+
+ @Test
+ public void testStop() {
+ MockClientScript clientScript = new MockClientScript();
+ ShellResult result = clientScript.stop(params);
+ assertEquals(MessageConstants.SUCCESS_CODE, result.getExitCode());
+ }
+
+ @Test
+ public void testStatus() {
+ MockClientScript clientScript = new MockClientScript();
+ ShellResult result = clientScript.status(params);
+ assertEquals(MessageConstants.SUCCESS_CODE, result.getExitCode());
+ }
+
+ private static class MockClientScript extends AbstractClientScript {
+
+ @Override
+ public ShellResult start(Params params) {
+ return super.start(params);
+ }
+
+ @Override
+ public ShellResult stop(Params params) {
+ return super.stop(params);
+ }
+
+ @Override
+ public ShellResult status(Params params) {
+ return super.status(params);
+ }
+
+ @Override
+ public String getComponentName() {
+ return "MockClientScript";
+ }
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/tarball/ChecksumValidatorTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/tarball/ChecksumValidatorTest.java
new file mode 100644
index 00000000..beb375a4
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/tarball/ChecksumValidatorTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.tarball;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@Slf4j
+class ChecksumValidatorTest {
+
+ @TempDir
+ private Path tempDir;
+
+ @Test
+ void testValidateChecksum_HappyPath() throws Exception {
+ // Create an empty temporary file
+ Path tempFilePath = tempDir.resolve("testfile.txt");
+ Files.write(tempFilePath, new byte[0]);
+ File file = tempFilePath.toFile();
+
+ String expectedChecksum =
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
+ boolean result = ChecksumValidator.validateChecksum("SHA-256",
expectedChecksum, file);
+
+ assertTrue(result, "Checksum validation should succeed for valid
case");
+ }
+
+ @Test
+ void testValidateChecksum_EdgeCase_UnsupportedAlgorithm() throws Exception
{
+ // Create an empty temporary file
+ Path tempFilePath = tempDir.resolve("testfile.txt");
+ Files.write(tempFilePath, new byte[0]);
+ File file = tempFilePath.toFile();
+
+ boolean result =
ChecksumValidator.validateChecksum("INVALID-ALGORITHM", "any-checksum", file);
+
+ assertFalse(result, "Should return false for unsupported algorithm");
+ }
+
+ @Test
+ void testValidateChecksum_EdgeCase_FileNotExist() {
+ // Use a non-existent file path
+ File file = tempDir.resolve("non_existent.txt").toFile();
+ boolean result = ChecksumValidator.validateChecksum("SHA-256",
"any-checksum", file);
+
+ assertFalse(result, "Should return false for non-existent file");
+ }
+
+ @Test
+ void testValidateChecksum_EdgeCase_EmptyFile() throws Exception {
+ // Create an empty temporary file
+ Path tempFilePath = tempDir.resolve("emptyfile.txt");
+ Files.write(tempFilePath, new byte[0]);
+ File file = tempFilePath.toFile();
+
+ String expectedChecksum =
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
+ boolean result = ChecksumValidator.validateChecksum("SHA-256",
expectedChecksum, file);
+
+ assertTrue(result, "Checksum validation should succeed for empty
file");
+ }
+
+ @Test
+ void testValidateChecksum_EdgeCase_ChecksumMismatch() throws Exception {
+ // Create a temporary file with content
+ Path tempFilePath = tempDir.resolve("datafile.txt");
+ Files.write(tempFilePath, "test_data".getBytes());
+ File file = tempFilePath.toFile();
+
+ boolean result = ChecksumValidator.validateChecksum("SHA-256",
"wrong_checksum", file);
+
+ assertFalse(result, "Should return false for checksum mismatch");
+ }
+
+ @Test
+ void testValidateChecksum_EdgeCase_CaseInsensitive() throws Exception {
+ // Create an empty temporary file
+ Path tempFilePath = tempDir.resolve("casefile.txt");
+ Files.write(tempFilePath, new byte[0]);
+ File file = tempFilePath.toFile();
+
+ String expectedChecksum =
"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855";
+ boolean result = ChecksumValidator.validateChecksum("sha-256",
expectedChecksum, file);
+
+ assertTrue(result, "Checksum validation should be case-insensitive");
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/LocalSettingsTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/LocalSettingsTest.java
new file mode 100644
index 00000000..fef270bf
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/LocalSettingsTest.java
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.utils;
+
+import org.apache.bigtop.manager.common.utils.JsonUtils;
+import org.apache.bigtop.manager.common.utils.ProjectPathUtils;
+import org.apache.bigtop.manager.grpc.pojo.ClusterInfo;
+import org.apache.bigtop.manager.grpc.pojo.RepoInfo;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
+
+public class LocalSettingsTest {
+
+ private MockedStatic<JsonUtils> jsonUtilsMockedStatic;
+
+ private MockedStatic<ProjectPathUtils> projectPathUtilsMockedStatic;
+
+ private MockedStatic<LocalSettings> localSettingsMockedStatic;
+
+ @BeforeEach
+ public void setUp() {
+ jsonUtilsMockedStatic = mockStatic(JsonUtils.class);
+ projectPathUtilsMockedStatic = mockStatic(ProjectPathUtils.class);
+ localSettingsMockedStatic = mockStatic(LocalSettings.class);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ jsonUtilsMockedStatic.close();
+ projectPathUtilsMockedStatic.close();
+ localSettingsMockedStatic.close();
+ }
+
+ @Test
+ public void testConfigurations() throws Exception {
+ String service = "serviceA";
+ String type = "typeA";
+ String key = "keyA";
+ String defaultValue = "defaultValue";
+
+ Map<String, Object> configDataMap = new HashMap<>();
+ configDataMap.put(key, "valueA");
+ String configDataMapJson = new
ObjectMapper().writeValueAsString(configDataMap);
+
+ Map<String, Map<String, Object>> configJson = new HashMap<>();
+ configJson.put(service, new HashMap<>());
+ configJson.get(service).put(type, configDataMapJson);
+
+ File file = mock(File.class);
+
localSettingsMockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn("/mock/path/");
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.createFile(anyString()))
+ .thenReturn(file);
+ when(file.exists()).thenReturn(true);
+ localSettingsMockedStatic
+ .when(() -> JsonUtils.readFromFile(any(File.class),
any(TypeReference.class)))
+ .thenReturn(configJson);
+ localSettingsMockedStatic
+ .when(() -> JsonUtils.readFromString(anyString(),
any(TypeReference.class)))
+ .thenCallRealMethod();
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.configurations(anyString(),
anyString(), anyString(), any()))
+ .thenCallRealMethod();
+
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.configurations(anyString(),
anyString()))
+ .thenCallRealMethod();
+ assertEquals("valueA", LocalSettings.configurations(service, type,
key, defaultValue));
+
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.configurations(anyString(),
anyString()))
+ .thenReturn(null);
+ assertEquals("defaultValue", LocalSettings.configurations(service,
type, key, defaultValue));
+ }
+
+ @Test
+ public void testHosts() {
+ String componentName = "componentA";
+
+ Map<String, List<String>> hostJson = new HashMap<>();
+ hostJson.put(componentName, List.of("host1", "host2"));
+
+ File file = mock(File.class);
+
localSettingsMockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn("/mock/path/");
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.createFile(anyString()))
+ .thenReturn(file);
+ when(file.exists()).thenReturn(true);
+ localSettingsMockedStatic
+ .when(() -> JsonUtils.readFromFile(any(File.class),
any(TypeReference.class)))
+ .thenReturn(hostJson);
+ localSettingsMockedStatic.when(() ->
LocalSettings.hosts(anyString())).thenCallRealMethod();
+
localSettingsMockedStatic.when(LocalSettings::hosts).thenCallRealMethod();
+
+ List<String> expectedHosts = List.of("host1", "host2");
+ assertEquals(expectedHosts, LocalSettings.hosts(componentName));
+ }
+
+ @Test
+ public void testBasicInfo() {
+ Map<String, Object> settingsData = new HashMap<>();
+ settingsData.put("key1", "value1");
+
+ File file = mock(File.class);
+
localSettingsMockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn("/mock/path/");
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.createFile(anyString()))
+ .thenReturn(file);
+ when(file.exists()).thenReturn(true);
+ localSettingsMockedStatic
+ .when(() -> JsonUtils.readFromFile(any(File.class),
any(TypeReference.class)))
+ .thenReturn(settingsData);
+
localSettingsMockedStatic.when(LocalSettings::basicInfo).thenCallRealMethod();
+
+ Map<String, Object> expectedSettings = new HashMap<>();
+ expectedSettings.put("key1", "value1");
+ assertEquals(expectedSettings, LocalSettings.basicInfo());
+ }
+
+ @Test
+ public void testUsers() {
+ Map<String, String> userMap = new HashMap<>();
+ userMap.put("user1", "password1");
+
+ File file = mock(File.class);
+
localSettingsMockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn("/mock/path/");
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.createFile(anyString()))
+ .thenReturn(file);
+ when(file.exists()).thenReturn(true);
+ localSettingsMockedStatic
+ .when(() -> JsonUtils.readFromFile(any(File.class),
any(TypeReference.class)))
+ .thenReturn(userMap);
+
localSettingsMockedStatic.when(LocalSettings::users).thenCallRealMethod();
+
+ Map<String, String> expectedUserMap = new HashMap<>();
+ expectedUserMap.put("user1", "password1");
+ assertEquals(expectedUserMap, LocalSettings.users());
+ }
+
+ @Test
+ public void testRepos() {
+ RepoInfo repo1 = new RepoInfo("repo1", "x86_64", "http://repo1.com",
1);
+ RepoInfo repo2 = new RepoInfo("repo2", "arch64", "http://repo2.com",
2);
+ List<RepoInfo> repoInfoList = List.of(repo1, repo2);
+
+ File file = mock(File.class);
+
localSettingsMockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn("/mock/path/");
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.createFile(anyString()))
+ .thenReturn(file);
+ when(file.exists()).thenReturn(true);
+ localSettingsMockedStatic
+ .when(() -> JsonUtils.readFromFile(any(File.class),
any(TypeReference.class)))
+ .thenReturn(repoInfoList);
+
localSettingsMockedStatic.when(LocalSettings::repos).thenCallRealMethod();
+
+ List<RepoInfo> expectedRepoInfoList = List.of(
+ new RepoInfo("repo1", "x86_64", "http://repo1.com", 1),
+ new RepoInfo("repo2", "arch64", "http://repo2.com", 2));
+ assertEquals(expectedRepoInfoList, LocalSettings.repos());
+ }
+
+ @Test
+ public void testCluster() {
+ ClusterInfo clusterInfo = new ClusterInfo();
+ clusterInfo.setName("Test Cluster");
+
+ File file = mock(File.class);
+
localSettingsMockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn("/mock/path/");
+ localSettingsMockedStatic
+ .when(() -> LocalSettings.createFile(anyString()))
+ .thenReturn(file);
+ when(file.exists()).thenReturn(true);
+ localSettingsMockedStatic
+ .when(() -> JsonUtils.readFromFile(any(File.class),
any(TypeReference.class)))
+ .thenReturn(clusterInfo);
+
localSettingsMockedStatic.when(LocalSettings::cluster).thenCallRealMethod();
+
+ ClusterInfo expectedClusterInfo = new ClusterInfo();
+ expectedClusterInfo.setName("Test Cluster");
+ assertEquals(expectedClusterInfo, LocalSettings.cluster());
+ }
+
+ @Test
+ public void testPackages() {
+ List<String> expectedPackages = List.of();
+ assertEquals(expectedPackages, LocalSettings.packages());
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/PackageUtilsTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/PackageUtilsTest.java
new file mode 100644
index 00000000..18565cde
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/PackageUtilsTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.utils;
+
+import org.apache.bigtop.manager.common.shell.ShellResult;
+import org.apache.bigtop.manager.stack.core.spi.repo.YumPackageManager;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+public class PackageUtilsTest {
+
+ @Mock
+ private YumPackageManager yumPackageManager;
+
+ private MockedStatic<PackageUtils> packageUtilsMockedStatic;
+
+ @BeforeEach
+ public void setUp() {
+ packageUtilsMockedStatic = mockStatic(PackageUtils.class);
+
packageUtilsMockedStatic.when(PackageUtils::getPackageManager).thenReturn(yumPackageManager);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ packageUtilsMockedStatic.close();
+ }
+
+ @Test
+ public void testInstall() {
+ packageUtilsMockedStatic.when(() ->
PackageUtils.install(any())).thenCallRealMethod();
+
+ ShellResult expectedResult = new ShellResult();
+ expectedResult.setExitCode(0);
+ expectedResult.setErrMsg("Installation successful");
+
+
when(yumPackageManager.installPackage(any())).thenReturn(expectedResult);
+
+ ShellResult result = PackageUtils.install(Arrays.asList("package1",
"package2"));
+
+ assertEquals(0, result.getExitCode());
+ assertEquals("Installation successful", result.getErrMsg());
+
+ verify(yumPackageManager, times(1)).installPackage(any());
+ }
+
+ @Test
+ public void testInstallWithEmptyPackageList() {
+ packageUtilsMockedStatic.when(() ->
PackageUtils.install(any())).thenCallRealMethod();
+
+ ShellResult result = PackageUtils.install(Collections.emptyList());
+
+ assertEquals(-1, result.getExitCode());
+ assertEquals("packageList is empty", result.getErrMsg());
+
+ verify(yumPackageManager, never()).installPackage(any());
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/PropertiesUtilsTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/PropertiesUtilsTest.java
new file mode 100644
index 00000000..f411b113
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/PropertiesUtilsTest.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.utils;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class PropertiesUtilsTest {
+
+ private File testFile;
+
+ @BeforeEach
+ public void setUp() throws IOException {
+ testFile = File.createTempFile("test", ".properties");
+ }
+
+ @AfterEach
+ public void tearDown() {
+ if (testFile != null) {
+ testFile.delete();
+ }
+ }
+
+ @Test
+ public void testWritePropertiesWithMap() throws IOException {
+ Map<String, Object> configMap = new HashMap<>();
+ configMap.put("key1", "value1");
+ configMap.put("key2", "value2");
+
+ PropertiesUtils.writeProperties(testFile.getAbsolutePath(), configMap);
+
+ Properties properties = new Properties();
+ properties.load(new FileReader(testFile, StandardCharsets.UTF_8));
+
+ assertEquals("value1", properties.getProperty("key1"));
+ assertEquals("value2", properties.getProperty("key2"));
+ }
+
+ @Test
+ public void testWritePropertiesWithList() throws IOException {
+ Map<String, Object> map1 = new HashMap<>();
+ map1.put("name", "key1");
+ map1.put("value", "value1");
+
+ Map<String, Object> map2 = new HashMap<>();
+ map2.put("name", "key2");
+ map2.put("value", "value2");
+
+ List<Map<String, Object>> configList = List.of(map1, map2);
+
+ PropertiesUtils.writeProperties(testFile.getAbsolutePath(),
configList);
+
+ Properties properties = new Properties();
+ properties.load(new FileReader(testFile, StandardCharsets.UTF_8));
+
+ assertEquals("value1", properties.getProperty("key1"));
+ assertEquals("value2", properties.getProperty("key2"));
+ }
+
+ @Test
+ public void testReadProperties() {
+ Map<String, Object> configMap = new HashMap<>();
+ configMap.put("key1", "value1");
+ configMap.put("key2", "value2");
+
+ PropertiesUtils.writeProperties(testFile.getAbsolutePath(), configMap);
+
+ Map<Object, Object> properties =
PropertiesUtils.readProperties(testFile.getAbsolutePath());
+
+ assertEquals("value1", properties.get("key1"));
+ assertEquals("value2", properties.get("key2"));
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxAccountUtilsTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxAccountUtilsTest.java
new file mode 100644
index 00000000..96dcf7ce
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxAccountUtilsTest.java
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.utils.linux;
+
+import org.apache.bigtop.manager.common.shell.ShellResult;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockedStatic;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.isNull;
+import static org.mockito.Mockito.mockStatic;
+
+public class LinuxAccountUtilsTest {
+
+ private MockedStatic<LinuxAccountUtils> mockStatic;
+
+ @BeforeEach
+ public void setUp() {
+ mockStatic = mockStatic(LinuxAccountUtils.class);
+
+ // Mock sudoExecCmd method to simulate successful command execution
+ mockStatic.when(() ->
LinuxAccountUtils.sudoExecCmd(anyList())).thenAnswer(invocation -> {
+ List<String> cmd = invocation.getArgument(0);
+ return ShellResult.success(cmd.toString());
+ });
+
+ // Mock isUserExists and isGroupExists methods to return false by
default
+ mockStatic.when(() ->
LinuxAccountUtils.isUserExists(anyString())).thenReturn(false);
+ mockStatic.when(() ->
LinuxAccountUtils.isGroupExists(anyString())).thenReturn(false);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ mockStatic.close();
+ }
+
+ @Test
+ public void testUserDel() {
+ String user = "testUser";
+
+ // Mock isUserExists to return true for the test user
+ mockStatic.when(() ->
LinuxAccountUtils.isUserExists(user)).thenReturn(true);
+ mockStatic.when(() ->
LinuxAccountUtils.userDel(anyString())).thenCallRealMethod();
+
+ // Capture the arguments passed to sudoExecCmd
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+
+ // Call the method under test
+ LinuxAccountUtils.userDel(user);
+
+ // Verify that sudoExecCmd was called and capture the arguments
+ mockStatic.verify(() ->
LinuxAccountUtils.sudoExecCmd(captor.capture()));
+
+ // Get the captured arguments and perform assertions
+ List<String> builderParameters = captor.getValue();
+ assertNotNull(builderParameters);
+ assertEquals(2, builderParameters.size());
+ assertTrue(builderParameters.contains("/usr/sbin/userdel"));
+ assertTrue(builderParameters.contains(user));
+ }
+
+ @Test
+ public void testUserAdd() {
+ String user = "testUser";
+ String group = "testGroup";
+
+ // Mock isGroupExists to return true for the test group
+ mockStatic.when(() ->
LinuxAccountUtils.isGroupExists(group)).thenReturn(true);
+ mockStatic
+ .when(() -> LinuxAccountUtils.userAdd(anyString(),
anyString()))
+ .thenCallRealMethod();
+ mockStatic
+ .when(() -> LinuxAccountUtils.userAdd(
+ anyString(), anyString(), isNull(), isNull(),
isNull(), isNull(), isNull(), eq(false)))
+ .thenCallRealMethod();
+
+ // Capture the arguments passed to sudoExecCmd
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+
+ // Call the method under test
+ LinuxAccountUtils.userAdd(user, group);
+
+ // Verify that sudoExecCmd was called and capture the arguments
+ mockStatic.verify(() ->
LinuxAccountUtils.sudoExecCmd(captor.capture()));
+
+ // Get the captured arguments and perform assertions
+ List<String> builderParameters = captor.getValue();
+ assertNotNull(builderParameters);
+ assertTrue(builderParameters.contains("/usr/sbin/useradd"));
+ assertTrue(builderParameters.contains("-m"));
+ assertTrue(builderParameters.contains("-g"));
+ assertTrue(builderParameters.contains(group));
+ assertTrue(builderParameters.contains(user));
+ }
+
+ @Test
+ public void testGroupDel() {
+ String group = "testGroup";
+
+ // Mock isGroupExists to return true for the test group
+ mockStatic.when(() ->
LinuxAccountUtils.isGroupExists(group)).thenReturn(true);
+ mockStatic.when(() ->
LinuxAccountUtils.groupDel(anyString())).thenCallRealMethod();
+
+ // Capture the arguments passed to sudoExecCmd
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+
+ // Call the method under test
+ LinuxAccountUtils.groupDel(group);
+
+ // Verify that sudoExecCmd was called and capture the arguments
+ mockStatic.verify(() ->
LinuxAccountUtils.sudoExecCmd(captor.capture()));
+
+ // Get the captured arguments and perform assertions
+ List<String> builderParameters = captor.getValue();
+ assertNotNull(builderParameters);
+ assertEquals(2, builderParameters.size());
+ assertTrue(builderParameters.contains("/usr/sbin/groupdel"));
+ assertTrue(builderParameters.contains(group));
+ }
+
+ @Test
+ public void testGroupAdd() {
+ String group = "testGroup";
+
+ // Mock isGroupExists to return false, so groupAdd will be called
+ mockStatic.when(() ->
LinuxAccountUtils.isGroupExists(group)).thenReturn(false);
+ mockStatic.when(() ->
LinuxAccountUtils.groupAdd(anyString())).thenCallRealMethod();
+ mockStatic
+ .when(() -> LinuxAccountUtils.groupAdd(anyString(), isNull(),
isNull()))
+ .thenCallRealMethod();
+
+ // Capture the arguments passed to sudoExecCmd
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+
+ // Call the method under test
+ LinuxAccountUtils.groupAdd(group);
+
+ // Verify that sudoExecCmd was called and capture the arguments
+ mockStatic.verify(() ->
LinuxAccountUtils.sudoExecCmd(captor.capture()));
+
+ // Get the captured arguments and perform assertions
+ List<String> builderParameters = captor.getValue();
+ assertNotNull(builderParameters);
+ assertEquals(2, builderParameters.size());
+ assertTrue(builderParameters.contains("/usr/sbin/groupadd"));
+ assertTrue(builderParameters.contains(group));
+ }
+
+ @Test
+ public void testIsUserExists() throws IOException {
+ String user = "testUser";
+
+ // Mock sudoExecCmd to simulate successful user existence check
+ mockStatic.when(() ->
LinuxAccountUtils.isUserExists(user)).thenCallRealMethod();
+ mockStatic.when(() ->
LinuxAccountUtils.sudoExecCmd(anyList())).thenReturn(new ShellResult(0, "",
""));
+
+ // Call the method under test
+ boolean exists = LinuxAccountUtils.isUserExists(user);
+
+ // Perform assertions
+ assertTrue(exists);
+
+ // Capture the arguments passed to sudoExecCmd
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+ mockStatic.verify(() ->
LinuxAccountUtils.sudoExecCmd(captor.capture()));
+
+ // Get the captured arguments and perform assertions
+ List<String> builderParameters = captor.getValue();
+ assertNotNull(builderParameters);
+ assertTrue(builderParameters.contains("sh"));
+ assertTrue(builderParameters.contains("-c"));
+ assertTrue(builderParameters.get(2).contains("grep"));
+ }
+
+ @Test
+ public void testIsGroupExists() throws IOException {
+ String group = "testGroup";
+
+ // Mock sudoExecCmd to simulate successful group existence check
+ mockStatic.when(() ->
LinuxAccountUtils.isGroupExists(group)).thenCallRealMethod();
+ mockStatic.when(() ->
LinuxAccountUtils.sudoExecCmd(anyList())).thenReturn(new ShellResult(0, "",
""));
+
+ // Call the method under test
+ boolean exists = LinuxAccountUtils.isGroupExists(group);
+
+ // Perform assertions
+ assertTrue(exists);
+
+ // Capture the arguments passed to sudoExecCmd
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+ mockStatic.verify(() ->
LinuxAccountUtils.sudoExecCmd(captor.capture()));
+
+ // Get the captured arguments and perform assertions
+ List<String> builderParameters = captor.getValue();
+ assertNotNull(builderParameters);
+ assertTrue(builderParameters.contains("sh"));
+ assertTrue(builderParameters.contains("-c"));
+ assertTrue(builderParameters.get(2).contains("grep"));
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxOSUtilsTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxOSUtilsTest.java
new file mode 100644
index 00000000..051cff20
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/linux/LinuxOSUtilsTest.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.utils.linux;
+
+import org.apache.bigtop.manager.common.shell.ShellExecutor;
+import org.apache.bigtop.manager.common.shell.ShellResult;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockedStatic;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.Mockito.mockStatic;
+
+public class LinuxOSUtilsTest {
+
+ private MockedStatic<LinuxAccountUtils> mockLinuxAccountUtils;
+ private MockedStatic<ShellExecutor> mockShellExecutor;
+
+ @BeforeEach
+ public void setUp() {
+ mockLinuxAccountUtils = mockStatic(LinuxAccountUtils.class);
+ mockShellExecutor = mockStatic(ShellExecutor.class);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ mockLinuxAccountUtils.close();
+ mockShellExecutor.close();
+ }
+
+ @Test
+ public void testSudoExecCmdWithTenant() throws IOException {
+ String command = "echo Hello";
+ String tenant = "testUser";
+
+ // Mock the behavior of execCmd method
+ mockLinuxAccountUtils.when(() ->
LinuxAccountUtils.isUserExists(tenant)).thenReturn(true);
+ mockShellExecutor.when(() ->
ShellExecutor.execCommand(anyList())).thenReturn(new ShellResult(0, "Hello",
""));
+
+ // Call the method under test
+ ShellResult result = LinuxOSUtils.sudoExecCmd(command, tenant);
+
+ // Capture the arguments passed to ShellExecutor.execCommand
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+ mockShellExecutor.verify(() ->
ShellExecutor.execCommand(captor.capture()));
+
+ // Assert the result
+ assertNotNull(result);
+ assertEquals(0, result.getExitCode());
+ assertTrue(result.getOutput().contains("Hello"));
+
+ // Assert that sudoExecCmd passes the correct parameters
+ List<String> commandArgs = captor.getValue();
+ assertTrue(commandArgs.contains("sudo"));
+ assertTrue(commandArgs.contains("-u"));
+ assertTrue(commandArgs.contains(tenant));
+ assertTrue(commandArgs.contains("sh"));
+ assertTrue(commandArgs.contains("-c"));
+ assertTrue(commandArgs.contains(command));
+ }
+
+ @Test
+ public void testSudoExecCmdWithoutTenant() throws IOException {
+ String command = "echo Hello";
+
+ // Mock the behavior of execCmd method
+ mockShellExecutor.when(() ->
ShellExecutor.execCommand(anyList())).thenReturn(new ShellResult(0, "Hello",
""));
+
+ // Call the method under test with null tenant
+ ShellResult result = LinuxOSUtils.sudoExecCmd(command, null);
+
+ // Capture the arguments passed to ShellExecutor.execCommand
+ ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+ mockShellExecutor.verify(() ->
ShellExecutor.execCommand(captor.capture()));
+
+ // Assert the result
+ assertNotNull(result);
+ assertEquals(0, result.getExitCode());
+ assertTrue(result.getOutput().contains("Hello"));
+
+ // Assert that sudoExecCmd passes "root" as the tenant when tenant is
null
+ List<String> commandArgs = captor.getValue();
+ assertTrue(commandArgs.contains("sudo"));
+ assertTrue(commandArgs.contains("-u"));
+ assertTrue(commandArgs.contains("root"));
+ assertTrue(commandArgs.contains("sh"));
+ assertTrue(commandArgs.contains("-c"));
+ assertTrue(commandArgs.contains(command));
+ }
+
+ @Test
+ public void testGetTenantWithExistingUser() {
+ String tenant = "testUser";
+
+ // Mock the isUserExists method to return true for the test user
+ mockLinuxAccountUtils.when(() ->
LinuxAccountUtils.isUserExists(tenant)).thenReturn(true);
+
+ // Call the method under test
+ String result = LinuxOSUtils.getTenant(tenant);
+
+ // Assert that the correct tenant is returned
+ assertEquals(tenant, result);
+ }
+
+ @Test
+ public void testGetTenantWithNonExistingUser() {
+ String tenant = "nonExistentUser";
+
+ // Mock the isUserExists method to return false for the non-existent
user
+ mockLinuxAccountUtils.when(() ->
LinuxAccountUtils.isUserExists(tenant)).thenReturn(false);
+
+ // Call the method under test
+ String result = LinuxOSUtils.getTenant(tenant);
+
+ // Assert that "root" is returned as the default tenant
+ assertEquals("root", result);
+ }
+
+ @Test
+ public void testCheckProcessWhenPidFileDoesNotExist() {
+ String filepath = "/path/to/pidfile";
+
+ // Mock the behavior of the file check
+ mockShellExecutor.when(() ->
LinuxFileUtils.readFile(filepath)).thenThrow(IOException.class);
+
+ // Call the method under test
+ ShellResult result = LinuxOSUtils.checkProcess(filepath);
+
+ // Assert that the process is not running
+ assertEquals(-1, result.getExitCode());
+ assertTrue(result.getErrMsg().contains("Component is not running"));
+ }
+
+ @Test
+ public void testExecCmd() throws IOException {
+ String command = "echo Hello";
+
+ // Mock the behavior of execCmd method
+ mockShellExecutor.when(() ->
ShellExecutor.execCommand(anyList())).thenReturn(new ShellResult(0, "Hello",
""));
+
+ // Call the method under test
+ ShellResult result = LinuxOSUtils.execCmd(command);
+
+ // Assert the result
+ assertNotNull(result);
+ assertEquals(0, result.getExitCode());
+ assertTrue(result.getOutput().contains("Hello"));
+ }
+}
diff --git
a/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/template/TemplateUtilsTest.java
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/template/TemplateUtilsTest.java
new file mode 100644
index 00000000..80c263b4
--- /dev/null
+++
b/bigtop-manager-stack/bigtop-manager-stack-core/src/test/java/org/apache/bigtop/manager/stack/core/utils/template/TemplateUtilsTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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 org.apache.bigtop.manager.stack.core.utils.template;
+
+import org.apache.bigtop.manager.stack.core.enums.ConfigType;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.MockedStatic;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.times;
+
+@ExtendWith(MockitoExtension.class)
+public class TemplateUtilsTest {
+
+ private MockedStatic<BaseTemplate> baseTemplateMockedStatic;
+
+ @BeforeEach
+ public void setUp() {
+ baseTemplateMockedStatic = mockStatic(BaseTemplate.class);
+ baseTemplateMockedStatic
+ .when(() -> BaseTemplate.writeTemplate(anyString(), any(),
anyString()))
+ .thenAnswer(invocation -> null);
+ baseTemplateMockedStatic
+ .when(() -> BaseTemplate.writeTemplateAsString(any(),
anyString()))
+ .thenAnswer(invocation -> null);
+ baseTemplateMockedStatic
+ .when(() -> BaseTemplate.writeCustomTemplate(anyString(),
any(), anyString()))
+ .thenAnswer(invocation -> null);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ baseTemplateMockedStatic.close();
+ }
+
+ @Test
+ public void testMap2TemplateWithoutParamMap() {
+ ConfigType configType = ConfigType.UNKNOWN;
+ String fileName = "fileName";
+ Map<String, Object> configMap = new HashMap<>();
+
+ TemplateUtils.map2Template(configType, fileName, configMap, null);
+ baseTemplateMockedStatic.verify(() ->
BaseTemplate.writeTemplate(eq(fileName), any(), anyString()), times(1));
+ }
+
+ @Test
+ public void testMap2TemplateWithParamMap() {
+ ConfigType configType = ConfigType.UNKNOWN;
+ String fileName = "fileName";
+ Map<String, Object> configMap = new HashMap<>();
+ Map<String, Object> paramMap = new HashMap<>();
+
+ TemplateUtils.map2Template(configType, fileName, configMap, paramMap);
+ baseTemplateMockedStatic.verify(() ->
BaseTemplate.writeTemplateAsString(any(), anyString()), times(1));
+ baseTemplateMockedStatic.verify(() ->
BaseTemplate.writeCustomTemplate(eq(fileName), any(), any()), times(1));
+ }
+
+ @Test
+ public void testMap2CustomTemplateWithoutParamMap() {
+ String template = "template";
+ String fileName = "fileName";
+ Map<String, Object> configMap = new HashMap<>();
+
+ TemplateUtils.map2CustomTemplate(template, fileName, configMap, null);
+ baseTemplateMockedStatic.verify(
+ () -> BaseTemplate.writeCustomTemplate(eq(fileName),
eq(configMap), any()), times(1));
+ }
+
+ @Test
+ public void testMap2CustomTemplateWithParamMap() {
+ String template = "template";
+ String fileName = "fileName";
+ Map<String, Object> configMap = new HashMap<>();
+ Map<String, Object> paramMap = new HashMap<>();
+
+ TemplateUtils.map2CustomTemplate(template, fileName, configMap,
paramMap);
+ baseTemplateMockedStatic.verify(
+ () -> BaseTemplate.writeCustomTemplateAsString(eq(configMap),
eq(template)), times(1));
+ baseTemplateMockedStatic.verify(
+ () -> BaseTemplate.writeCustomTemplate(eq(fileName),
eq(paramMap), any()), times(1));
+ }
+}