/*
 * 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.database.dao;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import java.sql.Connection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.syncany.config.Config;
import org.syncany.database.ChunkEntry;
import org.syncany.database.ChunkEntry.ChunkChecksum;
import org.syncany.database.DatabaseVersion;
import org.syncany.database.DatabaseVersionHeader;
import org.syncany.database.FileContent;
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.MultiChunkEntry;
import org.syncany.database.MultiChunkEntry.MultiChunkId;
import org.syncany.database.PartialFileHistory;
import org.syncany.database.PartialFileHistory.FileHistoryId;
import org.syncany.database.dao.ChunkSqlDao;
import org.syncany.database.dao.DatabaseVersionSqlDao;
import org.syncany.database.dao.FileContentSqlDao;
import org.syncany.database.dao.FileHistorySqlDao;
import org.syncany.database.dao.FileVersionSqlDao;
import org.syncany.database.dao.MultiChunkSqlDao;
import org.syncany.operations.down.DatabaseBranch;
import org.syncany.tests.util.TestCollectionUtil;
import org.syncany.tests.util.TestConfigUtil;
import org.syncany.tests.util.TestDatabaseUtil;
import org.syncany.tests.util.TestSqlUtil;

public class DatabaseVersionDaoTest {
	@Test
	public void testGetDatabaseVersionsMasterAndDirty() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set1.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
		
		Iterator<DatabaseVersion> databaseVersionsDirty = databaseVersionDao.getDirtyDatabaseVersions();
		
		// Test				
		assertNotNull(databaseVersionsDirty);
		
		List<DatabaseVersion> databaseVersionsDirtyList = TestCollectionUtil.toList(databaseVersionsDirty);
		assertEquals(1, databaseVersionsDirtyList.size());
		
		DatabaseVersion databaseVersionB1 = databaseVersionsDirtyList.get(0);
		assertEquals("(B1)", databaseVersionB1.getVectorClock().toString());
		assertEquals(1, databaseVersionB1.getChunks().size());
		assertEquals(1, databaseVersionB1.getMultiChunks().size());
		assertEquals(1, databaseVersionB1.getFileContents().size());
		assertEquals(2, databaseVersionB1.getFileHistories().size());
		
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}
	
	@Test
	public void testGetDatabaseVersionsTo() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set1.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
		
		Iterator<DatabaseVersion> databaseVersionsToA2 = databaseVersionDao.getDatabaseVersionsTo("A", 2);
		Iterator<DatabaseVersion> databaseVersionsToA5 = databaseVersionDao.getDatabaseVersionsTo("A", 5);
		Iterator<DatabaseVersion> databaseVersionsToB1 = databaseVersionDao.getDatabaseVersionsTo("B", 1); // B1 is DIRTY !
		
		List<DatabaseVersion> databaseVersionsToA2List = TestCollectionUtil.toList(databaseVersionsToA2);
		List<DatabaseVersion> databaseVersionsToA5List = TestCollectionUtil.toList(databaseVersionsToA5);		
		List<DatabaseVersion> databaseVersionsToB1List = TestCollectionUtil.toList(databaseVersionsToB1);
		
		// Test
		assertNotNull(databaseVersionsToA2);
		assertEquals(2, databaseVersionsToA2List.size());
		assertEquals("(A1)", databaseVersionsToA2List.get(0).getHeader().getVectorClock().toString());
		assertEquals("(A2)", databaseVersionsToA2List.get(1).getHeader().getVectorClock().toString());
		
		assertNotNull(databaseVersionsToA5);
		assertEquals(5, databaseVersionsToA5List.size());
		assertEquals("(A1)", databaseVersionsToA5List.get(0).getHeader().getVectorClock().toString());
		assertEquals("(A2)", databaseVersionsToA5List.get(1).getHeader().getVectorClock().toString());
		assertEquals("(A3)", databaseVersionsToA5List.get(2).getHeader().getVectorClock().toString());
		assertEquals("(A4)", databaseVersionsToA5List.get(3).getHeader().getVectorClock().toString());
		assertEquals("(A5)", databaseVersionsToA5List.get(4).getHeader().getVectorClock().toString());
		
		assertNotNull(databaseVersionsToB1);
		assertEquals(0, databaseVersionsToB1List.size());
				
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}
	
	@Test
	public void testGetLastDatabaseVersionHeader1() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set3.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
		
		DatabaseVersionHeader lastDatabaseVersionHeader = databaseVersionDao.getLastDatabaseVersionHeader();
		
		// Test
		assertNotNull(lastDatabaseVersionHeader);
		assertEquals("(A8,B3)", lastDatabaseVersionHeader.getVectorClock().toString());
		assertEquals("A/(A8,B3)/T=1389977288000", lastDatabaseVersionHeader.toString());		
		
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}
	
	@Test
	public void testPersistDatabaseVersion() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set1.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
		
		// a. Capture database version header (now)
		DatabaseVersionHeader lastDatabaseVersionHeaderBefore = databaseVersionDao.getLastDatabaseVersionHeader();
		
		// b. Add new database header (with one file history)
		DatabaseVersion newDatabaseVersion = new DatabaseVersion();
		DatabaseVersionHeader newDatabaseVersionHeader = new DatabaseVersionHeader();
		
		newDatabaseVersionHeader.setClient("C");
		newDatabaseVersionHeader.setDate(new Date(1489977288000L));
		newDatabaseVersionHeader.setVectorClock(TestDatabaseUtil.createVectorClock("A5,C1"));
		
		newDatabaseVersion.setHeader(newDatabaseVersionHeader);
		
		PartialFileHistory newFileHistory = new PartialFileHistory(FileHistoryId.secureRandomFileId());
		FileVersion newFileVersion = new FileVersion();
		
		newFileVersion.setVersion(1L);
		newFileVersion.setPath("newfile");
		newFileVersion.setChecksum(FileChecksum.parseFileChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"));
		newFileVersion.setLinkTarget(null);
		newFileVersion.setPosixPermissions("rwxrwxrwx");
		newFileVersion.setDosAttributes(null);
		newFileVersion.setStatus(FileStatus.NEW);
		newFileVersion.setLastModified(new Date());
		newFileVersion.setUpdated(new Date());
		newFileVersion.setSize(1L);
		newFileVersion.setType(FileType.FILE);

		newFileHistory.addFileVersion(newFileVersion);
		newDatabaseVersion.addFileHistory(newFileHistory);

		ChunkEntry newChunkEntry = new ChunkEntry(ChunkChecksum.parseChunkChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"), 1);
		newDatabaseVersion.addChunk(newChunkEntry);
		
		MultiChunkEntry newMultiChunkEntry = new MultiChunkEntry(MultiChunkId.parseMultiChunkId("1234567890987654321234567876543456555555"), 10);
		newMultiChunkEntry.addChunk(newChunkEntry.getChecksum());
		newDatabaseVersion.addMultiChunk(newMultiChunkEntry);
		
		FileContent newFileContent = new FileContent();
		newFileContent.setChecksum(FileChecksum.parseFileChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"));
		newFileContent.setSize(1L);		
		newFileContent.addChunk(newChunkEntry.getChecksum());
		newDatabaseVersion.addFileContent(newFileContent);		
		
		// c. Persist database version
		databaseVersionDao.writeDatabaseVersion(newDatabaseVersion);
		
		// d. Capture new last database version header
		DatabaseVersionHeader lastDatabaseVersionHeaderAfter = databaseVersionDao.getLastDatabaseVersionHeader();	
		
		// Test
		assertNotNull(lastDatabaseVersionHeaderBefore);
		assertEquals("A/(A5)/T=1388935689000", lastDatabaseVersionHeaderBefore.toString());
		
		assertNotNull(lastDatabaseVersionHeaderAfter);
		assertEquals("C/(A5,C1)/T=1489977288000", lastDatabaseVersionHeaderAfter.toString());
		assertEquals(newDatabaseVersionHeader.getVectorClock(), lastDatabaseVersionHeaderAfter.getVectorClock());
		
		assertEquals(newChunkEntry, chunkDao.getChunk(ChunkChecksum.parseChunkChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f")));
		assertEquals(newFileContent, fileContentDao.getFileContent(FileChecksum.parseFileChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"), true));
		
		Map<MultiChunkId, MultiChunkEntry> multiChunkIds = multiChunkDao.getMultiChunks(newDatabaseVersionHeader.getVectorClock());
		assertNotNull(multiChunkIds);
		assertEquals(1, multiChunkIds.size());
		
		MultiChunkEntry actualNewMultiChunkEntry = multiChunkIds.get(MultiChunkId.parseMultiChunkId("1234567890987654321234567876543456555555"));
		assertNotNull(actualNewMultiChunkEntry);
		assertEquals(newMultiChunkEntry.getId(), actualNewMultiChunkEntry.getId());
		
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}
	
	@Test
	public void testGetLocalDatabaseBranch1() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set3.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
		
		DatabaseBranch localDatabaseBranch = databaseVersionDao.getLocalDatabaseBranch();
		
		// Test
		assertNotNull(localDatabaseBranch);
		assertEquals(11, localDatabaseBranch.size());
		assertEquals(11, localDatabaseBranch.getAll().size());
		 
		assertEquals(TestDatabaseUtil.createBranch(
			new String[] {
				"A/(A1)/T=1389977166000",
				"A/(A2)/T=1389977199000",
				"A/(A3)/T=1389977203000",
				"A/(A4)/T=1389977207000",
				"A/(A5)/T=1389977214000",
				"A/(A6)/T=1389977222000",
				"B/(A6,B1)/T=1389977233000",
				"A/(A7,B1)/T=1389977234000",
				"B/(A7,B2)/T=1389977258000",
				"B/(A7,B3)/T=1389977264000",
				"A/(A8,B3)/T=1389977288000",
			}
		), localDatabaseBranch);		
				
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}
	
	@Test
	public void testGetLocalDatabaseBranch2() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set1.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
		
		DatabaseBranch localDatabaseBranch = databaseVersionDao.getLocalDatabaseBranch();
		
		// Test
		assertNotNull(localDatabaseBranch);
		assertEquals(5, localDatabaseBranch.size());
		assertEquals(5, localDatabaseBranch.getAll().size());
		 
		assertEquals(TestDatabaseUtil.createBranch(
			new String[] {
				"A/(A1)/T=1388589969000",
				"A/(A2)/T=1388676369000",
				"A/(A3)/T=1388762769000", // Note: Does NOT contain B1 (because: DIRTY!)
				"A/(A4)/T=1388849289000",
				"A/(A5)/T=1388935689000"
			}
		), localDatabaseBranch);		
				
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}
	
	@Test
	public void testGetMaxDirtyVectorClock() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set1.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
		
		Long maxDirtyVectorClockA = databaseVersionDao.getMaxDirtyVectorClock("A");
		Long maxDirtyVectorClockB = databaseVersionDao.getMaxDirtyVectorClock("B");
		
		// Test
		assertNull(maxDirtyVectorClockA);
		assertNotNull(maxDirtyVectorClockB);
		assertEquals(1, (long) maxDirtyVectorClockB);
				
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}
	
	@Test
	public void testMarkDatabaseVersionDirty() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set2.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
				
		databaseVersionDao.markDatabaseVersionDirty(TestDatabaseUtil.createVectorClock("A48"));
		databaseVersionDao.markDatabaseVersionDirty(TestDatabaseUtil.createVectorClock("A49"));
		databaseVersionDao.markDatabaseVersionDirty(TestDatabaseUtil.createVectorClock("A50"));
		
		List<DatabaseVersion> dirtyDatabaseVersions = TestCollectionUtil.toList(databaseVersionDao.getDirtyDatabaseVersions());
		
		// Test
		assertNotNull(dirtyDatabaseVersions);
		assertEquals(3, dirtyDatabaseVersions.size());
		assertEquals("(A48)", dirtyDatabaseVersions.get(0).getVectorClock().toString());
		assertEquals("(A49)", dirtyDatabaseVersions.get(1).getVectorClock().toString());
		assertEquals("(A50)", dirtyDatabaseVersions.get(2).getVectorClock().toString());		
				
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}	
	
	@Test
	public void testRemoveDirtyDatabaseVersions() throws Exception {
		// Setup
		Config testConfig = TestConfigUtil.createTestLocalConfig();
		Connection databaseConnection = testConfig.createDatabaseConnection();

		// Run
		TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set1.sql");
		
		ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
		MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
		FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
		FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
		FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
		DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);

		// a. Test before
		List<DatabaseVersion> dirtyDatabaseVersionsBefore = TestCollectionUtil.toList(databaseVersionDao.getDirtyDatabaseVersions());		
		assertNotNull(dirtyDatabaseVersionsBefore);
		assertNotNull(chunkDao.getChunk(ChunkChecksum.parseChunkChecksum("beefbeefbeefbeefbeefbeefbeefbeefbeefbeef")));
		assertNotNull(multiChunkDao.getDirtyMultiChunkIds());
		assertEquals(1, multiChunkDao.getDirtyMultiChunkIds().size());
		
		// b. Add new database version with DIRTY multichunk; remove DIRTY version		
		DatabaseVersion newDatabaseVersion = new DatabaseVersion();
		newDatabaseVersion.setVectorClock(TestDatabaseUtil.createVectorClock("A5,B2"));
		
		long newDatabaseVersionId = databaseVersionDao.writeDatabaseVersion(newDatabaseVersion);		
		databaseVersionDao.removeDirtyDatabaseVersions(newDatabaseVersionId); 
				
		// c. Test after		
		
		// Database version
		List<DatabaseVersion> dirtyDatabaseVersionsAfter = TestCollectionUtil.toList(databaseVersionDao.getDirtyDatabaseVersions());		
		assertNotNull(dirtyDatabaseVersionsAfter);
		assertEquals(0, dirtyDatabaseVersionsAfter.size());
		
		// Multichunk from dirty version "moved" to new version
		Map<MultiChunkId, MultiChunkEntry> multiChunksA5B2 = multiChunkDao.getMultiChunks(TestDatabaseUtil.createVectorClock("A5,B2"));		
		assertNotNull(multiChunksA5B2);
		assertEquals(1, multiChunksA5B2.size());
		assertNotNull(multiChunksA5B2.get(MultiChunkId.parseMultiChunkId("1234567890987654321123456789098765433222")));
		
		// File version/history/content ARE removed
		assertNull(fileContentDao.getFileContent(FileChecksum.parseFileChecksum("beefbeefbeefbeefbeefbeefbeefbeefbeefbeef"), true));
		
		// TODO [low] Test file version and file history removal		
		
		// Chunks and multichunks are NOT removed!
		assertNotNull(chunkDao.getChunk(ChunkChecksum.parseChunkChecksum("beefbeefbeefbeefbeefbeefbeefbeefbeefbeef")));
		
		assertNotNull(multiChunkDao.getMultiChunks(TestDatabaseUtil.createVectorClock("B1")));
		assertEquals(0, multiChunkDao.getMultiChunks(TestDatabaseUtil.createVectorClock("B1")).size());
		
		assertNotNull(multiChunkDao.getDirtyMultiChunkIds());
		assertEquals(0, multiChunkDao.getDirtyMultiChunkIds().size());		
				
		// Tear down
		databaseConnection.close();
		TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
	}	
}
