git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278320 13f79535-47bb-0310-9956-ffa450edef68master
@@ -9,6 +9,12 @@ | |||
<property name="ftp.filesep" value="/"/> | |||
<property name="tmp.dir" location="tmp"/> | |||
<property name="tmp.get.dir" location="tmp.get"/> | |||
<property name="tmp.local" location="${tmp.get.dir}"/> | |||
<property name="tmp.remote" location="${tmp.dir}"/> | |||
<property name="tstamp.format" value="yyyy-MM-dd HH:mm"/> | |||
<property name="server.timestamp.granularity.millis" value="60000"/> | |||
<property name="ftp.server.timezone" value="GMT"/> | |||
<fileset dir="${tmp.get.dir}" id="fileset-destination-with-selector"> | |||
<include name="alpha/**"/> | |||
<filename name="**/alpha.xml" /> | |||
@@ -25,12 +31,23 @@ | |||
<fileset dir="${tmp.get.dir}" id="fileset-destination-nofollowsymlinks" followsymlinks="false"> | |||
<include name="alpha/**"/> | |||
</fileset> | |||
<filelist dir="${tmp.local}" id="timed-files" files="A.timed,B.timed,C.timed,D.timed"/> | |||
<patternset id="timed-test-files"> | |||
<include name="A.timed"/> | |||
<include name="B.timed"/> | |||
<include name="C.timed"/> | |||
<include name="D.timed"/> | |||
</patternset> | |||
<target name="setup"> | |||
<mkdir dir="${tmp.get.dir}"/> | |||
<mkdir dir="${tmp.dir}/alpha/beta/gamma"/> | |||
<touch file="${tmp.dir}/alpha/beta/gamma/gamma.xml"/> | |||
<touch file="${tmp.dir}/alpha/beta/beta.xml"/> | |||
</target> | |||
<target name="ftp-get-with-selector"> | |||
<ftp action="get" | |||
server="${ftp.host}" | |||
@@ -104,5 +121,76 @@ | |||
<include name="**"/> | |||
</fileset> | |||
</ftp> | |||
</target> | |||
<target name="timed.test.setup"> | |||
<touch> | |||
<filelist refid="timed-files"/> | |||
</touch> | |||
<ftp action="put" | |||
server="${ftp.host}" | |||
userid="${ftp.user}" | |||
password="${ftp.password}" | |||
separator="${ftp.filesep}" | |||
remotedir="${tmp.remote}" | |||
> | |||
<fileset dir="${tmp.local}"> | |||
<patternset refid="timed-test-files"/> | |||
</fileset> | |||
</ftp> | |||
</target> | |||
<target name="timed.test.put.older"> | |||
<tstamp> | |||
<format property="five.minutes.older" pattern="${tstamp.format}" offset="-5" unit="minute"/> | |||
</tstamp> | |||
<touch datetime="${five.minutes.older}" pattern="${tstamp.format}" verbose="true"> | |||
<fileset dir="${tmp.remote}"> | |||
<include name="A.timed"/> | |||
</fileset> | |||
</touch> | |||
<ftp action="put" | |||
server="${ftp.host}" | |||
userid="${ftp.user}" | |||
password="${ftp.password}" | |||
separator="${ftp.filesep}" | |||
remotedir="${tmp.remote}" | |||
timediffmillis="${server.timestamp.granularity.millis}" | |||
newer="true" | |||
serverTimeZoneConfig="${ftp.server.timezone}" | |||
> | |||
<fileset dir="${tmp.local}"> | |||
<patternset refid="timed-test-files"/> | |||
</fileset> | |||
</ftp> | |||
</target> | |||
<target name="timed.test.get.older"> | |||
<tstamp> | |||
<format property="five.minutes.older" pattern="${tstamp.format}" offset="-5" unit="minute"/> | |||
</tstamp> | |||
<touch datetime="${five.minutes.older}" pattern="${tstamp.format}" verbose="true"> | |||
<fileset dir="${tmp.local}"> | |||
<include name="A.timed"/> | |||
<include name="C.timed"/> | |||
<include name="D.timed"/> | |||
</fileset> | |||
</touch> | |||
<ftp action="get" | |||
server="${ftp.host}" | |||
userid="${ftp.user}" | |||
password="${ftp.password}" | |||
separator="${ftp.filesep}" | |||
remotedir="${tmp.remote}" | |||
preservelastmodified="true" | |||
newer="true" | |||
serverTimeZoneConfig="${ftp.server.timezone}" | |||
> | |||
<fileset dir="${tmp.local}"> | |||
<patternset refid="timed-test-files"/> | |||
</fileset> | |||
</ftp> | |||
</target> | |||
</project> |
@@ -16,16 +16,23 @@ | |||
*/ | |||
package org.apache.tools.ant.taskdefs.optional.net; | |||
import org.apache.tools.ant.BuildEvent; | |||
import org.apache.tools.ant.BuildFileTest; | |||
import org.apache.tools.ant.BuildListener; | |||
import org.apache.tools.ant.BuildLogger; | |||
import org.apache.tools.ant.DefaultLogger; | |||
import org.apache.tools.ant.DirectoryScanner; | |||
import org.apache.tools.ant.types.FileSet; | |||
import org.apache.tools.ant.taskdefs.optional.net.FTP; | |||
import org.apache.tools.ant.util.JavaEnvUtils; | |||
import org.apache.tools.ant.util.regexp.RegexpMatcher; | |||
import org.apache.tools.ant.util.regexp.RegexpMatcherFactory; | |||
import org.apache.tools.ant.taskdefs.condition.Os; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Arrays; | |||
import java.util.Vector; | |||
import org.apache.commons.net.ftp.FTPClient; | |||
@@ -537,6 +544,82 @@ public class FTPTest extends BuildFileTest{ | |||
new String[] {"alpha/beta", "alpha/beta/gamma", "delta"}); | |||
} | |||
/** | |||
* This class enables the use of the log messages as a way of testing | |||
* the number of files actually transferred. | |||
* It uses the ant regular expression mechanism to get a regex parser | |||
* to parse the log output. | |||
*/ | |||
private class CountLogListener extends DefaultLogger { | |||
private Vector lastMatchGroups = null; | |||
private RegexpMatcher matcher = new RegexpMatcherFactory().newRegexpMatcher(); | |||
/** | |||
* The only constructor for a CountLogListener | |||
* @param pattern a regular expression pattern. It should have | |||
* one parenthesized group and that group should contain the | |||
* number desired. | |||
*/ | |||
public CountLogListener(String pattern) { | |||
super(); | |||
this.matcher.setPattern(pattern); | |||
} | |||
/* | |||
* @param event the build event that is being logged. | |||
*/ | |||
public void messageLogged(BuildEvent event) { | |||
String message = event.getMessage(); | |||
if (this.matcher.matches(message)) { | |||
lastMatchGroups = this.matcher.getGroups(message); | |||
} | |||
super.messageLogged(event); | |||
} | |||
/** | |||
* returns the desired number that results from parsing the log | |||
* message | |||
* @return the number of files indicated in the desired message or -1 | |||
* if a matching log message was never found. | |||
*/ | |||
public int getCount() { | |||
if (this.lastMatchGroups == null) { | |||
return -1; | |||
} | |||
return Integer.parseInt((String) this.lastMatchGroups.get(1)); | |||
} | |||
} | |||
/** | |||
* Tests the combination of the newer parameter and the | |||
* serverTimezoneConfig parameter in the PUT action. The default | |||
* configuration is an ftp server on localhost which formats | |||
* timestamps as GMT. | |||
*/ | |||
public void testTimezonePut() { | |||
CountLogListener log = new CountLogListener("(\\d+) files? sent"); | |||
getProject().executeTarget("timed.test.setup"); | |||
getProject().addBuildListener(log); | |||
getProject().executeTarget("timed.test.put.older"); | |||
assertEquals(1, log.getCount()); | |||
} | |||
/** | |||
* Tests the combination of the newer parameter and the | |||
* serverTimezoneConfig parameter in the GET action. The default | |||
* configuration is an ftp server on localhost which formats | |||
* timestamps as GMT. | |||
*/ | |||
public void testTimezoneGet() { | |||
CountLogListener log = new CountLogListener("(\\d+) files? retrieved"); | |||
getProject().executeTarget("timed.test.setup"); | |||
getProject().addBuildListener(log); | |||
getProject().executeTarget("timed.test.get.older"); | |||
assertEquals(3, log.getCount()); | |||
} | |||
/** | |||
* this test is inspired by a user reporting that deletions of directories with the ftp task do not work | |||
*/ | |||