| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.tradefed.cluster; |
| |
| import static org.mockito.Mockito.times; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import com.android.tradefed.command.remote.DeviceDescriptor; |
| import com.android.tradefed.config.OptionSetter; |
| import com.android.tradefed.device.DeviceAllocationState; |
| import com.android.tradefed.monitoring.LabResourceDeviceMonitor; |
| import com.android.tradefed.util.CommandResult; |
| import com.android.tradefed.util.CommandStatus; |
| import com.android.tradefed.util.IRunUtil; |
| |
| import com.google.dualhomelab.monitoringagent.resourcemonitoring.LabResource; |
| import com.google.dualhomelab.monitoringagent.resourcemonitoring.Metric; |
| import com.google.dualhomelab.monitoringagent.resourcemonitoring.MonitoredEntity; |
| import com.google.dualhomelab.monitoringagent.resourcemonitoring.Resource; |
| import com.google.protobuf.util.Timestamps; |
| |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| import org.mockito.ArgumentCaptor; |
| import org.mockito.Mock; |
| import org.mockito.Mockito; |
| import org.mockito.MockitoAnnotations; |
| |
| import java.time.Instant; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** Unit tests for {@link ClusterDeviceMonitor}. */ |
| @RunWith(JUnit4.class) |
| public class ClusterDeviceMonitorTest { |
| |
| private static final String PRODCERTSTATUS_KEY = "LOAS status"; |
| private static final String KRBSTATUS_KEY = "Kerberos status"; |
| private static final String PRODCERTSTATUS_CMD = "prodcertstatus"; |
| private static final String KRBSTATUS_CMD = "krbstatus"; |
| @Mock IRunUtil mRunUtil; |
| private ClusterDeviceMonitor mClusterDeviceMonitor = null; |
| private OptionSetter mClusterDeviceMonitorSetter = null; |
| private ClusterDeviceMonitor.EventDispatcher mEventDispatcher = null; |
| private IClusterOptions mClusterOptions = null; |
| @Mock IClusterEventUploader<ClusterHostEvent> mHostEventUploader; |
| private OptionSetter mClusterOptionSetter = null; |
| |
| @Before |
| public void setUp() throws Exception { |
| MockitoAnnotations.initMocks(this); |
| |
| mClusterOptions = new ClusterOptions(); |
| |
| mClusterDeviceMonitor = |
| new ClusterDeviceMonitor() { |
| @Override |
| public IRunUtil getRunUtil() { |
| return mRunUtil; |
| } |
| |
| @Override |
| List<DeviceDescriptor> listDevices() { |
| List<DeviceDescriptor> devices = new ArrayList<DeviceDescriptor>(); |
| devices.add( |
| new DeviceDescriptor( |
| "device1", |
| false, |
| DeviceAllocationState.Available, |
| "product1", |
| "variant1", |
| "sdkVersion", |
| "buildId", |
| "batteryLevel")); |
| return devices; |
| } |
| |
| @Override |
| protected LabResource getCachedLabResource() { |
| return LabResource.newBuilder() |
| .addDevice( |
| MonitoredEntity.newBuilder() |
| .putIdentifier( |
| LabResourceDeviceMonitor.DEVICE_SERIAL_KEY, |
| "device1") |
| .addResource( |
| Resource.newBuilder() |
| .setResourceName("resource1") |
| .setTimestamp( |
| Timestamps.fromMillis( |
| Instant.now() |
| .toEpochMilli())) |
| .addMetric( |
| Metric.newBuilder() |
| .setTag("tag1") |
| .setValue(10.0f)))) |
| .build(); |
| } |
| }; |
| mClusterDeviceMonitorSetter = new OptionSetter(mClusterDeviceMonitor); |
| mEventDispatcher = |
| mClusterDeviceMonitor.new EventDispatcher() { |
| @Override |
| public IClusterOptions getClusterOptions() { |
| return mClusterOptions; |
| } |
| |
| @Override |
| public IClusterEventUploader<ClusterHostEvent> getEventUploader() { |
| return mHostEventUploader; |
| } |
| }; |
| mClusterOptionSetter = new OptionSetter(mClusterOptions); |
| mClusterOptionSetter.setOptionValue("cluster:cluster", "cluster1"); |
| mClusterOptionSetter.setOptionValue("cluster:next-cluster", "cluster2"); |
| mClusterOptionSetter.setOptionValue("cluster:next-cluster", "cluster3"); |
| mClusterOptionSetter.setOptionValue("cluster:lab-name", "lab1"); |
| } |
| |
| @Test |
| public void testDispatch() throws Exception { |
| ArgumentCaptor<ClusterHostEvent> capture = ArgumentCaptor.forClass(ClusterHostEvent.class); |
| |
| mEventDispatcher.dispatch(); |
| |
| verify(mHostEventUploader).postEvent(capture.capture()); |
| verify(mHostEventUploader).flush(); |
| ClusterHostEvent hostEvent = capture.getValue(); |
| Assert.assertNotNull(hostEvent.getHostName()); |
| Assert.assertNotNull(hostEvent.getData().get(ClusterHostEvent.TEST_HARNESS_START_TIME_KEY)); |
| Assert.assertNotNull(hostEvent.getTimestamp()); |
| Assert.assertEquals("cluster1", hostEvent.getClusterId()); |
| Assert.assertEquals(Arrays.asList("cluster2", "cluster3"), hostEvent.getNextClusterIds()); |
| Assert.assertEquals("lab1", hostEvent.getLabName()); |
| Assert.assertEquals("", hostEvent.getData().get("label")); |
| |
| Assert.assertEquals(1, hostEvent.getDeviceInfos().size()); |
| ClusterDeviceInfo device = hostEvent.getDeviceInfos().get(0); |
| Assert.assertEquals("device1", device.getDeviceDescriptor().getSerial()); |
| } |
| |
| @Test |
| public void testLabel() throws Exception { |
| mClusterOptionSetter.setOptionValue("cluster:label", "label1"); |
| mClusterOptionSetter.setOptionValue("cluster:label", "label2"); |
| ArgumentCaptor<ClusterHostEvent> capture = ArgumentCaptor.forClass(ClusterHostEvent.class); |
| |
| mEventDispatcher.dispatch(); |
| |
| verify(mHostEventUploader).postEvent(capture.capture()); |
| verify(mHostEventUploader).flush(); |
| ClusterHostEvent hostEvent = capture.getValue(); |
| Assert.assertNotNull(hostEvent.getHostName()); |
| Assert.assertNotNull(hostEvent.getTimestamp()); |
| Assert.assertEquals("cluster1", hostEvent.getClusterId()); |
| Assert.assertEquals(Arrays.asList("cluster2", "cluster3"), hostEvent.getNextClusterIds()); |
| Assert.assertEquals("lab1", hostEvent.getLabName()); |
| Assert.assertEquals("label1,label2", hostEvent.getData().get("label")); |
| } |
| |
| void setOptions() throws Exception { |
| mClusterDeviceMonitorSetter.setOptionValue( |
| "host-info-cmd", PRODCERTSTATUS_KEY, PRODCERTSTATUS_CMD); |
| mClusterDeviceMonitorSetter.setOptionValue("host-info-cmd", KRBSTATUS_KEY, KRBSTATUS_CMD); |
| } |
| |
| // Test getting additional host information |
| @Test |
| public void testGetAdditionalHostInfo() throws Exception { |
| setOptions(); |
| String prodcertstatusOutput = "LOAS cert expires in 13h 5m"; |
| CommandResult prodcertstatusMockResult = new CommandResult(); |
| prodcertstatusMockResult.setStdout(prodcertstatusOutput); |
| prodcertstatusMockResult.setStatus(CommandStatus.SUCCESS); |
| when(mRunUtil.runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(PRODCERTSTATUS_CMD))) |
| .thenReturn(prodcertstatusMockResult); |
| |
| String krbstatusOutput = "android-test ticket expires in 65d 19h"; |
| CommandResult krbstatusMockResult = new CommandResult(); |
| krbstatusMockResult.setStdout(krbstatusOutput); |
| krbstatusMockResult.setStatus(CommandStatus.SUCCESS); |
| when(mRunUtil.runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(KRBSTATUS_CMD))) |
| .thenReturn(krbstatusMockResult); |
| |
| Map<String, String> expected = new HashMap<>(); |
| expected.put(PRODCERTSTATUS_KEY, prodcertstatusOutput); |
| expected.put(KRBSTATUS_KEY, krbstatusOutput); |
| |
| Assert.assertEquals(expected, mClusterDeviceMonitor.getAdditionalHostInfo()); |
| verify(mRunUtil, times(1)) |
| .runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(PRODCERTSTATUS_CMD)); |
| verify(mRunUtil, times(1)) |
| .runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(KRBSTATUS_CMD)); |
| } |
| |
| // Test getting additional host information with no commands to run |
| @Test |
| public void testGetAdditionalHostInfo_noCommands() { |
| Map<String, String> expected = new HashMap<>(); |
| Assert.assertEquals(expected, mClusterDeviceMonitor.getAdditionalHostInfo()); |
| } |
| |
| // Test getting additional host information with failures |
| @Test |
| public void testGetAdditionalHostInfo_commandFailed() throws Exception { |
| setOptions(); |
| String prodcertstatusOutput = "LOAS cert expires in 13h 5m"; |
| CommandResult prodcertstatusMockResult = new CommandResult(); |
| prodcertstatusMockResult.setStdout(prodcertstatusOutput); |
| prodcertstatusMockResult.setStatus(CommandStatus.SUCCESS); |
| when(mRunUtil.runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(PRODCERTSTATUS_CMD))) |
| .thenReturn(prodcertstatusMockResult); |
| |
| String krbstatusOutput = "android-test ticket expires in 65d 19h"; |
| String krbstatusError = "Some terrible failure"; |
| CommandResult krbstatusMockResult = new CommandResult(); |
| krbstatusMockResult.setStdout(krbstatusOutput); |
| krbstatusMockResult.setStderr(krbstatusError); |
| krbstatusMockResult.setStatus(CommandStatus.FAILED); |
| when(mRunUtil.runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(KRBSTATUS_CMD))) |
| .thenReturn(krbstatusMockResult); |
| |
| Map<String, String> expected = new HashMap<>(); |
| expected.put(PRODCERTSTATUS_KEY, prodcertstatusOutput); |
| expected.put(KRBSTATUS_KEY, krbstatusError); |
| |
| Assert.assertEquals(expected, mClusterDeviceMonitor.getAdditionalHostInfo()); |
| verify(mRunUtil, times(1)) |
| .runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(PRODCERTSTATUS_CMD)); |
| verify(mRunUtil, times(1)) |
| .runTimedCmdSilently(Mockito.anyLong(), Mockito.eq(KRBSTATUS_CMD)); |
| } |
| |
| @Test |
| public void testDeviceExtraInfo() throws Exception { |
| ArgumentCaptor<ClusterHostEvent> capture = ArgumentCaptor.forClass(ClusterHostEvent.class); |
| |
| mEventDispatcher.dispatch(); |
| |
| verify(mHostEventUploader).postEvent(capture.capture()); |
| verify(mHostEventUploader).flush(); |
| ClusterHostEvent hostEvent = capture.getValue(); |
| Assert.assertNotNull(hostEvent.getHostName()); |
| Assert.assertNotNull(hostEvent.getTimestamp()); |
| Assert.assertEquals("cluster1", hostEvent.getClusterId()); |
| Assert.assertEquals(Arrays.asList("cluster2", "cluster3"), hostEvent.getNextClusterIds()); |
| Assert.assertEquals(1, hostEvent.getDeviceInfos().size()); |
| ClusterDeviceInfo device = hostEvent.getDeviceInfos().get(0); |
| Assert.assertEquals("device1", device.getDeviceDescriptor().getSerial()); |
| Assert.assertEquals(2, device.getExtraInfo().size()); |
| Assert.assertEquals("10.0", device.getExtraInfo().get("resource1-tag1")); |
| } |
| } |