/*
* 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.util;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.syncany.chunk.Transformer;
import org.syncany.database.DatabaseVersion;
import org.syncany.database.DatabaseVersionHeader;
import org.syncany.database.FileContent.FileChecksum;
import org.syncany.database.FileVersion;
import org.syncany.database.FileVersion.FileStatus;
import org.syncany.database.FileVersion.FileType;
import org.syncany.database.MemoryDatabase;
import org.syncany.database.VectorClock;
import org.syncany.database.dao.DatabaseXmlSerializer;
import org.syncany.database.dao.DatabaseXmlSerializer.DatabaseReadType;
import org.syncany.operations.down.DatabaseBranch;
import org.syncany.tests.unit.util.TestFileUtil;
public class TestDatabaseUtil {
private static Pattern databaseVersionHeaderPattern = Pattern.compile("([^/]+)/\\(([^)]+)\\)/T=?(\\d+)");
private static Pattern vectorClockElementPattern = Pattern.compile("([^\\d]+)(\\d+)");
public static DatabaseVersionHeader createFromString(String databaseVersionHeaderString) throws Exception {
Matcher databaseVersionHeaderMatcher = databaseVersionHeaderPattern.matcher(databaseVersionHeaderString);
if (!databaseVersionHeaderMatcher.matches()) {
throw new Exception("Invalid database version header string: " + databaseVersionHeaderString);
}
String client = databaseVersionHeaderMatcher.group(1);
String vectorClockString = databaseVersionHeaderMatcher.group(2);
long databaseVersionHeaderTime = Long.parseLong(databaseVersionHeaderMatcher.group(3));
VectorClock vectorClock = createVectorClock(vectorClockString);
DatabaseVersionHeader newDatabaseVersionHeader = new DatabaseVersionHeader();
newDatabaseVersionHeader.setDate(new Date(databaseVersionHeaderTime));
newDatabaseVersionHeader.setVectorClock(vectorClock);
newDatabaseVersionHeader.setClient(client);
return newDatabaseVersionHeader;
}
public static VectorClock createVectorClock(String vectorClockString) throws Exception {
String[] vectorClockElements = vectorClockString.split(",");
VectorClock vectorClock = new VectorClock();
for (String vectorClockElement : vectorClockElements) {
if ("".equals(vectorClockElement.trim())) {
continue;
}
Matcher vectorClockElementMatcher = vectorClockElementPattern.matcher(vectorClockElement);
if (!vectorClockElementMatcher.matches()) {
throw new Exception("Invalid vector clock element string: " + vectorClockElement);
}
String vectorClockMachineName = vectorClockElementMatcher.group(1);
long vectorClockTime = Long.parseLong(vectorClockElementMatcher.group(2));
vectorClock.setClock(vectorClockMachineName, vectorClockTime);
}
return vectorClock;
}
public static TreeMap<String, DatabaseVersionHeader> createMapWithMachineKey(String[] keysAndDatabaseVersionHeaderStrings) throws Exception {
TreeMap<String, DatabaseVersionHeader> databaseVersionHeaderMap = new TreeMap<String, DatabaseVersionHeader>();
for (int i = 0; i < keysAndDatabaseVersionHeaderStrings.length; i += 2) {
String machineName = keysAndDatabaseVersionHeaderStrings[i];
DatabaseVersionHeader databaseVersionHeader = createFromString(keysAndDatabaseVersionHeaderStrings[i + 1]);
databaseVersionHeaderMap.put(machineName, databaseVersionHeader);
}
return databaseVersionHeaderMap;
}
public static DatabaseBranch createBranch(String[] databaseVersionHeaderStrings) throws Exception {
DatabaseBranch branch = new DatabaseBranch();
for (String databaseVersionHeaderString : databaseVersionHeaderStrings) {
DatabaseVersionHeader databaseVersionHeader = createFromString(databaseVersionHeaderString);
branch.add(databaseVersionHeader);
}
return branch;
}
public static MemoryDatabase readDatabaseFileFromDisk(File databaseFile, Transformer transformer) throws IOException {
MemoryDatabase db = new MemoryDatabase();
DatabaseXmlSerializer dao = new DatabaseXmlSerializer(transformer);
dao.load(db, databaseFile, null, null, DatabaseReadType.FULL);
return db;
}
public static void writeDatabaseFileToDisk(MemoryDatabase db, File writtenDatabaseFile, Transformer transformer) throws IOException {
DatabaseXmlSerializer dao = new DatabaseXmlSerializer(transformer);
dao.save(db.getDatabaseVersions(), writtenDatabaseFile);
}
public static FileVersion createFileVersion(String path) {
FileVersion fileVersion = new FileVersion();
fileVersion.setChecksum(new FileChecksum(TestFileUtil.createRandomArray(20)));
fileVersion.setLastModified(new Date());
fileVersion.setPath(path);
fileVersion.setStatus(FileStatus.NEW);
fileVersion.setType(FileType.FILE);
fileVersion.setUpdated(new Date());
fileVersion.setVersion(1L);
return fileVersion;
}
public static FileVersion createFileVersion(String path, FileVersion basedOnFileVersion) {
FileVersion fileVersion = basedOnFileVersion.clone();
fileVersion.setPath(path);
fileVersion.setStatus(FileStatus.CHANGED);
fileVersion.setVersion(basedOnFileVersion.getVersion() + 1);
return fileVersion;
}
// TODO [medium] Add performance tests for the cache and optimize Database.addDatabaseVersion()-cache handling
public static DatabaseVersion createDatabaseVersion() {
return createDatabaseVersion(null, new Date());
}
public static DatabaseVersion createDatabaseVersion(DatabaseVersion basedOnDatabaseVersion) {
if (basedOnDatabaseVersion == null) {
return createDatabaseVersion(null, new Date());
}
else {
return createDatabaseVersion(basedOnDatabaseVersion.getHeader(), new Date());
}
}
public static DatabaseVersion createDatabaseVersion(DatabaseVersionHeader basedOnDatabaseVersionHeader) {
return createDatabaseVersion(basedOnDatabaseVersionHeader, new Date());
}
public static DatabaseVersion createDatabaseVersion(DatabaseVersionHeader basedOnDatabaseVersionHeader, Date date) {
VectorClock vectorClock = (basedOnDatabaseVersionHeader != null) ? basedOnDatabaseVersionHeader.getVectorClock().clone() : new VectorClock();
vectorClock.incrementClock("someclient");
DatabaseVersion databaseVersion = new DatabaseVersion();
databaseVersion.setClient("someclient");
databaseVersion.setTimestamp(date);
databaseVersion.setVectorClock(vectorClock);
return databaseVersion;
}
}