/* * Copyright 2015 herd contributors * * 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 org.finra.herd.dao; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import com.amazonaws.services.ec2.model.DescribeSpotPriceHistoryRequest; import com.amazonaws.services.ec2.model.DescribeSpotPriceHistoryResult; import com.amazonaws.services.ec2.model.SpotPrice; import com.google.common.base.Objects; import org.apache.commons.collections4.CollectionUtils; import org.junit.Test; import org.mockito.ArgumentMatcher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.finra.herd.dao.helper.AwsHelper; import org.finra.herd.dao.impl.Ec2DaoImpl; import org.finra.herd.dao.impl.MockEc2OperationsImpl; import org.finra.herd.dao.impl.MockSpotPrice; import org.finra.herd.model.dto.AwsParamsDto; /** * This class tests functionality of Ec2Dao. */ @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) public class Ec2DaoTest extends AbstractDaoTest { @Autowired private AwsHelper awsHelper; @Test public void testAddSecurityGroupsToEc2Instance() { // Add the security groups to an EC2 instance. List<String> testSecurityGroups = Arrays.asList(EC2_SECURITY_GROUP_1, EC2_SECURITY_GROUP_2); List<String> resultSecurityGroups = ec2Dao.addSecurityGroupsToEc2Instance(EC2_INSTANCE_ID, testSecurityGroups, awsHelper.getAwsParamsDto()); // Validate the results. assertNotNull(resultSecurityGroups); assertTrue(resultSecurityGroups.containsAll(testSecurityGroups)); } @Test public void testGetEc2Client() throws Exception { // Get the EMR client with proxy configuration. AwsParamsDto awsParamsDto = awsHelper.getAwsParamsDto(); awsParamsDto.setHttpProxyHost(HTTP_PROXY_HOST); awsParamsDto.setHttpProxyPort(HTTP_PROXY_PORT); assertNotNull(ec2Dao.getEc2Client(awsParamsDto)); // Set the proxy host as blank to get the EMR client without proxy. awsParamsDto.setHttpProxyHost(BLANK_TEXT); awsParamsDto.setHttpProxyPort(HTTP_PROXY_PORT); assertNotNull(ec2Dao.getEc2Client(awsParamsDto)); // Set the proxy port as null to get the EMR client without proxy. awsParamsDto.setHttpProxyHost(HTTP_PROXY_HOST); awsParamsDto.setHttpProxyPort(null); assertNotNull(ec2Dao.getEc2Client(awsParamsDto)); // Set the proxy host as blank and proxy port as null to get the EMR client without proxy. awsParamsDto.setHttpProxyHost(BLANK_TEXT); awsParamsDto.setHttpProxyPort(null); assertNotNull(ec2Dao.getEc2Client(awsParamsDto)); } @Test public void testGetLatestSpotPricesAssertConstructsCorrectDescribeSpotPriceHistoryRequest() { // Initialize inputs. String availabilityZone = "a"; Collection<String> instanceTypes = Arrays.asList("a", "b", "c"); Collection<String> productDescriptions = Arrays.asList("b", "c", "d"); // Set up mock. mock(RetryPolicyFactory.class); Ec2Operations ec2Operations = mock(Ec2Operations.class); ((Ec2DaoImpl) ec2Dao).setEc2Operations(ec2Operations); DescribeSpotPriceHistoryResult describeSpotPriceHistoryResult = new DescribeSpotPriceHistoryResult(); when(ec2Operations.describeSpotPriceHistory(any(), any())).thenReturn(describeSpotPriceHistoryResult); // Execute MUT. ec2Dao.getLatestSpotPrices(availabilityZone, instanceTypes, productDescriptions, new AwsParamsDto()); // Verify that the dependency was called with the correct parameters. verify(ec2Operations).describeSpotPriceHistory(any(), equalsDescribeSpotPriceHistoryRequest(availabilityZone, instanceTypes, productDescriptions)); } @Test public void testGetLatestSpotPricesSpotPriceHistoryContainDuplicateTypeInstances() { // Initialize inputs. Collection<String> instanceTypes = Arrays.asList(MockEc2OperationsImpl.INSTANCE_TYPE_1, MockEc2OperationsImpl.INSTANCE_TYPE_2); Collection<String> productDescriptions = Arrays.asList("b", "c"); // Set up mock. mock(RetryPolicyFactory.class); Ec2Operations ec2Operations = mock(Ec2Operations.class); ((Ec2DaoImpl) ec2Dao).setEc2Operations(ec2Operations); DescribeSpotPriceHistoryResult describeSpotPriceHistoryResult = new DescribeSpotPriceHistoryResult(); List<SpotPrice> spotPrices = new ArrayList<>(); spotPrices.add( new MockSpotPrice(MockEc2OperationsImpl.INSTANCE_TYPE_1, MockEc2OperationsImpl.AVAILABILITY_ZONE_1, MockEc2OperationsImpl.SPOT_PRICE_HIGH) .toAwsObject()); spotPrices.add( new MockSpotPrice(MockEc2OperationsImpl.INSTANCE_TYPE_1, MockEc2OperationsImpl.AVAILABILITY_ZONE_2, MockEc2OperationsImpl.SPOT_PRICE_HIGH) .toAwsObject()); describeSpotPriceHistoryResult.setSpotPriceHistory(spotPrices); when(ec2Operations.describeSpotPriceHistory(any(), any())).thenReturn(describeSpotPriceHistoryResult); // Execute MUT. List<SpotPrice> result = ec2Dao.getLatestSpotPrices(MockEc2OperationsImpl.AVAILABILITY_ZONE_1, instanceTypes, productDescriptions, new AwsParamsDto()); // Verify that the dependency was called with the correct parameters. verify(ec2Operations).describeSpotPriceHistory(any(), equalsDescribeSpotPriceHistoryRequest(MockEc2OperationsImpl.AVAILABILITY_ZONE_1, instanceTypes, productDescriptions)); // Verify that result contains only one spot price entry. assertEquals(1, CollectionUtils.size(result)); } /** * Returns a matcher proxy which matches a DescribeSpotPriceHistoryRequest with the given parameters. * * @param availabilityZone Availability zone * @param instanceTypes Instance types * @param productDescriptions Product descriptions * * @return DescribeSpotPriceHistoryRequest matcher proxy */ private DescribeSpotPriceHistoryRequest equalsDescribeSpotPriceHistoryRequest(String availabilityZone, Collection<String> instanceTypes, Collection<String> productDescriptions) { return argThat(new EqualsDescribeSpotPriceHistoryRequest(availabilityZone, instanceTypes, productDescriptions)); } /** * Argument matcher which matches a DescribeSpotPriceHistoryRequest */ private static class EqualsDescribeSpotPriceHistoryRequest extends ArgumentMatcher<DescribeSpotPriceHistoryRequest> { private String availabilityZone; private Collection<String> instanceTypes; private Collection<String> productDescriptions; public EqualsDescribeSpotPriceHistoryRequest(String availabilityZone, Collection<String> instanceTypes, Collection<String> productDescriptions) { this.availabilityZone = availabilityZone; this.instanceTypes = instanceTypes; this.productDescriptions = productDescriptions; } @Override public boolean matches(Object argument) { DescribeSpotPriceHistoryRequest describeSpotPriceHistoryRequest = (DescribeSpotPriceHistoryRequest) argument; return Objects.equal(availabilityZone, describeSpotPriceHistoryRequest.getAvailabilityZone()) && Objects.equal(instanceTypes, describeSpotPriceHistoryRequest.getInstanceTypes()) && Objects.equal(productDescriptions, describeSpotPriceHistoryRequest.getProductDescriptions()); } } }