예제 #1
0
파일: TestFile.cs 프로젝트: lefi7z/h5ohm
            public void ClosePreviouslyInitializedFile()
            {
                string path = Path.GetTempFileName();

                H5File FILE = H5File.Open(path, mode: "w");

                // initialize a test-object, which creates two datasets:
                var PIG = new GuineaPig(FILE.Root);

                Assert.True(PIG.stringset.ID > 0);
                Assert.True(PIG.byteset.ID > 0);

                // th test-object must be disposed of as this is not automatic:
                PIG.Dispose();

                FILE.Dispose();

                // trying to re-open is a surefire way to check if FILE was closed correctly:
                H5File FILE2 = H5File.Open(path, mode: "w");

                FILE2.Dispose();

                Assert.Equal((hid_t)0, PIG.stringset.ID);
                Assert.Equal((hid_t)0, PIG.byteset.ID);

                File.Delete(path);

                Assert.False(File.Exists(FILE.Path));
            }
예제 #2
0
 public void Test_Link_Dont_Exist(string key)
 {
     using (H5File hf = H5File.Open(demodata + "test_link_exists.h5", mode: "r"))
     {
         Assert.False(H5Link.Exists(hf.ID, key));
     }
 }
예제 #3
0
        public void CanReadDataset_CompactTestFile()
        {
            TestUtils.RunForAllVersions(version =>
            {
                // Arrange
                var filePath = "testfiles/h5ex_d_compact.h5";
                var expected = new int[4, 7];

                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 7; j++)
                    {
                        expected[i, j] = i * j - j;
                    }
                }

                // Act
                using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                var parent     = root;
                var dataset    = parent.Dataset("DS1");
                var actual     = dataset.Read <int>();

                // Assert
                Assert.True(actual.SequenceEqual(expected.Cast <int>()));
            });
        }
예제 #4
0
파일: TestGroup.cs 프로젝트: lefi7z/h5ohm
            public void InjectReadonly()
            {
                string path = Path.Combine(demodata, "test_inject_readonly.h5");

                if (!File.Exists(path))
                {
                    using (H5File hf = H5File.Open(path, "x"))
                    {
                        var dset = hf.Root.CreateDataset("existing", 1, new long[] { 1 }, typeof(int));
                        // make sure, the file is closed properly:
                        dset.Dispose();
                    }
                }

                // first try: readonly file mode..
                using (var hf = H5File.Open(path, "r"))
                {
                    using (ReadOnlyObject myo = new ReadOnlyObject(hf.Root))
                    {
                        // ..dataset has been skipped:
                        Assert.Null(myo.readonli);

                        Assert.NotNull(myo.existing);
                    }
                }
            }
예제 #5
0
        public void CanReadDataset_Chunked_Legacy()
        {
            var versions = new H5F.libver_t[]
            {
                H5F.libver_t.EARLIEST,
                H5F.libver_t.V18
            };

            TestUtils.RunForVersions(versions, version =>
            {
                foreach (var withShuffle in new bool[] { false, true })
                {
                    // Arrange
                    var filePath = TestUtils.PrepareTestFile(version, fileId => TestUtils.AddChunkedDataset_Legacy(fileId, withShuffle));

                    // Act
                    using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
                    var parent     = root.Group("chunked");
                    var dataset    = parent.Dataset("chunked");
                    var actual     = dataset.Read <int>();

                    // Assert
                    Assert.True(actual.SequenceEqual(TestData.MediumData));
                }
            });
        }
예제 #6
0
        public void CanDefilterBZip2()
        {
            // # Works only with Linux! On Windows, deflate is used instead.
            // import numpy
            // import tables


            // fileName = 'bzip2.h5'
            // shape = (1000,)
            // atom = tables.Int32Atom()
            // filters = tables.Filters(complevel=9, complib='bzip2')

            // with tables.open_file(fileName, 'w') as f:
            //     dataset = f.create_carray(f.root, 'bzip2', atom, shape, filters=filters)
            //     dataset[:] = list(range(0, 1000))

            // Arrange
            var filePath = "./testfiles/bzip2.h5";
            var expected = Enumerable.Range(0, 1000).ToArray();

            H5Filter.Register(identifier: (H5FilterID)307, name: "bzip2", filterFunc: BZip2Helper.FilterFunc);

            // Act
            using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            var dataset = root.Dataset("bzip2");
            var actual  = dataset.Read <int>();

            // Assert
            Assert.True(actual.SequenceEqual(expected));
        }
