diff --git a/pom.xml b/pom.xml index 168c5a8..c3e5834 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,12 @@ + + org.easymock + easymock + 3.4 + test + org.seleniumhq.selenium selenium-server diff --git a/src/main/java/com/rmn/qa/AutomationUtils.java b/src/main/java/com/rmn/qa/AutomationUtils.java index 9012de1..9bb6ec3 100644 --- a/src/main/java/com/rmn/qa/AutomationUtils.java +++ b/src/main/java/com/rmn/qa/AutomationUtils.java @@ -12,6 +12,14 @@ package com.rmn.qa; +import com.rmn.qa.aws.AwsTagReporter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; import java.util.Calendar; import java.util.Date; @@ -28,6 +36,11 @@ public final class AutomationUtils { * @param unitType Measurement type (e.g. Calendar.SECONDS) * @return Modified date */ + + private static final Logger log = LoggerFactory.getLogger(AwsTagReporter.class); + static int AWS_METADATA_TIMEOUT = 3 * 1000; + private static String AWS_INSTANCE_METADATA_URI = "http://169.254.169.254/latest/meta-data"; + public static Date modifyDate(Date dateToModify,int unitsToModify,int unitType) { Calendar c = Calendar.getInstance(); c.setTime(dateToModify); @@ -59,4 +72,52 @@ public static boolean lowerCaseMatch(String string1, String string2) { return string2.equals(string1.toLowerCase().replace(" ", "")); } + /** + * Returns AWS instanceId of the hub, returns "NoResponse" if times out + * @return + */ + public static String getHubInstanceId() + { + String hubInstanceId="NoResponse"; + + try { + URL url = new URL(AWS_INSTANCE_METADATA_URI + "/instance-id"); + URLConnection urlConnection = url.openConnection(); + urlConnection.setConnectTimeout(AWS_METADATA_TIMEOUT); + urlConnection.setReadTimeout(AWS_METADATA_TIMEOUT); + BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8")); + hubInstanceId=readMetaURIResponse(reader); + + } catch (Exception e) { + log.warn("Cannot create unique tag name using the Hub's instanceId, if you use multiple Hub,this may result in grid nodes being terminated by other hub(s)"); + log.info("Exception while retrieving the instanceId of the hub via metadata uri:" + e); + + } + + return hubInstanceId; + } + + /** + * Returns the value in the BufferReader, "NoResponse" if response is empty + * @param reader Buffer reader of AWS META DATA URI + * @return + */ + public static String readMetaURIResponse (BufferedReader reader) + { + String line = "NoResponse"; + try { + + while ((line = reader.readLine()) != null) { + + return line; + } + + } catch (Exception e) { + + log.info("Exception while reading the response of AWS META DATA URI: " + e); + + } + return line; + } + } diff --git a/src/main/java/com/rmn/qa/aws/AwsTagReporter.java b/src/main/java/com/rmn/qa/aws/AwsTagReporter.java index ca126bb..64c1733 100644 --- a/src/main/java/com/rmn/qa/aws/AwsTagReporter.java +++ b/src/main/java/com/rmn/qa/aws/AwsTagReporter.java @@ -18,6 +18,7 @@ import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.Tag; import com.google.common.annotations.VisibleForTesting; +import com.rmn.qa.AutomationUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -121,7 +122,7 @@ private void setTagsForInstance(String instanceId) { } } // Including a hard coded tag here so we can track which resources originate from this plugin - Tag nodeTag = new Tag("LaunchSource","SeleniumGridScalerPlugin"); + Tag nodeTag = new Tag("LaunchSource","SeleniumGridScalerPlugin_"+ AutomationUtils.getHubInstanceId()); log.info("Adding hard-coded tag: " + nodeTag); tags.add(nodeTag); CreateTagsRequest ctr = new CreateTagsRequest(Arrays.asList(instanceId),tags); diff --git a/src/main/java/com/rmn/qa/task/AutomationReaperTask.java b/src/main/java/com/rmn/qa/task/AutomationReaperTask.java index 18c5b27..94d78a3 100644 --- a/src/main/java/com/rmn/qa/task/AutomationReaperTask.java +++ b/src/main/java/com/rmn/qa/task/AutomationReaperTask.java @@ -36,7 +36,7 @@ public void doWork() { log.info("Running " + AutomationReaperTask.NAME); DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest(); Filter filter = new Filter("tag:LaunchSource"); - filter.withValues("SeleniumGridScalerPlugin"); + filter.withValues("SeleniumGridScalerPlugin_"+ AutomationUtils.getHubInstanceId()); describeInstancesRequest.withFilters(filter); List reservations = ec2.describeInstances(describeInstancesRequest); for(Reservation reservation : reservations) { diff --git a/src/test/java/com/rmn/qa/AutomationUtilsTest.java b/src/test/java/com/rmn/qa/AutomationUtilsTest.java index e2f2000..df5be7d 100644 --- a/src/test/java/com/rmn/qa/AutomationUtilsTest.java +++ b/src/test/java/com/rmn/qa/AutomationUtilsTest.java @@ -14,7 +14,7 @@ import junit.framework.Assert; import org.junit.Test; - +import org.easymock.EasyMock; import java.util.Calendar; import java.util.Date; @@ -51,4 +51,20 @@ public void testDateIsAfter() { Assert.assertTrue("Date should be considered after", AutomationUtils.isCurrentTimeAfterDate(afterDate,9,Calendar.SECOND)); } + @Test + public void testReadMetaURIResponseWhenNoResponse() throws IOException { + BufferedReader reader = EasyMock.createMock(BufferedReader.class); + EasyMock.expect(reader.readLine()).andReturn("NoResponse"); + EasyMock.replay(reader); + Assert.assertEquals("NoResponse",AutomationUtils.readMetaURIResponse(reader)); + } + + @Test + public void testReadMetaURIResponse() throws IOException { + BufferedReader reader = EasyMock.createMock(BufferedReader.class); + EasyMock.expect(reader.readLine()).andReturn("fake123"); + EasyMock.replay(reader); + Assert.assertEquals("fake123",AutomationUtils.readMetaURIResponse(reader)); + } + } diff --git a/src/test/java/com/rmn/qa/task/AutomationReaperTaskTest.java b/src/test/java/com/rmn/qa/task/AutomationReaperTaskTest.java index 2f548c9..fc96998 100644 --- a/src/test/java/com/rmn/qa/task/AutomationReaperTaskTest.java +++ b/src/test/java/com/rmn/qa/task/AutomationReaperTaskTest.java @@ -69,4 +69,39 @@ public void testTaskName() { AutomationReaperTask task = new AutomationReaperTask(null,null); Assert.assertEquals("Name should be the same",AutomationReaperTask.NAME, task.getDescription() ); } + + @Test + public void testNodeMatch(){ + Reservation reservation = new Reservation(); + Instance instance = new Instance(); + String instanceId = "foo"; + instance.setInstanceId(instanceId); + instance.setLaunchTime(AutomationUtils.modifyDate(new Date(),-5,Calendar.HOUR)); + AutomationContext.getContext().addNode(new AutomationDynamicNode("faky",instanceId,null,null,new Date(),1)); + List tags = new ArrayList<>(); + Tag nodeTag = new Tag("LaunchSource","SeleniumGridScalerPlugi_" + instanceId); + tags.add(nodeTag); + instance.setTags(tags); + reservation.setInstances(Arrays.asList(instance)); + String expectedTag = "Tags: [{Key: LaunchSource,Value: SeleniumGridScalerPlugi_foo}]"; + Assert.assertTrue("The node tag should match!",reservation.toString().contains(expectedTag)); + } + + @Test + public void testNodeDoNotMatch(){ + Reservation reservation = new Reservation(); + Instance instance = new Instance(); + String instanceId = "foo"; + instance.setInstanceId(instanceId); + instance.setLaunchTime(AutomationUtils.modifyDate(new Date(),-5,Calendar.HOUR)); + AutomationContext.getContext().addNode(new AutomationDynamicNode("faky",instanceId,null,null,new Date(),1)); + List tags = new ArrayList<>(); + Tag nodeTag = new Tag("LaunchSource","SeleniumGridScalerPlugi_" + instanceId); + tags.add(nodeTag); + instance.setTags(tags); + reservation.setInstances(Arrays.asList(instance)); + String expectedTag = "Tags: [{Key: LaunchSource,Value: SeleniumGridScalerPlugi_nofoo}]"; + reservation.setInstances(Arrays.asList(instance)); + Assert.assertFalse("The node tag should not match!",reservation.toString().contains(expectedTag)); + } }