From fad382eaec8762b8c370563e992e85833b6ff53f Mon Sep 17 00:00:00 2001 From: huangguojie2024 <503601315@qq.com> Date: Sat, 18 Jan 2025 13:10:56 +0800 Subject: [PATCH 1/3] Add some unit tests for agent module --- .../agent/service/CommandServiceGrpcImpl.java | 2 +- .../agent/holder/SpringContextHolderTest.java | 72 ++++++ .../monitoring/AgentHostMonitoringTest.java | 216 ++++++++++++++++++ .../service/CommandServiceGrpcImplTest.java | 205 +++++++++++++++++ .../ComponentStatusServiceGrpcImplTest.java | 115 ++++++++++ .../service/HostInfoServiceGrpcImplTest.java | 117 ++++++++++ .../service/JobCacheServiceGrpcImplTest.java | 101 ++++++++ 7 files changed, 827 insertions(+), 1 deletion(-) create mode 100644 bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java create mode 100644 bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java create mode 100644 bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java create mode 100644 bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java create mode 100644 bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java create mode 100644 bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.java diff --git a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImpl.java b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImpl.java index 920e418b..6bff53ca 100644 --- a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImpl.java +++ b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImpl.java @@ -63,7 +63,7 @@ public void exec(CommandRequest request, StreamObserver responseOb } } - private void truncateLogFile(Long taskId) { + protected void truncateLogFile(Long taskId) { String filePath = ProjectPathUtils.getLogFilePath(taskId); File file = new File(filePath); if (file.exists()) { diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java new file mode 100644 index 00000000..f4b1d737 --- /dev/null +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java @@ -0,0 +1,72 @@ +/* + * 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.agent.holder; + +import org.apache.bigtop.manager.agent.executor.CommandExecutor; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.context.ApplicationContext; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +public class SpringContextHolderTest { + + @Mock + private ApplicationContext mockApplicationContext; + + @Mock + private CommandExecutor mockCommandExecutor; + + @BeforeEach + public void setUp() throws Exception { + MockitoAnnotations.openMocks(this); + + // Use reflection to set the static variable applicationContext + Field field = SpringContextHolder.class.getDeclaredField("applicationContext"); + field.setAccessible(true); + field.set(null, mockApplicationContext); + } + + @Test + public void testGetCommandExecutors() { + // Prepare test data + Map commandExecutorsMap = new HashMap<>(); + commandExecutorsMap.put("commandExecutor1", mockCommandExecutor); + when(mockApplicationContext.getBeansOfType(CommandExecutor.class)).thenReturn(commandExecutorsMap); + + // Execute the method under test + Map result = SpringContextHolder.getCommandExecutors(); + + // Validate the result + assertNotNull(result); + assertEquals(1, result.size()); + assertTrue(result.containsKey("commandExecutor1")); + assertSame(mockCommandExecutor, result.get("commandExecutor1")); + + // Verify method calls + verify(mockApplicationContext, times(1)).getBeansOfType(CommandExecutor.class); + } +} diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java new file mode 100644 index 00000000..d482315b --- /dev/null +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java @@ -0,0 +1,216 @@ +/* + * 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.agent.monitoring; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.micrometer.core.instrument.MultiGauge; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import oshi.SystemInfo; +import oshi.hardware.GlobalMemory; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.software.os.OperatingSystem; + +import java.net.UnknownHostException; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class AgentHostMonitoringTest { + + @Mock + private SystemInfo systemInfo; + + @Mock + private HardwareAbstractionLayer hardwareAbstractionLayer; + + @Mock + private GlobalMemory globalMemory; + + + @Mock + private MultiGauge diskMultiGauge; + + @Mock + private MultiGauge memMultiGauge; + + @Mock + private MultiGauge cpuMultiGauge; + + @Mock + private MultiGauge diskIOMultiGauge; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + when(systemInfo.getOperatingSystem()).thenReturn(mock(OperatingSystem.class)); + when(systemInfo.getHardware()).thenReturn(hardwareAbstractionLayer); + when(hardwareAbstractionLayer.getMemory()).thenReturn(globalMemory); + when(globalMemory.getAvailable()).thenReturn(100000L); + when(globalMemory.getTotal()).thenReturn(200000L); + } + + @Test + void testGetHostInfo() throws UnknownHostException { + JsonNode hostInfo = AgentHostMonitoring.getHostInfo(); + + // Check if the host information contains expected fields + assertTrue(hostInfo.has(AgentHostMonitoring.AGENT_BASE_INFO)); + assertTrue(hostInfo.has(AgentHostMonitoring.BOOT_TIME)); + assertTrue(hostInfo.has(AgentHostMonitoring.MEM_IDLE)); + assertTrue(hostInfo.has(AgentHostMonitoring.MEM_TOTAL)); + } + + @Test + void testGetDiskGauge() { + // Create a mock JsonNode object + JsonNode agentMonitoring = mock(JsonNode.class); + + // Create a mock agentHostInfo object and set its fields + ObjectNode agentHostInfo = mock(ObjectNode.class); + when(agentMonitoring.get(AgentHostMonitoring.AGENT_BASE_INFO)).thenReturn(agentHostInfo); + when(agentHostInfo.fieldNames()).thenReturn(Collections.emptyIterator()); + + // Create a mock disksBaseInfo object and set its fields + ArrayNode disksBaseInfo = mock(ArrayNode.class); + when(agentMonitoring.get(AgentHostMonitoring.DISKS_BASE_INFO)).thenReturn(disksBaseInfo); + + // Create a mock diskJsonNode object and set its fields + ObjectNode diskJsonNode = mock(ObjectNode.class); + when(disksBaseInfo.get(0)).thenReturn(diskJsonNode); + when(diskJsonNode.get(AgentHostMonitoring.DISK_NAME)).thenReturn(mock(JsonNode.class)); + when(diskJsonNode.get(AgentHostMonitoring.DISK_IDLE)).thenReturn(mock(JsonNode.class)); + when(diskJsonNode.get(AgentHostMonitoring.DISK_TOTAL)).thenReturn(mock(JsonNode.class)); + when(diskJsonNode.get(AgentHostMonitoring.DISK_NAME).asText()).thenReturn("disk1"); + when(diskJsonNode.get(AgentHostMonitoring.DISK_IDLE).asDouble()).thenReturn(0.9); + when(diskJsonNode.get(AgentHostMonitoring.DISK_TOTAL).asDouble()).thenReturn(100.0); + + // Call the getDiskGauge method + Map, Map, Double>> diskGauge = AgentHostMonitoring.getDiskGauge(agentMonitoring); + + // Assert that the disk gauge data is populated correctly + assertNotNull(diskGauge); + assertFalse(diskGauge.isEmpty()); + } + + @Test + void testGetCPUGauge() { + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode agentMonitoring = objectMapper.createObjectNode(); + ObjectNode agentHostInfo = objectMapper.createObjectNode(); + + // Set AGENT_BASE_INFO fields + agentHostInfo.put("field1", "value1"); + agentHostInfo.put("field2", "value2"); + agentMonitoring.set(AgentHostMonitoring.AGENT_BASE_INFO, agentHostInfo); + + // Set CPU related fields + agentMonitoring + .put(AgentHostMonitoring.CPU_LOAD_AVG_MIN_1, 1.0) + .put(AgentHostMonitoring.CPU_LOAD_AVG_MIN_5, 5.0) + .put(AgentHostMonitoring.CPU_LOAD_AVG_MIN_15, 15.0) + .put(AgentHostMonitoring.CPU_USAGE, 10.0); + + Map, Map, Double>> cpuGauge = AgentHostMonitoring.getCPUGauge(agentMonitoring); + + // Assert that the CPU gauge data is populated correctly + assertNotNull(cpuGauge); + assertFalse(cpuGauge.isEmpty()); + } + + @Test + void testGetMEMGauge() { + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode agentMonitoring = objectMapper.createObjectNode(); + ObjectNode agentHostInfo = objectMapper.createObjectNode(); + + // Set AGENT_BASE_INFO fields + agentHostInfo.put("field1", "value1"); + agentHostInfo.put("field2", "value2"); + agentMonitoring.set(AgentHostMonitoring.AGENT_BASE_INFO, agentHostInfo); + + // Set MEM related fields + agentMonitoring + .put(AgentHostMonitoring.MEM_IDLE, 2000.0) + .put(AgentHostMonitoring.MEM_TOTAL, 4000.0); + + Map, Map, Double>> memGauge = AgentHostMonitoring.getMEMGauge(agentMonitoring); + + // Assert that the MEM gauge data is populated correctly + assertNotNull(memGauge); + assertFalse(memGauge.isEmpty()); + } + + + @Test + void testMultiGaugeUpdateData() { + // Create a mock Map object + Map, Map, Double>> diskGauge = new HashMap<>(); + Map, Double> innerMap = new HashMap<>(); + innerMap.put(new ArrayList<>(Arrays.asList("label1", "label2")), 1.0); + diskGauge.put(new ArrayList<>(Arrays.asList("label1", "label2")), innerMap); + + // Create a mock MultiGauge object + MultiGauge diskMultiGauge = mock(MultiGauge.class); + + // Call the test method + AgentHostMonitoring.multiGaugeUpdateData(diskMultiGauge, diskGauge); + + // Verify that the register method is called once + verify(diskMultiGauge, times(1)).register(anyList(), eq(true)); + } + + @Test + void testDiskMultiGaugeUpdateData() { + AgentHostMonitoring.diskMultiGaugeUpdateData(diskMultiGauge); + + // Verify that the multi-gauge update method was called + verify(diskMultiGauge, times(1)).register(anyList(), eq(true)); + } + + @Test + void testMemMultiGaugeUpdateData() { + AgentHostMonitoring.memMultiGaugeUpdateData(memMultiGauge); + + // Verify that the multi-gauge update method was called + verify(memMultiGauge, times(1)).register(anyList(), eq(true)); + } + + @Test + void testCpuMultiGaugeUpdateData() { + AgentHostMonitoring.cpuMultiGaugeUpdateData(cpuMultiGauge); + + // Verify that the multi-gauge update method was called + verify(cpuMultiGauge, times(1)).register(anyList(), eq(true)); + } + + @Test + void testDiskIOMultiGaugeUpdateData() { + AgentHostMonitoring.diskIOMultiGaugeUpdateData(diskIOMultiGauge); + + // Verify that the multi-gauge update method was called + verify(diskIOMultiGauge, times(1)).register(anyList(), eq(true)); + } +} diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java new file mode 100644 index 00000000..2f93af86 --- /dev/null +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java @@ -0,0 +1,205 @@ +/* + * 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.agent.service; + +import io.grpc.StatusRuntimeException; +import io.grpc.stub.StreamObserver; +import org.apache.bigtop.manager.agent.executor.CommandExecutor; +import org.apache.bigtop.manager.agent.executor.CommandExecutors; +import org.apache.bigtop.manager.agent.holder.SpringContextHolder; +import org.apache.bigtop.manager.grpc.generated.CommandReply; +import org.apache.bigtop.manager.grpc.generated.CommandRequest; +import org.apache.bigtop.manager.grpc.generated.CommandType; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.context.ApplicationContext; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + + +@ExtendWith(MockitoExtension.class) +public class CommandServiceGrpcImplTest { + + + private CommandServiceGrpcImpl commandServiceGrpc; + + @BeforeEach + public void setUp() { + SpringContextHolder springContextHolder = new SpringContextHolder(); + ApplicationContext mockApplicationContext = mock(ApplicationContext.class); + + CommandExecutor mockExecutor = mock(CommandExecutor.class); + when(mockApplicationContext.getBeansOfType(CommandExecutor.class)) + .thenReturn(Map.of("mockExecutor", mockExecutor)); + + springContextHolder.setApplicationContext(mockApplicationContext); + + // Initialize CommandServiceGrpcImpl + commandServiceGrpc = new CommandServiceGrpcImpl(); + } + + @Test + public void testExecCommand() { + // Arrange + CommandRequest request = CommandRequest.newBuilder() + .setPayload("Test Payload") + .setTaskId(1L) + .setType(CommandType.COMPONENT) + .build(); + + CommandReply expectedReply = CommandReply.newBuilder() + .setCode(0) + .setResult("Success") + .setTaskId(1L) + .build(); + + CommandExecutor mockExecutor = mock(CommandExecutor.class); + when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)).thenReturn(mockExecutor); + when(mockExecutor.execute(request)).thenReturn(expectedReply); + + StreamObserver responseObserver = mock(StreamObserver.class); + ArgumentCaptor captor = ArgumentCaptor.forClass(CommandReply.class); + + // Act + commandServiceGrpc.exec(request, responseObserver); + + // Assert + verify(responseObserver).onNext(captor.capture()); + verify(responseObserver).onCompleted(); + + CommandReply actualReply = captor.getValue(); + assertEquals(expectedReply.getCode(), actualReply.getCode()); + assertEquals(expectedReply.getResult(), actualReply.getResult()); + assertEquals(expectedReply.getTaskId(), actualReply.getTaskId()); + } + + @Test + public void testExecCommandExecutorThrowsException() { + // Arrange + CommandRequest request = CommandRequest.newBuilder() + .setPayload("Test Payload") + .setTaskId(1L) + .setType(CommandType.COMPONENT) + .build(); + + when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)) + .thenThrow(new RuntimeException("Executor not found")); + + StreamObserver responseObserver = mock(StreamObserver.class); + + // Act + commandServiceGrpc.exec(request, responseObserver); + + // Assert + verify(responseObserver).onError(any(RuntimeException.class)); + } + + @Test + public void testExecCommandExecutionThrowsException() { + // Arrange + CommandRequest request = CommandRequest.newBuilder() + .setPayload("Test Payload") + .setTaskId(1L) + .setType(CommandType.COMPONENT) + .build(); + + CommandExecutor mockExecutor = mock(CommandExecutor.class); + when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)).thenReturn(mockExecutor); + when(mockExecutor.execute(request)).thenThrow(new RuntimeException("Execution failed")); + + StreamObserver responseObserver = mock(StreamObserver.class); + + // Act + commandServiceGrpc.exec(request, responseObserver); + + // Assert + verify(responseObserver).onError(any(RuntimeException.class)); + } + + @Test + public void testExecCommandLogFileOperationFails() { + // Arrange + CommandRequest request = CommandRequest.newBuilder() + .setPayload("Test Payload") + .setTaskId(1L) + .setType(CommandType.COMPONENT) + .build(); + + CommandReply expectedReply = CommandReply.newBuilder() + .setCode(1) + .setResult("File operation failed") + .setTaskId(1L) + .build(); + + CommandExecutor mockExecutor = mock(CommandExecutor.class); + lenient().when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)).thenReturn(mockExecutor); + lenient().when(mockExecutor.execute(request)).thenReturn(expectedReply); + + StreamObserver responseObserver = mock(StreamObserver.class); + + // Mock truncateLogFile to throw an exception + CommandServiceGrpcImpl commandServiceGrpcSpy = spy(commandServiceGrpc); + doThrow(new RuntimeException("File operation failed")) + .when(commandServiceGrpcSpy).truncateLogFile(anyLong()); + + // Act + commandServiceGrpcSpy.exec(request, responseObserver); + + // Assert + verify(responseObserver, never()).onCompleted(); + verify(responseObserver).onError(any(StatusRuntimeException.class)); + } + + @Test + public void testExecCommandResponseObserverThrowsException() { + // Arrange + CommandRequest request = CommandRequest.newBuilder() + .setPayload("Test Payload") + .setTaskId(1L) + .setType(CommandType.COMPONENT) + .build(); + + CommandReply expectedReply = CommandReply.newBuilder() + .setCode(0) + .setResult("Success") + .setTaskId(1L) + .build(); + + CommandExecutor mockExecutor = mock(CommandExecutor.class); + lenient().when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)).thenReturn(mockExecutor); + lenient().when(mockExecutor.execute(request)).thenReturn(expectedReply); + + StreamObserver responseObserver = mock(StreamObserver.class); + doThrow(new RuntimeException("Observer failed")).when(responseObserver).onNext(any()); + + // Act + commandServiceGrpc.exec(request, responseObserver); + + // Assert + verify(responseObserver, never()).onCompleted(); // Ensure onCompleted is not called + verify(responseObserver).onError(any(StatusRuntimeException.class)); + } + +} diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java new file mode 100644 index 00000000..81da3f1b --- /dev/null +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java @@ -0,0 +1,115 @@ +/* + * 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.agent.service; + +import io.grpc.Status; +import org.apache.bigtop.manager.common.message.entity.payload.CommandPayload; +import org.apache.bigtop.manager.common.shell.ShellResult; +import org.apache.bigtop.manager.grpc.generated.ComponentStatusReply; +import org.apache.bigtop.manager.grpc.generated.ComponentStatusRequest; +import org.apache.bigtop.manager.stack.core.executor.StackExecutor; + +import io.grpc.StatusRuntimeException; +import io.grpc.stub.StreamObserver; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class ComponentStatusServiceGrpcImplTest { + + private final ComponentStatusServiceGrpcImpl service = new ComponentStatusServiceGrpcImpl(); + + @Test + public void testGetComponentStatusSuccess() { + // Arrange + ComponentStatusRequest request = ComponentStatusRequest.newBuilder() + .setStackName("TestStack") + .setStackVersion("1.0") + .setServiceName("TestService") + .setServiceUser("TestUser") + .setComponentName("TestComponent") + .build(); + + ShellResult shellResult = new ShellResult(); + shellResult.setExitCode(0); + + // Mock StackExecutor + mockStatic(StackExecutor.class); + when(StackExecutor.execute(any(CommandPayload.class))).thenReturn(shellResult); + + StreamObserver responseObserver = mock(StreamObserver.class); + ArgumentCaptor captor = ArgumentCaptor.forClass(ComponentStatusReply.class); + + // Act + service.getComponentStatus(request, responseObserver); + + // Assert + verify(responseObserver).onNext(captor.capture()); + verify(responseObserver).onCompleted(); + + ComponentStatusReply reply = captor.getValue(); + assertEquals(0, reply.getStatus()); + } + + @Test + public void testGetComponentStatusExecutionFailure() { + // Arrange + ComponentStatusRequest request = ComponentStatusRequest.newBuilder() + .setStackName("TestStack") + .setStackVersion("1.0") + .setServiceName("TestService") + .setServiceUser("TestUser") + .setComponentName("TestComponent") + .build(); + + // Mock StackExecutor to throw an exception + mockStatic(StackExecutor.class); + when(StackExecutor.execute(any(CommandPayload.class))) + .thenThrow(new RuntimeException("Execution failed")); + + StreamObserver responseObserver = mock(StreamObserver.class); + + // Act + service.getComponentStatus(request, responseObserver); + + // Assert + verify(responseObserver).onError(any(StatusRuntimeException.class)); + + // Capture the exception and verify its message + ArgumentCaptor captor = ArgumentCaptor.forClass(Throwable.class); + verify(responseObserver).onError(captor.capture()); + + // Get the captured exception + Throwable actualException = captor.getValue(); + + // Check if it is an instance of StatusRuntimeException + assertInstanceOf(StatusRuntimeException.class, actualException, "Expected StatusRuntimeException"); + + StatusRuntimeException statusRuntimeException = (StatusRuntimeException) actualException; + + // Check that the status code is UNKNOWN and the message contains the expected error message + assertEquals(Status.UNKNOWN.getCode(), statusRuntimeException.getStatus().getCode()); + assertTrue(statusRuntimeException.getMessage().contains("Execution failed")); + } +} diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java new file mode 100644 index 00000000..d8cfe578 --- /dev/null +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java @@ -0,0 +1,117 @@ +/* + * 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.agent.service; + +import com.sun.management.OperatingSystemMXBean; +import io.grpc.StatusRuntimeException; +import io.grpc.stub.StreamObserver; +import org.apache.bigtop.manager.common.utils.os.OSDetection; +import org.apache.bigtop.manager.grpc.generated.HostInfoReply; +import org.apache.bigtop.manager.grpc.generated.HostInfoRequest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; + +import static org.mockito.Mockito.*; + + +@ExtendWith(MockitoExtension.class) +public class HostInfoServiceGrpcImplTest { + + @InjectMocks + private HostInfoServiceGrpcImpl service; + + + @Test + public void testGetHostInfoSuccess() { + // Arrange + HostInfoRequest request = HostInfoRequest.newBuilder().build(); + + // Mock InetAddress + InetAddress mockInetAddress = mock(InetAddress.class); + lenient().when(mockInetAddress.getHostName()).thenReturn("localhost"); + lenient().when(mockInetAddress.getHostAddress()).thenReturn("192.168.0.100"); + + // Mock static methods of OSDetection using MockedStatic + try (MockedStatic mockedStatic = mockStatic(OSDetection.class); + MockedStatic mockManagementFactory = mockStatic(ManagementFactory.class)) { + long oneGBInBytes = 1024L * 1024L * 1024L; + long freeDiskInBytes = 100L * oneGBInBytes; + long totalDiskInBytes = 500L * oneGBInBytes; + // Mock static methods for disk size + mockedStatic.when(OSDetection::freeDisk).thenReturn(freeDiskInBytes); + mockedStatic.when(OSDetection::totalDisk).thenReturn(totalDiskInBytes); + + // Mock OSDetection static methods for OS, version, and arch + mockedStatic.when(OSDetection::getOS).thenReturn("Linux"); + mockedStatic.when(OSDetection::getVersion).thenReturn("1.0"); + mockedStatic.when(OSDetection::getArch).thenReturn("x86_64"); + + // Mock OperatingSystemMXBean methods + OperatingSystemMXBean mockOsBean = mock(OperatingSystemMXBean.class); + mockManagementFactory.when(ManagementFactory::getOperatingSystemMXBean).thenReturn(mockOsBean); + when(mockOsBean.getAvailableProcessors()).thenReturn(4); + when(mockOsBean.getProcessCpuTime()).thenReturn(100L); + when(mockOsBean.getTotalMemorySize()).thenReturn(1024L * 1024 * 1024); + when(mockOsBean.getFreeMemorySize()).thenReturn(512L * 1024 * 1024); + when(mockOsBean.getTotalSwapSpaceSize()).thenReturn(2048L * 1024 * 1024); + when(mockOsBean.getFreeSwapSpaceSize()).thenReturn(1024L * 1024 * 1024); + when(mockOsBean.getCommittedVirtualMemorySize()).thenReturn(4096L * 1024 * 1024); + when(mockOsBean.getCpuLoad()).thenReturn(0.75); + when(mockOsBean.getProcessCpuLoad()).thenReturn(0.50); + when(mockOsBean.getSystemLoadAverage()).thenReturn(1.5); + + StreamObserver mockResponseObserver = mock(StreamObserver.class); + + // Act + service.getHostInfo(request, mockResponseObserver); + + // Assert + verify(mockResponseObserver).onNext(any(HostInfoReply.class)); + verify(mockResponseObserver).onCompleted(); + } + } + + @Test + public void testGetHostInfoFailure() { + // Arrange + HostInfoRequest request = HostInfoRequest.newBuilder().build(); + + try (MockedStatic mockInetAddress = mockStatic(InetAddress.class)) { + // Simulate an exception during execution + mockInetAddress.when(InetAddress::getLocalHost).thenThrow(new RuntimeException("Network error")); + + StreamObserver mockResponseObserver = mock(StreamObserver.class); + + // Act + service.getHostInfo(request, mockResponseObserver); + + // Assert + verify(mockResponseObserver).onError(any(StatusRuntimeException.class)); + } + + } + +} diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.java new file mode 100644 index 00000000..b70d8068 --- /dev/null +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.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.agent.service; + +import io.grpc.stub.StreamObserver; +import org.apache.bigtop.manager.common.utils.ProjectPathUtils; +import org.apache.bigtop.manager.grpc.generated.JobCacheReply; +import org.apache.bigtop.manager.grpc.generated.JobCacheRequest; +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.nio.file.Files; +import java.nio.file.Path; + +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class JobCacheServiceGrpcImplTest { + + private JobCacheServiceGrpcImpl jobCacheServiceGrpcImpl; + + @Mock + private StreamObserver responseObserver; + + + @BeforeEach + public void setUp() { + // Initialize mock objects + jobCacheServiceGrpcImpl = new JobCacheServiceGrpcImpl(); + } + + @Test + public void testSaveSuccess() { + // Mock the static behavior of ProjectPathUtils.getAgentCachePath method + try (MockedStatic mockedStatic = mockStatic(ProjectPathUtils.class)) { + String cacheDir = "mock/cache/dir"; + mockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn(cacheDir); + + // Construct JobCacheRequest + String payloadJson = "{\"configurations\": {\"configKey\": {\"subKey\": \"subValue\"}}}"; + JobCacheRequest request = JobCacheRequest.newBuilder() + .setJobId(123L) + .setPayload(payloadJson) + .build(); + + // Execute the save method + jobCacheServiceGrpcImpl.save(request, responseObserver); + + // Verify that JsonUtils.writeToFile method was called correctly + verify(responseObserver).onNext(any(JobCacheReply.class)); + verify(responseObserver).onCompleted(); + } + } + + @Test + public void testSaveDirectoryCreationFailure() { + // Mock the static behavior of ProjectPathUtils.getAgentCachePath method + try (MockedStatic mockedStatic = mockStatic(ProjectPathUtils.class)) { + String cacheDir = "mock/cache/dir"; + mockedStatic.when(ProjectPathUtils::getAgentCachePath).thenReturn(cacheDir); + + // Mock Files.createDirectories to throw an exception + try (MockedStatic mockedFiles = mockStatic(Files.class)) { + mockedFiles.when(() -> Files.createDirectories(any(Path.class))).thenThrow(new RuntimeException("Directory creation failed")); + + // Construct JobCacheRequest + String payloadJson = "{\"configurations\": {\"configKey\": {\"subKey\": \"subValue\"}}}"; + JobCacheRequest request = JobCacheRequest.newBuilder() + .setJobId(123L) + .setPayload(payloadJson) + .build(); + + // Execute the save method, expecting onError to be called + jobCacheServiceGrpcImpl.save(request, responseObserver); + + // Verify that onError was called with the expected exception + verify(responseObserver).onError(any(RuntimeException.class)); + } + } + } +} From c57580a23dcffe62964a41f21c880ad9b9a6b15f Mon Sep 17 00:00:00 2001 From: huangguojie2024 <503601315@qq.com> Date: Sun, 19 Jan 2025 11:31:28 +0800 Subject: [PATCH 2/3] Fix code style --- .../agent/holder/SpringContextHolderTest.java | 10 +- .../monitoring/AgentHostMonitoringTest.java | 43 +++--- .../service/CommandServiceGrpcImplTest.java | 33 +++-- .../ComponentStatusServiceGrpcImplTest.java | 133 ++++++++++-------- .../service/HostInfoServiceGrpcImplTest.java | 26 ++-- .../service/JobCacheServiceGrpcImplTest.java | 13 +- 6 files changed, 154 insertions(+), 104 deletions(-) diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java index f4b1d737..4eb0e7d6 100644 --- a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/holder/SpringContextHolderTest.java @@ -19,6 +19,7 @@ package org.apache.bigtop.manager.agent.holder; import org.apache.bigtop.manager.agent.executor.CommandExecutor; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -29,8 +30,13 @@ import java.util.HashMap; import java.util.Map; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class SpringContextHolderTest { diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java index d482315b..8fcb8cbc 100644 --- a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/monitoring/AgentHostMonitoringTest.java @@ -18,25 +18,37 @@ */ package org.apache.bigtop.manager.agent.monitoring; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import io.micrometer.core.instrument.MultiGauge; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import oshi.SystemInfo; import oshi.hardware.GlobalMemory; import oshi.hardware.HardwareAbstractionLayer; import oshi.software.os.OperatingSystem; import java.net.UnknownHostException; -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertFalse; +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.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; class AgentHostMonitoringTest { @@ -49,7 +61,6 @@ class AgentHostMonitoringTest { @Mock private GlobalMemory globalMemory; - @Mock private MultiGauge diskMultiGauge; @@ -108,7 +119,8 @@ void testGetDiskGauge() { when(diskJsonNode.get(AgentHostMonitoring.DISK_TOTAL).asDouble()).thenReturn(100.0); // Call the getDiskGauge method - Map, Map, Double>> diskGauge = AgentHostMonitoring.getDiskGauge(agentMonitoring); + Map, Map, Double>> diskGauge = + AgentHostMonitoring.getDiskGauge(agentMonitoring); // Assert that the disk gauge data is populated correctly assertNotNull(diskGauge); @@ -133,7 +145,8 @@ void testGetCPUGauge() { .put(AgentHostMonitoring.CPU_LOAD_AVG_MIN_15, 15.0) .put(AgentHostMonitoring.CPU_USAGE, 10.0); - Map, Map, Double>> cpuGauge = AgentHostMonitoring.getCPUGauge(agentMonitoring); + Map, Map, Double>> cpuGauge = + AgentHostMonitoring.getCPUGauge(agentMonitoring); // Assert that the CPU gauge data is populated correctly assertNotNull(cpuGauge); @@ -152,18 +165,16 @@ void testGetMEMGauge() { agentMonitoring.set(AgentHostMonitoring.AGENT_BASE_INFO, agentHostInfo); // Set MEM related fields - agentMonitoring - .put(AgentHostMonitoring.MEM_IDLE, 2000.0) - .put(AgentHostMonitoring.MEM_TOTAL, 4000.0); + agentMonitoring.put(AgentHostMonitoring.MEM_IDLE, 2000.0).put(AgentHostMonitoring.MEM_TOTAL, 4000.0); - Map, Map, Double>> memGauge = AgentHostMonitoring.getMEMGauge(agentMonitoring); + Map, Map, Double>> memGauge = + AgentHostMonitoring.getMEMGauge(agentMonitoring); // Assert that the MEM gauge data is populated correctly assertNotNull(memGauge); assertFalse(memGauge.isEmpty()); } - @Test void testMultiGaugeUpdateData() { // Create a mock Map object diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java index 2f93af86..add9773c 100644 --- a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/CommandServiceGrpcImplTest.java @@ -18,14 +18,13 @@ */ package org.apache.bigtop.manager.agent.service; -import io.grpc.StatusRuntimeException; -import io.grpc.stub.StreamObserver; import org.apache.bigtop.manager.agent.executor.CommandExecutor; import org.apache.bigtop.manager.agent.executor.CommandExecutors; import org.apache.bigtop.manager.agent.holder.SpringContextHolder; import org.apache.bigtop.manager.grpc.generated.CommandReply; import org.apache.bigtop.manager.grpc.generated.CommandRequest; import org.apache.bigtop.manager.grpc.generated.CommandType; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -33,16 +32,25 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.context.ApplicationContext; +import io.grpc.StatusRuntimeException; +import io.grpc.stub.StreamObserver; + import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.*; - +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class CommandServiceGrpcImplTest { - private CommandServiceGrpcImpl commandServiceGrpc; @BeforeEach @@ -51,7 +59,8 @@ public void setUp() { ApplicationContext mockApplicationContext = mock(ApplicationContext.class); CommandExecutor mockExecutor = mock(CommandExecutor.class); - when(mockApplicationContext.getBeansOfType(CommandExecutor.class)) + lenient() + .when(mockApplicationContext.getBeansOfType(CommandExecutor.class)) .thenReturn(Map.of("mockExecutor", mockExecutor)); springContextHolder.setApplicationContext(mockApplicationContext); @@ -154,7 +163,9 @@ public void testExecCommandLogFileOperationFails() { .build(); CommandExecutor mockExecutor = mock(CommandExecutor.class); - lenient().when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)).thenReturn(mockExecutor); + lenient() + .when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)) + .thenReturn(mockExecutor); lenient().when(mockExecutor.execute(request)).thenReturn(expectedReply); StreamObserver responseObserver = mock(StreamObserver.class); @@ -162,7 +173,8 @@ public void testExecCommandLogFileOperationFails() { // Mock truncateLogFile to throw an exception CommandServiceGrpcImpl commandServiceGrpcSpy = spy(commandServiceGrpc); doThrow(new RuntimeException("File operation failed")) - .when(commandServiceGrpcSpy).truncateLogFile(anyLong()); + .when(commandServiceGrpcSpy) + .truncateLogFile(anyLong()); // Act commandServiceGrpcSpy.exec(request, responseObserver); @@ -188,7 +200,9 @@ public void testExecCommandResponseObserverThrowsException() { .build(); CommandExecutor mockExecutor = mock(CommandExecutor.class); - lenient().when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)).thenReturn(mockExecutor); + lenient() + .when(CommandExecutors.getCommandExecutor(CommandType.COMPONENT)) + .thenReturn(mockExecutor); lenient().when(mockExecutor.execute(request)).thenReturn(expectedReply); StreamObserver responseObserver = mock(StreamObserver.class); @@ -201,5 +215,4 @@ public void testExecCommandResponseObserverThrowsException() { verify(responseObserver, never()).onCompleted(); // Ensure onCompleted is not called verify(responseObserver).onError(any(StatusRuntimeException.class)); } - } diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java index 81da3f1b..47fe536d 100644 --- a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java @@ -18,22 +18,32 @@ */ package org.apache.bigtop.manager.agent.service; -import io.grpc.Status; import org.apache.bigtop.manager.common.message.entity.payload.CommandPayload; import org.apache.bigtop.manager.common.shell.ShellResult; import org.apache.bigtop.manager.grpc.generated.ComponentStatusReply; import org.apache.bigtop.manager.grpc.generated.ComponentStatusRequest; import org.apache.bigtop.manager.stack.core.executor.StackExecutor; -import io.grpc.StatusRuntimeException; -import io.grpc.stub.StreamObserver; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; +import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; +import io.grpc.stub.StreamObserver; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class ComponentStatusServiceGrpcImplTest { @@ -42,74 +52,75 @@ public class ComponentStatusServiceGrpcImplTest { @Test public void testGetComponentStatusSuccess() { - // Arrange - ComponentStatusRequest request = ComponentStatusRequest.newBuilder() - .setStackName("TestStack") - .setStackVersion("1.0") - .setServiceName("TestService") - .setServiceUser("TestUser") - .setComponentName("TestComponent") - .build(); - - ShellResult shellResult = new ShellResult(); - shellResult.setExitCode(0); - - // Mock StackExecutor - mockStatic(StackExecutor.class); - when(StackExecutor.execute(any(CommandPayload.class))).thenReturn(shellResult); - - StreamObserver responseObserver = mock(StreamObserver.class); - ArgumentCaptor captor = ArgumentCaptor.forClass(ComponentStatusReply.class); - - // Act - service.getComponentStatus(request, responseObserver); - - // Assert - verify(responseObserver).onNext(captor.capture()); - verify(responseObserver).onCompleted(); - - ComponentStatusReply reply = captor.getValue(); - assertEquals(0, reply.getStatus()); + try (MockedStatic mockedStatic = mockStatic(StackExecutor.class)) { + // Arrange + ComponentStatusRequest request = ComponentStatusRequest.newBuilder() + .setStackName("TestStack") + .setStackVersion("1.0") + .setServiceName("TestService") + .setServiceUser("TestUser") + .setComponentName("TestComponent") + .build(); + + ShellResult shellResult = new ShellResult(); + shellResult.setExitCode(0); + + // Mock StackExecutor + mockedStatic.when(() -> StackExecutor.execute(any(CommandPayload.class))).thenReturn(shellResult); + + StreamObserver responseObserver = mock(StreamObserver.class); + ArgumentCaptor captor = ArgumentCaptor.forClass(ComponentStatusReply.class); + + // Act + service.getComponentStatus(request, responseObserver); + + // Assert + verify(responseObserver).onNext(captor.capture()); + verify(responseObserver).onCompleted(); + + ComponentStatusReply reply = captor.getValue(); + assertEquals(0, reply.getStatus()); + } } @Test public void testGetComponentStatusExecutionFailure() { - // Arrange - ComponentStatusRequest request = ComponentStatusRequest.newBuilder() - .setStackName("TestStack") - .setStackVersion("1.0") - .setServiceName("TestService") - .setServiceUser("TestUser") - .setComponentName("TestComponent") - .build(); + try (MockedStatic mockedStatic = mockStatic(StackExecutor.class)) { + // Arrange + ComponentStatusRequest request = ComponentStatusRequest.newBuilder() + .setStackName("TestStack") + .setStackVersion("1.0") + .setServiceName("TestService") + .setServiceUser("TestUser") + .setComponentName("TestComponent") + .build(); - // Mock StackExecutor to throw an exception - mockStatic(StackExecutor.class); - when(StackExecutor.execute(any(CommandPayload.class))) - .thenThrow(new RuntimeException("Execution failed")); + // Mock StackExecutor to throw an exception + mockedStatic.when(() -> StackExecutor.execute(any(CommandPayload.class))).thenThrow(new RuntimeException("Execution failed")); - StreamObserver responseObserver = mock(StreamObserver.class); + StreamObserver responseObserver = mock(StreamObserver.class); - // Act - service.getComponentStatus(request, responseObserver); + // Act + service.getComponentStatus(request, responseObserver); - // Assert - verify(responseObserver).onError(any(StatusRuntimeException.class)); + // Assert + verify(responseObserver).onError(any(StatusRuntimeException.class)); - // Capture the exception and verify its message - ArgumentCaptor captor = ArgumentCaptor.forClass(Throwable.class); - verify(responseObserver).onError(captor.capture()); + // Capture the exception and verify its message + ArgumentCaptor captor = ArgumentCaptor.forClass(Throwable.class); + verify(responseObserver).onError(captor.capture()); - // Get the captured exception - Throwable actualException = captor.getValue(); + // Get the captured exception + Throwable actualException = captor.getValue(); - // Check if it is an instance of StatusRuntimeException - assertInstanceOf(StatusRuntimeException.class, actualException, "Expected StatusRuntimeException"); + // Check if it is an instance of StatusRuntimeException + assertInstanceOf(StatusRuntimeException.class, actualException, "Expected StatusRuntimeException"); - StatusRuntimeException statusRuntimeException = (StatusRuntimeException) actualException; + StatusRuntimeException statusRuntimeException = (StatusRuntimeException) actualException; - // Check that the status code is UNKNOWN and the message contains the expected error message - assertEquals(Status.UNKNOWN.getCode(), statusRuntimeException.getStatus().getCode()); - assertTrue(statusRuntimeException.getMessage().contains("Execution failed")); + // Check that the status code is UNKNOWN and the message contains the expected error message + assertEquals(Status.UNKNOWN.getCode(), statusRuntimeException.getStatus().getCode()); + assertTrue(statusRuntimeException.getMessage().contains("Execution failed")); + } } } diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java index d8cfe578..2c4b87e9 100644 --- a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/HostInfoServiceGrpcImplTest.java @@ -18,24 +18,29 @@ */ package org.apache.bigtop.manager.agent.service; -import com.sun.management.OperatingSystemMXBean; -import io.grpc.StatusRuntimeException; -import io.grpc.stub.StreamObserver; import org.apache.bigtop.manager.common.utils.os.OSDetection; import org.apache.bigtop.manager.grpc.generated.HostInfoReply; import org.apache.bigtop.manager.grpc.generated.HostInfoRequest; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; +import com.sun.management.OperatingSystemMXBean; +import io.grpc.StatusRuntimeException; +import io.grpc.stub.StreamObserver; + import java.lang.management.ManagementFactory; import java.net.InetAddress; -import static org.mockito.Mockito.*; - +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class HostInfoServiceGrpcImplTest { @@ -43,7 +48,6 @@ public class HostInfoServiceGrpcImplTest { @InjectMocks private HostInfoServiceGrpcImpl service; - @Test public void testGetHostInfoSuccess() { // Arrange @@ -56,7 +60,7 @@ public void testGetHostInfoSuccess() { // Mock static methods of OSDetection using MockedStatic try (MockedStatic mockedStatic = mockStatic(OSDetection.class); - MockedStatic mockManagementFactory = mockStatic(ManagementFactory.class)) { + MockedStatic mockManagementFactory = mockStatic(ManagementFactory.class)) { long oneGBInBytes = 1024L * 1024L * 1024L; long freeDiskInBytes = 100L * oneGBInBytes; long totalDiskInBytes = 500L * oneGBInBytes; @@ -71,7 +75,9 @@ public void testGetHostInfoSuccess() { // Mock OperatingSystemMXBean methods OperatingSystemMXBean mockOsBean = mock(OperatingSystemMXBean.class); - mockManagementFactory.when(ManagementFactory::getOperatingSystemMXBean).thenReturn(mockOsBean); + mockManagementFactory + .when(ManagementFactory::getOperatingSystemMXBean) + .thenReturn(mockOsBean); when(mockOsBean.getAvailableProcessors()).thenReturn(4); when(mockOsBean.getProcessCpuTime()).thenReturn(100L); when(mockOsBean.getTotalMemorySize()).thenReturn(1024L * 1024 * 1024); @@ -111,7 +117,5 @@ public void testGetHostInfoFailure() { // Assert verify(mockResponseObserver).onError(any(StatusRuntimeException.class)); } - } - } diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.java index b70d8068..61e13878 100644 --- a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.java +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/JobCacheServiceGrpcImplTest.java @@ -18,10 +18,10 @@ */ package org.apache.bigtop.manager.agent.service; -import io.grpc.stub.StreamObserver; import org.apache.bigtop.manager.common.utils.ProjectPathUtils; import org.apache.bigtop.manager.grpc.generated.JobCacheReply; import org.apache.bigtop.manager.grpc.generated.JobCacheRequest; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -29,10 +29,14 @@ import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; +import io.grpc.stub.StreamObserver; + import java.nio.file.Files; import java.nio.file.Path; -import static org.mockito.Mockito.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) public class JobCacheServiceGrpcImplTest { @@ -42,7 +46,6 @@ public class JobCacheServiceGrpcImplTest { @Mock private StreamObserver responseObserver; - @BeforeEach public void setUp() { // Initialize mock objects @@ -81,7 +84,9 @@ public void testSaveDirectoryCreationFailure() { // Mock Files.createDirectories to throw an exception try (MockedStatic mockedFiles = mockStatic(Files.class)) { - mockedFiles.when(() -> Files.createDirectories(any(Path.class))).thenThrow(new RuntimeException("Directory creation failed")); + mockedFiles + .when(() -> Files.createDirectories(any(Path.class))) + .thenThrow(new RuntimeException("Directory creation failed")); // Construct JobCacheRequest String payloadJson = "{\"configurations\": {\"configKey\": {\"subKey\": \"subValue\"}}}"; From 1e87d9810987f9d2bae1736ab77ee71a5721f92a Mon Sep 17 00:00:00 2001 From: huangguojie2024 <503601315@qq.com> Date: Sun, 19 Jan 2025 12:13:06 +0800 Subject: [PATCH 3/3] Fix code style --- .../ComponentStatusServiceGrpcImplTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java index 47fe536d..5b9b2a2f 100644 --- a/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java +++ b/bigtop-manager-agent/src/test/java/org/apache/bigtop/manager/agent/service/ComponentStatusServiceGrpcImplTest.java @@ -24,7 +24,6 @@ import org.apache.bigtop.manager.grpc.generated.ComponentStatusRequest; import org.apache.bigtop.manager.stack.core.executor.StackExecutor; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -39,11 +38,9 @@ import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class ComponentStatusServiceGrpcImplTest { @@ -66,7 +63,9 @@ public void testGetComponentStatusSuccess() { shellResult.setExitCode(0); // Mock StackExecutor - mockedStatic.when(() -> StackExecutor.execute(any(CommandPayload.class))).thenReturn(shellResult); + mockedStatic + .when(() -> StackExecutor.execute(any(CommandPayload.class))) + .thenReturn(shellResult); StreamObserver responseObserver = mock(StreamObserver.class); ArgumentCaptor captor = ArgumentCaptor.forClass(ComponentStatusReply.class); @@ -96,7 +95,9 @@ public void testGetComponentStatusExecutionFailure() { .build(); // Mock StackExecutor to throw an exception - mockedStatic.when(() -> StackExecutor.execute(any(CommandPayload.class))).thenThrow(new RuntimeException("Execution failed")); + mockedStatic + .when(() -> StackExecutor.execute(any(CommandPayload.class))) + .thenThrow(new RuntimeException("Execution failed")); StreamObserver responseObserver = mock(StreamObserver.class); @@ -119,7 +120,8 @@ public void testGetComponentStatusExecutionFailure() { StatusRuntimeException statusRuntimeException = (StatusRuntimeException) actualException; // Check that the status code is UNKNOWN and the message contains the expected error message - assertEquals(Status.UNKNOWN.getCode(), statusRuntimeException.getStatus().getCode()); + assertEquals( + Status.UNKNOWN.getCode(), statusRuntimeException.getStatus().getCode()); assertTrue(statusRuntimeException.getMessage().contains("Execution failed")); } }