예제 #7
0
        public void CanReadDataset_Reference_Object()
        {
            TestUtils.RunForAllVersions(version =>
            {
                // Arrange
                var filePath = TestUtils.PrepareTestFile(version, fileId => TestUtils.AddObjectReference(fileId, ContainerType.Dataset));

                // Act
                using var root         = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
                var dataset_references = root.Group("reference").Dataset("object_reference");
                var references         = dataset_references.Read <H5ObjectReference>();

                var dereferenced = references
                                   .Select(reference => root.Get(reference))
                                   .ToArray();

                // Assert
                for (int i = 0; i < TestData.NumericalData.Count; i++)
                {
                    var dataset     = (H5Dataset)dereferenced[i];
                    var expected    = (Array)TestData.NumericalData[i][1];
                    var elementType = expected.GetType().GetElementType();

                    var method  = typeof(TestUtils).GetMethod(nameof(TestUtils.ReadAndCompare), BindingFlags.Public | BindingFlags.Static);
                    var generic = method.MakeGenericMethod(elementType);
                    var result  = (bool)generic.Invoke(null, new object[] { dataset, expected });

                    Assert.True(result);
                }
            });
        }
예제 #8
0
        public void CanReadDataset_Reference_Region()
        {
            TestUtils.RunForAllVersions(version =>
            {
                // Arrange
                var filePath = TestUtils.PrepareTestFile(version, fileId => TestUtils.AddRegionReference(fileId, ContainerType.Dataset));

                // Act
                using var root         = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
                var dataset_references = root.Group("reference").Dataset("region_reference");
                var references         = dataset_references.Read <H5RegionReference>();

                var reference = references[0];
                root.Context.Reader.Seek((long)reference.CollectionAddress, SeekOrigin.Begin);

                // H5Rint.c (H5R__get_region)
#warning use more structs?
                var globalHeapId = new GlobalHeapId(root.Context.Superblock)
                {
                    CollectionAddress = reference.CollectionAddress,
                    ObjectIndex       = reference.ObjectIndex
                };

                var globalHeapCollection = globalHeapId.Collection;
                var globalHeapObject     = globalHeapCollection.GlobalHeapObjects[(int)globalHeapId.ObjectIndex - 1];
                var localReader          = new H5BinaryReader(new MemoryStream(globalHeapObject.ObjectData));
                var address   = root.Context.Superblock.ReadOffset(localReader);
                var selection = new DataspaceSelection(localReader);

                throw new NotImplementedException();
            });
        }
예제 #9
0
            public void double2d_Arrays()
            {
                using (H5File hf = H5File.Open(testfile, mode: "r"))
                {
                    dset2d <double> DSET = hf.Root["datasets/double2d"] as dset2d <double>;

                    Assert.NotNull(DSET);
                    Assert.Equal(Square, DSET.Length);

                    Assert.Equal(new double[] { 0, 0, 4, 0, 0, 0, 0 }, DSET.Row(2));
                    Assert.Equal(new double[] { 0, 0, 0, 9, 0, 0, 0 }, DSET.Row(3));
                    Assert.Equal(new double[] { 0, 0, 0, 0, 0, 25, 0 }, DSET.Row(5));
                    Assert.Equal(new double[] { 0, 1, 4, 9, 16, 25, 36 }, DSET.Row(6));

                    Assert.Equal(new double[] { 0, 0, 4, 0, 0, 0, 4 }, DSET.Column(2));
                    Assert.Equal(new double[] { 0, 0, 0, 9, 0, 0, 9 }, DSET.Column(3));
                    Assert.Equal(new double[] { 0, 0, 0, 0, 0, 25, 25 }, DSET.Column(5));
                    Assert.Equal(new double[] { 0, 0, 0, 0, 0, 0, 36 }, DSET.Column(6));

                    Assert.Throws <IndexOutOfRangeException>(() => DSET.Row(7));
                    Assert.Throws <IndexOutOfRangeException>(() => DSET.Row(17));
                    Assert.Throws <IndexOutOfRangeException>(() => DSET.Row(-1));

                    Assert.Throws <IndexOutOfRangeException>(() => DSET.Column(7));
                    Assert.Throws <IndexOutOfRangeException>(() => DSET.Column(17));
                    Assert.Throws <IndexOutOfRangeException>(() => DSET.Column(-1));
                }
            }
