Browse Source

Moving isreachable to reflect on the new method. On java <=1.4; if the hostname can be resolved then we are reachable.

All tests run against localhost. This *should* work everywhere, but no doubt someone with a confused /etc/hosts or no IPv4 stack will have different opinions.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277887 13f79535-47bb-0310-9956-ffa450edef68
master
Steve Loughran 20 years ago
parent
commit
80593698b1
6 changed files with 540 additions and 314 deletions
  1. +281
    -281
      build.xml
  2. +5
    -1
      docs/manual/CoreTasks/conditions.html
  3. +104
    -0
      src/etc/testcases/taskdefs/conditions/isreachable.xml
  4. +68
    -31
      src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java
  5. +1
    -1
      src/main/org/apache/tools/ant/types/defaults.properties
  6. +81
    -0
      src/testcases/org/apache/tools/ant/taskdefs/condition/IsReachableTest.java

+ 281
- 281
build.xml
File diff suppressed because it is too large
View File


+ 5
- 1
docs/manual/CoreTasks/conditions.html View File

@@ -537,7 +537,11 @@ Check for Xerces-specific definition of the location of the no namespace schema.

<p>Uses Java1.5+ networking APIs to probe for a (remote) system being
reachable. Exactly what probe mechanisms are used is an implementation
feature of the JVM. They may include ICMP "ping" packets
feature of the JVM. They may include ICMP "ping" packets, UDP or TCP connections
to port 7 "echo service" or other means. On Java1.4 and earlier, being able
to resolve the hostname is considered success. This means that if DNS is not
working or a URL/hostname is bad, the test will fail, but otherwise succeed
even if the remote host is actually absent.

</p>
<p>


+ 104
- 0
src/etc/testcases/taskdefs/conditions/isreachable.xml View File

@@ -0,0 +1,104 @@
<project name="isreachable">
<!--
* Copyright 2005 The Apache Software Foundation
*
* 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.
*
-->


<macrodef name="assertHostReachable">
<attribute name="host"/>
<sequential>
<fail message="not reachable: @{host}">
<condition>
<not>
<isreachable host="@{host}"/>
</not>
</condition>
</fail>
</sequential>
</macrodef>

<macrodef name="assertHostNotReachable">
<attribute name="host"/>
<sequential>
<fail message="unexpectedly reachable: @{host}">
<condition>
<isreachable host="@{host}"/>
</condition>
</fail>
</sequential>
</macrodef>

<macrodef name="assertUrlReachable">
<attribute name="url"/>
<sequential>
<fail message="not reachable: @{url}">
<condition>
<not>
<isreachable url="@{url}"/>
</not>
</condition>
</fail>
</sequential>
</macrodef>

<target name="testLocalhost">
<assertHostReachable host="localhost"/>
</target>

<!-- bugs in XPSP2 mean this is the only IPv4 loopback addr allowed -->
<target name="testIpv4localhost">
<assertHostReachable host="127.0.0.1"/>
</target>

<target name="testBoth">
<condition property="both">
<isreachable host="localhost" url="http://localhost"/>
</condition>
<fail>Expected failure before here</fail>
</target>

<target name="testLocalhostURL">
<assertUrlReachable url="http://localhost"/>
</target>

<target name="testIpv4localhostURL">
<assertUrlReachable url="http://127.0.0.1/"/>
</target>

<target name="testFTPURL">
<assertUrlReachable url="ftp://localhost"/>
</target>

<target name="testFile">
<assertUrlReachable url="file://build.xml"/>
</target>

<target name="testBadURL">
<assertUrlReachable url="uuid:3349-4404-0ac0ddee"/>
</target>

<target name="testBadTimeout">
<condition property="testBadTimeout">
<isreachable host="localhost" timeout="-1"/>
</condition>
</target>

<target name="testNoTargets">
<condition property="none">
<isreachable/>
</condition>
</target>
</project>

src/main/org/apache/tools/ant/taskdefs/optional/condition/IsPingable.java → src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java View File

@@ -15,42 +15,43 @@
*
*/

