Exemplo n.º 1
0
    def test_generate_aws_events_with_args_and_some_times(self):
        """Assert generation of InstanceEvents with all specified args."""
        account = helper.generate_cloud_account()
        ec2_ami_id = util_helper.generate_dummy_image_id()
        image = helper.generate_image(ec2_ami_id=ec2_ami_id)
        instance = helper.generate_instance(account, image=image)
        powered_times = (
            (None, util_helper.utc_dt(2017, 1, 1)),
            (util_helper.utc_dt(2017, 1, 2), util_helper.utc_dt(2017, 1, 3)),
            (util_helper.utc_dt(2017, 1, 4), None),
        )
        instance_type = util_helper.get_random_instance_type()
        subnet = str(uuid.uuid4())
        events = helper.generate_instance_events(
            instance,
            powered_times,
            instance_type=instance_type,
            subnet=subnet,
        )

        self.assertEqual(len(events), 4)
        # We don't care to check *everything* in the events since that should
        # already be covered by ``test_generate_events_with_some_times``.
        # Here we only care that argument values were set correctly.
        for event in events:
            if event.event_type != event.TYPE.power_off:
                self.assertEqual(
                    event.instance.machine_image.content_object.ec2_ami_id, ec2_ami_id
                )
            self.assertEqual(event.content_object.instance_type, instance_type)
            self.assertEqual(event.content_object.subnet, subnet)
Exemplo n.º 2
0
def generate_single_instance_event(
    instance,
    occurred_at,
    event_type=None,
    instance_type=None,
    subnet=None,
    no_instance_type=False,
    no_subnet=False,
    cloud_type=AWS_PROVIDER_STRING,
):
    """
    Generate single AwsInstanceEvent for testing.

    The ``powered_time`` is a datetime.datetime that defines when
    the instance event (either powering on or powering off) occurred.

    Args:
        instance (Instance): instance that owns the events.
        occurred_at (datetime.datetime): Time that the instance occurred.
        event_type (str): AWS event type
        instance_type (str): Optional AWS instance type.
        subnet (str): Optional subnet ID where instance runs.
        no_instance_type (bool): If true, don't assign an instance type.
        no_subnet (bool): If true, don't create and assign a subnet.

    Returns:
        AwsInstanceEvent: The created AwsInstanceEvent.

    """
    if no_instance_type:
        instance_type = None
    elif instance_type is None:
        instance_type = helper.get_random_instance_type(cloud_type=cloud_type)

    if event_type is None:
        event_type = InstanceEvent.TYPE.power_off

    if cloud_type == AZURE_PROVIDER_STRING:
        cloud_provider_event = AzureInstanceEvent.objects.create(
            instance_type=instance_type, )

    else:
        if no_subnet:
            subnet = None
        elif subnet is None:
            subnet = helper.generate_dummy_subnet_id()

        cloud_provider_event = AwsInstanceEvent.objects.create(
            subnet=subnet,
            instance_type=instance_type,
        )
    event = InstanceEvent.objects.create(
        instance=instance,
        event_type=event_type,
        occurred_at=occurred_at,
        content_object=cloud_provider_event,
    )
    return event
Exemplo n.º 3
0
 def create_random_definition(self):
     """Create and save a random definition."""
     InstanceDefinition.objects.create(
         instance_type=helper.get_random_instance_type(),
         memory=random.randrange(4),
         vcpu=random.randrange(4),
         json_definition='{"test": "data"}',
         cloud_type="aws",
     )
Exemplo n.º 4
0
def generate_cloudtrail_instance_event(
    instance,
    occurred_at,
    event_type=None,
    instance_type=None,
    subnet=None,
    no_instance_type=False,
    no_subnet=False,
):
    """
    Generate a single CloudTrailInstanceEvent for testing.

    Any optional arguments not provided will be randomly generated.

    Args:
        instance (Instance): instance that owns the events.
        occurred_at (datetime): Time periods the instance is powered on.
        instance_type (str): Optional AWS instance type.
        subnet (str): Optional subnet ID where instance runs.
        no_instance_type (bool): If true, instance_type is not set

    Returns:
        CloudTrailInstanceEvent: The created CloudTrailInstanceEvent.

    """
    if no_instance_type:
        instance_type = None
    elif instance_type is None:
        instance_type = helper.get_random_instance_type()

    if no_subnet:
        subnet = None
    elif subnet is None:
        subnet = helper.generate_dummy_subnet_id()

    if event_type is None:
        event_type = InstanceEvent.TYPE.power_off

    event = CloudTrailInstanceEvent(
        occurred_at=occurred_at,
        event_type=event_type,
        instance_type=instance_type,
        aws_account_id=instance.cloud_account.id,
        region=instance.machine_image.content_object.region,
        ec2_instance_id=instance.content_object.ec2_instance_id,
        ec2_ami_id=instance.machine_image.content_object.ec2_ami_id,
        subnet_id=subnet,
    )
    return event
