Author: xavier
Date: Thu Nov 29 06:15:25 2007
New Revision: 599450
URL: http://svn.apache.org/viewvc?rev=599450&view=rev
Log:
add new test for atomic publish and fix a bug revealed by one of these tests
(IVY-492)
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
Modified:
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java?rev=599450&r1=599449&r2=599450&view=diff
==============================================================================
---
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
(original)
+++
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/FileSystemResolver.java
Thu Nov 29 06:15:25 2007
@@ -20,8 +20,10 @@
import java.io.File;
import java.io.IOException;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -37,15 +39,43 @@
private static final String TRANSACTION_DESTINATION_SUFFIX = ".part";
private static final Pattern TRANSACTION_PATTERN =
- Pattern.compile("(.*\\[revision\\])[/\\\\][^/\\\\]+");
+ Pattern.compile("(.*\\[revision\\])([/\\\\][^/\\\\]+)");
+ /**
+ * Transactional mode.
+ *
+ * auto: use transaction if possible, only log verbose message if not
+ * true: always use transaction, fail if not supported
+ * false: never use transactions
+ */
private String transactional = "auto"; // one of 'auto', 'true' or 'false'
+ /**
+ * When set indicates if this resolver supports transaction
+ */
private Boolean supportTransaction;
+ /**
+ * The pattern leading to the directory where files are published before
being moved at the end
+ * of a transaction
+ */
private String baseTransactionPattern;
-
+ /**
+ * Map between actual patterns and patterns used during the transaction to
put files in a
+ * temporary directory
+ */
+ private Map/*<String,String>*/ fullTransactionPatterns = new HashMap();
+
+ /**
+ * Is the current transaction open in overwrite mode?
+ */
private boolean overwriteTransaction = false;
+ /**
+ * Location where files are published during the transaction
+ */
private File transactionTempDir;
+ /**
+ * Location where files should end up at the end of the transaction
+ */
private File transactionDestDir;
public FileSystemResolver() {
@@ -71,10 +101,16 @@
protected String getDestination(String pattern, Artifact artifact,
ModuleRevisionId mrid) {
if (supportTransaction() && !overwriteTransaction) {
+
+ String destPattern = (String) fullTransactionPatterns.get(pattern);
+ if (destPattern == null) {
+ throw new IllegalArgumentException(
+ "unsupported pattern for publish destination pattern: " +
pattern
+ + ". supported patterns: " +
fullTransactionPatterns.keySet());
+ }
return IvyPatternHelper.substitute(
- pattern,
- ModuleRevisionId.newInstance(
- mrid, mrid.getRevision() +
TRANSACTION_DESTINATION_SUFFIX),
+ destPattern,
+ mrid,
artifact);
} else {
return super.getDestination(pattern, artifact, mrid);
@@ -159,6 +195,8 @@
return;
} else {
baseTransactionPattern = m.group(1);
+ fullTransactionPatterns.put(pattern,
+ m.group(1) + TRANSACTION_DESTINATION_SUFFIX +
m.group(2));
}
}
if (artifactPatterns.size() > 0) {
@@ -172,9 +210,14 @@
unsupportedTransaction("ivy pattern and artifact
pattern "
+ "do not use the same directory for revision");
return;
+ } else {
+ fullTransactionPatterns.put(pattern,
+ m.group(1) + TRANSACTION_DESTINATION_SUFFIX +
m.group(2));
}
} else {
baseTransactionPattern = m.group(1);
+ fullTransactionPatterns.put(pattern,
+ m.group(1) + TRANSACTION_DESTINATION_SUFFIX +
m.group(2));
}
}
supportTransaction = Boolean.TRUE;
Modified:
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
URL:
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java?rev=599450&r1=599449&r2=599450&view=diff
==============================================================================
---
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
(original)
+++
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/resolver/FileSystemResolverTest.java
Thu Nov 29 06:15:25 2007
@@ -567,17 +567,10 @@
Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
"myext");
File src = new File("test/repositories/ivysettings.xml");
- boolean successfullyPublished = false;
resolver.beginPublishTransaction(mrid, false);
- try {
- resolver.publish(ivyArtifact, src, false);
- resolver.publish(artifact, src, false);
- resolver.commitPublishTransaction();
- successfullyPublished = true;
- } finally {
- if (!successfullyPublished)
- resolver.abortPublishTransaction();
- }
+ resolver.publish(ivyArtifact, src, false);
+ resolver.publish(artifact, src, false);
+ resolver.commitPublishTransaction();
assertTrue(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
assertTrue(new File(
@@ -588,6 +581,45 @@
}
}
+ public void testPublishTransaction() throws Exception {
+ try {
+ FileSystemResolver resolver = new FileSystemResolver();
+ resolver.setName("test");
+ resolver.setSettings(settings);
+
+ resolver.addIvyPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact].[ext]");
+ resolver.addArtifactPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
+
+ ModuleRevisionId mrid = ModuleRevisionId.newInstance("myorg",
"mymodule", "myrevision");
+ Artifact ivyArtifact = new DefaultArtifact(mrid, new Date(),
"ivy", "ivy", "xml");
+ Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
+ "myext");
+ File src = new File("test/repositories/ivysettings.xml");
+
+ resolver.beginPublishTransaction(mrid, false);
+
+ // files should not be available until the transaction is committed
+ resolver.publish(ivyArtifact, src, false);
+ assertFalse(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
+
+ resolver.publish(artifact, src, false);
+ assertFalse(new File(
+
"test/repositories/1/myorg/mymodule/mytypes/myartifact-myrevision.myext")
+ .exists());
+
+ resolver.commitPublishTransaction();
+
+ assertTrue(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
+ assertTrue(new File(
+
"test/repositories/1/myorg/mymodule/myrevision/myartifact-myrevision.myext")
+ .exists());
+ } finally {
+ FileUtil.forceDelete(new File("test/repositories/1/myorg"));
+ }
+ }
+
public void testAbortTransaction() throws Exception {
try {
FileSystemResolver resolver = new FileSystemResolver();
@@ -611,12 +643,139 @@
assertFalse(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
assertFalse(new File(
-
"test/repositories/1/myorg/mymodule/mytypes/myartifact-myrevision.myext")
+
"test/repositories/1/myorg/mymodule/myrevision/myartifact-myrevision.myext")
+ .exists());
+ } finally {
+ FileUtil.forceDelete(new File("test/repositories/1/myorg"));
+ }
+ }
+
+ public void testUnsupportedTransaction() throws Exception {
+ try {
+ FileSystemResolver resolver = new FileSystemResolver();
+ resolver.setName("test");
+ resolver.setSettings(settings);
+ resolver.setTransactional("true");
+
+ resolver.addArtifactPattern(
+ // this pattern is not supported for transaction publish
+
"test/repositories/1/[organisation]/[module]/[artifact]-[revision].[ext]");
+
+ ModuleRevisionId mrid = ModuleRevisionId.newInstance("myorg",
"mymodule", "myrevision");
+ Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
+ "myext");
+ File src = new File("test/repositories/ivysettings.xml");
+ try {
+ resolver.beginPublishTransaction(mrid, false);
+
+ resolver.publish(artifact, src, false);
+ fail("publishing with transaction=true and an unsupported
pattern should raise an exception");
+ } catch (IllegalStateException ex) {
+ assertTrue(ex.getMessage().indexOf("transactional") != -1);
+ }
+ } finally {
+ FileUtil.forceDelete(new File("test/repositories/1/myorg"));
+ }
+ }
+
+ public void testUnsupportedTransaction2() throws Exception {
+ try {
+ FileSystemResolver resolver = new FileSystemResolver();
+ resolver.setName("test");
+ resolver.setSettings(settings);
+ resolver.setTransactional("true");
+
+ // the two patterns are inconsistent and thus not supported for
transactions
+ resolver.addIvyPattern(
+
"test/repositories/1/[organisation]-[module]/[revision]/[artifact]-[revision].[ext]");
+ resolver.addArtifactPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
+
+ ModuleRevisionId mrid = ModuleRevisionId.newInstance("myorg",
"mymodule", "myrevision");
+ Artifact ivyArtifact = new DefaultArtifact(mrid, new Date(),
"ivy", "ivy", "xml");
+ Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
+ "myext");
+ File src = new File("test/repositories/ivysettings.xml");
+ try {
+ resolver.beginPublishTransaction(mrid, false);
+ resolver.publish(ivyArtifact, src, false);
+ resolver.publish(artifact, src, false);
+ fail("publishing with transaction=true and an unsupported
combination of patterns should raise an exception");
+ } catch (IllegalStateException ex) {
+ assertTrue(ex.getMessage().indexOf("transactional") != -1);
+ }
+ } finally {
+ FileUtil.forceDelete(new File("test/repositories/1/myorg"));
+ }
+ }
+
+ public void testUnsupportedTransaction3() throws Exception {
+ try {
+ FileSystemResolver resolver = new FileSystemResolver();
+ resolver.setName("test");
+ resolver.setSettings(settings);
+ resolver.setTransactional("true");
+
+ resolver.addArtifactPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
+
+ ModuleRevisionId mrid = ModuleRevisionId.newInstance("myorg",
"mymodule", "myrevision");
+ Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
+ "myext");
+ File src = new File("test/repositories/ivysettings.xml");
+ try {
+ // overwrite transaction not supported
+ resolver.beginPublishTransaction(mrid, true);
+
+ resolver.publish(artifact, src, true);
+ fail("publishing with transaction=true and overzrite mode
should raise an exception");
+ } catch (IllegalStateException ex) {
+ assertTrue(ex.getMessage().indexOf("transactional") != -1);
+ }
+ } finally {
+ FileUtil.forceDelete(new File("test/repositories/1/myorg"));
+ }
+ }
+
+ public void testDisableTransaction() throws Exception {
+ try {
+ FileSystemResolver resolver = new FileSystemResolver();
+ resolver.setName("test");
+ resolver.setSettings(settings);
+ resolver.setTransactional("false");
+
+ resolver.addIvyPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact].[ext]");
+ resolver.addArtifactPattern(
+
"test/repositories/1/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]");
+
+ ModuleRevisionId mrid = ModuleRevisionId.newInstance("myorg",
"mymodule", "myrevision");
+ Artifact ivyArtifact = new DefaultArtifact(mrid, new Date(),
"ivy", "ivy", "xml");
+ Artifact artifact = new DefaultArtifact(mrid, new Date(),
"myartifact", "mytype",
+ "myext");
+ File src = new File("test/repositories/ivysettings.xml");
+ resolver.beginPublishTransaction(mrid, false);
+
+ // with transactions disabled the file should be available as soon
as they are published
+ resolver.publish(ivyArtifact, src, false);
+ assertTrue(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
+
+ resolver.publish(artifact, src, false);
+ assertTrue(new File(
+
"test/repositories/1/myorg/mymodule/myrevision/myartifact-myrevision.myext")
+ .exists());
+
+ resolver.commitPublishTransaction();
+
+ assertTrue(new
File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
+ assertTrue(new File(
+
"test/repositories/1/myorg/mymodule/myrevision/myartifact-myrevision.myext")
.exists());
} finally {
FileUtil.forceDelete(new File("test/repositories/1/myorg"));
}
}
+
public void testListing() throws Exception {
FileSystemResolver resolver = new FileSystemResolver();