package org.apache.tools.ant.taskdefs.optional.condition;
package org.apache.tools.ant.taskdefs.condition;

import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.condition.Condition;
import org.apache.tools.ant.ProjectComponent;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.IOException;
import java.net.URL;
import java.net.UnknownHostException;

/**
* Test for a host being reachable using ICMP "ping" packets.
* Test for a host being reachable using ICMP "ping" packets & echo operations.
* Ping packets are very reliable for assessing reachability in a LAN or WAN,
* but they do not get through any well-configured firewall.
* but they do not get through any well-configured firewall. Echo (port 7) may.
* <p/>
* This condition turns unknown host exceptions into false conditions. This is
* because on a laptop, DNS is one of the first services when the network goes; you
* are implicitly offline.
* because on a laptop, DNS is one of the first services when the network goes;
* you are implicitly offline.
* <p/>
* If a URL is supplied instead of a host, the hostname is extracted
* and used in the test - all other parts of the URL are discarded.
* If a URL is supplied instead of a host, the hostname is extracted and used in
* the test - all other parts of the URL are discarded.
* <p/>
* The test may not work through firewalls, that is, something may be reachable
* using a protocol such as HTTP, while the lower level ICMP packets get dropped
* on the floor. Similarly, a host may detected as reachable with ICMP, but
* not reachable on other ports (i.e. port 80), because of firewalls.
* on the floor. Similarly, a host may detected as reachable with ICMP, but not
* reachable on other ports (i.e. port 80), because of firewalls.
* <p/>
* Requires Java1.5+ to work
* Requires Java1.5+ to work properly. On Java1.4 and earlier, if a hostname is
* resolveable, the destination is assumed to be reachable.
*
* @ant.condition name="isreachable"
* @since Ant1.7
*/
public class IsPingable extends ProjectComponent implements Condition {
public class IsReachable extends ProjectComponent implements Condition {

private String host;
private String url;
@@ -71,12 +72,15 @@ public class IsPingable extends ProjectComponent implements Condition {
/**
* Unknown host message is seen.
*/
public static final String ERROR_UNKNOWN_HOST = "Unknown host:";
public static final String WARN_UNKNOWN_HOST = "Unknown host:";
/**
* Network error message is seen.
*/
public static final String ERROR_ON_NETWORK = "network error to ";
public static final String ERROR_BOTH_TARGETS = "Both url and host have been specified";
public static final String MSG_NO_REACHABLE_TEST = "cannot do a proper reachability test on this Java version";
public static final String ERROR_BAD_URL = "Bad URL ";
public static final String ERROR_NO_HOST_IN_URL = "No hostname in URL ";

/**
* The host to ping.
@@ -109,16 +113,20 @@ public class IsPingable extends ProjectComponent implements Condition {
* emptyness test
*
* @param string param to check
*
* @return true if it is empty
*/
private boolean empty(String string) {
return string == null || string.length() == 0;
}

private static Class[] parameterTypes = {Integer.class};

/**
* Is this condition true?
*
* @return true if the condition is true.
*
* @throws org.apache.tools.ant.BuildException
* if an error occurs
*/
@@ -138,25 +146,54 @@ public class IsPingable extends ProjectComponent implements Condition {
//get the host of a url
URL realURL = new URL(url);
target = realURL.getHost();
if (empty(target)) {
throw new BuildException(ERROR_NO_HOST_IN_URL + url);
}
} catch (MalformedURLException e) {
throw new BuildException("Bad URL " + url, e);
throw new BuildException(ERROR_BAD_URL + url, e);
}
}
log("Probing host " + target, Project.MSG_VERBOSE);
InetAddress address;
try {
log("Probing host " + target, Project.MSG_VERBOSE);
InetAddress address = InetAddress.getByName(target);
log("Host address =" + address.getHostAddress(),
Project.MSG_VERBOSE);
final boolean reachable = address.isReachable(timeout * 1000);
log("host is " + (reachable ? "" : "not") + " reachable",
Project.MSG_VERBOSE);
return reachable;
} catch (UnknownHostException e) {
log(ERROR_UNKNOWN_HOST + target);
return false;
} catch (IOException e) {
log(ERROR_ON_NETWORK + target + ": " + e.toString());
log(WARN_UNKNOWN_HOST + target);
address = InetAddress.getByName(target);
} catch (UnknownHostException e1) {
return false;

}
log("Host address =" + address.getHostAddress(),
Project.MSG_VERBOSE);
boolean reachable;
//Java1.5: reachable = address.isReachable(timeout * 1000);
Method reachableMethod = null;
try {
reachableMethod = InetAddress.class.getMethod("reachable",
parameterTypes);
Object[] params = new Object[1];
params[0] = new Integer(timeout * 1000);
try {
reachable = ((Boolean) reachableMethod.invoke(address, params))
.booleanValue();
} catch (IllegalAccessException e) {
//utterly implausible, but catered for anyway
throw new BuildException("When calling " + reachableMethod);
} catch (InvocationTargetException e) {
//assume this is an IOexception about un readability
Throwable nested = e.getTargetException();
log(ERROR_ON_NETWORK + target + ": " + nested.toString());
//any kind of fault: not reachable.
reachable = false;
}
} catch (NoSuchMethodException e) {
//java1.4 or earlier
log(MSG_NO_REACHABLE_TEST);
reachable = true;

}

log("host is " + (reachable ? "" : "not") + " reachable",
Project.MSG_VERBOSE);
return reachable;
}
}