예제 #10
0
            public void float2d_To2dArray()
            {
                using (H5File hf = H5File.Open(testfile, mode: "r"))
                {
                    dset2d <float> DSET = hf.Root["datasets/float2d"] as dset2d <float>;

                    Assert.NotNull(DSET);
                    Assert.Equal(Square, DSET.Length);

                    var expect = new float[7, 7] {
                        { 0, 0, 0, 0, 0, 0, 0 },
                        { 0, 1, 0, 0, 0, 0, 0 },
                        { 0, 0, 4, 0, 0, 0, 0 },
                        { 0, 0, 0, 9, 0, 0, 0 },
                        { 0, 0, 0, 0, 16, 0, 0 },
                        { 0, 0, 0, 0, 0, 25, 0 },
                        { 0, 1, 4, 9, 16, 25, 36 },
                    };

                    var actual = DSET.Values;

                    for (int i = 0; i < 7; i++)
                    {
                        for (int j = 0; j < 7; j++)
                        {
                            Assert.Equal(expect[i, j], actual[i, j]);
                        }
                    }
                }
            }
예제 #11
0
            public void string2d_To2dArray()
            {
                using (H5File hf = H5File.Open(testfile, mode: "r"))
                {
                    string2d DSET = hf.Root["datasets/string2d"] as string2d;

                    Assert.NotNull(DSET);
                    Assert.Equal(5 * 5, DSET.Length);

                    var expect = new string[5, 5] {
                        { "foo", "", "", "", "", },
                        { "", "bar", "", "", "", },
                        { "", "", "zoom", "", "", },
                        { "", "", "", "grok", "", },
                        { "foo", "bar", "zoom", "grok", "yom" },
                    };

                    var actual = DSET.Values;

                    for (int i = 0; i < 5; i++)
                    {
                        for (int j = 0; j < 5; j++)
                        {
                            Assert.Equal(expect[i, j], actual[i, j]);
                        }
                    }
                }
            }
예제 #12
0
            public void Elements()
            {
                using (H5File hf = H5File.Open(testfile, mode: "r"))
                {
                    using (dset1d <int> DSET = hf.Root["datasets/int1d"] as dset1d <int>)
                    {
                        Assert.NotNull(DSET);

                        var actual = DSET.Elements().ToArray();

                        var expected = new int[] { 0, 1, 2, 3, 4, 5, 6 };

                        Assert.Equal(expected, actual);
                    }

                    using (dset2d <int> DSET = hf.Root["datasets/int2d"] as dset2d <int>)
                    {
                        Assert.NotNull(DSET);

                        var actual = DSET.Elements().Skip(5 * 7 + 4).Take(7).ToArray();

                        var expected = new int[7] {
                            0, 25, 0, 0, 1, 4, 9
                        };

                        Assert.Equal(expected, actual);
                    }
                }
            }
예제 #13
0
            public void DisposeOfProperly()
            {
                int N = H5Base.nObjects;

                using (H5File hf = H5File.Open(testfile, mode: "r"))
                {
                    Assert.Equal(N + 2, H5Base.nObjects);  // +file +root

                    H5DataSet DSET = hf.Root["datasets/float2d"];

                    Assert.Equal(N + 3, H5Base.nObjects);  // +dataset

                    Assert.NotNull(DSET);

                    Assert.Equal(2, DSET.Rank);
                    Assert.Equal(Edge, DSET.Dims[0]);
                    Assert.Equal(Edge, DSET.Dims[1]);
                    Assert.Equal(Edge, DSET.MaxDims[0]);
                    Assert.Equal(Edge, DSET.MaxDims[1]);
                    Assert.Equal(Square, DSET.Length);
                    Assert.Equal(typeof(float), DSET.PrimitiveType);

                    // check, that the object count is stable..
                    Assert.Equal(N + 3, H5Base.nObjects);  // +/- 0

                    DSET.Dispose();

                    Assert.Equal(N + 2, H5Base.nObjects); // -dataset
                }
                Assert.Equal(N + 0, H5Base.nObjects);     // -root -file
            }
