use of org.syncany.operations.down.DownOperationResult in project syncany by syncany.
the class CleanupOperationTest method testCleanupAfterFailedUpOperation.
@Test
public void testCleanupAfterFailedUpOperation() throws Exception {
// Setup
UnreliableLocalTransferSettings testConnection = TestConfigUtil.createTestUnreliableLocalConnection(Arrays.asList(new String[] { // << 3 retries!
"rel=[456].+upload.+multichunk" }));
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
StatusOperationOptions forceChecksumStatusOperationOptions = new StatusOperationOptions();
forceChecksumStatusOperationOptions.setForceChecksum(true);
UpOperationOptions noCleanupAndForceUpOperationOptions = new UpOperationOptions();
noCleanupAndForceUpOperationOptions.setForceUploadEnabled(true);
noCleanupAndForceUpOperationOptions.setStatusOptions(forceChecksumStatusOperationOptions);
// Run
// 1. Call A.up(); this fails AFTER the first multichunk
clientA.createNewFile("A-file1", 5 * 1024 * 1024);
boolean operationFailed = false;
try {
clientA.up();
} catch (Exception e) {
// That is supposed to happen!
operationFailed = true;
}
File repoMultiChunkDir = new File(testConnection.getPath() + "/multichunks");
File repoActionsDir = new File(testConnection.getPath() + "/actions");
assertTrue(operationFailed);
// Atomic operation, so multichunk is not yet present at location
assertEquals(0, repoMultiChunkDir.listFiles().length);
assertEquals(1, repoActionsDir.listFiles().length);
// 2. Call A.cleanup(); this does not run, because there are local changes
CleanupOperationResult cleanupOperationResultA = clientA.cleanup();
assertEquals(CleanupResultCode.NOK_LOCAL_CHANGES, cleanupOperationResultA.getResultCode());
// 3. Call B.cleanup(); this does not run, because of the leftover 'action' file
CleanupOperationResult cleanupOperationResultB = clientB.cleanup();
assertEquals(CleanupResultCode.NOK_OTHER_OPERATIONS_RUNNING, cleanupOperationResultB.getResultCode());
// 4. Call B.down(); this does not deliver any results, because no databases have been uploaded
DownOperationResult downOperationResult = clientB.down();
assertEquals(DownResultCode.OK_NO_REMOTE_CHANGES, downOperationResult.getResultCode());
// 5. Call 'up' again, this uploads previously crashed stuff, and then runs cleanup.
// The cleanup then removes the old multichunk and the old action files.
UpOperationResult secondUpResult = clientA.up();
assertEquals(UpResultCode.OK_CHANGES_UPLOADED, secondUpResult.getResultCode());
assertEquals(2, repoMultiChunkDir.listFiles().length);
assertEquals(0, repoActionsDir.listFiles().length);
// 6. Call 'cleanup' manually (Nothing happens, since transaction was cleaned on second up)
CleanupOperationResult cleanupOperationResult = clientA.cleanup();
assertEquals(CleanupOperationResult.CleanupResultCode.OK_NOTHING_DONE, cleanupOperationResult.getResultCode());
assertEquals(0, cleanupOperationResult.getRemovedMultiChunksCount());
assertEquals(0, repoActionsDir.listFiles().length);
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
}
use of org.syncany.operations.down.DownOperationResult in project syncany by syncany.
the class ChangedAttributesScenarioTest method testNewFileWithDifferingAttributes.
@Test
public void testNewFileWithDifferingAttributes() throws Exception {
// Setup
TransferSettings testConnection = TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
// Create new file with differing attributes
clientA.createNewFile("file1.jpg");
FileUtils.copyFile(clientA.getLocalFile("file1.jpg"), clientB.getLocalFile("file1.jpg"));
// Client B's attributes differ!
File aFile = clientA.getLocalFile("file1.jpg");
Path aFilePath = Paths.get(aFile.getAbsolutePath());
Object aReadOnlyAttribute = null;
Set<PosixFilePermission> aPosixFilePermissions = null;
// Client B's attributes differ!
File bFile = clientB.getLocalFile("file1.jpg");
Path bFilePath = Paths.get(bFile.getAbsolutePath());
if (EnvironmentUtil.isWindows()) {
aReadOnlyAttribute = Files.getAttribute(aFilePath, "dos:readonly");
Files.setAttribute(bFilePath, "dos:readonly", true);
} else if (EnvironmentUtil.isUnixLikeOperatingSystem()) {
aPosixFilePermissions = Files.getPosixFilePermissions(aFilePath);
Files.setPosixFilePermissions(bFilePath, PosixFilePermissions.fromString("rwxrwxrwx"));
}
clientA.upWithForceChecksum();
// This is the key operation
DownOperationResult downResult = clientB.down();
// Test 1: Check result sets for inconsistencies
assertTrue("File should be downloaded.", downResult.getChangeSet().hasChanges());
// Test 2: file1.jpg permissions (again!
if (EnvironmentUtil.isWindows()) {
Object bReadOnlyAttribute = Files.getAttribute(aFilePath, "dos:readonly");
assertEquals("Read-only should be true.", aReadOnlyAttribute, bReadOnlyAttribute);
} else if (EnvironmentUtil.isUnixLikeOperatingSystem()) {
Set<PosixFilePermission> bPosixFilePermissions = Files.getPosixFilePermissions(aFilePath);
assertEquals("Should be rwxrwxrwx.", PosixFilePermissions.toString(aPosixFilePermissions), PosixFilePermissions.toString(bPosixFilePermissions));
}
// Test 3: The rest
assertFileListEquals(clientA.getLocalFilesExcludeLockedAndNoRead(), clientB.getLocalFilesExcludeLockedAndNoRead());
assertSqlDatabaseEquals(clientA.getDatabaseFile(), clientB.getDatabaseFile());
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
}
use of org.syncany.operations.down.DownOperationResult in project syncany by syncany.
the class DirtyDatabaseVersionsScenarioTest method testThreeClientsOneLoser.
@Test
public void testThreeClientsOneLoser() throws Exception {
// Setup
TransferSettings testConnection = TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
TestClient clientC = new TestClient("C", testConnection);
UpOperationOptions cUpOptionsWithForce = new UpOperationOptions();
cUpOptionsWithForce.setForceUploadEnabled(true);
// Run
clientA.createNewFile("file1.jpg");
clientA.upWithForceChecksum();
clientB.down();
clientB.createNewFile("file2.jpg");
clientB.upWithForceChecksum();
// Client C: No down!
clientC.createNewFile("file3.jpg");
clientC.up(cUpOptionsWithForce);
// A tries to upload, this fails due to C's unknown database
clientA.createNewFile("file4.jpg");
//
UpOperationResult aUpResult = clientA.upWithForceChecksum();
assertEquals("Expected to fail, because db-C-1 has not been looked at", UpResultCode.NOK_UNKNOWN_DATABASES, aUpResult.getResultCode());
assertFalse(clientA.getLocalFile("file2.jpg").exists());
assertFalse(clientA.getLocalFile("file3.jpg").exists());
// A downloads C's changes, no file changes are expected
DownOperationResult aDownResult = clientA.down();
assertEquals("Expected to succeed with remote changes (a new database file, but no file changes!).", DownResultCode.OK_WITH_REMOTE_CHANGES, aDownResult.getResultCode());
assertTrue(clientA.getLocalFile("file2.jpg").exists());
assertFalse(clientA.getLocalFile("file3.jpg").exists());
// TODO [low] Add assert: "no file changes are expected"
// A uploads again, this time it should succeed, because C's file is in knowndbs.list
aUpResult = clientA.upWithForceChecksum();
assertEquals("Expected to succeed, because db-C-1 has already been looked at", UpResultCode.OK_CHANGES_UPLOADED, aUpResult.getResultCode());
// C calls down and up, to sync its changes
// Adds dirty database
clientC.down();
assertSqlResultEquals(clientC.getDatabaseFile(), "select count(*) from databaseversion where status='DIRTY'", "1");
clientC.upWithForceChecksum();
assertSqlResultEquals(clientC.getDatabaseFile(), "select count(*) from databaseversion where status='DIRTY'", "0");
clientA.down();
assertFileListEquals(clientA.getLocalFilesExcludeLockedAndNoRead(), clientC.getLocalFilesExcludeLockedAndNoRead());
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
clientC.deleteTestData();
}
use of org.syncany.operations.down.DownOperationResult in project syncany by syncany.
the class Issue227_2_ScenarioTest method testIssue227_multiple_resolve.
@Test
public void testIssue227_multiple_resolve() throws Exception {
// Setup
LocalTransferSettings testConnection = (LocalTransferSettings) TestConfigUtil.createTestLocalConnection();
TestClient clientIH = new TestClient("iH", testConnection);
TestClient clientMOM = new TestClient("MOM", testConnection);
TestClient clientHSE = new TestClient("hSE", testConnection);
TestClient clientMee = new TestClient("Mee", testConnection);
TestClient clientIHtwo = new TestClient("IHtwo", testConnection);
UpOperationOptions upOptionsWithForce = new UpOperationOptions();
upOptionsWithForce.setForceUploadEnabled(true);
clientIH.createNewFile("file1.jpg");
clientIH.up();
clientIH.createNewFile("file2.jpg");
clientIH.up();
clientMOM.down();
clientHSE.down();
// -
clientMOM.createNewFile("file3.jpg");
clientMOM.up();
clientMOM.createNewFile("file4.jpg");
clientMOM.up();
clientIH.down();
clientIHtwo.down();
clientHSE.down();
// All in sync
/*
* We want to create a time difference situation here between different clients.
*
* In reality:
* - Client "hSE" uploads a new database AFTER client "MOM"
*
* In this test:
* 1. Client "hSE" uploads a new database BEFORE client "MOM"
* 2. We hide "hSE"'s database by moving it to a temp. file
* // ...
* 5. When we do 'down' at client "IH", the databases of client "MOM" are considered DIRTY
*
*/
// 1. Upload new database for hSE
clientHSE.createNewFile("fileHSE-1.jpg");
clientHSE.up(upOptionsWithForce);
File[] hSEDatabaseFiles = new File(testConnection.getPath() + "/databases/").listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.contains("hSE");
}
});
assertEquals(1, hSEDatabaseFiles.length);
// 2. Hide database from other clients
File hSEDatabaseFile = hSEDatabaseFiles[0];
File hSEDatabaseFileHidden = new File(hSEDatabaseFile.getParentFile(), "HIDE_THIS_FILE_" + hSEDatabaseFile.getName());
hSEDatabaseFile.renameTo(hSEDatabaseFileHidden);
// 3. This shouldn't do anything; no new databases!
DownOperationResult downOperationResult = clientIH.down();
assertEquals(0, downOperationResult.getDownloadedUnknownDatabases().size());
// same as IH!
clientIHtwo.down();
// 4. Upload database from client "MOM" (later considered DIRTY)
clientMOM.createNewFile("fileMOM-1.jpg");
clientMOM.changeFile("file1.jpg");
clientMOM.up(upOptionsWithForce);
clientMOM.createNewFile("fileMOM-2.jpg");
clientMOM.up(upOptionsWithForce);
// 5. Download changes from "MOM" (apply databases and files that will later be DIRTY)
downOperationResult = clientIH.down();
assertEquals(0, downOperationResult.getDirtyDatabasesCreated().size());
// same as IH!
clientIHtwo.down();
// 6. Rename hidden database (= the later winner!)Now download the changes that
// Databases of client "MOM" will be considered "DIRTY"
hSEDatabaseFileHidden.renameTo(hSEDatabaseFile);
downOperationResult = clientIH.down();
assertEquals(2, downOperationResult.getDirtyDatabasesCreated().size());
// same as IH!
clientIHtwo.down();
// 7. This should remove DIRTY database versions from the database
// and ADD the multichunks from the previous database versions to the new database version (<< this is what kills MOM)
clientIH.up(upOptionsWithForce);
clientIHtwo.up(upOptionsWithForce);
/*clientIH.down();
clientIH.copyFile("file2.jpg", "file2copy.jpg"); // <<< This copies a file for which the filecontent has been deleted
clientIH.up();*/
// << This should throw Philipp's stack trace in #227
clientMee.down();
// Tear down
clientIH.deleteTestData();
clientMOM.deleteTestData();
clientHSE.deleteTestData();
clientMee.deleteTestData();
clientIHtwo.deleteTestData();
}
use of org.syncany.operations.down.DownOperationResult in project syncany by syncany.
the class Issue227_2_ScenarioTest method testIssue227_MOM.
@Test
public void testIssue227_MOM() throws Exception {
// Setup
LocalTransferSettings testConnection = (LocalTransferSettings) TestConfigUtil.createTestLocalConnection();
TestClient clientIH = new TestClient("iH", testConnection);
TestClient clientMOM = new TestClient("MOM", testConnection);
TestClient clientHSE = new TestClient("hSE", testConnection);
UpOperationOptions upOptionsWithForce = new UpOperationOptions();
upOptionsWithForce.setForceUploadEnabled(true);
clientIH.createNewFile("file1.jpg");
clientIH.up();
clientIH.createNewFile("file2.jpg");
clientIH.up();
clientMOM.down();
clientHSE.down();
// -
clientMOM.createNewFile("file3.jpg");
clientMOM.up();
clientMOM.createNewFile("file4.jpg");
clientMOM.up();
clientIH.down();
clientHSE.down();
// All in sync
/*
* We want to create a time difference situation here between different clients.
*
* In reality:
* - Client "hSE" uploads a new database AFTER client "MOM"
*
* In this test:
* 1. Client "hSE" uploads a new database BEFORE client "MOM"
* 2. We hide "hSE"'s database by moving it to a temp. file
* // ...
* 5. When we do 'down' at client "IH", the databases of client "MOM" are considered DIRTY
*
*/
// 1. Upload new database for hSE
clientHSE.createNewFile("fileHSE-1.jpg");
clientHSE.up(upOptionsWithForce);
File[] hSEDatabaseFiles = new File(testConnection.getPath() + "/databases/").listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.contains("hSE");
}
});
assertEquals(1, hSEDatabaseFiles.length);
// 2. Hide database from other clients
File hSEDatabaseFile = hSEDatabaseFiles[0];
File hSEDatabaseFileHidden = new File(hSEDatabaseFile.getParentFile(), "HIDE_THIS_FILE_" + hSEDatabaseFile.getName());
hSEDatabaseFile.renameTo(hSEDatabaseFileHidden);
// 3. This shouldn't do anything; no new databases!
DownOperationResult downOperationResult = clientIH.down();
assertEquals(0, downOperationResult.getDownloadedUnknownDatabases().size());
// 4. Upload database from client "MOM" (later considered DIRTY)
clientMOM.createNewFile("fileMOM-1.jpg");
clientMOM.up(upOptionsWithForce);
clientMOM.createNewFile("fileMOM-2.jpg");
clientMOM.up(upOptionsWithForce);
// 5. Download changes from "MOM" (apply databases and files that will later be DIRTY)
downOperationResult = clientIH.down();
assertEquals(0, downOperationResult.getDirtyDatabasesCreated().size());
// 6. Rename hidden database (= the later winner!)Now download the changes that
// Databases of client "MOM" will be considered "DIRTY"
hSEDatabaseFileHidden.renameTo(hSEDatabaseFile);
downOperationResult = clientIH.down();
assertEquals(2, downOperationResult.getDirtyDatabasesCreated().size());
// 7. This should remove DIRTY database versions from the database
// and ADD the multichunks from the previous database versions to the new database version (<< this is what kills MOM)
clientIH.up();
// <<<<<<<< This should produce Pim's stack trace from issue #227
clientMOM.down();
// Tear down
clientIH.deleteTestData();
clientMOM.deleteTestData();
clientHSE.deleteTestData();
}
Aggregations