diff --git a/MANIFEST.in b/MANIFEST.in index 63d1d941..07e83520 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,2 @@ include nise/aws-template-manifest.json -include nise/ocp-template-manifest.json include nise/yaml_generators/static/* diff --git a/nise/__init__.py b/nise/__init__.py index 14f0ca77..bad76ba7 100644 --- a/nise/__init__.py +++ b/nise/__init__.py @@ -1,3 +1,3 @@ -__version__ = "4.3.3" +__version__ = "4.4.0" VERSION = __version__.split(".") diff --git a/nise/__main__.py b/nise/__main__.py index 66b18aeb..2ae1d8cb 100644 --- a/nise/__main__.py +++ b/nise/__main__.py @@ -21,10 +21,12 @@ import os import sys import time +from datetime import timezone from pathlib import Path from pprint import pformat from dateutil import parser as date_parser +from dateutil.parser import ParserError from dateutil.relativedelta import relativedelta from nise import __version__ from nise.report import aws_create_marketplace_report @@ -50,11 +52,13 @@ class NiseError(Exception): def valid_date(date_string): """Create date from date string.""" + if "T" in date_string and not date_string.endswith("+0000"): + date_string += " +0000" try: - valid = datetime.datetime.strptime(date_string, "%Y-%m-%d") - except ValueError: + valid = date_parser.parse(date_string) + except ParserError as e: msg = f"{date_string} is an unsupported date format." - raise argparse.ArgumentTypeError(msg) + raise argparse.ArgumentTypeError(msg) from e return valid @@ -85,7 +89,7 @@ def valid_currency(currency): def today(): """Create the date of today.""" - return datetime.datetime.now().replace(microsecond=0, second=0, minute=0) + return datetime.datetime.now(tz=timezone.utc).replace(microsecond=0, second=0, minute=0) def add_aws_parser_args(parser): @@ -274,6 +278,13 @@ def add_ocp_parser_args(parser): action="store_true", help="Generate ROS for Openshift data", ) + parser.add_argument( + "--daily-reports", + dest="daily_reports", + required=False, + action="store_true", + help="Flag used to add the `daily_reports` marker to manifests.", + ) def add_oci_parser_args(parser): @@ -324,21 +335,21 @@ def create_parser(): parent_parser.add_argument( "-s", "--start-date", - metavar="YYYY-MM-DD", + metavar="YYYY-MM-DD[THH:MM:SS +0000]", dest="start_date", required=False, type=valid_date, - help="Date to start generating data (YYYY-MM-DD)", + help="Date to start generating data (YYYY-MM-DD[THH:MM:SS +0000])", ) parent_parser.add_argument( "-e", "--end-date", - metavar="YYYY-MM-DD", + metavar="YYYY-MM-DD[THH:MM:SS +0000]", dest="end_date", required=False, type=valid_date, default=today(), - help="Date to end generating data (YYYY-MM-DD). Default is today.", + help="Date to end generating data (YYYY-MM-DD[THH:MM:SS +0000]). Default is today.", ) parent_parser.add_argument( "--file-row-limit", @@ -654,7 +665,6 @@ def _load_static_report_data(options): start_date = get_start_date(attributes, options) generated_start_date = calculate_start_date(start_date) start_dates.append(generated_start_date) - if attributes.get("end_date"): generated_end_date = calculate_end_date(generated_start_date, attributes.get("end_date")) elif options.get("end_date") and options.get("end_date").date() != today().date(): @@ -705,6 +715,8 @@ def calculate_start_date(start_date): generated_start_date = date_parser.parse(start_date) else: generated_start_date = today().replace(day=1, hour=0, minute=0, second=0) + if generated_start_date.tzinfo is None: + generated_start_date = generated_start_date.replace(tzinfo=timezone.utc) return generated_start_date @@ -726,6 +738,8 @@ def calculate_end_date(start_date, end_date): generated_end_date = offset_date else: generated_end_date = min(start_date + relativedelta(days=offset), today()) + if generated_end_date.tzinfo is None: + generated_end_date = generated_end_date.replace(tzinfo=timezone.utc) if generated_end_date < start_date: raise ValueError("Static yaml error: End date must be after start date.") return generated_end_date @@ -734,9 +748,16 @@ def calculate_end_date(start_date, end_date): def fix_dates(options, provider_type): """Correct any unique dates.""" # Azure end_date is always the following day + if options["start_date"].tzinfo is None: + options["start_date"] = options["start_date"].replace(tzinfo=timezone.utc) + if options["end_date"].tzinfo is None: + options["end_date"] = options["end_date"].replace(tzinfo=timezone.utc) if provider_type == "azure": options["end_date"] += relativedelta(days=1) + if options["end_date"] < options["start_date"]: + raise ValueError("End date must be after start date.") + def run(provider_type, options): """Run nise.""" @@ -746,6 +767,8 @@ def run(provider_type, options): if not static_data_bool: fix_dates(options, provider_type) + LOG.debug("Options are: %s", pformat(options)) + LOG.info("Creating reports...") if provider_type == "aws": aws_create_report(options) diff --git a/nise/generators/gcp/cloud_storage_generator.py b/nise/generators/gcp/cloud_storage_generator.py index c651be3b..217e5bfd 100644 --- a/nise/generators/gcp/cloud_storage_generator.py +++ b/nise/generators/gcp/cloud_storage_generator.py @@ -85,7 +85,7 @@ def _update_data(self, row): # noqa: C901 credit, credit_total = self._gen_credit(self.credit_total, self._credit_amount) self.credit_total = credit_total row["credits"] = credit - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") row["invoice.month"] = f"{usage_date.year}{usage_date.month:02d}" if self.attributes: @@ -151,8 +151,8 @@ def _update_data(self, row): # noqa: C901 row["cost_type"] = "regular" row["currency_conversion_rate"] = 1 invoice = {} - year = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S").year - month = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S").month + year = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m").year + month = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m").month invoice["month"] = f"{year}{month:02d}" row["invoice"] = invoice if self.resource_level: diff --git a/nise/generators/gcp/compute_engine_generator.py b/nise/generators/gcp/compute_engine_generator.py index dc6d447c..45185909 100644 --- a/nise/generators/gcp/compute_engine_generator.py +++ b/nise/generators/gcp/compute_engine_generator.py @@ -103,7 +103,7 @@ def _update_data(self, row): # noqa: C901 credit, credit_total = self._gen_credit(self.credit_total, self._credit_amount) self.credit_total = credit_total row["credits"] = credit - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") row["invoice.month"] = f"{usage_date.year}{usage_date.month:02d}" if self.attributes: @@ -170,8 +170,8 @@ def _update_data(self, row): # noqa: C901 row["cost_type"] = "regular" row["currency_conversion_rate"] = 1 invoice = {} - year = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S").year - month = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S").month + year = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m").year + month = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m").month invoice["month"] = f"{year}{month:02d}" row["invoice"] = invoice if self.resource_level: diff --git a/nise/generators/gcp/gcp_database_generator.py b/nise/generators/gcp/gcp_database_generator.py index fd5ac4f0..cbfbe4a3 100644 --- a/nise/generators/gcp/gcp_database_generator.py +++ b/nise/generators/gcp/gcp_database_generator.py @@ -90,7 +90,7 @@ def _update_data(self, row): # noqa: C901 credit, credit_total = self._gen_credit(self.credit_total, self._credit_amount) self.credit_total = credit_total row["credits"] = credit - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") row["invoice.month"] = f"{usage_date.year}{usage_date.month:02d}" if self.attributes: @@ -157,9 +157,9 @@ def _update_data(self, row): # noqa: C901 credit, credit_total = self._gen_credit(self.credit_total, self._credit_amount, True) self.credit_total = credit_total row["credits"] = credit - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") invoice = {} - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") invoice["month"] = f"{usage_date.year}{usage_date.month:02d}" row["invoice"] = invoice if self.resource_level: diff --git a/nise/generators/gcp/gcp_network_generator.py b/nise/generators/gcp/gcp_network_generator.py index f17d0e2f..65c9c4c9 100644 --- a/nise/generators/gcp/gcp_network_generator.py +++ b/nise/generators/gcp/gcp_network_generator.py @@ -96,7 +96,7 @@ def _update_data(self, row): # noqa: C901 credit, credit_total = self._gen_credit(self.credit_total, self._credit_amount) self.credit_total = credit_total row["credits"] = credit - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") row["invoice.month"] = f"{usage_date.year}{usage_date.month:02d}" if self.attributes: @@ -162,9 +162,9 @@ def _update_data(self, row): # noqa: C901 credit, credit_total = self._gen_credit(self.credit_total, self._credit_amount, True) self.credit_total = credit_total row["credits"] = credit - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") invoice = {} - usage_date = datetime.strptime(row.get("usage_start_time"), "%Y-%m-%dT%H:%M:%S") + usage_date = datetime.strptime(row.get("usage_start_time")[:7], "%Y-%m") invoice["month"] = f"{usage_date.year}{usage_date.month:02d}" row["invoice"] = invoice if self.resource_level: diff --git a/nise/generators/generator.py b/nise/generators/generator.py index f8f682b9..3eda7013 100644 --- a/nise/generators/generator.py +++ b/nise/generators/generator.py @@ -27,10 +27,11 @@ class AbstractGenerator(ABC): """Defines a abstract class for generators.""" - def __init__(self, start_date, end_date): + def __init__(self, start_date, end_date, hour_delta=datetime.timedelta(minutes=60)): """Initialize the generator.""" self.start_date = start_date self.end_date = end_date + self.hour_delta = hour_delta self.hours = self._set_hours() self.quarter_hours = self._set_quarter_hours() self.days = self._set_days() @@ -49,12 +50,11 @@ def _set_hours(self): if self.end_date < self.start_date: raise ValueError("start_date must be a date object less than end_date.") - one_hour = datetime.timedelta(minutes=60) cur_date = self.start_date - while (cur_date + one_hour) <= self.end_date: - cur_hours = {"start": cur_date, "end": cur_date + one_hour} + while (cur_date + self.hour_delta) <= self.end_date: + cur_hours = {"start": cur_date, "end": cur_date + self.hour_delta} hours.append(cur_hours) - cur_date = cur_date + one_hour + cur_date = cur_date + datetime.timedelta(minutes=60) return hours def _set_quarter_hours(self): diff --git a/nise/generators/ocp/ocp_generator.py b/nise/generators/ocp/ocp_generator.py index 588f3a24..d1e975bb 100644 --- a/nise/generators/ocp/ocp_generator.py +++ b/nise/generators/ocp/ocp_generator.py @@ -195,7 +195,7 @@ def __init__(self, start_date, end_date, attributes, ros_ocp_info=False): if attributes: self._nodes = attributes.get("nodes") - super().__init__(start_date, end_date) + super().__init__(start_date, end_date, hour_delta=datetime.timedelta(minutes=59, seconds=59)) self.apps = [ self.fake.word(), self.fake.word(), diff --git a/nise/manifest.py b/nise/manifest.py index 8b2b8486..042d4e0b 100644 --- a/nise/manifest.py +++ b/nise/manifest.py @@ -24,7 +24,6 @@ TEMPLATE_DIR = os.path.dirname(__file__) AWS_TEMPLATE_FILE = "aws-template-manifest.json" -OCP_TEMPLATE_FILE = "ocp-template-manifest.json" def _manifest_datetime_str(date_time): @@ -51,7 +50,7 @@ def _manifest_datetime_range(start, end): """ start_str = start.strftime("%Y%m%d") end_str = end.strftime("%Y%m%d") - return start_str + "-" + end_str + return f"{start_str}-{end_str}" def aws_generate_manifest(fake, template_data): @@ -111,8 +110,5 @@ def ocp_generate_manifest(template_data): (String): Rendered template data """ - template_loader = jinja2.FileSystemLoader(searchpath=TEMPLATE_DIR) - template_env = jinja2.Environment(loader=template_loader) - template = template_env.get_template(OCP_TEMPLATE_FILE) - output = template.render(template_data) - return output + # template_data["cr_status"] = json.dumps(template_data["cr_status"], indent=2) + return json.dumps(template_data, indent=2) diff --git a/nise/ocp-template-manifest.json b/nise/ocp-template-manifest.json deleted file mode 100644 index 98769fa8..00000000 --- a/nise/ocp-template-manifest.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "uuid": "{{ ocp_assembly_id }}", - "cluster_id": "{{ ocp_cluster_id }}", - "version": "{{ version }}", - "date": "{{ report_datetime }}", - "files": ["{{ files }}"], - "resource_optimization_files": {% if ros_files %} ["{{ros_files}}"] {% else %} null {% endif %}, - "start": "{{ start }}", - "end": "{{ end }}", - "certified": "{{ certified }}", - "cr_status": {{ cr_status }} -} diff --git a/nise/report.py b/nise/report.py index 9d304634..3ccdd7df 100644 --- a/nise/report.py +++ b/nise/report.py @@ -28,6 +28,7 @@ import string import tarfile from datetime import datetime +from datetime import timezone from random import randint from tempfile import gettempdir from tempfile import NamedTemporaryFile @@ -289,28 +290,28 @@ def _create_month_list(start_date, end_date): while current <= end_date: month = { "name": calendar.month_name[current.month], - "start": datetime(year=current.year, month=current.month, day=1), + "start": datetime(year=current.year, month=current.month, day=1, tzinfo=timezone.utc), "end": datetime( year=current.year, month=current.month, day=calendar.monthrange(year=current.year, month=current.month)[1], hour=23, minute=59, + tzinfo=timezone.utc, ), } - if current.month == start_date.month: + if current.year == start_date.year and current.month == start_date.month: # First month start with start_date - month["start"] = start_date + month["start"] = start_date.replace(tzinfo=timezone.utc) if current < end_month_first_day: # can not compare months in this case - January < December month["end"] = (month.get("end") + relativedelta(days=1)).replace(hour=0, minute=0) - if current.month == end_date.month: + if current.year == end_date.year and current.month == end_date.month: # Last month ends with end_date - month["end"] = end_date.replace(hour=23, minute=59) + month["end"] = end_date.replace(tzinfo=timezone.utc) months.append(month) current += relativedelta(months=+1) - return months @@ -405,9 +406,9 @@ def _get_generators(generator_list): for generator_cls, attributes in item.items(): generator_obj = {"generator": getattr(importlib.import_module(__name__), generator_cls)} if attributes.get("start_date"): - attributes["start_date"] = parser.parse(attributes.get("start_date")) + attributes["start_date"] = parser.parse(attributes.get("start_date")).replace(tzinfo=timezone.utc) if attributes.get("end_date"): - attributes["end_date"] = parser.parse(attributes.get("end_date")) + attributes["end_date"] = parser.parse(attributes.get("end_date")).replace(tzinfo=timezone.utc) generator_obj["attributes"] = attributes generators.append(generator_obj) return generators @@ -421,9 +422,9 @@ def _get_jsonl_generators(generator_list): for generator_cls, attributes in item.items(): generator_obj = {"generator": getattr(importlib.import_module(__name__), "JSONL" + generator_cls)} if attributes.get("start_date"): - attributes["start_date"] = parser.parse(attributes.get("start_date")) + attributes["start_date"] = parser.parse(attributes.get("start_date")).replace(tzinfo=timezone.utc) if attributes.get("end_date"): - attributes["end_date"] = parser.parse(attributes.get("end_date")) + attributes["end_date"] = parser.parse(attributes.get("end_date")).replace(tzinfo=timezone.utc) if attributes.get("currency"): attributes["currency"] = attributes.get("currency") generator_obj["attributes"] = attributes @@ -808,7 +809,7 @@ def ocp_create_report(options): # noqa: C901 gen = generator_cls(gen_start_date, gen_end_date, attributes, ros_ocp_info) for report_type in gen.ocp_report_generation.keys(): - LOG.info(f"Generating data for {report_type} for {month.get('name')}") + LOG.info(f"Generating data for {report_type} for {month}") for hour in gen.generate_data(report_type): data[report_type] += [hour] if len(data[report_type]) == options.get("row_limit"): @@ -857,14 +858,8 @@ def ocp_create_report(options): # noqa: C901 monthly_ros_files[num_file], temp_filename, "payload" ) - manifest_file_names = ", ".join(f'"{w}"' for w in temp_files) - if not temp_ros_files: - manifest_ros_data = None - elif len(temp_ros_files) == 1: - (key,) = temp_ros_files.keys() - manifest_ros_data = f"{key}" - else: - manifest_ros_data = ", ".join(f'"{w}"' for w in temp_ros_files)[1:-1] + manifest_file_names = list(temp_files) + manifest_ros_data = list(temp_ros_files) if temp_ros_files else None cr_status = { "clusterID": "4e009161-4f40-42c8-877c-3e59f6baea3d", "clusterVersion": "stable-4.6", @@ -897,19 +892,22 @@ def ocp_create_report(options): # noqa: C901 "check_cycle": 1440, }, } - cr_status = json.dumps(cr_status) manifest_values = { - "ocp_cluster_id": cluster_id, - "ocp_assembly_id": ocp_assembly_id, - "report_datetime": report_datetime, - "files": manifest_file_names[1:-1], - "ros_files": manifest_ros_data, - "start": gen_start_date, - "end": gen_end_date, + "cluster_id": str(cluster_id), + "uuid": str(ocp_assembly_id), + "date": report_datetime.isoformat(timespec="microseconds"), + "files": manifest_file_names, + "start": gen_start_date.isoformat(timespec="microseconds"), + "end": gen_end_date.isoformat(timespec="microseconds"), "version": __version__, "certified": False, "cr_status": cr_status, } + if manifest_ros_data: + manifest_values["resource_optimization_files"] = manifest_ros_data + if options.get("daily_reports"): + manifest_values["daily_reports"] = True + manifest_data = ocp_generate_manifest(manifest_values) temp_manifest = _write_manifest(manifest_data) temp_manifest_name = create_temporary_copy(temp_manifest, "manifest.json", "payload") diff --git a/tests/test_main.py b/tests/test_main.py index 2f234b05..abb86ad7 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -20,6 +20,7 @@ from datetime import date from datetime import datetime from datetime import timedelta +from datetime import timezone from unittest import TestCase from unittest.mock import patch @@ -367,11 +368,12 @@ def test_load_static_report_data_azure_dates(self): _load_static_report_data(options) gen_values = dict(*options.get("static_report_data").get("generators")[0].values()) self.assertEqual( - gen_values.get("start_date"), str(datetime.now().replace(microsecond=0, second=0, minute=0, hour=0)) + gen_values.get("start_date"), + str(datetime.now(tz=timezone.utc).replace(microsecond=0, second=0, minute=0, hour=0)), ) self.assertEqual( gen_values.get("end_date"), - str(datetime.now().replace(microsecond=0, second=0, minute=0) + timedelta(hours=24)), + str(datetime.now(tz=timezone.utc).replace(microsecond=0, second=0, minute=0) + timedelta(hours=24)), ) def test_invalid_gcp_inputs(self): @@ -557,14 +559,26 @@ def test_aws_dates(self, mock_load): ] static_report_data = {"generators": aws_gens} expected = { - "aws_gen_first": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, - "aws_gen_first_second": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 2, 0, 0)}, + "aws_gen_first": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + }, + "aws_gen_first_second": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 2, 0, 0, tzinfo=timezone.utc), + }, "aws_gen_first_start": { - "start_date": datetime(2020, 6, 1, 0, 0), - "end_date": datetime.now().replace(minute=0, second=0, microsecond=0), + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime.now(tz=timezone.utc).replace(minute=0, second=0, microsecond=0), + }, + "aws_gen_last": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + }, + "aws_gen_last_first": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), }, - "aws_gen_last": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 5, 31, 0, 0)}, - "aws_gen_last_first": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, } options = {"provider": "aws", "static_report_file": "tests/aws_static_report.yml"} mock_load.return_value = static_report_data @@ -602,19 +616,25 @@ def test_aws_market_dates(self, mock_load): ] static_report_data = {"generators": aws_mp_gens} expected = { - "aws_mp_gen_first": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, + "aws_mp_gen_first": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + }, "aws_mp_gen_first_second": { - "start_date": datetime(2020, 6, 1, 0, 0), - "end_date": datetime(2020, 6, 2, 0, 0), + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 2, 0, 0, tzinfo=timezone.utc), }, "aws_mp_gen_first_start": { - "start_date": datetime(2020, 6, 1, 0, 0), - "end_date": datetime.now().replace(minute=0, second=0, microsecond=0), + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime.now(tz=timezone.utc).replace(minute=0, second=0, microsecond=0), + }, + "aws_mp_gen_last": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), }, - "aws_mp_gen_last": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 5, 31, 0, 0)}, "aws_mp_gen_last_first": { - "start_date": datetime(2020, 5, 31, 0, 0), - "end_date": datetime(2020, 6, 1, 0, 0), + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), }, } options = {"provider": "aws-marketplace", "static_report_file": "tests/aws_static_report.yml"} @@ -630,7 +650,7 @@ def test_aws_market_dates(self, mock_load): def test_ocp_dates(self, mock_load): """Test that select static-data-file dates return correct dates.""" ocp_gens = [ - {"ocp_gen_first": {"start_date": datetime(2020, 6, 1).date(), "end_date": datetime(2020, 6, 1).date()}}, + {"ocp_gen_first": {"start_date": "2020-06-01", "end_date": datetime(2020, 6, 1).date()}}, { "ocp_gen_first_second": { "start_date": datetime(2020, 6, 1).date(), @@ -645,17 +665,34 @@ def test_ocp_dates(self, mock_load): "end_date": datetime(2020, 6, 1).date(), } }, + {"ocp_gen_times": {"start_date": "2023-08-01T05", "end_date": "2023-08-02T23:45"}}, ] static_report_data = {"generators": ocp_gens} expected = { - "ocp_gen_first": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, - "ocp_gen_first_second": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 2, 0, 0)}, + "ocp_gen_first": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + }, + "ocp_gen_first_second": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 2, 0, 0, tzinfo=timezone.utc), + }, "ocp_gen_first_start": { - "start_date": datetime(2020, 6, 1, 0, 0), - "end_date": datetime.now().replace(minute=0, second=0, microsecond=0), + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime.now(tz=timezone.utc).replace(minute=0, second=0, microsecond=0), + }, + "ocp_gen_last": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + }, + "ocp_gen_last_first": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + }, + "ocp_gen_times": { + "start_date": datetime(2023, 8, 1, 5, 0, tzinfo=timezone.utc), + "end_date": datetime(2023, 8, 2, 23, 45, tzinfo=timezone.utc), }, - "ocp_gen_last": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 5, 31, 0, 0)}, - "ocp_gen_last_first": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, } options = {"provider": "ocp", "static_report_file": "tests/ocp_static_report.yml"} mock_load.return_value = static_report_data @@ -688,19 +725,26 @@ def test_azure_dates(self, mock_load): ] static_report_data = {"generators": azure_gens} expected = { - "azure_gen_first": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 2, 0, 0)}, + "azure_gen_first": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 2, 0, 0, tzinfo=timezone.utc), + }, "azure_gen_first_second": { - "start_date": datetime(2020, 6, 1, 0, 0), - "end_date": datetime(2020, 6, 3, 0, 0), + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 3, 0, 0, tzinfo=timezone.utc), }, "azure_gen_first_start": { - "start_date": datetime(2020, 6, 1, 0, 0), - "end_date": datetime.now().replace(microsecond=0, second=0, minute=0) + timedelta(hours=24), + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime.now(tz=timezone.utc).replace(microsecond=0, second=0, minute=0) + + timedelta(hours=24), + }, + "azure_gen_last": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), }, - "azure_gen_last": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, "azure_gen_last_first": { - "start_date": datetime(2020, 5, 31, 0, 0), - "end_date": datetime(2020, 6, 2, 0, 0), + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 2, 0, 0, tzinfo=timezone.utc), }, } options = {"provider": "azure", "static_report_file": "tests/azure_static_report.yml"} @@ -734,14 +778,26 @@ def test_oci_dates(self, mock_load): ] static_report_data = {"generators": oci_gens} expected = { - "oci_gen_first": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, - "oci_gen_first_second": {"start_date": datetime(2020, 6, 1, 0, 0), "end_date": datetime(2020, 6, 2, 0, 0)}, + "oci_gen_first": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + }, + "oci_gen_first_second": { + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 2, 0, 0, tzinfo=timezone.utc), + }, "oci_gen_first_start": { - "start_date": datetime(2020, 6, 1, 0, 0), - "end_date": datetime.now().replace(minute=0, second=0, microsecond=0), + "start_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), + "end_date": datetime.now(tz=timezone.utc).replace(minute=0, second=0, microsecond=0), + }, + "oci_gen_last": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + }, + "oci_gen_last_first": { + "start_date": datetime(2020, 5, 31, 0, 0, tzinfo=timezone.utc), + "end_date": datetime(2020, 6, 1, 0, 0, tzinfo=timezone.utc), }, - "oci_gen_last": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 5, 31, 0, 0)}, - "oci_gen_last_first": {"start_date": datetime(2020, 5, 31, 0, 0), "end_date": datetime(2020, 6, 1, 0, 0)}, } options = {"provider": "oci", "static_report_file": "tests/oci_static_report.yml"} mock_load.return_value = static_report_data diff --git a/tests/test_report.py b/tests/test_report.py index 23b4ef5c..d0c999fc 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -30,6 +30,7 @@ import faker from dateutil.relativedelta import relativedelta +from nise.__main__ import fix_dates from nise.generators.oci.oci_generator import OCI_REPORT_TYPE_TO_COLS from nise.generators.ocp.ocp_generator import OCP_REPORT_TYPE_TO_COLS from nise.report import _convert_bytes @@ -153,36 +154,45 @@ def test_create_generator_for_dates_from_yaml_middle_month(self): def test_create_month_list(self): """Test to create month lists.""" + self.maxDiff = None test_matrix = [ { "start_date": datetime.datetime(year=2018, month=1, day=15), - "end_date": datetime.datetime(year=2018, month=1, day=30), + "end_date": datetime.datetime(year=2018, month=1, day=30, hour=23, minute=59), "expected_list": [ { "name": "January", - "start": datetime.datetime(year=2018, month=1, day=15), - "end": datetime.datetime(year=2018, month=1, day=30, hour=23, minute=59), + "start": datetime.datetime(year=2018, month=1, day=15, tzinfo=datetime.timezone.utc), + "end": datetime.datetime( + year=2018, month=1, day=30, hour=23, minute=59, tzinfo=datetime.timezone.utc + ), } ], }, { "start_date": datetime.datetime(year=2018, month=11, day=15), - "end_date": datetime.datetime(year=2019, month=1, day=5), + "end_date": datetime.datetime(year=2019, month=1, day=5, hour=23, minute=59), "expected_list": [ { "name": "November", - "start": datetime.datetime(year=2018, month=11, day=15), - "end": datetime.datetime(year=2018, month=12, day=1, hour=0, minute=0), + "start": datetime.datetime(year=2018, month=11, day=15, tzinfo=datetime.timezone.utc), + "end": datetime.datetime( + year=2018, month=12, day=1, hour=0, minute=0, tzinfo=datetime.timezone.utc + ), }, { "name": "December", - "start": datetime.datetime(year=2018, month=12, day=1), - "end": datetime.datetime(year=2019, month=1, day=1, hour=0, minute=0), + "start": datetime.datetime(year=2018, month=12, day=1, tzinfo=datetime.timezone.utc), + "end": datetime.datetime( + year=2019, month=1, day=1, hour=0, minute=0, tzinfo=datetime.timezone.utc + ), }, { "name": "January", - "start": datetime.datetime(year=2019, month=1, day=1), - "end": datetime.datetime(year=2019, month=1, day=5, hour=23, minute=59), + "start": datetime.datetime(year=2019, month=1, day=1, tzinfo=datetime.timezone.utc), + "end": datetime.datetime( + year=2019, month=1, day=5, hour=23, minute=59, tzinfo=datetime.timezone.utc + ), }, ], }, @@ -192,21 +202,26 @@ def test_create_month_list(self): "expected_list": [ { "name": "June", - "start": datetime.datetime(year=2021, month=6, day=1), - "end": datetime.datetime(year=2021, month=7, day=1, hour=0, minute=0), + "start": datetime.datetime(year=2021, month=6, day=1, tzinfo=datetime.timezone.utc), + "end": datetime.datetime( + year=2021, month=7, day=1, hour=0, minute=0, tzinfo=datetime.timezone.utc + ), }, { "name": "July", - "start": datetime.datetime(year=2021, month=7, day=1), - "end": datetime.datetime(year=2021, month=7, day=29, hour=23, minute=59), + "start": datetime.datetime(year=2021, month=7, day=1, tzinfo=datetime.timezone.utc), + "end": datetime.datetime( + year=2021, month=7, day=29, hour=0, minute=0, tzinfo=datetime.timezone.utc + ), }, ], }, ] for test_case in test_matrix: - output = _create_month_list(test_case["start_date"], test_case["end_date"]) - self.assertCountEqual(output, test_case["expected_list"]) + with self.subTest(test=test_case): + output = _create_month_list(test_case["start_date"], test_case["end_date"]) + self.assertCountEqual(output, test_case["expected_list"]) def test_get_generators(self): """Test the _get_generators helper function.""" @@ -351,6 +366,7 @@ def test_aws_create_report_with_s3(self, mock_upload_to_s3): "aws_report_name": "cur_report", "write_monthly": True, } + fix_dates(options, "aws") aws_create_report(options) month_output_file_name = "{}-{}-{}".format(calendar.month_name[now.month], now.year, "cur_report") expected_month_output_file = "{}/{}.csv".format(os.getcwd(), month_output_file_name) @@ -370,6 +386,7 @@ def test_aws_create_report_with_local_dir(self): "aws_report_name": "cur_report", "write_monthly": True, } + fix_dates(options, "aws") aws_create_report(options) month_output_file_name = "{}-{}-{}".format(calendar.month_name[now.month], now.year, "cur_report") expected_month_output_file = "{}/{}.csv".format(os.getcwd(), month_output_file_name) @@ -391,6 +408,7 @@ def test_aws_create_report_with_local_dir_report_prefix(self): "aws_prefix_name": "my_prefix", "write_monthly": True, } + fix_dates(options, "aws") aws_create_report(options) month_output_file_name = "{}-{}-{}".format(calendar.month_name[now.month], now.year, "cur_report") expected_month_output_file = "{}/{}.csv".format(os.getcwd(), month_output_file_name) @@ -529,6 +547,7 @@ def test_aws_create_report_with_local_dir_static_generation(self): "static_report_data": static_aws_data, "write_monthly": True, } + fix_dates(options, "aws") aws_create_report(options) month_output_file_name = "{}-{}-{}".format(calendar.month_name[now.month], now.year, "cur_report") expected_month_output_file = "{}/{}.csv".format(os.getcwd(), month_output_file_name) @@ -555,6 +574,7 @@ def test_aws_create_report_with_local_dir_static_generation_dates(self): "static_report_data": static_aws_data, "write_monthly": True, } + fix_dates(options, "aws") aws_create_report(options) month_output_file_name = "{}-{}-{}".format(calendar.month_name[now.month], now.year, "cur_report") expected_month_output_file = "{}/{}.csv".format(os.getcwd(), month_output_file_name) @@ -643,6 +663,7 @@ def test_aws_create_report_with_local_dir_static_generation_multi_file(self): "row_limit": 20, "write_monthly": True, } + fix_dates(options, "aws") aws_create_report(options) month_output_file_name = "{}-{}-{}".format(calendar.month_name[now.month], now.year, "cur_report") expected_month_output_file_1 = "{}/{}-1.csv".format(os.getcwd(), month_output_file_name) @@ -809,6 +830,7 @@ def test_ocp_create_report(self): "write_monthly": True, "ros_ocp_info": True, } + fix_dates(options, "ocp") ocp_create_report(options) for report_type in OCP_REPORT_TYPE_TO_COLS.keys(): month_output_file_name = "{}-{}-{}-{}".format( @@ -833,6 +855,7 @@ def test_ocp_create_report_with_local_dir(self): "write_monthly": True, "ros_ocp_info": True, } + fix_dates(options, "ocp") ocp_create_report(options) for report_type in OCP_REPORT_TYPE_TO_COLS.keys(): month_output_file_name = "{}-{}-{}-{}".format( @@ -903,6 +926,7 @@ def test_ocp_create_report_with_local_dir_static_generation(self): "static_report_data": static_ocp_data, "write_monthly": True, } + fix_dates(options, "ocp") ocp_create_report(options) for report_type in OCP_REPORT_TYPE_TO_COLS.keys(): @@ -989,6 +1013,7 @@ def test_ocp_create_report_with_local_dir_static_generation_with_dates(self): "static_report_data": static_ocp_data, "write_monthly": True, } + fix_dates(options, "ocp") ocp_create_report(options) for report_type in OCP_REPORT_TYPE_TO_COLS.keys(): @@ -1032,6 +1057,7 @@ def test_ocp_create_report_without_write_monthly(self): yesterday = now - one_day cluster_id = "11112222" options = {"start_date": yesterday, "end_date": now, "ocp_cluster_id": cluster_id, "ros_ocp_info": True} + fix_dates(options, "ocp") ocp_create_report(options) for report_type in OCP_REPORT_TYPE_TO_COLS.keys(): month_output_file_name = "{}-{}-{}-{}".format( @@ -1105,6 +1131,7 @@ def test_ocp_create_report_with_local_dir_static_generation_multi_file(self): "row_limit": 5, "write_monthly": True, } + fix_dates(options, "ocp") ocp_create_report(options) for report_type in OCP_REPORT_TYPE_TO_COLS.keys(): @@ -1167,6 +1194,7 @@ def test_azure_create_report(self, mock_name): one_day = datetime.timedelta(days=1) yesterday = now - one_day options = {"start_date": yesterday, "end_date": now, "write_monthly": True} + fix_dates(options, "azure") azure_create_report(options) local_path = self.MOCK_AZURE_REPORT_FILENAME self.assertTrue(os.path.isfile(local_path)) @@ -1210,7 +1238,7 @@ def test_azure_create_report_with_static_data(self, mock_name): "static_report_data": static_azure_data, "write_monthly": True, } - + fix_dates(options, "azure") azure_create_report(options) local_path = self.MOCK_AZURE_REPORT_FILENAME self.assertTrue(os.path.isfile(local_path)) @@ -1231,6 +1259,7 @@ def test_azure_create_report_with_local_dir(self, mock_name): "azure_report_name": "cur_report", "write_monthly": True, } + fix_dates(options, "azure") azure_create_report(options) expected_month_output_file = self.MOCK_AZURE_REPORT_FILENAME self.assertTrue(os.path.isfile(expected_month_output_file)) @@ -1268,6 +1297,7 @@ def test_azure_create_report_upload_to_azure(self, mock_name, mock_upload): "azure_report_name": "cur_report", "write_monthly": True, } + fix_dates(options, "azure") azure_create_report(options) mock_upload.assert_called() os.remove(self.MOCK_AZURE_REPORT_FILENAME) @@ -1280,6 +1310,7 @@ def test_azure_create_report_without_write_monthly(self, mock_name): one_day = datetime.timedelta(days=1) yesterday = now - one_day options = {"start_date": yesterday, "end_date": now} + fix_dates(options, "azure") azure_create_report(options) local_path = self.MOCK_AZURE_REPORT_FILENAME self.assertFalse(os.path.isfile(local_path)) @@ -1296,9 +1327,9 @@ def test_gcp_create_report(self): one_day = datetime.timedelta(days=1) yesterday = now - one_day report_prefix = "test_report" - gcp_create_report( - {"start_date": yesterday, "end_date": now, "gcp_report_prefix": report_prefix, "write_monthly": True} - ) + options = {"start_date": yesterday, "end_date": now, "gcp_report_prefix": report_prefix, "write_monthly": True} + fix_dates(options, "gcp") + gcp_create_report(options) output_file_name = f"{report_prefix}.csv" expected_output_file_path = "{}/{}".format(os.getcwd(), output_file_name) @@ -1311,16 +1342,16 @@ def test_gcp_create_report_resource_level(self): one_day = datetime.timedelta(days=1) yesterday = now - one_day report_prefix = "test_report" - gcp_create_report( - { - "start_date": yesterday, - "end_date": now, - "gcp_report_prefix": report_prefix, - "write_monthly": True, - "gcp_dataset_name": "gcp-resource-dataset", - "gcp_resource_level": True, - } - ) + options = { + "start_date": yesterday, + "end_date": now, + "gcp_report_prefix": report_prefix, + "write_monthly": True, + "gcp_dataset_name": "gcp-resource-dataset", + "gcp_resource_level": True, + } + fix_dates(options, "gcp") + gcp_create_report(options) output_file_name = f"{report_prefix}.json" expected_output_file_path = "{}/{}".format(os.getcwd(), output_file_name) @@ -1334,16 +1365,17 @@ def test_gcp_create_report_with_dataset_name(self): yesterday = now - one_day report_prefix = "test_report" dataset_name = "test_name" - gcp_create_report( - { - "start_date": yesterday, - "end_date": now, - "currency": "USD", - "gcp_report_prefix": report_prefix, - "write_monthly": True, - "gcp_dataset_name": dataset_name, - } - ) + options = { + "start_date": yesterday, + "end_date": now, + "currency": "USD", + "gcp_report_prefix": report_prefix, + "write_monthly": True, + "gcp_dataset_name": dataset_name, + } + + fix_dates(options, "gcp") + gcp_create_report(options) output_file_name = f"{report_prefix}.json" expected_output_file_path = "{}/{}".format(os.getcwd(), output_file_name) @@ -1357,16 +1389,17 @@ def test_gcp_create_report_with_dataset_name_no_report_prefix(self): yesterday = now - one_day dataset_name = "test_name" etag = "test_tag" - gcp_create_report( - { - "start_date": yesterday, - "end_date": now, - "currency": "USD", - "write_monthly": True, - "gcp_dataset_name": dataset_name, - "gcp_etag": etag, - } - ) + options = { + "start_date": yesterday, + "end_date": now, + "currency": "USD", + "write_monthly": True, + "gcp_dataset_name": dataset_name, + "gcp_etag": etag, + } + + fix_dates(options, "gcp") + gcp_create_report(options) invoice_month = yesterday.strftime("%Y%m") scan_start = yesterday.date() scan_end = now.date() @@ -1381,7 +1414,9 @@ def test_gcp_create_report_no_report_prefix(self, patch_etag): now = datetime.datetime.now().replace(microsecond=0, second=0, minute=0, hour=0) one_day = datetime.timedelta(days=1) yesterday = now - one_day - gcp_create_report({"start_date": yesterday, "end_date": now, "write_monthly": True}) + options = {"start_date": yesterday, "end_date": now, "write_monthly": True} + fix_dates(options, "gcp") + gcp_create_report(options) invoice_month = yesterday.strftime("%Y%m") scan_start = yesterday.date() scan_end = now.date() @@ -1421,7 +1456,9 @@ def test_gcp_create_report_without_write_monthly(self): one_day = datetime.timedelta(days=1) yesterday = now - one_day report_prefix = "test_report" - gcp_create_report({"start_date": yesterday, "end_date": now, "gcp_report_prefix": report_prefix}) + options = {"start_date": yesterday, "end_date": now, "gcp_report_prefix": report_prefix} + fix_dates(options, "gcp") + gcp_create_report(options) output_file_name = "{}-{}.csv".format(report_prefix, yesterday.strftime("%Y-%m-%d")) expected_output_file_path = "{}/{}".format(os.getcwd(), output_file_name) @@ -1465,16 +1502,17 @@ def test_gcp_create_report_with_dataset_name_static_data(self): } ], } - gcp_create_report( - { - "start_date": yesterday, - "end_date": now, - "gcp_report_prefix": report_prefix, - "write_monthly": True, - "gcp_dataset_name": dataset_name, - "static_report_data": static_gcp_data, - } - ) + + options = { + "start_date": yesterday, + "end_date": now, + "gcp_report_prefix": report_prefix, + "write_monthly": True, + "gcp_dataset_name": dataset_name, + "static_report_data": static_gcp_data, + } + fix_dates(options, "gcp") + gcp_create_report(options) output_file_name = f"{report_prefix}.json" expected_output_file_path = "{}/{}".format(os.getcwd(), output_file_name) @@ -1518,15 +1556,15 @@ def test_gcp_create_report_static_data(self): } ], } - gcp_create_report( - { - "start_date": yesterday, - "end_date": now, - "gcp_report_prefix": report_prefix, - "write_monthly": True, - "static_report_data": static_gcp_data, - } - ) + options = { + "start_date": yesterday, + "end_date": now, + "gcp_report_prefix": report_prefix, + "write_monthly": True, + "static_report_data": static_gcp_data, + } + fix_dates(options, "gcp") + gcp_create_report(options) output_file_name = f"{report_prefix}.csv" expected_output_file_path = "{}/{}".format(os.getcwd(), output_file_name) @@ -1557,6 +1595,7 @@ def test_oci_create_report(self, mock_remove_files): one_day = datetime.timedelta(days=1) yesterday = now - one_day options = {"start_date": yesterday, "end_date": now, "write_monthly": False, "file_num": 343545} + fix_dates(options, "oci") oci_create_report(options) for report_type in OCI_REPORT_TYPE_TO_COLS: month_num = f"0{now.month}" if now.month < 10 else now.month @@ -1596,6 +1635,7 @@ def test_oci_write_file_to_local_bucket_exists(self, mock_copy_to_local_dir): "write_monthly": True, "file_num": 343545, } + fix_dates(options, "oci") oci_create_report(options) assert mock_copy_to_local_dir.called @@ -1622,6 +1662,7 @@ def test_oci_write_file_to_local_bucket_not_exist(self, mock_copy_to_local_dir): "write_monthly": True, "file_num": 343545, } + fix_dates(options, "oci") oci_create_report(options) assert mock_copy_to_local_dir.called @@ -1736,6 +1777,7 @@ def test_oci_create_report_static_data(self): "static_report_data": static_oci_data, "file_num": 343545, } + fix_dates(options, "oci") oci_create_report(options) month_num = f"0{now.month}" if now.month < 10 else str(now.month) cost_file_path = f"{os.getcwd()}/report_cost-{options.get('file_num')}_{now.year}-{month_num}.csv" @@ -1804,6 +1846,7 @@ def test_oci_create_report_end_date_before_today(self): "static_report_data": static_oci_data, "file_num": 343545, } + fix_dates(options, "oci") oci_create_report(options) month_num = f"0{now.month}" if now.month < 10 else str(now.month) cost_file_path = f"{os.getcwd()}/report_cost-{options.get('file_num')}_{now.year}-{month_num}.csv" @@ -1872,6 +1915,7 @@ def test_oci_create_report_end_date_after_today(self): "static_report_data": static_oci_data, "file_num": 343545, } + fix_dates(options, "oci") oci_create_report(options) month_num = f"0{now.month}" if now.month < 10 else str(now.month) cost_file_path = f"{os.getcwd()}/report_cost-{options.get('file_num')}_{now.year}-{month_num}.csv"