From 1bb099f47451c594a06debe32393f0ea0e11c7ed Mon Sep 17 00:00:00 2001 From: James Mudd Date: Wed, 27 Nov 2019 18:56:36 +0000 Subject: [PATCH 1/2] Add better exceptions when unsupported b-tree record types are encountered --- jhdf/src/main/java/io/jhdf/btree/BTreeV2.java | 2 +- .../io/jhdf/btree/record/BTreeRecord.java | 38 +++++++++++++------ .../io/jhdf/btree/record/BTreeRecordTest.java | 27 +++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java diff --git a/jhdf/src/main/java/io/jhdf/btree/BTreeV2.java b/jhdf/src/main/java/io/jhdf/btree/BTreeV2.java index 22211531..c129b229 100644 --- a/jhdf/src/main/java/io/jhdf/btree/BTreeV2.java +++ b/jhdf/src/main/java/io/jhdf/btree/BTreeV2.java @@ -122,7 +122,7 @@ private void readRecords(HdfFileChannel hdfFc, long address, int depth, int numb throw new HdfException("Unsupported B tree v2 internal node version detected. Version: " + version); } - final byte type = bb.get(); + final int type = bb.get(); for (int i = 0; i < numberOfRecords; i++) { records.add(readRecord(type, createSubBuffer(bb, recordSize), datasetInfo)); diff --git a/jhdf/src/main/java/io/jhdf/btree/record/BTreeRecord.java b/jhdf/src/main/java/io/jhdf/btree/record/BTreeRecord.java index 7686e102..e2330cd2 100644 --- a/jhdf/src/main/java/io/jhdf/btree/record/BTreeRecord.java +++ b/jhdf/src/main/java/io/jhdf/btree/record/BTreeRecord.java @@ -11,25 +11,41 @@ import io.jhdf.dataset.chunked.DatasetInfo; import io.jhdf.exceptions.HdfException; +import io.jhdf.exceptions.UnsupportedHdfException; import java.nio.ByteBuffer; public abstract class BTreeRecord { @SuppressWarnings("unchecked") // Requires that the b-tree is of the correct type for the record - public static T readRecord(byte type, ByteBuffer buffer, DatasetInfo datasetInfo) { + public static T readRecord(int type, ByteBuffer buffer, DatasetInfo datasetInfo) { switch (type) { - case 5: - return (T) new LinkNameForIndexedGroupRecord(buffer); - case 8: - return (T) new AttributeNameForIndexedAttributesRecord(buffer); - case 10: - return (T) new NonFilteredDatasetChunks(buffer, datasetInfo); + case 0: + throw new HdfException("b-tree record type 0. Should only be used for testing"); + case 1: + throw new UnsupportedHdfException("b-tree record type 1. Currently not supported"); + case 2: + throw new UnsupportedHdfException("b-tree record type 2. Currently not supported"); + case 3: + throw new UnsupportedHdfException("b-tree record type 3. Currently not supported"); + case 4: + throw new UnsupportedHdfException("b-tree record type 4. Currently not supported"); + case 5: + return (T) new LinkNameForIndexedGroupRecord(buffer); + case 6: + throw new UnsupportedHdfException("b-tree record type 6. Currently not supported"); + case 7: + throw new UnsupportedHdfException("b-tree record type 7. Currently not supported"); + case 8: + return (T) new AttributeNameForIndexedAttributesRecord(buffer); + case 9: + throw new UnsupportedHdfException("b-tree record type 9. Currently not supported"); + case 10: + return (T) new NonFilteredDatasetChunks(buffer, datasetInfo); case 11: - return (T) new FilteredDatasetChunks(buffer, datasetInfo); - - default: - throw new HdfException("Unknown b-tree record type. Type = " + type); + return (T) new FilteredDatasetChunks(buffer, datasetInfo); + default: + throw new HdfException("Unknown b-tree record type. Type = " + type); } } diff --git a/jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java b/jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java new file mode 100644 index 00000000..8208282a --- /dev/null +++ b/jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java @@ -0,0 +1,27 @@ +package io.jhdf.btree.record; + +import io.jhdf.exceptions.HdfException; +import io.jhdf.exceptions.UnsupportedHdfException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class BTreeRecordTest { + + @Test + void testUnsupportedRecordTypesThrow() { + assertThrows(HdfException.class, () -> BTreeRecord.readRecord(0, null, null)); + assertThrows(UnsupportedHdfException.class, () -> BTreeRecord.readRecord(1, null, null)); + assertThrows(UnsupportedHdfException.class, () -> BTreeRecord.readRecord(2, null, null)); + assertThrows(UnsupportedHdfException.class, () -> BTreeRecord.readRecord(3, null, null)); + assertThrows(UnsupportedHdfException.class, () -> BTreeRecord.readRecord(4, null, null)); + assertThrows(UnsupportedHdfException.class, () -> BTreeRecord.readRecord(6, null, null)); + assertThrows(UnsupportedHdfException.class, () -> BTreeRecord.readRecord(7, null, null)); + assertThrows(UnsupportedHdfException.class, () -> BTreeRecord.readRecord(9, null, null)); + } + + @Test + void testUnreconizedRecordTypeThrows() { + assertThrows(HdfException.class, () -> BTreeRecord.readRecord(63, null, null)); + } +} \ No newline at end of file From e6671204768f19a04958aa08c7ed7ac9e1914c70 Mon Sep 17 00:00:00 2001 From: James Mudd Date: Wed, 27 Nov 2019 20:12:29 +0000 Subject: [PATCH 2/2] Add additional tests where lazy initialization is used --- .../java/io/jhdf/btree/record/BTreeRecordTest.java | 11 ++++++++++- jhdf/src/test/java/io/jhdf/examples/TestAllFiles.java | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java b/jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java index 8208282a..bfaa69b2 100644 --- a/jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java +++ b/jhdf/src/test/java/io/jhdf/btree/record/BTreeRecordTest.java @@ -1,3 +1,12 @@ +/* + * This file is part of jHDF. A pure Java library for accessing HDF5 files. + * + * http://jhdf.io + * + * Copyright 2019 James Mudd + * + * MIT License see 'LICENSE' file + */ package io.jhdf.btree.record; import io.jhdf.exceptions.HdfException; @@ -24,4 +33,4 @@ void testUnsupportedRecordTypesThrow() { void testUnreconizedRecordTypeThrows() { assertThrows(HdfException.class, () -> BTreeRecord.readRecord(63, null, null)); } -} \ No newline at end of file +} diff --git a/jhdf/src/test/java/io/jhdf/examples/TestAllFiles.java b/jhdf/src/test/java/io/jhdf/examples/TestAllFiles.java index a894578d..0c41c0e2 100644 --- a/jhdf/src/test/java/io/jhdf/examples/TestAllFiles.java +++ b/jhdf/src/test/java/io/jhdf/examples/TestAllFiles.java @@ -136,12 +136,20 @@ private void verifyDataset(Dataset dataset, Group group) { assertThat(dataset.getParent(), is(sameInstance(group))); int[] dims = dataset.getDimensions(); assertThat(dims, is(notNullValue())); + + // Call getAttributes twice to check lazy initialisation + assertThat(dataset.getAttributes(), is(notNullValue())); assertThat(dataset.getAttributes(), is(notNullValue())); + assertThat(dataset.isGroup(), is(false)); assertThat(dataset.isLink(), is(false)); assertThat(dataset.getType(), is(NodeType.DATASET)); assertThat(dataset.getDataLayout(), is(notNullValue())); + + // Call getData twice to check cases of lazy initialisation are working correctly + dataset.getData(); final Object data = dataset.getData(); + if (dataset.isEmpty()) { assertThat(data, is(nullValue())); // Empty so should have 0 size