예제 #14
0
파일: TestFile.cs 프로젝트: lefi7z/h5ohm
            public void AttemptToWriteClosedFileFails()
            {
                string path = Path.GetTempFileName();

                H5File FILE = H5File.Open(path, mode: "w");

                // create some stuff..
                H5Group GROUP = FILE.Root.SubGroup("foo", create: true);

                GROUP.CreateDataset("bar", 1, new long[] { 7L }, typeof(byte));
                dset1d <byte> DSET = GROUP["bar"] as dset1d <byte>;

                Assert.NotNull(DSET);

                DSET[3] = 5;

                // close all H5Objects manually in this test-scenario:
                GROUP.Dispose();
                DSET.Dispose();
                FILE.Dispose();

                // the file.ID becomes the H5F.close() return value, which is often
                // (but not guaranteed to be) zero / non-negative:
                Assert.Equal((H5Ohm.hid_t) 0, FILE.ID);
                Assert.Equal((H5Ohm.hid_t) 0, FILE.Root.ID);
                Assert.Equal((H5Ohm.hid_t) 0, DSET.ID);
                Assert.Equal((H5Ohm.hid_t) 0, GROUP.ID);

                Assert.Throws <InvalidOperationException>(() => FILE.Root["foo/bar"]);
                Assert.Throws <InvalidOperationException>(() => DSET[5] = 3);
                Assert.Throws <InvalidOperationException>(() => GROUP["bar"]);
            }
        public void CanReadWrappedFiles()
        {
            // Arrange
            var filePath = "testfiles/secret.mat";

            // Act
            using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
            var children = root.Children.ToList();
        }
예제 #16
0
파일: TestFile.cs 프로젝트: lefi7z/h5ohm
            public void OpenNonExistingFails()
            {
                string path = Path.Combine(demodata, "aeroiyu359hnfna.soie");

                Assert.False(File.Exists(path));

                Assert.Throws <FileNotFoundException>(() => H5File.Open(path, mode: "r"));
                Assert.Throws <FileNotFoundException>(() => H5File.Open(path, mode: "r+"));
            }
예제 #17
0
파일: Utils.cs 프로젝트: lefi7z/h5ohm
        public TempH5FileContainer(string filemode = "w")
        {
            string temp_path = System.IO.Path.GetTempFileName();

            hf = H5File.Open(temp_path, mode: "w");
            // close..
            hf.Dispose();
            // ..to reopen:
            hf = H5File.Open(temp_path, mode: filemode);
        }
예제 #18
0
 static void Main(string[] args)
 {
     using (var hf = H5File.Open("example.h5", "w"))
     {
         using (new MyObject(hf.Root))
         {
             // ... work, work, work ...
         }
     }
 }
예제 #19
0
파일: TestGroup.cs 프로젝트: lefi7z/h5ohm
            public void LocateDatasetWith2DProperties(string key)
            {
                using (H5File hf = H5File.Open(demodata + "test_link_exists.h5", mode: "r"))
                {
                    H5DataSet dset = hf.Root[key];

                    Assert.Equal(2, dset.Rank);
                    Assert.Equal(49L, dset.Length);
                    Assert.Equal(new long[] { 7, 7 }, dset.Dims);
                }
            }
예제 #20
0
        public void Test_Attribute_Exist()
        {
            using (H5File hf = H5File.Open(demodata + "test_link_exists.h5", mode: "r"))
            {
                var grp = hf.Root.SubGroup("level1");

                Assert.True(H5Attribute.Exists(grp.ID, "attr1"));
                Assert.True(H5Attribute.Exists(grp["dset1"].ID, "dset_attr"));

                Assert.False(H5Attribute.Exists(grp.ID, "foo"));
            }
        }
        public void GetsH5UnresolvedLinkForDanglingLinks()
        {
            // Arrange
            var filePath = TestUtils.PrepareTestFile(H5F.libver_t.LATEST, fileId => TestUtils.AddExternalFileLink(fileId, "not-existing.h5"));

            // Act
            using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
            var link = root.Get("/links/external_link") as H5UnresolvedLink;

            // Assert
            Assert.NotNull(link);
            Assert.Equal("Unable to open external file 'not-existing.h5'.", link.Reason.Message);
        }
