/* * Copyright 2010 Outerthought bvba * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.lilyproject.repository.impl.test; import java.math.BigDecimal; import java.net.URI; import java.util.ArrayList; import java.util.List; import org.apache.hadoop.hbase.util.Bytes; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.lilyproject.hadooptestfw.TestHelper; import org.lilyproject.repository.api.Blob; import org.lilyproject.repository.api.HierarchyPath; import org.lilyproject.repository.api.IdGenerator; import org.lilyproject.repository.api.Link; import org.lilyproject.repository.api.QName; import org.lilyproject.repository.api.Record; import org.lilyproject.repository.api.RecordException; import org.lilyproject.repository.api.Repository; import org.lilyproject.repository.api.TypeManager; import org.lilyproject.repotestfw.RepositorySetup; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class RecordTest { private static final RepositorySetup repoSetup = new RepositorySetup(); private static TypeManager typeManager; private static Repository repository; private static IdGenerator idGenerator; @BeforeClass public static void setUpBeforeClass() throws Exception { TestHelper.setupLogging(); // TODO this test relies on all blobs being inline blobs, since it reuses blob values repoSetup.setBlobLimits(Long.MAX_VALUE, -1); repoSetup.setupCore(); repoSetup.setupRepository(); typeManager = repoSetup.getTypeManager(); repository = (Repository)repoSetup.getRepositoryManager().getDefaultRepository().getDefaultTable(); idGenerator = repoSetup.getIdGenerator(); } @AfterClass public static void tearDownAfterClass() throws Exception { repoSetup.stop(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testCloneRecord() throws Exception { String namespace = "testCloneRecord"; QName stringFieldName = new QName(namespace, "stringField"); QName integerFieldName = new QName(namespace, "integerField"); QName longFieldName = new QName(namespace, "longField"); QName doubleFieldName = new QName(namespace, "doubleField"); QName decimalFieldName = new QName(namespace, "decimalField"); QName booleanFieldName = new QName(namespace, "booleanField"); QName dateFieldName = new QName(namespace, "dateField"); QName dateTimeFieldName = new QName(namespace, "dateTimeField"); QName linkFieldName = new QName(namespace, "linkField"); QName blobFieldName = new QName(namespace, "blobField"); QName uriFieldName = new QName(namespace, "uriField"); QName listFieldName = new QName(namespace, "listField"); QName pathFieldName = new QName(namespace, "pathField"); QName recordFieldName = new QName(namespace, "recordField"); QName recordFieldName2 = new QName(namespace, "recordField2"); String stringValue = "abc"; Integer integerValue = 123; Long longValue = 123L; Double doubleValue = new Double(2.2d); BigDecimal decimalValue = BigDecimal.valueOf(Double.MIN_EXPONENT); Boolean booleanValue = true; LocalDate dateValue = new LocalDate(2900, 10, 14); DateTime dateTimeValue = new DateTime(Long.MAX_VALUE); Link linkValue = new Link(idGenerator.newRecordId()); Blob blobValue = new Blob(Bytes.toBytes("anotherKey"), "image/jpeg", Long.MIN_VALUE, "images/image.jpg"); URI uriValue = URI.create("http://foo.com/bar"); List<String> listValue = new ArrayList<String>(); listValue.add("abc"); HierarchyPath pathValue = new HierarchyPath("abc"); Record recordValue = repository.recordBuilder().field(stringFieldName, "foo").build(); Record record = repository.recordBuilder() .field(stringFieldName, stringValue) .field(integerFieldName, integerValue) .field(longFieldName, longValue) .field(doubleFieldName, doubleValue) .field(decimalFieldName, decimalValue) .field(booleanFieldName, booleanValue) .field(dateFieldName, dateValue) .field(dateTimeFieldName, dateTimeValue) .field(linkFieldName, linkValue) .field(blobFieldName, blobValue) .field(uriFieldName, uriValue) .field(listFieldName, listValue) .field(pathFieldName, pathValue) .field(recordFieldName, recordValue) .build(); // Clone record record = record.cloneRecord(); // Change mutable values listValue.add("def"); pathValue.getElements()[0] = "def"; blobValue.setSize(0L); recordValue.setField(integerFieldName, 777); // Validate cloned record does not contain mutations List<String> list = record.getField(listFieldName); assertTrue(list.size() == 1); assertEquals("abc", list.get(0)); HierarchyPath path = record.getField(pathFieldName); assertEquals("abc", path.getElements()[0]); Blob blob = record.getField(blobFieldName); assertTrue(Long.MIN_VALUE == blob.getSize()); Record recordField = record.getField(recordFieldName); assertFalse(recordField.hasField(integerFieldName)); // Put a record in itself // This should normally not be done, but we need to test that the clone method does not choke on this. record.setField(recordFieldName2, record); try { record = record.cloneRecord(); Assert.fail("A record should not be nested in itself"); } catch (RecordException expected) { } } }