use of org.syncany.plugins.local.LocalTransferSettings in project syncany by syncany.
the class Issue288ScenarioTest method testIssue288.
@Test
public void testIssue288() throws Exception {
/*
* This tests issue #288, an issue in which a file with duplicate chunks are created
* incorrectly, because the cleanup throws away too many entries in the filecontent_chunks
* database table.
*
* The test first creates a file with duplicate chunks, then syncs this file, and then
* moves this file on both clients -- that forces the other client to recreate the file
* from scratch.
*/
// Setup
LocalTransferSettings testConnection = (LocalTransferSettings) TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
java.sql.Connection databaseConnectionA = DatabaseConnectionFactory.createConnection(clientA.getDatabaseFile(), false);
java.sql.Connection databaseConnectionB = DatabaseConnectionFactory.createConnection(clientB.getDatabaseFile(), false);
CleanupOperationOptions cleanupOptionsKeepOne = new CleanupOperationOptions();
cleanupOptionsKeepOne.setForce(true);
// Create file content with two duplicate chunks
// The file has 4 chunks (4 * 512 bytes), the middle chunks are identical
// 1 MB
byte[] fileContentA = new byte[2 * 1024 * 1024];
for (int i = 0; i < 512 * 1024; i++) {
// First chunk
fileContentA[i] = (byte) i;
}
for (int i = 512 * 1024; i < 1536 * 1024; i++) {
// Two identical middle chunks
fileContentA[i] = 99;
}
for (int i = 1536 * 1024; i < 2 * 1024 * 1024; i++) {
// Last chunk
fileContentA[i] = (byte) (i + i);
}
FileUtils.writeByteArrayToFile(clientA.getLocalFile("fileA"), fileContentA);
clientA.upWithForceChecksum();
assertEquals("3", TestSqlUtil.runSqlSelect("select count(*) from chunk", databaseConnectionA));
assertEquals("4", TestSqlUtil.runSqlSelect("select count(*) from filecontent_chunk", databaseConnectionA));
// Sync file to client B
clientB.down();
assertEquals("3", TestSqlUtil.runSqlSelect("select count(*) from chunk", databaseConnectionB));
assertEquals("4", TestSqlUtil.runSqlSelect("select count(*) from filecontent_chunk", databaseConnectionB));
// Move file, sync again and perform cleanup (wipe everything but one file version)
clientA.moveFile("fileA", "fileA-moved");
clientA.upWithForceChecksum();
clientA.cleanup(cleanupOptionsKeepOne);
// Delete file locally and sync down
clientB.deleteFile("fileA");
// <<<< This throws an exception!
clientB.down();
// Tear down
clientB.deleteTestData();
clientA.deleteTestData();
}
use of org.syncany.plugins.local.LocalTransferSettings in project syncany by syncany.
the class FileLockedScenarioTest method runUpAndTestForEmptyDatabase.
private void runUpAndTestForEmptyDatabase(TransferSettings connection, TestClient client) throws Exception {
UpOperationResult upResult = client.up();
StatusOperationResult statusResult = upResult.getStatusResult();
// Test 1: Check result sets for inconsistencies
assertFalse("Status command expected to return NO changes.", statusResult.getChangeSet().hasChanges());
assertFalse("File should NOT be uploaded while it is locked.", upResult.getChangeSet().hasChanges());
// Test 2: Check database for inconsistencies
SqlDatabase database = client.loadLocalDatabase();
assertEquals("File should NOT be uploaded while it is locked.", 0, database.getFileList("large-test-file", null, false, false, false, null).size());
assertNull("There should NOT be a new database version, because file should not have been added.", database.getLastDatabaseVersionHeader());
// Test 3: Check file system for inconsistencies
File repoPath = ((LocalTransferSettings) connection).getPath();
String[] repoFileList = repoPath.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith("database-");
}
});
assertEquals("Repository should NOT contain any files.", 0, repoFileList.length);
}
use of org.syncany.plugins.local.LocalTransferSettings in project syncany by syncany.
the class AssemblerTest method testAssembler.
/**
* Alters multichunk data to test whether integrity checks work.
*/
@Test
public void testAssembler() throws Exception {
LocalTransferSettings testConnection = (LocalTransferSettings) TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
// small, only one chunk, one multichunk
clientA.createNewFile("file1.jpg", 20);
clientA.upWithForceChecksum();
// Read chunk from original multichunk
File repoMultiChunksFolder = new File(testConnection.getPath(), "multichunks");
File multiChunkFile = repoMultiChunksFolder.listFiles()[0];
MultiChunk multiChunk = clientA.getConfig().getMultiChunker().createMultiChunk(clientA.getConfig().getTransformer().createInputStream(new FileInputStream(multiChunkFile)));
Chunk chunk = multiChunk.read();
multiChunk.close();
// Flip byte in chunk and write new "altered" multichunk
File alteredMultiChunkFile = new File(multiChunkFile + "-altered");
MultiChunk alteredMultiChunk = clientA.getConfig().getMultiChunker().createMultiChunk(multiChunk.getId(), clientA.getConfig().getTransformer().createOutputStream(new FileOutputStream(alteredMultiChunkFile)));
// Flip one byte!
chunk.getContent()[0] ^= 0x01;
alteredMultiChunk.write(chunk);
alteredMultiChunk.close();
// Now delete old multichunk, and swap by "altered" file
multiChunkFile.delete();
FileUtils.moveFile(alteredMultiChunkFile, multiChunkFile);
boolean exceptionThrown = false;
try {
// If this does not throw an exception, it's bad!
clientB.down();
} catch (Exception e) {
exceptionThrown = true;
}
assertTrue(exceptionThrown);
clientA.deleteTestData();
clientB.deleteTestData();
}
use of org.syncany.plugins.local.LocalTransferSettings in project syncany by syncany.
the class CleanupOperationTest method testCleanupMaxDatabaseFiles.
@Test
public void testCleanupMaxDatabaseFiles() throws Exception {
// Setup
LocalTransferSettings testConnection = (LocalTransferSettings) TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
CleanupOperationOptions options = new CleanupOperationOptions();
options.setMinSecondsBetweenCleanups(0);
options.setPurgeFileVersionSettings(new TreeMap<Long, TimeUnit>());
options.setRemoveOldVersions(true);
options.setMaxDatabaseFiles(3);
// Run
// A: Create some file versions
clientA.createNewFile("file.jpg");
for (int i = 1; i <= 4; i++) {
clientA.changeFile("file.jpg");
clientA.upWithForceChecksum();
}
// B: Cleanup
CleanupOperationResult cleanupOperationResult = clientA.cleanup(options);
assertEquals(CleanupResultCode.OK, cleanupOperationResult.getResultCode());
assertEquals(4, cleanupOperationResult.getMergedDatabaseFilesCount());
assertEquals(0, cleanupOperationResult.getRemovedMultiChunksCount());
assertEquals(0, cleanupOperationResult.getRemovedOldVersionsCount());
TestClient clientB = new TestClient("B", testConnection);
clientB.down();
// B: Create some file versions
clientB.createNewFile("file-B.jpg");
for (int i = 1; i <= 6; i++) {
clientB.changeFile("file-B.jpg");
clientB.upWithForceChecksum();
}
// B: Cleanup (2 clients, so 7 databases is too much)
cleanupOperationResult = clientB.cleanup(options);
assertEquals(CleanupResultCode.OK, cleanupOperationResult.getResultCode());
assertEquals(7, cleanupOperationResult.getMergedDatabaseFilesCount());
assertEquals(0, cleanupOperationResult.getRemovedMultiChunksCount());
assertEquals(0, cleanupOperationResult.getRemovedOldVersionsCount());
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
}
use of org.syncany.plugins.local.LocalTransferSettings in project syncany by syncany.
the class CleanupOperationTest method testQuickDoubleCleanup.
@Test
public void testQuickDoubleCleanup() throws Exception {
// Setup
LocalTransferSettings testConnection = (LocalTransferSettings) TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
CleanupOperationOptions options = new CleanupOperationOptions();
options.setRemoveOldVersions(false);
options.setRemoveVersionsByInterval(false);
options.setMinSecondsBetweenCleanups(40000000);
// Run
// A: Create some file versions
clientA.createNewFile("file.jpg");
for (int i = 1; i <= 16; i++) {
clientA.changeFile("file.jpg");
clientA.upWithForceChecksum();
}
// B: Cleanup
CleanupOperationResult cleanupOperationResult = clientA.cleanup(options);
assertEquals(CleanupResultCode.OK, cleanupOperationResult.getResultCode());
assertEquals(16, cleanupOperationResult.getMergedDatabaseFilesCount());
assertEquals(0, cleanupOperationResult.getRemovedMultiChunksCount());
assertEquals(0, cleanupOperationResult.getRemovedOldVersionsCount());
for (int i = 1; i <= 15; i++) {
clientA.changeFile("file.jpg");
clientA.upWithForceChecksum();
}
// Because of minimum timeout, this cleanup should not do anything
cleanupOperationResult = clientA.cleanup(options);
assertEquals(CleanupResultCode.NOK_RECENTLY_CLEANED, cleanupOperationResult.getResultCode());
// When force is on, the cleanup should go through
options.setForce(true);
cleanupOperationResult = clientA.cleanup(options);
assertEquals(CleanupResultCode.OK, cleanupOperationResult.getResultCode());
assertEquals(16, cleanupOperationResult.getMergedDatabaseFilesCount());
assertEquals(0, cleanupOperationResult.getRemovedMultiChunksCount());
assertEquals(0, cleanupOperationResult.getRemovedOldVersionsCount());
// Tear down
clientA.deleteTestData();
}
Aggregations