예제 #22
0
파일: TestGroup.cs 프로젝트: lefi7z/h5ohm
            public void InvalidPathLookupFails()
            {
                using (H5File hf = H5File.Open(demodata + "test_link_exists.h5", mode: "r"))
                {
                    Assert.True(H5Link.Exists(hf.ID, "level1/dset1"));

                    // absolute paths are not allowed, as those undermine the local-ness of a group
                    Assert.Throws <KeyNotFoundException>(() => hf.Root["/level1/dset1"]);

                    // dataset cannot have trailing slash, because this would look like a group
                    Assert.Throws <KeyNotFoundException>(() => hf.Root["level1/dset1/"]);
                }
            }
예제 #23
0
        public void CanDefilterBlosc2(string datasetName, bool shouldSuccess)
        {
            // import h5py
            // import hdf5plugin

            // def blosc_opts(complevel=9, complib='blosc:lz4', shuffle=True):
            //     shuffle = 2 if shuffle == 'bit' else 1 if shuffle else 0
            //     compressors = ['blosclz', 'lz4', 'lz4hc', 'snappy', 'zlib', 'zstd']
            //     complib = ['blosc:' + c for c in compressors].index(complib)
            //     args = {
            //         'compression': 32001,
            //         'compression_opts': (0, 0, 0, 0, complevel, shuffle, complib)
            //     }
            //     if shuffle:
            //         args['shuffle'] = False
            //     return args

            // with h5py.File('blosc.h5', 'w') as f:
            //     f.create_dataset('blosclz', data=list(range(0, 1000)), **blosc_opts(9, 'blosc:blosclz', True))
            //     f.create_dataset('lz4', data=list(range(0, 1000)), **blosc_opts(9, 'blosc:lz4', True))
            //     f.create_dataset('lz4hc', data=list(range(0, 1000)), **blosc_opts(9, 'blosc:lz4hc', True))
            //     f.create_dataset('snappy', data=list(range(0, 1000)), **blosc_opts(9, 'blosc:snappy', True))
            //     f.create_dataset('zlib', data=list(range(0, 1000)), **blosc_opts(9, 'blosc:zlib', True))
            //     f.create_dataset('zstd', data=list(range(0, 1000)), **blosc_opts(9, 'blosc:zstd', True))
            //     f.create_dataset('blosclz_bit', data=list(range(0, 1000)), **blosc_opts(9, 'blosc:blosclz', 'bit'))

            // Arrange
            var filePath = "./testfiles/blosc.h5";
            var expected = Enumerable.Range(0, 1000).ToArray();

            H5Filter.Register(identifier: (FilterIdentifier)32001, name: "blosc2", filterFunc: BloscHelper.FilterFunc);

            // Act
            using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            var dataset = root.Dataset(datasetName);

            if (shouldSuccess)
            {
                var actual = dataset.Read <int>();

                // Assert
                Assert.True(actual.SequenceEqual(expected));
            }
            else
            {
                var exception = Assert.Throws <Exception>(() => dataset.Read <int>());

                // Assert
                Assert.Contains("snappy", exception.InnerException.Message);
            }
        }
        public void CanCheckAttribute_ExistsUTF8()
        {
            // Arrange
            var version  = H5F.libver_t.LATEST;
            var filePath = TestUtils.PrepareTestFile(version, fileId => TestUtils.AddMass(fileId, ContainerType.Attribute));

            // Act
            using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
            var parent = root.Group("mass_attributes");
            var actual = parent.AttributeExists("字形碼 / 字形码, Zìxíngmǎ");

            // Assert
            Assert.True(actual);
        }
예제 #25
0
파일: TestGroup.cs 프로젝트: lefi7z/h5ohm
            public void LocateDataset()
            {
                using (H5File hf = H5File.Open(demodata + "test_link_exists.h5", mode: "r"))
                {
                    H5DataSet dset = hf.Root["level1/dset1"];
                    Assert.NotNull(dset);

                    H5DataSet dset_clone = hf.Root.SubGroup("level1")["dset1"];
                    Assert.NotNull(dset_clone);

                    H5DataSet dset_link = hf.Root["level1/level2/dset1_link"];
                    Assert.NotNull(dset_link);
                }
            }