+ 1
- 1
src/main/org/apache/tools/ant/types/defaults.properties View File

@@ -37,7 +37,7 @@ assertions=org.apache.tools.ant.types.Assertions
concatfilter=org.apache.tools.ant.filters.ConcatFilter
issigned=org.apache.tools.ant.taskdefs.condition.IsSigned
isfileselected=org.apache.tools.ant.taskdefs.condition.IsFileSelected
isreachable=org.apache.tools.ant.taskdefs.optional.condition.IsPingable
isreachable=org.apache.tools.ant.taskdefs.condition.IsReachable
mavenrepository=org.apache.tools.ant.taskdefs.repository.MavenRepository
scriptselector=org.apache.tools.ant.types.optional.ScriptSelector
scriptcondition=org.apache.tools.ant.types.optional.ScriptCondition


+ 81
- 0
src/testcases/org/apache/tools/ant/taskdefs/condition/IsReachableTest.java View File

@@ -0,0 +1,81 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* 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.apache.tools.ant.taskdefs.condition;

import org.apache.tools.ant.BuildFileTest;

/**
* test for reachable things
*/
public class IsReachableTest extends BuildFileTest {

public IsReachableTest(String name) {
super(name);
}

public void setUp() {
configureProject(
"src/etc/testcases/taskdefs/conditions/isreachable.xml");
}


public void testLocalhost() throws Exception {
executeTarget("testLocalhost");
}

public void testLocalhostURL() throws Exception {
executeTarget("testLocalhostURL");
}

public void testIpv4localhost() throws Exception {
executeTarget("testIpv4localhost");
}

public void testFTPURL() throws Exception {
executeTarget("testFTPURL");
}

public void testBoth() throws Exception {
expectBuildExceptionContaining("testBoth",
"error on two targets",
IsReachable.ERROR_BOTH_TARGETS);
}

public void testNoTargets() throws Exception {
expectBuildExceptionContaining("testNoTargets",
"no params",
IsReachable.ERROR_NO_HOSTNAME);
}

public void testBadTimeout() throws Exception {
expectBuildExceptionContaining("testBadTimeout",
"error on -ve timeout",
IsReachable.ERROR_BAD_TIMEOUT);
}

public void NotestFile() throws Exception {
expectBuildExceptionContaining("testFile",
"error on file URL",
IsReachable.ERROR_NO_HOST_IN_URL);
}

public void testBadURL() throws Exception {
expectBuildExceptionContaining("testBadURL",
"error in URL",
IsReachable.ERROR_BAD_URL);
}
}

Loading…
Cancel
Save