diff options
author | olaaun <ola.aunroe@gmail.com> | 2017-08-02 04:35:52 +0800 |
---|---|---|
committer | Andreas Eriksen <andreer@pvv.ntnu.no> | 2017-08-01 22:35:52 +0200 |
commit | b4d4f7f54513cb3907884b7863d20b6efab5aaee (patch) | |
tree | cc7b8d3ab29db2a82021e4995d813bcc76cbabb4 /node-maintainer | |
parent | fbbc7b131fd449705114e6aeada900a626bba16f (diff) |
Interns/verification fix (#3039)
* Now stores netInfo also if ping6 did not work
* Added information to README
* Changed disk benchmark command to use conv = fdatasync
* Diskretriever now sums up all sizes from df to get disk size
* Extracted test JSON strings to separate files
* Disk retriever now ignores RAM and first row
* Changed mock input for disk size retriever test
* using pvdisplay to retrieve disk size
* Changed to not assume IPv4 address exist in node repo
* DiskRetriever now handles multiple disks by adding them to get tot disk size
* IPAddressVerifier now verifies both IP addresses against hostname reported by node repo JSON
* NetRetriever now throws exceptions in a consistent way
* MemoryRetriver throws exception similar to other retrievers
* More detailed logging in case of exception in DiskRetriever
* Changed logging depending on exception type in NetRetriever
* Now compares ipv6 connectivity with node repo
* attempt to make Pogo seperate out verifications with errors
* The complete match metric is now also dependent on ping response
* Added check making sure spec verification is not run on virtual machines
Diffstat (limited to 'node-maintainer')
23 files changed, 499 insertions, 201 deletions
diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HardwareNodeComparator.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HardwareNodeComparator.java index a61ba11ff22..8a635e2e3ec 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HardwareNodeComparator.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HardwareNodeComparator.java @@ -87,8 +87,10 @@ public class HardwareNodeComparator { specReportMetrics.setExpectedInterfaceSpeed(expectedInterfaceSpeed); specReportMetrics.setActualInterfaceSpeed(actualInterfaceSpeed); } - if (!actualHardware.isIpv6Connection()) { - specReportMetrics.setActualIpv6Connection(false); + + if (node.isIpv6Connection() != actualHardware.isIpv6Connection()) { + specReportMetrics.setActualIpv6Connection(actualHardware.isIpv6Connection()); + specReportMetrics.setExpectedIpv6Connection(node.isIpv6Connection()); } } @@ -106,13 +108,13 @@ public class HardwareNodeComparator { private static boolean compareNetInterface(HardwareInfo node, HardwareInfo actualHardware, SpecReportDimensions specReportDimensions) { boolean equalNetInterfaceSpeed = insideThreshold(node.getInterfaceSpeedMbs(), actualHardware.getInterfaceSpeedMbs()); - boolean equalIpv6 = node.getIpv6Interface() == actualHardware.getIpv6Interface(); - boolean equalIpv4 = node.getIpv4Interface() == actualHardware.getIpv4Interface(); + boolean equalIpv6Interface = node.getIpv6Interface() == actualHardware.getIpv6Interface(); + boolean equalIpv4Interface = node.getIpv4Interface() == actualHardware.getIpv4Interface(); + boolean equalIpv6Connection = node.isIpv6Connection() == actualHardware.isIpv6Connection(); specReportDimensions.setNetInterfaceSpeedMatch(equalNetInterfaceSpeed); - specReportDimensions.setIpv6Match(equalIpv6); - specReportDimensions.setIpv4Match(equalIpv4); - return equalNetInterfaceSpeed && equalIpv6 && equalIpv4; - + specReportDimensions.setIpv6Match(equalIpv6Interface); + specReportDimensions.setIpv4Match(equalIpv4Interface); + return equalNetInterfaceSpeed && equalIpv6Interface && equalIpv4Interface && equalIpv6Connection; } private static boolean compareDisk(HardwareInfo node, HardwareInfo actualHardware, SpecReportDimensions specReportDimensions) { diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGenerator.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGenerator.java index 2fb81d4db63..157f618761d 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGenerator.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGenerator.java @@ -31,11 +31,19 @@ public class HostURLGenerator { return nodeInfoUrls; } - protected static URL buildNodeInfoURL(String configServerHostName, String nodeHostName) throws MalformedURLException { - if (configServerHostName.matches(PROTOCOL_REGEX)) { - return new URL(configServerHostName + NODE_HOSTNAME_PREFIX + nodeHostName); - } - return new URL(HTTP + configServerHostName + PORT_NUMBER + NODE_HOSTNAME_PREFIX + nodeHostName); + protected static String[] getConfigServerHostNames(CommandExecutor commandExecutor) throws IOException { + ArrayList<String> output = commandExecutor.executeCommand(CONFIG_SERVER_HOST_NAME_COMMAND); + if (output.size() != 1) + throw new IOException("Expected one line return from the command: " + CONFIG_SERVER_HOST_NAME_COMMAND); + String[] configServerHostNames = parseOutHostNames(output.get(0)); + return configServerHostNames; + } + + private static String[] parseOutHostNames(String output) throws IOException { + String[] outputSplit = output.trim().split(PARSE_OUT_HOSTNAMES_REGEX); + if (outputSplit.length != 2) throw new IOException("Expected config server host names to have index 1"); + String[] configServerHostNames = outputSplit[1].split(PARSE_ALL_HOSTNAMES_REGEX); + return configServerHostNames; } protected static String generateNodeHostName(CommandExecutor commandExecutor) throws IOException { @@ -51,19 +59,11 @@ public class HostURLGenerator { throw new IOException("Unexpected output from \"hostname\" command."); } - protected static String[] getConfigServerHostNames(CommandExecutor commandExecutor) throws IOException { - ArrayList<String> output = commandExecutor.executeCommand(CONFIG_SERVER_HOST_NAME_COMMAND); - if (output.size() != 1) - throw new IOException("Expected one line return from the command: " + CONFIG_SERVER_HOST_NAME_COMMAND); - String[] configServerHostNames = parseOutHostNames(output.get(0)); - return configServerHostNames; - } - - private static String[] parseOutHostNames(String output) throws IOException { - String[] outputSplit = output.trim().split(PARSE_OUT_HOSTNAMES_REGEX); - if (outputSplit.length != 2) throw new IOException("Expected config server hsot names to have index 1"); - String[] configServerHostNames = outputSplit[1].split(PARSE_ALL_HOSTNAMES_REGEX); - return configServerHostNames; + protected static URL buildNodeInfoURL(String configServerHostName, String nodeHostName) throws MalformedURLException { + if (configServerHostName.matches(PROTOCOL_REGEX)) { + return new URL(configServerHostName + NODE_HOSTNAME_PREFIX + nodeHostName); + } + return new URL(HTTP + configServerHostName + PORT_NUMBER + NODE_HOSTNAME_PREFIX + nodeHostName); } } diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifier.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifier.java index 08d5d1b1d74..c2b295684a8 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifier.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifier.java @@ -14,6 +14,7 @@ import com.yahoo.vespa.hosted.node.verification.spec.yamasreport.YamasSpecReport import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -24,9 +25,14 @@ import java.util.logging.Logger; public class SpecVerifier { private static final Logger logger = Logger.getLogger(SpecVerifier.class.getName()); + private static final String VIRTUAL_ENVIRONMENT= "VIRTUAL_MACHINE"; public static boolean verifySpec(CommandExecutor commandExecutor) throws IOException { NodeRepoJsonModel nodeRepoJsonModel = getNodeRepositoryJSON(commandExecutor); + if (nodeRepoJsonModel.getEnvironment().equals(VIRTUAL_ENVIRONMENT)) { + logger.log(Level.INFO, "Node is virtual machine - No need for verification"); + return true; + } HardwareInfo actualHardware = HardwareInfoRetriever.retrieve(commandExecutor); YamasSpecReport yamasSpecReport = makeYamasSpecReport(actualHardware, nodeRepoJsonModel); printResults(yamasSpecReport); @@ -58,7 +64,9 @@ public class SpecVerifier { public static void main(String[] args) throws IOException { CommandExecutor commandExecutor = new CommandExecutor(); - SpecVerifier.verifySpec(commandExecutor); + if (!SpecVerifier.verifySpec(commandExecutor)){ + System.exit(2); + } } } diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifier.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifier.java index 690a57ba242..9333a1e979a 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifier.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifier.java @@ -24,16 +24,57 @@ public class IPAddressVerifier { private static final Logger logger = Logger.getLogger(IPAddressVerifier.class.getName()); public void reportFaultyIpAddresses(NodeRepoJsonModel nodeRepoJsonModel, YamasSpecReport yamasSpecReport) { - String[] faultyIpAddresses = getFaultyIpAddresses(nodeRepoJsonModel.getIpv6Address(), nodeRepoJsonModel.getAdditionalIpAddresses()); + String[] faultyIpAddresses = getFaultyIpAddresses(nodeRepoJsonModel); if (faultyIpAddresses.length > 0) { yamasSpecReport.setFaultyIpAddresses(faultyIpAddresses); } } + public String[] getFaultyIpAddresses(NodeRepoJsonModel jsonModel) { + String expectedHostname = jsonModel.getHostname(); + ArrayList<String> faultyIpAddresses = new ArrayList<>(); + if (expectedHostname == null || expectedHostname.equals("")) + return new String[0]; + if (!isValidIpv4(jsonModel.getIpv4Address(), expectedHostname)) { + faultyIpAddresses.add(jsonModel.getIpv4Address()); + } + if (!isValidIpv6(jsonModel.getIpv6Address(), expectedHostname)) { + faultyIpAddresses.add(jsonModel.getIpv6Address()); + } + return faultyIpAddresses.stream().toArray(String[]::new); + } + + private boolean isValidIpv4(String ipv4Address, String expectedHostname) { + if (ipv4Address == null) { + return true; + } + String ipv4LookupFormat = convertIpv4ToLookupFormat(ipv4Address); + try { + String ipv4Hostname = reverseLookUp(ipv4LookupFormat); + return ipv4Hostname.equals(expectedHostname); + } catch (NamingException e) { + logger.log(Level.WARNING, "Could not get IPv4 hostname", e); + } + return false; + } + + private boolean isValidIpv6(String ipv6Address, String expectedHostname) { + if (ipv6Address == null) { + return true; + } + String ipv6LookupFormat = convertIpv6ToLookupFormat(ipv6Address); + try { + String ipv6Hostname = reverseLookUp(ipv6LookupFormat); + return ipv6Hostname.equals(expectedHostname); + } catch (NamingException e) { + logger.log(Level.WARNING, "Could not get IPv6 hostname", e); + } + return false; + } + protected String reverseLookUp(String ipAddress) throws NamingException { Hashtable<String, String> env = new Hashtable<>(); env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); - String ipAddressInLookupFormat = convertToLookupFormat(ipAddress); String attributeName = ipAddress; DirContext ctx = new InitialDirContext(env); Attributes attrs = ctx.getAttributes(attributeName, new String[]{"PTR"}); @@ -41,16 +82,17 @@ public class IPAddressVerifier { Attribute attr = ae.next(); Enumeration<?> vals = attr.getAll(); if (vals.hasMoreElements()) { - return vals.nextElement().toString(); + String hostname = vals.nextElement().toString(); + return hostname.substring(0, hostname.length() - 1); } } ctx.close(); return ""; } - protected String convertToLookupFormat(String ipAddress) { + protected String convertIpv6ToLookupFormat(String ipAddress) { StringBuilder newIpAddress = new StringBuilder(); - String doubleColonReplacement = "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0."; + String doubleColonReplacement = "0.0.0.0.0.0.0.0.0.0.0.0."; String domain = "ip6.arpa"; String[] hextets = ipAddress.split(":"); for (int i = hextets.length - 1; i >= 0; i--) { @@ -68,32 +110,15 @@ public class IPAddressVerifier { return newIpAddress.toString(); } - public String[] getFaultyIpAddresses(String ipAddress, String[] additionalIpAddresses) { - if (ipAddress == null || additionalIpAddresses == null || additionalIpAddresses.length == 0) - return new String[0]; - String realHostname; - ArrayList<String> faultyIpAddresses = new ArrayList<>(); - try { - realHostname = reverseLookUp(ipAddress); - } catch (NamingException e) { - logger.log(Level.WARNING, "Unable to look up host name of address " + ipAddress, e); - return new String[0]; - } - for (String additionalIpAddress : additionalIpAddresses) { - addIfFaultyIpAddress(realHostname, additionalIpAddress, faultyIpAddresses); - } - return faultyIpAddresses.stream().toArray(String[]::new); - } - - private void addIfFaultyIpAddress(String realHostname, String additionalIpAddress, ArrayList<String> faultyIpAddresses) { - try { - String additionalHostName = reverseLookUp(additionalIpAddress); - if (!realHostname.equals(additionalHostName)) { - faultyIpAddresses.add(additionalIpAddress); - } - } catch (NamingException e) { - logger.log(Level.WARNING, "Unable to retrieve hostname of additional address: " + additionalIpAddress, e); + protected String convertIpv4ToLookupFormat(String ipAddress) { + String domain = "in-addr.arpa"; + String[] octets = ipAddress.split("\\."); + StringBuilder convertedIpAddress = new StringBuilder(); + for (int i = octets.length - 1; i >= 0; i--) { + convertedIpAddress.append(octets[i] + "."); } + convertedIpAddress.append(domain); + return convertedIpAddress.toString(); } } diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeJsonConverter.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeJsonConverter.java index dfd2bb011a2..ec078624920 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeJsonConverter.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeJsonConverter.java @@ -9,20 +9,26 @@ import com.yahoo.vespa.hosted.node.verification.spec.retrievers.HardwareInfo; public class NodeJsonConverter { private static void addStandardSpecifications(HardwareInfo nodeRepoHardwareInfo) { - nodeRepoHardwareInfo.setIpv4Interface(true); nodeRepoHardwareInfo.setInterfaceSpeedMbs(1000); } - protected static void setIpv6AddressConnectivity(NodeRepoJsonModel nodeRepoJsonModel, HardwareInfo nodeRepoHardwareInfo) { + protected static void setIpv6Interface(NodeRepoJsonModel nodeRepoJsonModel, HardwareInfo nodeRepoHardwareInfo) { if (nodeRepoJsonModel.getIpv6Address() != null) { nodeRepoHardwareInfo.setIpv6Interface(true); } } + protected static void setIpv4Interface(NodeRepoJsonModel nodeRepoJsonModel, HardwareInfo nodeRepoHardwareInfo) { + if (nodeRepoJsonModel.getIpv4Address() != null) { + nodeRepoHardwareInfo.setIpv4Interface(true); + } + } + public static HardwareInfo convertJsonModelToHardwareInfo(NodeRepoJsonModel nodeRepoJsonModel) { HardwareInfo nodeRepoHardwareInfo = nodeRepoJsonModel.copyToHardwareInfo(); addStandardSpecifications(nodeRepoHardwareInfo); - setIpv6AddressConnectivity(nodeRepoJsonModel, nodeRepoHardwareInfo); + setIpv4Interface(nodeRepoJsonModel, nodeRepoHardwareInfo); + setIpv6Interface(nodeRepoJsonModel, nodeRepoHardwareInfo); return nodeRepoHardwareInfo; } diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoJsonModel.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoJsonModel.java index f946a7343dc..2367d255987 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoJsonModel.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoJsonModel.java @@ -24,6 +24,10 @@ public class NodeRepoJsonModel { private String[] ipAddresses; @JsonProperty("additionalIpAddresses") private String[] additionalIpAddresses; + @JsonProperty + private String hostname; + @JsonProperty + private String environment; public String[] getAdditionalIpAddresses() { return additionalIpAddresses; @@ -35,6 +39,7 @@ public class NodeRepoJsonModel { hardwareInfo.setMinDiskAvailableGb(this.minDiskAvailableGb); hardwareInfo.setMinCpuCores((int) Math.round(this.minCpuCores)); hardwareInfo.setDiskType(this.fastDisk ? DiskType.FAST : DiskType.SLOW); + hardwareInfo.setIpv6Connection(getIpv6Address() != null); return hardwareInfo; } @@ -48,6 +53,16 @@ public class NodeRepoJsonModel { return null; } + public String getIpv4Address() { + String ipv4Regex = "((1?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}(1?\\d\\d?|2[0-4]\\d|2\u200C\u200B5[0-5])"; + for (String ipAddress : ipAddresses) { + if (ipAddress.matches(ipv4Regex)) { + return ipAddress; + } + } + return null; + } + public double getMinDiskAvailableGb() { return minDiskAvailableGb; } @@ -68,4 +83,12 @@ public class NodeRepoJsonModel { return ipAddresses; } + public String getHostname() { + return hostname; + } + + public String getEnvironment() { + return environment; + } + } diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetriever.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetriever.java index 8fe9e04db30..42d459217a0 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetriever.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetriever.java @@ -17,15 +17,15 @@ import java.util.logging.Logger; */ public class DiskRetriever implements HardwareRetriever { private static final String DISK_CHECK_TYPE = "lsblk -d -o name,rota"; - private static final String DISK_CHECK_SIZE = "df -BG | grep -v tmpfs | awk '{s+=$2} END {print s-1}'"; + private static final String DISK_CHECK_SIZE = "sudo pvdisplay --units G | grep 'PV Size'"; private static final String DISK_NAME = "sda"; private static final String DISK_TYPE_REGEX_SPLIT = "\\s+"; private static final int DISK_TYPE_SEARCH_ELEMENT_INDEX = 0; private static final int DISK_TYPE_RETURN_ELEMENT_INDEX = 1; - private static final String DISK_SIZE_SEARCH_WORD = ".*\\d+.*"; + private static final String DISK_SIZE_SEARCH_WORD = "Size"; private static final String DISK_SIZE_REGEX_SPLIT = "\\s+"; - private static final int DISK_SIZE_SEARCH_ELEMENT_INDEX = 0; - private static final int DISK_SIZE_RETURN_ELEMENT_INDEX = 0; + private static final int DISK_SIZE_SEARCH_ELEMENT_INDEX = 1; + private static final int DISK_SIZE_RETURN_ELEMENT_INDEX = 2; private static final Logger logger = Logger.getLogger(DiskRetriever.class.getName()); private final HardwareInfo hardwareInfo; private final CommandExecutor commandExecutor; @@ -37,37 +37,42 @@ public class DiskRetriever implements HardwareRetriever { } public void updateInfo() { - try { updateDiskType(); updateDiskSize(); - } catch (IOException e) { - logger.log(Level.WARNING, "Failed to retrieve disk info", e); - } } - protected void updateDiskType() throws IOException { - ArrayList<String> commandOutput = commandExecutor.executeCommand(DISK_CHECK_TYPE); - ParseResult parseResult = parseDiskType(commandOutput); - setDiskType(parseResult); + protected void updateDiskType() { + try { + ArrayList<String> commandOutput = commandExecutor.executeCommand(DISK_CHECK_TYPE); + ParseResult parseResult = parseDiskType(commandOutput); + setDiskType(parseResult); + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to retrieve disk type", e); + } } - protected void updateDiskSize() throws IOException { - ArrayList<String> commandOutput = commandExecutor.executeCommand(DISK_CHECK_SIZE); - ParseResult parseResult = parseDiskSize(commandOutput); - setDiskSize(parseResult); + protected void updateDiskSize() { + try { + ArrayList<String> commandOutput = commandExecutor.executeCommand(DISK_CHECK_SIZE); + ArrayList<ParseResult> parseResult = parseDiskSize(commandOutput); + setDiskSize(parseResult); + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to retrieve disk size", e); + } } - protected ParseResult parseDiskType(ArrayList<String> commandOutput) { + protected ParseResult parseDiskType(ArrayList<String> commandOutput) throws IOException { ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(DISK_NAME)); ParseInstructions parseInstructions = new ParseInstructions(DISK_TYPE_SEARCH_ELEMENT_INDEX, DISK_TYPE_RETURN_ELEMENT_INDEX, DISK_TYPE_REGEX_SPLIT, searchWords); - return OutputParser.parseSingleOutput(parseInstructions, commandOutput); + ParseResult parseResult = OutputParser.parseSingleOutput(parseInstructions, commandOutput); + if (!parseResult.getSearchWord().equals(DISK_NAME)) { + throw new IOException("Parsing for disk type failed"); + } + return parseResult; } protected void setDiskType(ParseResult parseResult) { hardwareInfo.setDiskType(DiskType.UNKNOWN); - if (!parseResult.getSearchWord().equals(DISK_NAME)) { - return; - } String fastDiskSymbol = "0"; String nonFastDiskSymbol = "1"; if (parseResult.getValue().equals(fastDiskSymbol)) { @@ -77,20 +82,25 @@ public class DiskRetriever implements HardwareRetriever { } } - protected ParseResult parseDiskSize(ArrayList<String> commandOutput) { + protected ArrayList<ParseResult> parseDiskSize(ArrayList<String> commandOutput) { ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(DISK_SIZE_SEARCH_WORD)); ParseInstructions parseInstructions = new ParseInstructions(DISK_SIZE_SEARCH_ELEMENT_INDEX, DISK_SIZE_RETURN_ELEMENT_INDEX, DISK_SIZE_REGEX_SPLIT, searchWords); - return OutputParser.parseSingleOutput(parseInstructions, commandOutput); + return OutputParser.parseOutput(parseInstructions, commandOutput); } - protected void setDiskSize(ParseResult parseResult) { - try { - String sizeValue = parseResult.getValue().replaceAll("[^\\d.]", ""); - double diskSize = Double.parseDouble(sizeValue); - hardwareInfo.setMinDiskAvailableGb(diskSize); - } catch (NumberFormatException | NullPointerException e) { - return; - } + protected void setDiskSize(ArrayList<ParseResult> parseResults) { + double diskSize = 0; + try { + for (ParseResult parseResult : parseResults) { + String sizeValue = parseResult.getValue().replaceAll("[^\\d.]", ""); + diskSize += Double.parseDouble(sizeValue); + } + } catch (NumberFormatException | NullPointerException e) { + logger.log(Level.WARNING, "Parse results contained an invalid PV size - ", parseResults); + } + finally { + hardwareInfo.setMinDiskAvailableGb(diskSize); + } } }
\ No newline at end of file diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/MemoryRetriever.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/MemoryRetriever.java index 3cb2b1059ce..da7e82aefb7 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/MemoryRetriever.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/MemoryRetriever.java @@ -17,10 +17,10 @@ import java.util.logging.Logger; public class MemoryRetriever implements HardwareRetriever { private static final String MEMORY_INFO_COMMAND = "cat /proc/meminfo"; - private static final String searchWord = "MemTotal"; - private static final String regexSplit = ":\\s"; - private static final int searchElementIndex = 0; - private static final int returnElementIndex = 1; + private static final String SEARCH_WORD = "MemTotal"; + private static final String REGEX_SPLIT = ":\\s"; + private static final int SEARCH_ELEMENT_INDEX = 0; + private static final int RETURN_ELEMENT_INDEX = 1; private static final Logger logger = Logger.getLogger(MemoryRetriever.class.getName()); private final HardwareInfo hardwareInfo; private final CommandExecutor commandExecutor; @@ -37,14 +37,17 @@ public class MemoryRetriever implements HardwareRetriever { ParseResult parseResult = parseMemInfoFile(commandOutput); updateMemoryInfo(parseResult); } catch (IOException e) { - logger.log(Level.WARNING, "Failed to retrieve memory info", e); + logger.log(Level.WARNING, "Failed to retrieve memory info. ", e); } } - protected ParseResult parseMemInfoFile(ArrayList<String> commandOutput) { - ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(searchWord)); - ParseInstructions parseInstructions = new ParseInstructions(searchElementIndex, returnElementIndex, regexSplit, searchWords); + protected ParseResult parseMemInfoFile(ArrayList<String> commandOutput) throws IOException { + ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(SEARCH_WORD)); + ParseInstructions parseInstructions = new ParseInstructions(SEARCH_ELEMENT_INDEX, RETURN_ELEMENT_INDEX, REGEX_SPLIT, searchWords); ParseResult parseResult = OutputParser.parseSingleOutput(parseInstructions, commandOutput); + if (!parseResult.getSearchWord().matches(SEARCH_WORD)){ + throw new IOException("Failed to parse memory info file."); + } return parseResult; } diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetriever.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetriever.java index 0170d79b22d..c3ffd9adb6f 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetriever.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetriever.java @@ -4,6 +4,7 @@ import com.yahoo.vespa.hosted.node.verification.commons.CommandExecutor; import com.yahoo.vespa.hosted.node.verification.commons.OutputParser; import com.yahoo.vespa.hosted.node.verification.commons.ParseInstructions; import com.yahoo.vespa.hosted.node.verification.commons.ParseResult; +import org.apache.commons.exec.ExecuteException; import java.io.IOException; import java.util.ArrayList; @@ -45,37 +46,24 @@ public class NetRetriever implements HardwareRetriever { } public void updateInfo() { + ArrayList<ParseResult> parseResults = findInterface(); + findInterfaceSpeed(parseResults); + testPingResponse(parseResults); + updateHardwareInfoWithNet(parseResults); + } + + protected ArrayList<ParseResult> findInterface() { ArrayList<ParseResult> parseResults = new ArrayList<>(); try { - parseResults = findInterface(); - findInterfaceSpeed(parseResults); - testPingResponse(parseResults); + ArrayList<String> commandOutput = commandExecutor.executeCommand(NET_FIND_INTERFACE); + parseResults = parseNetInterface(commandOutput); + } catch (IOException e) { - logger.log(Level.WARNING, "Failed to retrieve net info", e); + logger.log(Level.WARNING, "Failed to retrieve net interface. ", e); } - finally { - updateHardwareInfoWithNet(parseResults); - } - } - - protected ArrayList<ParseResult> findInterface() throws IOException { - ArrayList<String> commandOutput = commandExecutor.executeCommand(NET_FIND_INTERFACE); - ArrayList<ParseResult> parseResults = parseNetInterface(commandOutput); return parseResults; } - protected void findInterfaceSpeed(ArrayList<ParseResult> parseResults) throws IOException { - String interfaceName = findInterfaceName(parseResults); - String command = NET_CHECK_INTERFACE_SPEED + " " + interfaceName; - ArrayList<String> commandOutput = commandExecutor.executeCommand(command); - parseResults.add(parseInterfaceSpeed(commandOutput)); - } - - protected void testPingResponse(ArrayList<ParseResult> parseResults) throws IOException { - ArrayList<String> commandOutput = commandExecutor.executeCommand(PING_NET_COMMAND); - parseResults.add(parsePingResponse(commandOutput)); - } - protected ArrayList<ParseResult> parseNetInterface(ArrayList<String> commandOutput) { ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(SEARCH_WORD_INTERFACE_IP4, SEARCH_WORD_INTERFACE_IPV6, SEARCH_WORD_INTERFACE_NAME)); ParseInstructions parseInstructions = new ParseInstructions(INTERFACE_NAME_SEARCH_ELEMENT_INDEX, INTERFACE_NAME_RETURN_ELEMENT_INDEX, INTERFACE_NAME_REGEX_SPLIT, searchWords); @@ -85,19 +73,16 @@ public class NetRetriever implements HardwareRetriever { return parseResults; } - protected ParseResult parseInterfaceSpeed(ArrayList<String> commandOutput) { - ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(SEARCH_WORD_INTERFACE_SPEED)); - ParseInstructions parseInstructions = new ParseInstructions(INTERFACE_SPEED_SEARCH_ELEMENT_INDEX, INTERFACE_SPEED_RETURN_ELEMENT_INDEX, INTERFACE_SPEED_REGEX_SPLIT, searchWords); - ParseResult parseResult = OutputParser.parseSingleOutput(parseInstructions, commandOutput); - return parseResult; - } - - protected ParseResult parsePingResponse(ArrayList<String> commandOutput) { - ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(PING_SEARCH_WORD)); - ParseInstructions parseInstructions = new ParseInstructions(PING_SEARCH_ELEMENT_INDEX, PING_RETURN_ELEMENT_INDEX, PING_SPLIT_REGEX_STRING, searchWords); - ParseResult parseResult = OutputParser.parseSingleOutput(parseInstructions, commandOutput); - parseResult = parseResult.getSearchWord().equals(PING_SEARCH_WORD) ? parseResult : new ParseResult(PING_SEARCH_WORD, "invalid"); - return parseResult; + protected void findInterfaceSpeed(ArrayList<ParseResult> parseResults){ + try { + String interfaceName = findInterfaceName(parseResults); + String command = NET_CHECK_INTERFACE_SPEED + " " + interfaceName; + ArrayList<String> commandOutput = commandExecutor.executeCommand(command); + ParseResult parseResult = parseInterfaceSpeed(commandOutput); + parseResults.add(parseResult); + } catch (IOException e) { + logger.log(Level.WARNING, "Failed to retrieve interface speed. ", e); + } } protected String findInterfaceName(ArrayList<ParseResult> parseResults) { @@ -108,8 +93,36 @@ public class NetRetriever implements HardwareRetriever { return ""; } - protected double convertInterfaceSpeed(String speed) { - return Double.parseDouble(speed.replaceAll("[^\\d.]", "")); + protected ParseResult parseInterfaceSpeed(ArrayList<String> commandOutput) throws IOException { + ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(SEARCH_WORD_INTERFACE_SPEED)); + ParseInstructions parseInstructions = new ParseInstructions(INTERFACE_SPEED_SEARCH_ELEMENT_INDEX, INTERFACE_SPEED_RETURN_ELEMENT_INDEX, INTERFACE_SPEED_REGEX_SPLIT, searchWords); + ParseResult parseResult = OutputParser.parseSingleOutput(parseInstructions, commandOutput); + if (!parseResult.getSearchWord().matches(SEARCH_WORD_INTERFACE_SPEED)) { + throw new IOException("Failed to parse interface speed output."); + } + return parseResult; + } + + protected void testPingResponse(ArrayList<ParseResult> parseResults) { + try { + ArrayList<String> commandOutput = commandExecutor.executeCommand(PING_NET_COMMAND); + parseResults.add(parsePingResponse(commandOutput)); + } + catch (ExecuteException e) { + logger.log(Level.WARNING, "Failed to execute ping6"); + } catch (IOException e) { + logger.log(Level.WARNING, e.getMessage()); + } + } + + protected ParseResult parsePingResponse(ArrayList<String> commandOutput) throws IOException { + ArrayList<String> searchWords = new ArrayList<>(Arrays.asList(PING_SEARCH_WORD)); + ParseInstructions parseInstructions = new ParseInstructions(PING_SEARCH_ELEMENT_INDEX, PING_RETURN_ELEMENT_INDEX, PING_SPLIT_REGEX_STRING, searchWords); + ParseResult parseResult = OutputParser.parseSingleOutput(parseInstructions, commandOutput); + if (!parseResult.getSearchWord().matches(PING_SEARCH_WORD)) { + throw new IOException("Failed to parse ping output."); + } + return parseResult; } protected void updateHardwareInfoWithNet(ArrayList<ParseResult> parseResults) { @@ -132,19 +145,21 @@ public class NetRetriever implements HardwareRetriever { break; default: if (parseResult.getSearchWord().matches(SEARCH_WORD_INTERFACE_NAME)) break; - throw new RuntimeException("Invalid ParseResult search word " + parseResult.getSearchWord()); + throw new RuntimeException("Invalid ParseResult search word: " + parseResult.getSearchWord()); } } } + protected double convertInterfaceSpeed(String speed) { + return Double.parseDouble(speed.replaceAll("[^\\d.]", "")); + } + protected void setIpv6Connectivity(ParseResult parseResult) { - if (parseResult.getSearchWord().equals(PING_SEARCH_WORD)) { - String pingResponse = parseResult.getValue(); - String packetLoss = pingResponse.replaceAll("[^\\d.]", ""); - if (packetLoss.equals("")) return; - if (Double.parseDouble(packetLoss) > 99) return; - hardwareInfo.setIpv6Connection(true); - } + String pingResponse = parseResult.getValue(); + String packetLoss = pingResponse.replaceAll("[^\\d.]", ""); + if (packetLoss.equals("")) return; + if (Double.parseDouble(packetLoss) > 99) return; + hardwareInfo.setIpv6Connection(true); } } diff --git a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/yamasreport/SpecReportMetrics.java b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/yamasreport/SpecReportMetrics.java index d835a1b29d3..23ddba32d5c 100644 --- a/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/yamasreport/SpecReportMetrics.java +++ b/node-maintainer/src/main/java/com/yahoo/vespa/hosted/node/verification/spec/yamasreport/SpecReportMetrics.java @@ -36,11 +36,16 @@ public class SpecReportMetrics { private String[] faultyIpAddresses; @JsonProperty private Boolean actualIpv6Connection; + @JsonProperty + private Boolean expectedIpv6Connection; public void setActualIpv6Connection(boolean actualIpv6Connection) { this.actualIpv6Connection = actualIpv6Connection; } + public void setExpectedIpv6Connection(Boolean expectedIpv6Connection) { + this.expectedIpv6Connection = expectedIpv6Connection; + } public void setMatch(boolean match) { this.match = match; diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGeneratorTest.java b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGeneratorTest.java index c992759b694..4ea1b2525d3 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGeneratorTest.java +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/HostURLGeneratorTest.java @@ -46,7 +46,7 @@ public class HostURLGeneratorTest { mockCommandExecutor.addCommand(CAT_CONFIG_SERVER_HOST_NAME_PATH); mockCommandExecutor.addCommand(CAT_WRONG_HOSTNAME_PATH); HostURLGenerator.generateNodeInfoUrl(mockCommandExecutor); - fail("Expected an IOExeption to be thrown"); + fail("Expected an IOException to be thrown"); } catch (IOException e) { String expectedExceptionMessage = "Unexpected output from \"hostname\" command."; assertEquals(expectedExceptionMessage, e.getMessage()); diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifierTest.java b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifierTest.java index a995c295ee2..c56bac698ad 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifierTest.java +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/SpecVerifierTest.java @@ -57,6 +57,13 @@ public class SpecVerifierTest { } @Test + public void verifySpec_environment_is_virtual_machine_should_return_true() throws Exception { + mockCommandExecutor.addCommand("echo notUsed " + URL_RESOURCE_PATH); + mockCommandExecutor.addCommand("echo nodeRepoVirtualMachine.json"); + assertTrue(SpecVerifier.verifySpec(mockCommandExecutor)); + } + + @Test public void verifySpec_inequal_nodeRepoInfo_and_hardware_should_return_false() throws Exception { mockCommandExecutor.addCommand("echo notUsed " + URL_RESOURCE_PATH); mockCommandExecutor.addCommand("echo nodeRepo.json"); @@ -71,7 +78,7 @@ public class SpecVerifierTest { } @Test - public void makeYamasSpecReport_should_return_false_interface_speed() throws Exception { + public void makeYamasSpecReport_should_return_false_interface_speed_and_ipv6_connection() throws Exception { HardwareInfo actualHardware = new HardwareInfo(); actualHardware.setMinCpuCores(24); actualHardware.setMinMainMemoryAvailableGb(24); @@ -79,6 +86,7 @@ public class SpecVerifierTest { actualHardware.setMinDiskAvailableGb(500); actualHardware.setIpv4Interface(true); actualHardware.setIpv6Interface(false); + actualHardware.setIpv6Connection(true); actualHardware.setDiskType(HardwareInfo.DiskType.SLOW); ArrayList<URL> url = new ArrayList<>(Arrays.asList(new File(NODE_REPO_PATH).toURI().toURL())); NodeRepoJsonModel nodeRepoJsonModel = NodeRepoInfoRetriever.retrieve(url); @@ -98,7 +106,7 @@ public class SpecVerifierTest { NodeRepoJsonModel actualNodeRepoJsonModel = SpecVerifier.getNodeRepositoryJSON(mockCommandExecutor); double expectedMinCpuCores = 4D; double expectedMinMainMemoryAvailableGb = 4.04D; - double expectedMinDiskAvailableGb = 63D; + double expectedMinDiskAvailableGb = 1759.84; boolean expectedFastDisk = true; String expectedIpv6Address = "2001:4998:c:2940::111c"; assertEquals(expectedIpv6Address, actualNodeRepoJsonModel.getIpv6Address()); diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifierTest.java b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifierTest.java index 49a0b15e8c3..f063b300ba9 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifierTest.java +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/IPAddressVerifierTest.java @@ -3,6 +3,11 @@ package com.yahoo.vespa.hosted.node.verification.spec.noderepo; import org.junit.Before; import org.junit.Test; +import java.net.URL; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.doReturn; @@ -11,47 +16,61 @@ import static org.mockito.Mockito.spy; public class IPAddressVerifierTest { private IPAddressVerifier ipAddressVerifier = spy(new IPAddressVerifier()); - private String ipAddress; - private String additionalIp1; - private String additionalIp2; - private String additionalIp3; - private String[] additionalIpAddresses; + private String ipv4Address; + private String ipv6Address; + private NodeRepoJsonModel nodeRepoJsonModel; + private static final String ABSOLUTE_PATH = Paths.get(".").toAbsolutePath().normalize().toString(); + private static final String RESOURCE_PATH = "src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/IPAddressVerifierTest.json"; + private static final String URL_RESOURCE_PATH = "file://" + ABSOLUTE_PATH + "/" + RESOURCE_PATH; + private String ipv4LookupFormat; + private String ipv6LookupFormat; @Before - public void setup() { - ipAddress = "2001:4998:c:2977::1060"; - additionalIp1 = "2001:4998:c:2977::106f"; - additionalIp2 = "2001:4998:c:2977::106a"; - additionalIp3 = "2001:4998:c:2977::106c"; - additionalIpAddresses = new String[]{additionalIp1, additionalIp2, additionalIp3}; + public void setup() throws Exception{ + ipv4Address = "10.213.181.113"; + ipv6Address = "2001:4998:c:2940::111c"; + ArrayList<URL> nodeRepoUrl = new ArrayList<>(Arrays.asList(new URL(URL_RESOURCE_PATH))); + nodeRepoJsonModel = NodeRepoInfoRetriever.retrieve(nodeRepoUrl); + ipv4LookupFormat = "113.181.213.10.in-addr.arpa"; + ipv6LookupFormat = "c.1.1.1.0.0.0.0.0.0.0.0.0.0.0.0.0.4.9.2.c.0.0.0.8.9.9.4.1.0.0.2.ip6.arpa"; + } + + @Test + public void getFaultyIpAddresses_should_return_IP_address_when_different_hostname() throws Exception { + String realHostName = "zt74722.ostk.bm2.prod.gq1.yahoo.com"; + String wrongHostName = "www.yahoo.com"; + doReturn(realHostName).when(ipAddressVerifier).reverseLookUp(ipv4LookupFormat); + doReturn(wrongHostName).when(ipAddressVerifier).reverseLookUp(ipv6LookupFormat); + String[] faultyIpAddresses = ipAddressVerifier.getFaultyIpAddresses(nodeRepoJsonModel); + String[] expectedFaultyIpAddresses = new String[]{ipv6Address}; + assertArrayEquals(expectedFaultyIpAddresses, faultyIpAddresses); } @Test - public void verifyAdditionalIpAddress_should_add_IP_address_when_different_hostname() throws Exception { - String realHostName = "www.yahoo.com"; - String wrongHostName = "www.nrk.no"; - doReturn(realHostName).when(ipAddressVerifier).reverseLookUp(ipAddress); - doReturn(realHostName).when(ipAddressVerifier).reverseLookUp(additionalIp1); - doReturn(realHostName).when(ipAddressVerifier).reverseLookUp(additionalIp2); - doReturn(wrongHostName).when(ipAddressVerifier).reverseLookUp(additionalIp3); - String[] faultyIpAddresses = ipAddressVerifier.getFaultyIpAddresses(ipAddress, additionalIpAddresses); - String[] expectedFaultyIpAddresses = new String[]{additionalIp3}; + public void getFaultyIpAddresses_should_return_empty_array_when_all_addresses_point_to_correct_hostname() throws Exception { + String realHostName = "zt74722.ostk.bm2.prod.gq1.yahoo.com"; + doReturn(realHostName).when(ipAddressVerifier).reverseLookUp(ipv4LookupFormat); + doReturn(realHostName).when(ipAddressVerifier).reverseLookUp(ipv6LookupFormat); + String[] faultyIpAddresses = ipAddressVerifier.getFaultyIpAddresses(nodeRepoJsonModel); + String[] expectedFaultyIpAddresses = new String[]{}; assertArrayEquals(expectedFaultyIpAddresses, faultyIpAddresses); } @Test - public void convertToLookupFormat_should_return_properly_converted_ipv6_address() { - String ipv6Address = "2001:db8::567:89ab"; - String actualConvertedAddress = ipAddressVerifier.convertToLookupFormat(ipv6Address); - String expectedConvertedAddress = "b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa"; - assertEquals(expectedConvertedAddress, actualConvertedAddress); + public void convertIpv6ToLookupFormat_should_return_properly_converted_ipv6_address() { + String actualConvertedAddress = ipAddressVerifier.convertIpv6ToLookupFormat(ipv6Address); + assertEquals(ipv6LookupFormat, actualConvertedAddress); + } + + @Test + public void convertIpv4ToLookupFormat_should_return_properly_converted_ipv6_address() { + String actualConvertedAddress = ipAddressVerifier.convertIpv4ToLookupFormat(ipv4Address); + assertEquals(ipv4LookupFormat, actualConvertedAddress); } @Test public void getFaultyIpAddresses_should_return_empty_array_when_parameters_are_invalid () { - assertEquals(0, ipAddressVerifier.getFaultyIpAddresses(null, null).length); - String invalidIpAddress = "This is an invalid IP address"; - assertEquals(0, ipAddressVerifier.getFaultyIpAddresses(invalidIpAddress, additionalIpAddresses).length); + assertEquals(0, ipAddressVerifier.getFaultyIpAddresses(new NodeRepoJsonModel()).length); } }
\ No newline at end of file diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoInfoRetrieverTest.java b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoInfoRetrieverTest.java index 1eeb6423645..8d07c519e44 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoInfoRetrieverTest.java +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/noderepo/NodeRepoInfoRetrieverTest.java @@ -39,7 +39,7 @@ public class NodeRepoInfoRetrieverTest { assertEquals(expectedMinCpuCores, nodeRepoJsonModel.getMinCpuCores(), DELTA); } @Test - public void retrieve_should_throw_IOEqxception_when_no_valid_URLs() throws MalformedURLException { + public void retrieve_should_throw_IOException_when_no_valid_URLs() throws MalformedURLException { urls = new ArrayList<>(); String exceptionMessage = "Failed to parse JSON from all possible config servers."; try { diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/IPAddressVerifierTest.json b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/IPAddressVerifierTest.json new file mode 100644 index 00000000000..377029da23c --- /dev/null +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/IPAddressVerifierTest.json @@ -0,0 +1,113 @@ +{ + "url": "https://api.vespa.corp.yahoo.com:4443/zone/v2/prod/us-west-1/nodes/v2/node/zt74722.ostk.bm2.prod.gq1.yahoo.com", + "id": "zt74722.ostk.bm2.prod.gq1.yahoo.com", + "state": "active", + "type": "host", + "hostname": "zt74722.ostk.bm2.prod.gq1.yahoo.com", + "openStackId": "653c39c1-bda4-47ee-a277-d5319eb57af7", + "flavor": "C-77E/256/960", + "canonicalFlavor": "C-77E/256/960", + "minDiskAvailableGb": 1920.0, + "minMainMemoryAvailableGb": 256.0, + "description": "BARE_METAL with 48.0 CPUs, 256.0 Gb memory and 1920.0 Gb ssd", + "minCpuCores": 48.0, + "cost": 150, + "fastDisk": true, + "environment": "BARE_METAL", + "owner": { + "tenant": "hosted-vespa", + "application": "routing", + "instance": "default" + }, + "membership": { + "clustertype": "container", + "clusterid": "node-admin", + "group": "0", + "index": 77, + "retired": false + }, + "restartGeneration": 0, + "currentRestartGeneration": 0, + "wantedDockerImage": "docker-registry.ops.yahoo.com:4443/vespa/ci:6.132.102", + "wantedVespaVersion": "6.132.102", + "rebootGeneration": 3, + "currentRebootGeneration": 3, + "vespaVersion": "6.132.102", + "currentDockerImage": "docker-registry.ops.yahoo.com:4443/vespa/ci:6.132.102", + "hostedVersion": "6.132.102", + "convergedStateVersion": "6.132.102", + "failCount": 1, + "hardwareFailure": false, + "wantToRetire": false, + "wantToDeprovision": false, + "history": [ + { + "event": "failed", + "at": 1499293603487, + "agent": "system" + }, + { + "event": "rebooted", + "at": 1499351267086, + "agent": "system" + }, + { + "event": "readied", + "at": 1499351270674, + "agent": "system" + }, + { + "event": "requested", + "at": 1499350936347, + "agent": "system" + }, + { + "event": "reserved", + "at": 1499353058227, + "agent": "application" + }, + { + "event": "activated", + "at": 1499353080459, + "agent": "application" + } + ], + "ipAddresses": [ + "10.213.181.113", + "2001:4998:c:2940::111c" + ], + "additionalIpAddresses": [ + "2001:4998:c:2940::1138", + "2001:4998:c:2940::1139", + "2001:4998:c:2940::1136", + "2001:4998:c:2940::1137", + "2001:4998:c:2940::1130", + "2001:4998:c:2940::1131", + "2001:4998:c:2940::1134", + "2001:4998:c:2940::1135", + "2001:4998:c:2940::1132", + "2001:4998:c:2940::1133", + "2001:4998:c:2940::111f", + "2001:4998:c:2940::111d", + "2001:4998:c:2940::111e", + "2001:4998:c:2940::113a", + "2001:4998:c:2940::113b", + "2001:4998:c:2940::113c", + "2001:4998:c:2940::1127", + "2001:4998:c:2940::1128", + "2001:4998:c:2940::1125", + "2001:4998:c:2940::1126", + "2001:4998:c:2940::1129", + "2001:4998:c:2940::1120", + "2001:4998:c:2940::1123", + "2001:4998:c:2940::1124", + "2001:4998:c:2940::1121", + "2001:4998:c:2940::1122", + "2001:4998:c:2940::112e", + "2001:4998:c:2940::112f", + "2001:4998:c:2940::112c", + "2001:4998:c:2940::112d", + "2001:4998:c:2940::112a", + "2001:4998:c:2940::112b" + ] +}
\ No newline at end of file diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/SpecVerifierReport b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/SpecVerifierReport index 8bfad7a32d1..39022f761cd 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/SpecVerifierReport +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/SpecVerifierReport @@ -1 +1 @@ -{"timeStamp":1501504035,"dimensions":{"memoryMatch":true,"cpuCoresMatch":true,"diskTypeMatch":true,"netInterfaceSpeedMatch":false,"diskAvailableMatch":true,"ipv4Match":true,"ipv6Match":true},"metrics":{"match":false,"expectedInterfaceSpeed":1000.0,"actualInterfaceSpeed":10009.0,"actualIpv6Connection":false},"routing":{"yamas":{"namespace":["Vespa"]}}} +{"timeStamp":1501504035,"dimensions":{"memoryMatch":true,"cpuCoresMatch":true,"diskTypeMatch":true,"netInterfaceSpeedMatch":false,"diskAvailableMatch":true,"ipv4Match":true,"ipv6Match":true},"metrics":{"match":false,"expectedInterfaceSpeed":1000.0,"actualInterfaceSpeed":10009.0,"actualIpv6Connection":true,"expectedIpv6Connection":false},"routing":{"yamas":{"namespace":["Vespa"]}}} diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/filesize b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/filesize index 4e9e2884874..d8148474ced 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/filesize +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/filesize @@ -1 +1,2 @@ -63
\ No newline at end of file + PV Size 799.65 GB / not usable 0.00 GB + PV Size 960.19 GB / not usable 0.01 GB
\ No newline at end of file diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodeInfoTest.json b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodeInfoTest.json index d0779af5feb..7017a4e6453 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodeInfoTest.json +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodeInfoTest.json @@ -3,7 +3,7 @@ "id": "20004731.ostk.bm1.prod.ir2.yahoo.com", "state": "ready", "type": "tenant", - "hostname": "20004731.ostk.bm1.prod.ir2.yahoo.com", + "hostname": "", "openStackId": "77df66c5-3cbc-4905-b0e9-f790bddd13bf", "fastDisk": false, "flavor": "C-2B/24/500", diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodes/v2/node/nodeRepo.json b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodes/v2/node/nodeRepo.json index 8631c2a51aa..81c8494ca6b 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodes/v2/node/nodeRepo.json +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodes/v2/node/nodeRepo.json @@ -7,7 +7,7 @@ "openStackId": "653c39c1-bda4-47ee-a277-d5319eb57af7", "flavor": "C-77E/256/960", "canonicalFlavor": "C-77E/256/960", - "minDiskAvailableGb": 63.0, + "minDiskAvailableGb": 1759.84, "minMainMemoryAvailableGb": 4.042128, "description": "BARE_METAL with 48.0 CPUs, 256.0 Gb memory and 1920.0 Gb ssd", "minCpuCores": 4.0, diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodes/v2/node/nodeRepoVirtualMachine.json b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodes/v2/node/nodeRepoVirtualMachine.json new file mode 100644 index 00000000000..6a0223d325c --- /dev/null +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/nodes/v2/node/nodeRepoVirtualMachine.json @@ -0,0 +1,51 @@ +{ + "url": "https://api.vespa.corp.yahoo.com:4443/zone/v2/prod/eu-west-1/nodes/v2/node/oxy-oxygen-0ac90d2e.ir2.yahoo.com", + "id": "oxy-oxygen-0ac90d2e.ir2.yahoo.com", + "state": "ready", + "type": "tenant", + "hostname": "oxy-oxygen-0ac90d2e.ir2.yahoo.com", + "parentHostname": "hv122.ostk.cl1.prod.ir2.yahoo.com", + "openStackId": "9171477a-35be-4a60-81b0-2b631a36c712", + "flavor": "v-4-8-100", + "canonicalFlavor": "v-4-8-100", + "minDiskAvailableGb": 100.0, + "minMainMemoryAvailableGb": 8.0, + "description": "VIRTUAL_MACHINE with 4.0 CPUs, 8.0 Gb memory and 100.0 Gb disk", + "minCpuCores": 4.0, + "cost": 15, + "fastDisk": false, + "environment": "VIRTUAL_MACHINE", + "rebootGeneration": 9, + "currentRebootGeneration": 9, + "vespaVersion": "6.132.102", + "currentDockerImage": "docker-registry.ops.yahoo.com:4443/vespa/ci:6.132.102", + "hostedVersion": "6.132.102", + "convergedStateVersion": "6.132.102", + "failCount": 2, + "hardwareFailure": false, + "wantToRetire": false, + "wantToDeprovision": false, + "history": [ + { + "event": "readied", + "at": 1488621028325, + "agent": "system" + }, + { + "event": "rebooted", + "at": 1500455903916, + "agent": "system" + }, + { + "event": "requested", + "at": 1501598263220, + "agent": "system" + } + ], + "ipAddresses": [ + "10.201.13.46" + ], + "additionalIpAddresses": [ + + ] +}
\ No newline at end of file diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetrieverTest.java b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetrieverTest.java index f93791bb78d..cf9bc3e1b89 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetrieverTest.java +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/DiskRetrieverTest.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.util.ArrayList; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; /** * Created by olaa on 06/07/2017. @@ -35,7 +36,7 @@ public class DiskRetrieverTest { commandExecutor.addCommand(CAT_RESOURCE_PATH + "filesize"); diskRetriever.updateInfo(); assertEquals(DiskType.FAST, hardwareInfo.getDiskType()); - double expectedSize = 63D; + double expectedSize = 1759.84; assertEquals(expectedSize, hardwareInfo.getMinDiskAvailableGb(), DELTA); } @@ -50,7 +51,7 @@ public class DiskRetrieverTest { public void updateDiskSize__should_store_diskSize_in_hardwareInfo() throws IOException { commandExecutor.addCommand(CAT_RESOURCE_PATH + "filesize"); diskRetriever.updateDiskSize(); - double expectedSize = 63D; + double expectedSize = 1759.84; assertEquals(expectedSize, hardwareInfo.getMinDiskAvailableGb(), DELTA); } @@ -72,24 +73,27 @@ public class DiskRetrieverTest { } @Test - public void parseDiskType_with_invalid_output_stream_should_not_find_disk_type() throws Exception { - ArrayList<String> mockOutput = commandExecutor.outputFromString("Name Rota \nsda x"); - ParseResult parseResult = diskRetriever.parseDiskType(mockOutput); - ParseResult expectedParseResult = new ParseResult("sda", "x"); - assertEquals(expectedParseResult, parseResult); - mockOutput = commandExecutor.outputFromString("Name Rota"); - parseResult = diskRetriever.parseDiskType(mockOutput); - expectedParseResult = new ParseResult("invalid", "invalid"); - assertEquals(expectedParseResult, parseResult); + public void parseDiskType_with_invalid_outputstream_does_not_contain_searchword_should_throw_exception() throws Exception { + ArrayList<String> mockOutput = commandExecutor.outputFromString("Name Rota"); + try{ + ParseResult parseResult = diskRetriever.parseDiskType(mockOutput); + fail("Should have thrown IOException when outputstream doesn't contain search word"); + } catch (IOException e) { + String expectedExceptionMessage = "Parsing for disk type failed"; + assertEquals(expectedExceptionMessage, e.getMessage()); + } + } @Test public void parseDiskSize_should_find_size_from_file_and_insert_into_parseResult() throws Exception { String filepath = "src/test/java/com/yahoo/vespa/hosted/node/verification/spec/resources/filesize"; ArrayList<String> mockOutput = MockCommandExecutor.readFromFile(filepath); - ParseResult parseResult = diskRetriever.parseDiskSize(mockOutput); - ParseResult expectedParseResult = new ParseResult("63", "63"); - assertEquals(expectedParseResult, parseResult); + ArrayList<ParseResult> parseResults = diskRetriever.parseDiskSize(mockOutput); + ParseResult expectedParseResult1 = new ParseResult("Size", "799.65"); + assertEquals(expectedParseResult1, parseResults.get(0)); + ParseResult expectedParseResult2 = new ParseResult("Size", "960.19"); + assertEquals(expectedParseResult2, parseResults.get(1)); } @Test diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/HardwareInfoRetrieverTest.java b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/HardwareInfoRetrieverTest.java index f549753918a..ffa0a44feb3 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/HardwareInfoRetrieverTest.java +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/HardwareInfoRetrieverTest.java @@ -36,7 +36,7 @@ public class HardwareInfoRetrieverTest { expectedHardwareInfo.setMinCpuCores(4); expectedHardwareInfo.setMinMainMemoryAvailableGb(4.042128); expectedHardwareInfo.setInterfaceSpeedMbs(1000); - expectedHardwareInfo.setMinDiskAvailableGb(63); + expectedHardwareInfo.setMinDiskAvailableGb(1759.84); expectedHardwareInfo.setIpv4Interface(true); expectedHardwareInfo.setIpv6Interface(false); expectedHardwareInfo.setIpv6Connection(false); diff --git a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetrieverTest.java b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetrieverTest.java index b3a273ddd39..73678d4a3b1 100644 --- a/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetrieverTest.java +++ b/node-maintainer/src/test/java/com/yahoo/vespa/hosted/node/verification/spec/retrievers/NetRetrieverTest.java @@ -12,6 +12,7 @@ import java.util.Arrays; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * Created by sgrostad on 07/07/2017. @@ -149,11 +150,15 @@ public class NetRetrieverTest { } @Test - public void parsePingResponse_invalid_ping_response_should_return_invalid_ParseResult() throws IOException { + public void parsePingResponse_invalid_ping_response_should_throw_IOException() throws IOException { ArrayList<String> mockCommandOutput = MockCommandExecutor.readFromFile(INVALID_PING_RESPONSE); - ParseResult parseResult = net.parsePingResponse(mockCommandOutput); - ParseResult expectedParseResult = new ParseResult(PING_SEARCH_WORD, "invalid"); - assertEquals(expectedParseResult, parseResult); + try { + ParseResult parseResult = net.parsePingResponse(mockCommandOutput); + fail("Expected an IOException to be thrown"); + } catch (IOException e) { + String expectedExceptionMessage = "Failed to parse ping output."; + assertEquals(expectedExceptionMessage, e.getMessage()); + } } @Test |