/*
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.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; version 2 of the License.
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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Jan 17, 2008
*/
package com.bigdata.bfs;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.bigdata.bfs.BigdataFileSystem;
import com.bigdata.bfs.Document;
import com.bigdata.bfs.DocumentImpl;
import com.bigdata.bfs.FileMetadataSchema;
import com.bigdata.bfs.RepositoryDocumentImpl;
import com.bigdata.journal.TimestampUtility;
import com.bigdata.sparse.ITPS;
import com.bigdata.sparse.ITPV;
/**
* Test operations on the file metadata index for the {@link BigdataFileSystem}.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
* @version $Id$
*/
public class TestFileMetadataIndex extends AbstractRepositoryTestCase {
/**
*
*/
public TestFileMetadataIndex() {
}
/**
* @param arg0
*/
public TestFileMetadataIndex(String arg0) {
super(arg0);
}
/**
* Create a binary file and verifies its metadata and content.
*
* @throws IOException
*/
public void test_create_binary01() throws IOException {
final String id = "test";
final String mimeType = "application/octet-stream";
final byte[] content = new byte[] { 1, 2, 3, 4, 5, 6 };
DocumentImpl doc = new DocumentImpl();
doc.setId(id);
doc.setContentType(mimeType);
doc.setProperty("foo", "bar");
doc.copyStream(content);
repo.create(doc);
Document actual = repo.read(id);
assertEquals("version", 0, ((RepositoryDocumentImpl) actual)
.getVersion());
assertEquals("user property", "bar", actual.getProperty("foo"));
assertEquals("Content-Type", mimeType, actual.getContentType());
assertEquals("content", content, read(actual.getInputStream()));
}
/**
* Create a text file and verify its metadata and content.
*
* @throws IOException
*/
public void test_create_text01() throws IOException {
final String id = "test";
final String encoding = "UTF-8";
final String mimeType = "text/plain; charset=" + encoding;
final String content = "Hello world!";
DocumentImpl doc = new DocumentImpl();
doc.setId(id);
doc.setContentType(mimeType);
doc.setContentEncoding(encoding);
doc.setProperty("foo", "bar");
doc.copyString(encoding, content);
repo.create(doc);
Document actual = repo.read(id);
assertEquals("version", 0, ((RepositoryDocumentImpl) actual)
.getVersion());
assertEquals("Content-Type", mimeType, actual.getContentType());
assertEquals("Content-Encoding", encoding, actual.getContentEncoding());
assertEquals("user property", "bar", actual.getProperty("foo"));
assertEquals("content", content, read(actual.getReader()));
}
/**
* Create an empty file and verify its metadata.
*/
public void test_create_empty() {
final String id = "test";
final Map<String, Object> metadata = new HashMap<String, Object>();
metadata.put(FileMetadataSchema.ID, id);
metadata.put("foo", "bar");
final int version = repo.create(metadata);
metadata.put(FileMetadataSchema.VERSION, Integer.valueOf(version));
assertEquals("version", 0, version);
RepositoryDocumentImpl doc = (RepositoryDocumentImpl) repo.read(id);
assertTrue("exists", doc.exists());
assertEquals("version", version, doc.getVersion());
assertNotSame("versionCreateTime", 0L, doc.getVersionCreateTime());
assertEquals("earliestVersionCreateTime", doc.getVersionCreateTime(), doc.getEarliestVersionCreateTime());
assertEquals("metadataUpdateTime", doc.getVersionCreateTime(), doc.getMetadataUpdateTime());
Map<String, Object> actual = doc.asMap();
assertEquals("id", id, actual.get(FileMetadataSchema.ID));
assertEquals("version", version, actual.get(FileMetadataSchema.VERSION));
assertEquals("user property", "bar", actual.get("foo"));
assertEquals("size", metadata.size(), actual.size());
}
/**
* Create an empty file and write some data on it. Then update its metadata,
* verify the new metadata and the updated version, and then write some data
* on the new version. Verify the both file versions can be read.
*
* @throws IOException
*/
public void test_create_update() throws IOException {
final String id = "test";
final Map<String, Object> metadata = new HashMap<String, Object>();
metadata.put(FileMetadataSchema.ID, id);
metadata.put("foo", "bar");
final int version0;
final long createTime0;
final byte[] expected0 = new byte[] { 1, 2, 3 };
{
version0 = repo.create(metadata);
metadata.put(FileMetadataSchema.VERSION, Integer.valueOf(version0));
assertEquals("version", 0, version0);
RepositoryDocumentImpl doc = (RepositoryDocumentImpl) repo.read(id);
createTime0 = doc.getVersionCreateTime();
Map<String, Object> actual = doc.asMap();
assertEquals("id", id, actual.get(FileMetadataSchema.ID));
assertEquals("version", version0, actual
.get(FileMetadataSchema.VERSION));
assertEquals("user property", "bar", actual.get("foo"));
assertEquals("size", metadata.size(), actual.size());
// write on the file version.
repo.copyStream(id, version0, new ByteArrayInputStream(expected0));
// verify read back.
assertEquals("version0", expected0, read(repo.inputStream(id,
version0)));
}
// update (new file version).
final int version1;
final long createTime1;
final byte[] expected1 = new byte[] { 4, 5, 6 };
{
// modify a user defined property.
metadata.put("foo", "baz");
DocumentImpl doc1 = new DocumentImpl(metadata);
doc1.copyStream(expected1);
version1 = repo.update( doc1 );
assertEquals("version", 1, version1);
metadata.put(FileMetadataSchema.VERSION, Integer.valueOf(version1));
RepositoryDocumentImpl doc = (RepositoryDocumentImpl) repo.read(id);
createTime1 = doc.getVersionCreateTime();
assertNotSame("createTime", 0L, createTime1);
assertNotSame("createTime", createTime0, createTime1);
Map<String, Object> actual = doc.asMap();
assertEquals("id", id, actual.get(FileMetadataSchema.ID));
assertEquals("version", version1, actual
.get(FileMetadataSchema.VERSION));
assertEquals("user property", "baz", actual.get("foo"));
assertEquals("size", metadata.size(), actual.size());
// // write on the file version.
// repo.copyStream(id, version1, new ByteArrayInputStream(expected1));
// verify read back.
assertEquals("version1", expected1, read(repo.inputStream(id,
version1)));
/*
* verify read back of version0 is now an empty byte[] since that
* version was deleted.
*/
assertEquals("version0", new byte[]{}, read(repo.inputStream(id,
version0)));
/*
* verify that version0 is now marked as deleted.
*/
{
/*
* all metadata for the file up to (but excluding) the create
* time for version1.
*/
ITPS tps = repo.readMetadata(id, createTime1 - 1L);
/*
* The version property for version0. This should have been
* overwritten to be deleted (a null) immediately before the new
* file version was created.
*/
ITPV tpv = tps.get(FileMetadataSchema.VERSION);
assertEquals("version", null, tpv.getValue());
}
}
}
/**
* Test of delete a file version verifies that the old version is marked as
* deleted and that the data for that version are deleted as well. The test
* also verifies that the deleted file version metadata and data remain
* readable.
*
* @todo test that the metadata and data are no longer readable after a
* suitable compacting merge.
*
* @throws IOException
*/
public void test_delete01() throws IOException {
final String id = "test";
final Map<String, Object> metadata = new HashMap<String, Object>();
metadata.put(FileMetadataSchema.ID, id);
metadata.put("foo", "bar");
final int version0;
final long createTime0;
final byte[] expected0 = new byte[] { 1, 2, 3 };
{
version0 = repo.create(metadata);
metadata.put(FileMetadataSchema.VERSION, Integer.valueOf(version0));
assertEquals("version", 0, version0);
RepositoryDocumentImpl doc = (RepositoryDocumentImpl) repo.read(id);
createTime0 = doc.getVersionCreateTime();
assertNotSame("createTime", 0L, createTime0);
Map<String, Object> actual = doc.asMap();
assertEquals("id", id, actual.get(FileMetadataSchema.ID));
assertEquals("version", version0, actual
.get(FileMetadataSchema.VERSION));
assertEquals("user property", "bar", actual.get("foo"));
assertEquals("size", metadata.size(), actual.size());
// write on the file version.
repo.copyStream(id, version0, new ByteArrayInputStream(expected0));
// verify read back.
assertEquals("version0", expected0, read(repo.inputStream(id,
version0)));
}
/*
* Delete the file version.
*
* @todo test that double-delete has no effect (returns false, does (or
* does not?) write another delete marker).
*/
assertTrue(repo.delete(id) > 0);
/*
* Verify the file version history metadata.
*/
ITPV[] a = repo.getAllVersionInfo(id);
assertEquals(2, a.length);
assertEquals("v0",0,((Integer)a[0].getValue()).intValue());
assertNull("delete(v0)", a[1].getValue());
/*
* verify read back of version0 is now an empty byte[] since that
* version was deleted.
*/
assertEquals("version0", new byte[]{}, read(repo.inputStream(id,
version0)));
/*
* Verify that you can still read back the file version data using a
* historical view of the file data index whose commit time is less than
* or equal to version1's timestamp. If it is equal then you will be
* reading from the last state of the prior version. If it is less than
* then you may be reading from some historical state of the prior
* version.
*/
{
// the timestamp before the version was deleted.
final long timestamp = a[1].getTimestamp();
// verify read back.
assertEquals("version0", expected0, read(repo.inputStream(id,
version0, TimestampUtility.asHistoricalRead(timestamp))));
}
}
}