/*
* This is the attempt to reproduce issue #58 https://github.com/syncany/syncany/issues/58
*/
// Setup
LocalTransferSettings testConnection = (LocalTransferSettings) TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
TestClient clientC = new TestClient("C", testConnection);
java.sql.Connection databaseConnectionA = DatabaseConnectionFactory.createConnection(clientA.getDatabaseFile());
java.sql.Connection databaseConnectionB = DatabaseConnectionFactory.createConnection(clientB.getDatabaseFile());
CleanupOperationOptions options = new CleanupOperationOptions();
options.setMergeRemoteFiles(true);
options.setRemoveOldVersions(true);
options.setKeepVersionsCount(5);
options.setMinSecondsBetweenCleanups(0);
options.setMaxDatabaseFiles(7);
StatusOperationOptions statusOptionsForceChecksum = new StatusOperationOptions();
statusOptionsForceChecksum.setForceChecksum(true);
UpOperationOptions upOperationOptionsWithCleanupForce = new UpOperationOptions();
upOperationOptionsWithCleanupForce.setStatusOptions(statusOptionsForceChecksum);
upOperationOptionsWithCleanupForce.setForceUploadEnabled(true);
// Run preparations
clientA.down();
clientA.createNewFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A1)
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000001").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000002").exists());
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A2)
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000002").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000003").exists());
clientB.down();
clientB.changeFile("A-file.jpg");
clientB.up(upOperationOptionsWithCleanupForce); // (A2,B1)
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000001").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-B-0000000002").exists());
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A3,B1)
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000003").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000004").exists());
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A4,B1)
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000004").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000005").exists());
clientB.down();
clientB.changeFile("A-file.jpg");
clientB.up(upOperationOptionsWithCleanupForce); // (A4,B2) + (A4,B3) [PURGE]
clientB.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000002").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000003").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-B-0000000004").exists());
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A5,B3) + (A6,B3) [PURGE]
clientA.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000005").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000006").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000007").exists());
clientB.down();
clientB.changeFile("A-file.jpg");
clientB.up(upOperationOptionsWithCleanupForce); // (A6,B4) + (A6,B5) [PURGE]
clientB.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000004").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000005").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-B-0000000006").exists());
/*
* For some reason, this chunk checksum in the following commit is the reason for the exception. So we record it here to see where it vanishes
* from the databases.
*/
clientA.down();
clientA.changeFile("A-file.jpg");
String fileAndChunkChecksumThatRaisesException = StringUtil.toHex(TestFileUtil.createChecksum(clientA.getLocalFile("A-file.jpg")));
System.out.println("Chunk/File checksum that raises the issue: " + fileAndChunkChecksumThatRaisesException);
clientA.createNewFile("ADDED_IN_DBV_A7_B5");
clientA.up(upOperationOptionsWithCleanupForce); // (A7,B5) + (A8,B5) [PURGE]
clientA.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000007").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000008").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000009").exists());
assertEquals("1", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionA));
clientB.down();
clientB.changeFile("A-file.jpg");
clientB.up(upOperationOptionsWithCleanupForce); // (A8,B6) + (A8,B7) [PURGE]
clientB.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000007").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-B-0000000008").exists());
assertEquals("1", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionB));
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A9,B7) + (A10,B7) [PURGE]
clientA.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000009").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000010").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000011").exists());
assertEquals("1", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionA));
clientB.down();
clientB.changeFile("A-file.jpg");
clientB.up(upOperationOptionsWithCleanupForce); // (A10,B8) + (A10,B9) [PURGE]
clientB.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000008").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000009").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-B-0000000010").exists());
assertEquals("1", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionB));
clientB.down();
clientB.changeFile("A-file.jpg");
clientB.up(upOperationOptionsWithCleanupForce); // (A10,B10) + (A10,B11) [PURGE]
clientB.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000010").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000011").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-B-0000000012").exists());
assertEquals("1", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionB));
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A11,B11) + (A12,B11) [PURGE]
clientA.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000011").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000012").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000013").exists());
assertEquals("0", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionA));
// ^^^ Old chunk deleted!
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A13,B11) + (A14,B11) [PURGE]
clientA.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000013").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000014").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000015").exists());
assertEquals("0", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionA));
clientB.down();
clientB.changeFile("A-file.jpg");
clientB.up(upOperationOptionsWithCleanupForce); // (A14,B12) + (A14,B13) [PURGE]
clientB.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000012").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-B-0000000013").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-B-0000000014").exists());
assertEquals("0", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionB));
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A15,B13) + (A16,B13) [PURGE]
clientA.cleanup(options);
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000015").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000016").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000017").exists());
assertEquals("0", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionA));
clientA.down();
clientA.changeFile("A-file.jpg");
clientA.up(upOperationOptionsWithCleanupForce); // (A17,B13) + (A18,B13) [PURGE]
clientA.cleanup(options);
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000017").exists());
assertTrue(new File(testConnection.getPath(), "databases/database-A-0000000018").exists());
assertFalse(new File(testConnection.getPath(), "databases/database-A-0000000019").exists());
assertEquals("0", TestSqlUtil.runSqlSelect("select count(*) from chunk where checksum='" + fileAndChunkChecksumThatRaisesException + "'",
databaseConnectionA));
// Sync them up
clientA.down();