/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2016 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 java.io.File;
import java.io.FilenameFilter;
import org.junit.Test;
import org.syncany.operations.down.DownOperationResult;
import org.syncany.operations.up.UpOperationOptions;
import org.syncany.plugins.local.LocalTransferSettings;
import org.syncany.tests.util.TestClient;
import org.syncany.tests.util.TestConfigUtil;
public class Issue227_2_ScenarioTest {
@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();
clientMOM.down(); // <<<<<<<< This should produce Pim's stack trace from issue #227
// Tear down
clientIH.deleteTestData();
clientMOM.deleteTestData();
clientHSE.deleteTestData();
}
@Test
public void testIssue227_IH() 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);
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.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());
// 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();
clientIH.down();
clientIH.copyFile("file2.jpg", "file2copy.jpg"); // <<< This copies a file for which the filecontent has been deleted
clientIH.up();
clientMee.down(); // << This should throw Philipp's stack trace in #227
// Tear down
clientIH.deleteTestData();
clientMOM.deleteTestData();
clientHSE.deleteTestData();
clientMee.deleteTestData();
}
@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());
clientIHtwo.down(); // same as IH!
// 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());
clientIHtwo.down(); // same as IH!
// 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());
clientIHtwo.down(); // same as IH!
// 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();*/
clientMee.down(); // << This should throw Philipp's stack trace in #227
// Tear down
clientIH.deleteTestData();
clientMOM.deleteTestData();
clientHSE.deleteTestData();
clientMee.deleteTestData();
clientIHtwo.deleteTestData();
}
}