Skip to content

Commit

Permalink
Added a new param for ros_ocp to support constant data generation (#522)
Browse files Browse the repository at this point in the history
* Added a new param for ros_ocp to support constant data generation
  • Loading branch information
yash2189 authored Jul 31, 2024
1 parent 02bc748 commit c87c693
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 20 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ The `make run-iqe` command by default will run the smoke tests. However, if you
--insights-upload UPLOAD_URL optional, Use local directory path to populate a
"local upload directory".
--ros-ocp-info Optional, Generate ROS for Openshift data.
--constant-values-ros-ocp Optional, Generate constant values for ROS for OpenShift data only
when used with the ros-ocp-info parameter.

OCI Report Options:
--oci-bucket-name BUCKET_NAME optional, OCI bucket name.
Expand Down
2 changes: 1 addition & 1 deletion nise/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = "4.6.4"
__version__ = "4.6.5"

VERSION = __version__.split(".")
7 changes: 7 additions & 0 deletions nise/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,13 @@ def add_ocp_parser_args(parser):
action="store_true",
help="Flag used to add the `daily_reports` marker to manifests.",
)
parser.add_argument(
"--constant-values-ros-ocp",
dest="constant_values_ros_ocp",
required=False,
action="store_true",
help="Flag to generate constant values for ROS for Openshift",
)


def add_oci_parser_args(parser):
Expand Down
54 changes: 36 additions & 18 deletions nise/generators/ocp/ocp_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,29 +172,40 @@ def get_owner_workload(pod, workload=None):
return pod, ok, pod, wt


def generate_randomized_ros_usage(usage_dict, limit_value):
# if usage value is provided in yaml -> avg_value = +- 5% of that specified usage value
if usage_value := usage_dict.get("full_period"):
avg_value = min(round(uniform(usage_value * 0.95, usage_value * 1.05), 5), limit_value)
# if usage value is not specified in yaml -> random avg_usage from 10% to 100% of the limit
else:
avg_value = round(uniform(limit_value * 0.1, limit_value), 5)
def generate_randomized_ros_usage(usage_dict, limit_value, generate_constant_value=False):
if generate_constant_value:
# will generate constant values
if usage_value := usage_dict.get("full_period"):
avg_value = min(round(usage_value, 5), limit_value)
else:
avg_value = round(uniform(limit_value * 0.1, limit_value), 5)

# min value - random float derived from avg_value,
min_value = round(uniform(avg_value * 0.8, avg_value), 5)
# max_value - random float derived from avg_value, but max of limit_value
max_value = min(round(uniform(avg_value, avg_value * 1.2), 5), limit_value)
min_value = avg_value
max_value = avg_value
else:
# This will generate randomised values
# if usage value is provided in yaml -> avg_value = +- 5% of that specified usage value
if usage_value := usage_dict.get("full_period"):
avg_value = min(round(uniform(usage_value * 0.95, usage_value * 1.05), 5), limit_value)
# if usage value is not specified in yaml -> random avg_usage from 10% to 100% of the limit
else:
avg_value = round(uniform(limit_value * 0.1, limit_value), 5)

# min value - random float derived from avg_value,
min_value = round(uniform(avg_value * 0.8, avg_value), 5)
# max_value - random float derived from avg_value, but max of limit_value
max_value = min(round(uniform(avg_value, avg_value * 1.2), 5), limit_value)
return avg_value, min_value, max_value


class OCPGenerator(AbstractGenerator):
"""Defines a abstract class for generators."""

def __init__(self, start_date, end_date, attributes, ros_ocp_info=False):
def __init__(self, start_date, end_date, attributes, ros_ocp_info=False, constant_values_ros_ocp=False):
"""Initialize the generator."""
self._nodes = None
self.ros_ocp_info = ros_ocp_info
self.constant_values_ros_ocp = constant_values_ros_ocp
if attributes:
self._nodes = attributes.get("nodes")

Expand Down Expand Up @@ -405,11 +416,16 @@ def _gen_pods(self, namespaces):
pod, specified_pod.get("workload")
)