예제 #26
0
파일: TestGroup.cs 프로젝트: lefi7z/h5ohm
            public void TestDataPersistance()
            {
                string testfile = demodata + "test_data_persistance.h5";

                try
                {
                    using (H5File hf = H5File.Open(testfile, "w"))
                    {
                        using (MyObject myo = new MyObject(hf.Root))
                        {
                            Assert.Equal(0, myo.floatset[0, 0]);
                            Assert.Equal(0, myo.doubleset[0, 0]);
                            Assert.Equal("", myo.stringset[0]);
                            Assert.Equal("", myo.stringset2[0, 0]);
                            Assert.Equal(0, myo.intset[0]);
                            Assert.Equal(0, myo.doubleset3[0, 0, 0]);

                            myo.floatset[0, 0]      = 42.0f;
                            myo.doubleset[0]        = new double[] { 42.0 };
                            myo.stringset[0]        = "foo";
                            myo.stringset2[0]       = new string[] { "zoom" };
                            myo.intset[0]           = 42;
                            myo.doubleset3[0, 0, 0] = 3.14;
                        }
                    }

                    using (H5File hf = H5File.Open(testfile, "r"))
                    {
                        using (MyObject myo = new MyObject(hf.Root))
                        {
                            Assert.Equal(1L, myo.doubleset.Length);
                            Assert.Equal(new long[] { 1, 1 }, myo.doubleset.Dims);

                            Assert.Equal(42.0f, myo.floatset[0, 0]);
                            Assert.Equal(new double[] { 42.0 }, myo.doubleset[0]);
                            Assert.Equal("foo", myo.stringset[0]);
                            Assert.Equal(new string[] { "zoom" }, myo.stringset2[0]);
                            Assert.Equal(42, myo.intset[0]);
                            Assert.Equal(new double[, ] {
                                { 3.14 }
                            }, myo.doubleset3[0]);
                        }
                    }
                }
                finally
                {
                    System.IO.File.Delete(testfile);
                }
            }
        public void CanOpenGroup(string path, string expected)
        {
            TestUtils.RunForAllVersions(version =>
            {
                // Arrange
                var filePath = TestUtils.PrepareTestFile(version, fileId => TestUtils.AddSomeLinks(fileId));

                // Act
                using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
                var group      = root.Group(path);

                // Assert
                Assert.Equal(expected, group.Name);
            });
        }
예제 #28
0
        public void CanReadDataset_ChunkedImplicit()
        {
            // Arrange
            var version  = H5F.libver_t.LATEST;
            var filePath = TestUtils.PrepareTestFile(version, fileId => TestUtils.AddChunkedDataset_Implicit(fileId));

            // Act
            using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);
            var parent  = root.Group("chunked");
            var dataset = parent.Dataset("chunked_implicit");
            var actual  = dataset.Read <int>();

            // Assert
            Assert.True(actual.SequenceEqual(TestData.MediumData));
        }
예제 #29
0
        public void Read()
        {
            using (H5File hf = H5File.Open(demodata + "test_generic_read.h5", mode: "r"))
            {
                H5Group grp = hf.Root.SubGroup("my_group");

                H5Attribute attr = grp.GetAttribute("group_attr");
                Assert.NotNull(attr);
                Assert.Equal(42, attr.Read <int>());

                attr = grp["float_1D"].GetAttribute("dataset_attr");
                Assert.NotNull(attr);
                Assert.Equal("a foo that bars", attr.Reads());
            }
        }
        public void CanFollowLinks()
        {
            TestUtils.RunForAllVersions(version =>
            {
                // Arrange
                var filePath = TestUtils.PrepareTestFile(version, fileId => TestUtils.AddLinks(fileId));

                // Act
                using var root = H5File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, deleteOnClose: true);

                var dataset_hard_1 = root.Dataset("links/hard_link_1/dataset");
                var dataset_hard_2 = root.Dataset("links/hard_link_2/dataset");
                var dataset_soft_2 = root.Dataset("links/soft_link_2/dataset");
                var dataset_direct = root.Dataset("links/dataset");
            });
        }