Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add steps for ram and cpu use #230

Merged
merged 5 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@
<artifactId>guice</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.4.7</version>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package com.aws.greengrass.testing.features;

import io.cucumber.guice.ScenarioScoped;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;

import java.util.ArrayList;


@ScenarioScoped
public class SystemSteps {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we rename this to something like SystemMetricSteps ?

private static final Logger LOGGER = LogManager.getLogger(SystemSteps.class);
private ArrayList<Double> ramList = new ArrayList<Double>();
private ArrayList<Double> cpuList = new ArrayList<Double>();
private SystemInfo si = new SystemInfo();
private HardwareAbstractionLayer hal = si.getHardware();
private CentralProcessor cpu = hal.getProcessor();
private GlobalMemory ram = hal.getMemory();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialize these in a constructor.


/**
* Record the current CPU or RAM usage depending on the step.
*
* @param stat the statistic to record, must be CPU or RAM
* @throws IllegalArgumentException when parameter is not CPU or RAM
*/
@When("I record the device's {word} usage statistic")
public void recordCpuOrRam(String stat) throws IllegalArgumentException {
switch (stat) {
case "CPU":
double cpuLoad = cpu.getSystemCpuLoad(500) * 100;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does 500 signify here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Milliseconds to wait as the time period we check the cpu load over

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This is good. But, can we have a step that stores the recorded value in scenario context? This will help us test the difference between any two values instead of just the last two. Eg. I record the device's {word} usage statistic as {word} and the test would look the following.

    When I record the device's RAM usage statistic as RAM_1
    And I wait 10 seconds
    When I record the device's RAM usage statistic as RAM_2
    And I wait 10 seconds
    When I record the device's RAM usage statistic as RAM_3
    Then the difference between RAM_1 and RAM_3 is less than 1024 MB

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that, replaced the old steps with these in latest commit.

LOGGER.info("System CPU load recorded as: " + cpuLoad + "%");
patrzhan marked this conversation as resolved.
Show resolved Hide resolved
cpuList.add(0, cpuLoad);
break;
case "RAM":
double usedRam = (ram.getTotal() - ram.getAvailable()) / (1024 * 1024);
LOGGER.info("Used RAM recorded as: " + usedRam + " MB");
ramList.add(0, usedRam);
break;
default:
throw new IllegalArgumentException("Please specify either CPU or RAM to track.");
}
}

/**
* Check difference between last two records and verify it is below a threshold.
*
* @param stat the statistic to record, must be CPU or RAM
* @param threshold the threshold to assert the difference is under, % for CPU and MB for RAM
* @throws Exception when step fails due to exceeding the provided threshold or sample steps haven't run twice
* @throws IllegalArgumentException when stat param is not CPU or RAM
*/
@Then("the difference in the last two {word} samples is less than {int}")
patrzhan marked this conversation as resolved.
Show resolved Hide resolved
public void checkSampleDiff(String stat, int threshold) throws Exception, IllegalArgumentException {
switch (stat) {
case "CPU":
if (cpuList.size() < 2) {
throw new Exception("Need at least two CPU samples first.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception is not very intuitive, it looks like that CPU or RAM usage is recorded implicitly and do not have enough data to compare instead of deliberately calling previous step to do so.

Same in line 77.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this exception since refactored the steps again, now the records will be saved to scenario context.

}
double cpuDiff = cpuList.get(0) - cpuList.get(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard coding the index is not good practice. What if the list has more than 2 records then last and second last index will not be 1 and 0.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also removed since we're now using scenario context, but in this context I was adding newest records to index 0 so that 0 and 1 would always be the latest two.

if (cpuDiff >= threshold) {
throw new Exception("CPU use was above the provided threshold.");
}
break;
case "RAM":
if (ramList.size() < 2) {
throw new Exception("Need at least two RAM samples first.");
}
double ramDiff = ramList.get(0) - ramList.get(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here.

if (ramDiff >= threshold) {
throw new Exception("RAM use was above the provided threshold.");
}
break;
default:
throw new IllegalArgumentException("Please specify either CPU or RAM to check.");
}
}
}
Loading