cpu_usage_avg, cpu_usage_min, cpu_usage_max = generate_randomized_ros_usage(cpu_usage, cpu_limit)
cpu_usage_avg, cpu_usage_min, cpu_usage_max = generate_randomized_ros_usage(
cpu_usage, cpu_limit, generate_constant_value=self.constant_values_ros_ocp
)
memory_usage_gig_avg, memory_usage_gig_min, memory_usage_gig_max = generate_randomized_ros_usage(
memory_usage_gig, mem_limit_gig
memory_usage_gig, mem_limit_gig, generate_constant_value=self.constant_values_ros_ocp
)
memory_rss_ratio = 1 / round(uniform(1.01, 1.9), 2)
if self.constant_values_ros_ocp:
memory_rss_ratio = 1 / round(1, 2)
else:
memory_rss_ratio = 1 / round(uniform(1.01, 1.9), 2)
cpu_throttle = choices([0, round(cpu_usage_avg / randint(10, 20), 5)], weights=(3, 1))[0]

ros_ocp_data_pods[pod] = {
Expand Down Expand Up @@ -479,9 +495,11 @@ def _gen_pods(self, namespaces):
"pod_labels": self._gen_openshift_labels(),
}
owner_name, owner_kind, workload, workload_type = get_owner_workload(pod)
cpu_usage_avg, cpu_usage_min, cpu_usage_max = generate_randomized_ros_usage({}, cpu_limit)
cpu_usage_avg, cpu_usage_min, cpu_usage_max = generate_randomized_ros_usage(
{}, cpu_limit, generate_constant_value=self.constant_values_ros_ocp
)
memory_usage_gig_avg, memory_usage_gig_min, memory_usage_gig_max = generate_randomized_ros_usage(
{}, mem_limit_gig
{}, mem_limit_gig, generate_constant_value=self.constant_values_ros_ocp
)
memory_rss_ratio = 1 / round(uniform(1.01, 1.9), 2)
cpu_throttle = choices([0, round(cpu_usage_avg / randint(10, 20), 5)], weights=(3, 1))[0]
Expand Down Expand Up @@ -737,7 +755,7 @@ def _randomize_ros_ocp_line_values(self, pod_in):
def _update_ros_ocp_pod_data(self, row, start, end, **kwargs):
"""Update data with generator specific data."""
pod = kwargs.get("pod")
if pod:
if pod and not self.constant_values_ros_ocp:
pod = self._randomize_ros_ocp_line_values(pod)
row.update(pod)
return row
Expand Down
3 changes: 2 additions & 1 deletion nise/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ def ocp_create_report(options): # noqa: C901
cluster_id = options.get("ocp_cluster_id")
static_report_data = options.get("static_report_data")
ros_ocp_info = options.get("ros_ocp_info")
constant_values_ros_ocp = options.get("constant_values_ros_ocp")

if static_report_data:
generators = _get_generators(static_report_data.get("generators"))
Expand Down Expand Up @@ -881,7 +882,7 @@ def ocp_create_report(options): # noqa: C901

gen_start_date, gen_end_date = _create_generator_dates_from_yaml(attributes, month)

gen = generator_cls(gen_start_date, gen_end_date, attributes, ros_ocp_info)
gen = generator_cls(gen_start_date, gen_end_date, attributes, ros_ocp_info, constant_values_ros_ocp)
for report_type in gen.ocp_report_generation.keys():
LOG.info(f"Generating data for {report_type} for {month}")
for hour in gen.generate_data(report_type):
Expand Down
22 changes: 22 additions & 0 deletions tests/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,28 @@ def test_ocp_create_report(self):
self.assertTrue(os.path.isfile(expected_month_output_file))
os.remove(expected_month_output_file)

def test_ocp_create_report_ros_ocp_constant_data_generation(self):
"""Test the ocp report creation method with constant_values_ros_ocp enabled."""
now = datetime.datetime.now().replace(microsecond=0, second=0, minute=0, hour=0)
one_day = datetime.timedelta(days=1)
yesterday = now - one_day
cluster_id = "11112222"
options = {
"start_date": yesterday,
"end_date": now,
"ocp_cluster_id": cluster_id,
"write_monthly": True,
"ros_ocp_info": True,
"constant_values_ros_ocp": True,
}
fix_dates(options, "ocp")
ocp_create_report(options)
for report_type in OCP_REPORT_TYPE_TO_COLS.keys():
month_output_file_name = f"{calendar.month_name[now.month]}-{now.year}-{cluster_id}-{report_type}"
expected_month_output_file = f"{os.getcwd()}/{month_output_file_name}.csv"
self.assertTrue(os.path.isfile(expected_month_output_file))
os.remove(expected_month_output_file)

def test_ocp_create_report_minio_upload(self):
"""Test the ocp report creation method."""
now = datetime.datetime.now().replace(microsecond=0, second=0, minute=0, hour=0)
Expand Down

0 comments on commit c87c693

Please sign in to comment.