/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2015 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.syncany.tests.integration.scenarios;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.syncany.tests.util.TestAssertUtil.assertFileListEquals;
import static org.syncany.tests.util.TestAssertUtil.assertSqlDatabaseEquals;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;
import org.syncany.database.SqlDatabase;
import org.syncany.operations.cleanup.CleanupOperationOptions;
import org.syncany.plugins.transfer.TransferSettings;
import org.syncany.tests.util.TestClient;
import org.syncany.tests.util.TestConfigUtil;
public class FileVanishedScenarioTest {
private static final Logger logger = Logger.getLogger(FileVanishedScenarioTest.class.getSimpleName());
// TODO [low] If a file has vanished, are its chunks and multichunks still added to the database, and then uploaded? If so, fix this!
@Test
public void testCallUpWhileDeletingFiles() throws Exception {
// Setup
final TransferSettings testConnection = TestConfigUtil.createTestLocalConnection();
final TestClient clientA = new TestClient("A", testConnection);
final TestClient clientB = new TestClient("B", testConnection);
final int numFiles = 100;
final int numFilesVanished = 50;
final int numFilesRemaining = numFiles - numFilesVanished;
final int sizeFiles = 500 * 1024;
CleanupOperationOptions options = new CleanupOperationOptions();
options.setMinKeepSeconds(0);
// Prepare by creating test files
logger.log(Level.INFO, "Creating test files ...");
for (int i = 0; i <= numFiles; i++) {
clientA.createNewFile("A-original" + i, sizeFiles);
}
// Prepare threads (delete & run up)
Thread deleteFilesThread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = numFiles; i >= numFilesVanished; i--) {
boolean deleteSuccess = clientA.deleteFile("A-original" + i);
if (deleteSuccess) {
logger.log(Level.SEVERE, "Deleted " + clientA.getLocalFile("A-original" + i));
}
else {
logger.log(Level.SEVERE, "FAILED TO DELETE FILE " + clientA.getLocalFile("A-original" + i));
}
try {
Thread.sleep(50);
}
catch (InterruptedException e) {
logger.log(Level.FINE, "Thread interrupted", e);
}
}
}
}, "A-delete");
Thread runUpThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(40);
clientA.up();
}
catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
}, "A-up");
// Before we start: init database (this takes a while)
clientA.status();
clientB.status();
// Delete files and run up simultaneously
// --> This will hopefully lead to a couple of 'vanished' files
logger.log(Level.INFO, "Starting 'up' thread ...");
runUpThread.start();
logger.log(Level.INFO, "Starting 'delete' thread ...");
deleteFilesThread.start();
runUpThread.join();
deleteFilesThread.join();
// Test 1: There should be between 50 and 100 file histories in the database
SqlDatabase databaseClientA = clientA.loadLocalDatabase();
assertTrue("There should be less file histories than originally added files.",
databaseClientA.getFileHistoriesWithFileVersions().size() < numFiles);
assertTrue("There should be more (or equal size) file histories than files there are.", databaseClientA.getFileHistoriesWithFileVersions()
.size() >= numFilesRemaining);
// Test 2: Now up the rest, there should be exactly 50 files in the database
clientA.up();
clientA.cleanup(options);
databaseClientA = clientA.loadLocalDatabase();
assertEquals("There should be EXACTLY " + numFilesRemaining + " file histories in the database.", numFilesRemaining, databaseClientA
.getFileHistoriesWithFileVersions().size());
// Test 3: After that, the sync between the clients should of course still work
clientB.down();
assertFileListEquals("Files of both clients should be identical.", clientA.getLocalFilesExcludeLockedAndNoRead(),
clientB.getLocalFilesExcludeLockedAndNoRead());
assertSqlDatabaseEquals(clientA.getDatabaseFile(), clientB.getDatabaseFile());
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
}
@Test
public void testFolderVanishesWhenSyncingDown() throws Exception {
// Setup
TransferSettings testConnection = TestConfigUtil.createTestLocalConnection();
TestClient clientA = new TestClient("A", testConnection);
TestClient clientB = new TestClient("B", testConnection);
// A
clientA.createNewFolder("folder1");
clientA.up();
// B
clientB.down();
assertFileListEquals(clientA.getLocalFilesExcludeLockedAndNoRead(), clientB.getLocalFilesExcludeLockedAndNoRead());
// A
clientA.createNewFile("folder1/file1");
clientA.up();
// B
clientB.deleteFile("folder1");
assertFalse(clientB.getLocalFile("folder1").exists());
clientB.down();
assertFileListEquals(clientA.getLocalFilesExcludeLockedAndNoRead(), clientB.getLocalFilesExcludeLockedAndNoRead());
// Tear down
clientA.deleteTestData();
clientB.deleteTestData();
}
}