Exemplo n.º 5
0
 def test_generate_dummy_describe_instance_with_values(self):
     """Assert generated instance contains given values."""
     image_id = helper.generate_dummy_image_id()
     instance_id = helper.generate_dummy_instance_id()
     subnet_id = helper.generate_dummy_subnet_id()
     state = aws.InstanceState.shutting_down
     instance_type = helper.get_random_instance_type()
     device_mapping = helper.generate_dummy_block_device_mapping()
     instance = helper.generate_dummy_describe_instance(
         instance_id=instance_id,
         image_id=image_id,
         subnet_id=subnet_id,
         state=state,
         instance_type=instance_type,
         device_mappings=[device_mapping],
     )
     self.assertEqual(instance["ImageId"], image_id)
     self.assertEqual(instance["InstanceId"], instance_id)
     self.assertEqual(instance["InstanceType"], instance_type)
     self.assertEqual(instance["SubnetId"], subnet_id)
     self.assertEqual(instance["State"]["Code"], state.value)
     self.assertEqual(instance["State"]["Name"], state.name)
     self.assertEqual(instance["State"]["Name"], state.name)
     self.assertEqual(instance["BlockDeviceMappings"], [device_mapping])
Exemplo n.º 6
0
    def test_new_run_deletes_concurrent_usage(self):
        """
        Test that creating a new run deletes the right ConcurrentUsage.

        When a run is saved that is related to ConcurrentUsage through
        the potentially_related_runs field, ensure those ConcurrentUsages
        are deleted. Creating a new Run should not remove ConcurrentUsages
        with no related runs.

        """
        user = util_helper.generate_test_user()
        aws_account_id = util_helper.generate_dummy_aws_account_id()
        account = api_helper.generate_cloud_account(
            aws_account_id=aws_account_id,
            user=user,
        )
        image = api_helper.generate_image(
            owner_aws_account_id=aws_account_id,
            rhel_detected=True,
        )
        instance = api_helper.generate_instance(account, image=image)
        instance_type = util_helper.get_random_instance_type()

        start_time = util_helper.utc_dt(2019, 5, 1, 1, 0, 0)
        end_time = util_helper.utc_dt(2019, 5, 1, 2, 0, 0)

        request_date = datetime.date(2019, 5, 1)

        # Calculating maximum usage for no runs generates one concurrent usage
        # with empty counts
        calculate_max_concurrent_usage(request_date, user_id=user.id)
        self.assertEqual(1, ConcurrentUsage.objects.all().count())
        self.assertEqual("[]",
                         ConcurrentUsage.objects.all()[0]._maximum_counts)

        # Create a run
        run = Run.objects.create(
            start_time=start_time,
            end_time=end_time,
            instance=instance,
            machineimage=image,
            instance_type=instance_type,
            vcpu=util_helper.SOME_EC2_INSTANCE_TYPES[instance_type]["vcpu"],
            memory=util_helper.SOME_EC2_INSTANCE_TYPES[instance_type]
            ["memory"],
        )
        # Creating a run should not delete the empty concurrent usage
        # since that concurrent usage isn't related to this run
        self.assertEqual(1, ConcurrentUsage.objects.all().count())
        self.assertEqual("[]",
                         ConcurrentUsage.objects.all()[0]._maximum_counts)

        # recalculating the maximum concurrent usage results in a nonempty
        # ConcurrentUsage maximum_counts
        calculate_max_concurrent_usage(request_date, user_id=user.id)
        self.assertNotEqual("[]",
                            ConcurrentUsage.objects.all()[0]._maximum_counts)

        # Re-saving the run should remove the related the concurrent usage.
        run.save()
        self.assertEqual(0, ConcurrentUsage.objects.all().count())
