use of org.syncany.operations.up.UpOperationResult in project syncany by syncany.
the class SplitSyncUpOperationTest method testUploadLocalDatabase.
private void testUploadLocalDatabase(int fileSize, int fileAmount, int expectedTransactions, UpOperationOptions options) throws Exception {
List<File> originalFiles = TestFileUtil.createRandomFilesInDirectory(testConfig.getLocalDir(), fileSize, fileAmount);
// Run!
AbstractTransferOperation op = new UpOperation(testConfig, options);
UpOperationResult opResult = (UpOperationResult) op.execute();
// Ensure that the expected number of transactions has been completed to upload the files
assertNotNull(opResult);
assertTrue(opResult.getTransactionsCompleted() == expectedTransactions);
// Get databases (for comparison)
LocalTransferSettings localConnection = (LocalTransferSettings) testConfig.getConnection();
File localDatabaseDir = testConfig.getDatabaseDir();
assertNotNull(localDatabaseDir.listFiles());
assertTrue(localDatabaseDir.listFiles().length > 0);
List<File> remoteDatabaseFiles = new ArrayList<>();
for (int transaction = 1; transaction <= expectedTransactions; transaction++) {
String databaseVersion = String.format("%010d", transaction);
File remoteDatabaseFile = new File(localConnection.getPath() + "/databases/database-" + testConfig.getMachineName() + "-" + databaseVersion);
assertTrue(remoteDatabaseFile.exists());
remoteDatabaseFiles.add(remoteDatabaseFile);
}
// Import remote databases into memory database
DatabaseXmlSerializer dDAO = new DatabaseXmlSerializer(testConfig.getTransformer());
MemoryDatabase remoteDatabase = new MemoryDatabase();
for (File remoteDatabaseFile : remoteDatabaseFiles) {
dDAO.load(remoteDatabase, remoteDatabaseFile, null, null, DatabaseXmlSerializer.DatabaseReadType.FULL);
}
// Open local SQL Database
SqlDatabase localDatabase = new SqlDatabase(testConfig);
// Compare!
assertEquals(localDatabase.getLastDatabaseVersionHeader(), remoteDatabase.getLastDatabaseVersion().getHeader());
Map<PartialFileHistory.FileHistoryId, PartialFileHistory> localFileHistories = localDatabase.getFileHistoriesWithFileVersions();
Collection<PartialFileHistory> remoteFileHistories = remoteDatabase.getFileHistories();
assertEquals(localDatabase.getCurrentFileTree().size(), fileAmount);
assertEquals(localFileHistories.size(), remoteDatabase.getFileHistories().size());
List<FileVersion> remoteFileVersions = new ArrayList<FileVersion>();
List<FileVersion> localFileVersions = new ArrayList<FileVersion>();
for (PartialFileHistory partialFileHistory : remoteFileHistories) {
remoteFileVersions.add(partialFileHistory.getLastVersion());
assertNotNull(localFileHistories.get(partialFileHistory.getFileHistoryId()));
}
for (PartialFileHistory partialFileHistory : localFileHistories.values()) {
localFileVersions.add(partialFileHistory.getLastVersion());
}
assertTrue(CollectionUtil.containsExactly(localFileVersions, remoteFileVersions));
compareFileVersionsAgainstOriginalFiles(originalFiles, localFileVersions);
compareFileVersionsAgainstOriginalFiles(originalFiles, remoteFileVersions);
}
use of org.syncany.operations.up.UpOperationResult 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.up.UpOperationResult in project syncany by syncany.
the class CallUpWhileStillWritingFileScenarioTest method testUpWhileWritingFile.
@Test
public void testUpWhileWritingFile() throws Exception {
// Setup
final TransferSettings testConnection = TestConfigUtil.createTestLocalConnection();
final TestClient clientA = new TestClient("A", testConnection);
final TestClient clientB = new TestClient("B", testConnection);
final File testFile = clientA.getLocalFile("large-test-file");
final long testFileLength = 100 * 1024 * 1024;
Thread writeFileThread = new Thread(new Runnable() {
@Override
public void run() {
try {
logger.log(Level.INFO, "Started thread to write file to " + testFile + " ...");
FileOutputStream fos = new FileOutputStream(testFile);
Random randomEngine = new Random();
byte[] buf = new byte[4096];
int writtenLen = 0;
while (writtenLen < testFileLength) {
randomEngine.nextBytes(buf);
fos.write(buf, 0, buf.length);
writtenLen += buf.length;
}
fos.close();
logger.log(Level.INFO, "Ended thread to write file to " + testFile + " ...");
} catch (IOException e) {
logger.log(Level.FINE, "Thread failed to write to file", e);
}
}
}, "writerThread");
// Before start: setup up databases (takes a while)
clientA.status();
clientB.status();
// Run!
writeFileThread.start();
Thread.sleep(50);
logger.log(Level.INFO, "Started clientA.up()");
UpOperationResult upResult = clientA.up();
StatusOperationResult statusResult = upResult.getStatusResult();
logger.log(Level.INFO, "Ended clientA.up()");
writeFileThread.join();
// Test 1: Check result sets for inconsistencies
assertTrue("Status command expected to return changes.", statusResult.getChangeSet().hasChanges());
assertFalse("File should NOT be uploaded while still writing (no half-file upload).", upResult.getChangeSet().hasChanges());
// Test 2: Check database for inconsistencies
SqlDatabase database = clientA.loadLocalDatabase();
assertEquals("File should NOT be uploaded while still writing (no half-file upload).", 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 = new File(((LocalTransferSettings) testConnection).getPath() + "/databases");
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);
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
}
use of org.syncany.operations.up.UpOperationResult in project syncany by syncany.
the class ChangedAttributesScenarioTest method testChangeAttributes.
@Test
public void testChangeAttributes() throws Exception {
// Setup
TransferSettings testConnection = TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
// Run
clientA.createNewFile("file1.jpg");
clientA.upWithForceChecksum();
clientB.down();
File bFile = clientB.getLocalFile("file1.jpg");
Path bFilePath = Paths.get(bFile.getAbsolutePath());
if (EnvironmentUtil.isWindows()) {
Files.setAttribute(bFilePath, "dos:readonly", true);
} else if (EnvironmentUtil.isUnixLikeOperatingSystem()) {
Files.setPosixFilePermissions(bFilePath, PosixFilePermissions.fromString("rwxrwxrwx"));
}
StatusOperationResult statusResult = clientB.status();
assertNotNull(statusResult);
ChangeSet changes = statusResult.getChangeSet();
assertTrue("Status-Operation should return changes.", changes.hasChanges());
UpOperationResult upResult = clientB.up();
StatusOperationResult statusResultFromUp = upResult.getStatusResult();
// Test 1: Check result sets for inconsistencies
assertTrue("Status should return changes.", statusResultFromUp.getChangeSet().hasChanges());
assertTrue("File should be uploaded.", upResult.getChangeSet().hasChanges());
// Test 2: Check database for inconsistencies
SqlDatabase database = clientB.loadLocalDatabase();
assertEquals("File should be uploaded.", 1, database.getFileList("file1.jpg", null, false, false, false, null).size());
assertEquals("There should be a new database version, because file should not have been added.", 2, database.getLocalDatabaseBranch().size());
// B down
clientA.down();
// Test 1: file1.jpg permissions
File aFile = clientA.getLocalFile("file1.jpg");
Path aFilePath = Paths.get(aFile.getAbsolutePath());
if (EnvironmentUtil.isWindows()) {
Object readOnlyAttribute = Files.getAttribute(aFilePath, "dos:readonly");
assertTrue("Read-only should be true.", (Boolean) readOnlyAttribute);
} else if (EnvironmentUtil.isUnixLikeOperatingSystem()) {
Set<PosixFilePermission> posixFilePermissions = Files.getPosixFilePermissions(aFilePath);
assertEquals("Should be rwxrwxrwx.", "rwxrwxrwx", PosixFilePermissions.toString(posixFilePermissions));
}
// Test 2: The rest
assertFileListEquals(clientA.getLocalFilesExcludeLockedAndNoRead(), clientB.getLocalFilesExcludeLockedAndNoRead());
assertSqlDatabaseEquals(clientA.getDatabaseFile(), clientB.getDatabaseFile());
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
}
use of org.syncany.operations.up.UpOperationResult 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();
}
Aggregations