/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2008 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* 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 Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/
package com.funambol.sync.client;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.util.Vector;
import java.util.Enumeration;
import com.funambol.platform.FileAdapter;
import com.funambol.storage.StringKeyValueStore;
import com.funambol.sync.SourceConfig;
import com.funambol.sync.SyncItem;
import com.funambol.sync.SyncSource;
import com.funambol.util.ConsoleAppender;
import com.funambol.util.Log;
import junit.framework.*;
public class RawFileSyncSourceTest extends TestCase {
private StringKeyValueStore store;
private RawFileSyncSource source;
private TestTracker tracker;
private String directory;
private SourceConfig config;
private class TestTracker implements ChangesTracker {
private Vector newItems = new Vector();
private Vector delItems = new Vector();
private Vector updItems = new Vector();
private Vector allItems = new Vector();
public TestTracker() {
}
public void setSyncSource(TrackableSyncSource ss) {
}
public void begin(int syncMode, boolean resume) throws TrackerException {
}
public void end() throws TrackerException {
}
public Enumeration getNewItems() throws TrackerException {
return newItems.elements();
}
public int getNewItemsCount() throws TrackerException {
return newItems.size();
}
public Enumeration getUpdatedItems() throws TrackerException {
return updItems.elements();
}
public int getUpdatedItemsCount() throws TrackerException {
return updItems.size();
}
public Enumeration getDeletedItems() throws TrackerException {
return delItems.elements();
}
public int getDeletedItemsCount() throws TrackerException {
return delItems.size();
}
public void setItemsStatus(Vector items) throws TrackerException {
}
public void reset() throws TrackerException {
}
public boolean removeItem(SyncItem item) throws TrackerException {
return false;
}
public void addNewItem(SyncItem item) {
newItems.addElement(item);
}
public void addUpdItem(SyncItem item) {
updItems.addElement(item);
}
public void addDelItem(SyncItem item) {
delItems.addElement(item);
}
public void addItem(SyncItem item) {
allItems.addElement(item);
}
public void empty() throws TrackerException {
}
public boolean supportsResume() {
return false;
}
public boolean hasChangedSinceLastSync(String key, long ts) {
return true;
}
public boolean filterItem(String key, boolean removed) {
return false;
}
}
public RawFileSyncSourceTest(String name) {
super(name);
Log.initLog(new ConsoleAppender());
Log.setLogLevel(Log.TRACE);
// Depending on the running platform we have different values for the
// "root" directory that we want to use
directory = System.getProperty("java.io.tmpdir");
if (directory == null) {
directory = "file:///root1";
}
}
public void setUp() {
}
private void prepareTestDirectory(String baseDir, String testDir) throws IOException {
FileAdapter fa = new FileAdapter(baseDir + '/' + testDir);
if (fa.exists()) {
Enumeration files = fa.list(false);
while(files.hasMoreElements()) {
String file = (String)files.nextElement();
String fullFile = baseDir + '/' + testDir + '/' + file;
FileAdapter fa1 = new FileAdapter(fullFile);
try {
fa1.delete();
} catch (Exception e) {
Log.error("Exception while deleting: " + fullFile + " -- " + e.toString());
}
fa1.close();
}
} else {
fa.mkdir();
}
fa.close();
directory = baseDir + '/' + testDir + '/';
tracker = new TestTracker();
config = new SourceConfig(SourceConfig.BRIEFCASE,SourceConfig.FILE_OBJECT_TYPE , "briefcase");
if (Log.isLoggable(Log.DEBUG)) {
Log.debug("directory = " + directory);
}
source = new RawFileSyncSource(config, tracker, directory);
}
public void testSlowSyncSimple() throws Throwable {
prepareTestDirectory(directory, "test0");
// Populate the directory with one file
String content = "This is a small file";
createFile("test-0.txt", content);
tracker.addItem(new SyncItem("test-0.txt"));
source.beginSync(SyncSource.FULL_SYNC, false);
SyncItem item = source.getNextItem();
assertTrue(item != null);
assertTrue(source.getNextItem() == null);
InputStream is = item.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int value = is.read();
while (value != -1) {
bos.write(value);
value = is.read();
}
String itemContent = bos.toString();
// The date formatted depends on the current date, so we do not consider
// it in the comparison
String item1 = content;
String item2 = itemContent;
assertTrue(content.equals(itemContent));
source.endSync();
}
public void testRound1() throws Throwable {
if (Log.isLoggable(Log.INFO)) {
Log.info("################# RawFileSyncSourceTest.testRound1");
}
prepareTestDirectory(directory, "test0");
// Populate the directory with one file
String content = "This is a small file";
createFile("test-0.txt", content);
tracker.addItem(new SyncItem("test-0.txt"));
source.beginSync(SyncSource.FULL_SYNC, false);
SyncItem item = source.getNextItem();
assertTrue(item != null);
assertTrue(source.getNextItem() == null);
InputStream is = item.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int value = is.read();
while (value != -1) {
bos.write(value);
value = is.read();
}
String itemContent = bos.toString();
source.endSync();
// Now start another sync and add this item
FileAdapter oldFile = new FileAdapter(directory+"test-0.txt");
try {
oldFile.delete();
} catch (Exception e) {
Log.error("Exception while deleting: " + directory+"test-0.txt" + " -- " + e.toString());
}
source.beginSync(SyncSource.INCREMENTAL_SYNC, false);
SyncItem sitem = source.createSyncItem("test-0.txt", SourceConfig.BRIEFCASE_TYPE,
SyncItem.STATE_NEW,
"", 0);
OutputStream os = sitem.getOutputStream();
os.write(itemContent.getBytes());
os.close();
source.addItem(sitem);
source.endSync();
FileAdapter newFile = new FileAdapter(directory+"test-0.txt");
assertTrue(newFile.exists());
}
public void testSyncSendLargeObject() throws Throwable {
// Populate the directory with one file
prepareTestDirectory(directory, "test1");
byte content[] = new byte[26*1024];
String fileContent = new String(content);
createFile("test-0.txt", fileContent);
tracker.addItem(new SyncItem("test-0.txt"));
source.beginSync(SyncSource.FULL_SYNC, false);
SyncItem chunk1 = source.getNextItem();
assertTrue(chunk1 != null);
assertTrue(source.getNextItem() == null);
source.endSync();
}
private void createFile(String fileName, String content) throws Throwable {
FileAdapter fa = new FileAdapter(directory + "/" + fileName);
OutputStream os = fa.openOutputStream(false);
os.write(content.getBytes());
os.close();
fa.close();
}
}