Exemplo n.º 7
0
def generate_single_run(
    instance,
    runtime,
    image=None,
    no_image=False,
    instance_type=None,
    no_instance_type=False,
    calculate_concurrent_usage=True,
):
    """
    Generate a single Run (and related events) for testing.

    Args:
        instance (Instance): instance that was ran.
        runtime (tuple(datetime.datetime, datetime.datetime)):
            time the run occured.
        image (Image): image that was ran.
        no_image (bool): If true, don't create and assign an image.
        instance_type (str): Optional AWS instance type.
        no_instance_type (bool): Optional indication that instance has no type.
        calculate_concurrent_usage (bool): Optional indicated if after creating
            the run we should run calculate_max_concurrent_usage_from_runs.
    Returns:
        Run: The created Run.

    """
    if no_instance_type:
        instance_type = None
    elif instance_type is None:
        instance_type = helper.get_random_instance_type()

    if not no_image and image is None:
        image = generate_image()

    run = Run.objects.create(
        start_time=runtime[0],
        end_time=runtime[1],
        instance=instance,
        machineimage=image,
        instance_type=instance_type,
        vcpu=helper.SOME_EC2_INSTANCE_TYPES[instance_type]["vcpu"]
        if instance_type in helper.SOME_EC2_INSTANCE_TYPES else None,
        memory=helper.SOME_EC2_INSTANCE_TYPES[instance_type]["memory"]
        if instance_type in helper.SOME_EC2_INSTANCE_TYPES else None,
    )
    generate_single_instance_event(
        instance=instance,
        occurred_at=runtime[0],
        event_type=InstanceEvent.TYPE.power_on,
        instance_type=instance_type,
        no_instance_type=no_instance_type,
    )
    if runtime[1]:
        generate_single_instance_event(
            instance=instance,
            occurred_at=runtime[1],
            event_type=InstanceEvent.TYPE.power_off,
            instance_type=instance_type,
            no_instance_type=no_instance_type,
        )
    if calculate_concurrent_usage:
        # Calculate the runs directly instead of scheduling a task for testing purposes
        with patch("api.util.schedule_concurrent_calculation_task"
                   ) as mock_schedule_concurrent_task:
            mock_schedule_concurrent_task.side_effect = calculate_max_concurrent_usage
            calculate_max_concurrent_usage_from_runs([run])
    return run
Exemplo n.º 8
0
def generate_instance_events(
    instance,
    powered_times,
    instance_type=None,
    subnet=None,
    no_instance_type=False,
    cloud_type=AWS_PROVIDER_STRING,
):
    """
    Generate list of InstanceEvents for the Instance for testing.

    Any optional arguments not provided will be randomly generated.

    The ``powered_times`` defines when the instance should be considered
    running for sake of the event types. The first element of the tuple
    is a datetime.datetime of when a "power on" event occurs, and the second
    element is a datetime.datetime of when a "power off" event occurs.

    Power-off events will never be created with an image defined in this helper
    function because in most real-world cases they do not have one.

    Args:
        instance (Instance): instance that owns the events.
        powered_times (list[tuple]): Time periods the instance is powered on.
        instance_type (str): Optional AWS instance type.
        subnet (str): Optional subnet ID where instance runs.
        no_instance_type (bool): If true, instance_type is not set

    Returns:
        list(InstanceEvent): The list of created AwsInstanceEvents.

    """
    if no_instance_type:
        instance_type = None
    elif instance_type is None:
        instance_type = helper.get_random_instance_type(cloud_type=cloud_type)
    if subnet is None:
        subnet = helper.generate_dummy_subnet_id()

    events = []
    for power_on_time, power_off_time in powered_times:
        if power_on_time is not None:
            event = generate_single_instance_event(
                instance=instance,
                occurred_at=power_on_time,
                event_type=InstanceEvent.TYPE.power_on,
                instance_type=instance_type,
                subnet=subnet,
                no_instance_type=no_instance_type,
                cloud_type=cloud_type,
            )
            events.append(event)
        if power_off_time is not None:
            # power_off events typically do *not* have an image defined.
            # So, ignore inputs and *always* set ec2_ami_id=None.
            event = generate_single_instance_event(
                instance=instance,
                occurred_at=power_off_time,
                event_type=InstanceEvent.TYPE.power_off,
                instance_type=instance_type,
                subnet=subnet,
                no_instance_type=no_instance_type,
                cloud_type=cloud_type,
            )
            events.append(event)
    return events