CNORXZ
Container with Native Operation Routines and Expressions
Loading...
Searching...
No Matches
h5_basic_unit_test.cc
Go to the documentation of this file.
1// -*- C++ -*-
12#include <cstdlib>
13#include <iostream>
14#include <fstream>
15#include <cstdio>
16
17#include "gtest/gtest.h"
18
19#include "cnorxz_hdf5.h"
20#include "test_numbers.h"
21
22namespace
23{
24 using namespace CNORXZ;
25 using namespace CNORXZ::hdf5;
26 using Test::Numbers;
27
28 static const String testh5file = "test_file.h5";
29
30 class NoFile_Test : public ::testing::Test
31 {
32 protected:
33
34 NoFile_Test()
35 {
36 mNoFileName = "no_file.h5";
37 mWrongFileName = "just_txt.h5";
38 std::fstream fs(mWrongFileName, std::ios::out);
39 fs << "This file is not a hdf5 file" << std::endl;
40 fs.close();
41 }
42
43 String mNoFileName;
44 String mWrongFileName;
45 };
46
47 class Group_Test : public ::testing::Test
48 {
49 protected:
50
51 Group_Test()
52 {
53 mFileName = testh5file;
54 mFs = {"field1","second","real"};
55 // Tuple has reverse (!) memory ordering:
57 ( { { 3.141, -6, 0 },
58 { 0.789, -8, 3 },
59 { 10.009, 4, 34 },
60 { -9.77, -777, 2 },
61 { -0.003, 0, 321 }
62 } );
63 RangePtr rs = CRangeFactory(v.size()).create();
64 RangePtr fs = CRangeFactory(mFs.size()).create();
65 mTabA = MArray<Tuple<Double,Int,SizeT>>(rs, std::move(v));
66 mTabD = MArray<DType>(rs*fs);
67 CIndex i(rs);
68 CIndex j(fs);
69 for(i = 0; i.lex() != rs->size(); ++i){
70 iter<0,3>( [&](auto jj)
71 { j = jj; mTabD[i*j] = DType(std::get<3-jj-1>(v[i.lex()])); }, NoF{} );
72 }
73
74 const SizeT ddim = 5;
78 dranges[2] = CRangeFactory(13).create();
82 mData = MArray<Double>( drange, Numbers::get(0,drange->size()) );
83 }
84
85 String mFileName;
86
87 Arr<String,3> mFs;
89 MArray<DType> mTabD;
90 MArray<Double> mData;
91 };
92
93
94 TEST_F(NoFile_Test, NoFile)
95 {
96 File f(mNoFileName, true);
97 EXPECT_THROW(f.open(), std::runtime_error);
98 }
99
100 TEST_F(NoFile_Test, NoH5Format)
101 {
102 File f1(mWrongFileName, true);
103 File f2(mWrongFileName, false);
104 EXPECT_THROW(f1.open(), std::runtime_error);
105 EXPECT_THROW(f2.open(), std::runtime_error);
106 }
107
108 TEST_F(Group_Test, Create)
109 {
110 std::remove(mFileName.c_str());
111 File h5f(mFileName, false);
112 EXPECT_FALSE(h5f.ro());
113 h5f.open();
114 h5f.addAttribute("fprop", static_cast<Double>(3.141));
115 h5f.addGroup("gr1");
116 h5f.getGroup("gr1")->addAttribute("att1", String("text"));
117 h5f.addGroup("gr2");
118 h5f.addGroup("foo");
119 h5f.addGroup("bar");
120 h5f.addGroup("moregroups");
121 auto moregroups = h5f.getGroup("moregroups");
122 moregroups->open().addGroup("evenmore");
123 auto evenmore = moregroups->getGroup("evenmore");
124 evenmore->open();
125 evenmore->addAttribute("moreatt", static_cast<Int>(12));
126 evenmore->addGroup("we");
127 evenmore->getGroup("we")->addAttribute("wex", static_cast<Int>(9));
128 evenmore->getGroup("we")->addAttribute("xy", String("xys"));
129 evenmore->addGroup("need");
130 evenmore->getGroup("need")->addAttribute("wex", static_cast<Int>(7));
131 evenmore->addGroup("more");
132 evenmore->getGroup("more")->addAttribute("wex", static_cast<Int>(4));
133 evenmore->addGroup("groups");
134 evenmore->getGroup("groups")->addAttribute("wex", static_cast<Int>(2));
135 EXPECT_EQ(h5f.get().size(), 5u);
136 h5f.close();
137 }
138
139 TEST_F(Group_Test, CreateTable)
140 {
141 File h5f(mFileName, false);
142 h5f.open();
143 h5f.getGroup("gr1")->open().addTable("tab1", mTabA, mFs);
144 h5f.getGroup("moregroups")->open().getGroup("evenmore")->open().getGroup("need")->open().addTable("tab1", mTabA, mFs);
145 h5f.close();
146 }
147
148 TEST_F(Group_Test, CreateDataset)
149 {
150 File h5f(mFileName, false);
151 h5f.open();
152 h5f.getGroup("gr2")->open().addDataset("dat1", mData);
153 h5f.close();
154 }
155
156 TEST_F(Group_Test, Read)
157 {
158 File h5f(mFileName, true);
159 h5f.open();
160 EXPECT_TRUE(h5f.ro());
161 EXPECT_EQ(h5f.get().size(), 5u);
162
163 EXPECT_THROW(h5f.getGroup("gr0"), std::runtime_error);
164 auto gr1 = h5f.getGroup("gr1");
165 gr1->open();
166 auto tab = gr1->getTable("tab1");
167 DType att = gr1->getAttribute("att1");
168 EXPECT_EQ(att.str(), "text");
169 VCHECK(tab->path());
170 EXPECT_EQ(tab->fields()->size(), 3u);
171 EXPECT_EQ(tab->records()->size(), 5u);
172
173 EXPECT_THROW(h5f.getTable("moregroups/evenmore/need/tab1/a"), std::runtime_error);
174 auto tab2 = h5f.getTable("moregroups/evenmore/need/tab1/");
175 EXPECT_EQ(tab2->fields()->size(), 3u);
176 EXPECT_EQ(tab2->records()->size(), 5u);
177
178 h5f.iter( [](const auto& c) { VCHECK(c->path()); } )();
179 h5f.iterRecursive( [](const auto& c) { VCHECK(c->path()); } )();
180 h5f.iterRecursive( [](const auto& c) { c->open(); VCHECK(toString(c->getRecursiveAttributes())); } )();
181 h5f.iterRecursive( [](const auto& c) {
182 if(c->type() == ContentType::TABLE) { c->open(); VCHECK(toString(c->getRecursiveAttributes())); }
183 } )();
184 h5f.close();
185 }
186
187 TEST_F(Group_Test, ReadTable)
188 {
190
191 File h5f(mFileName, true);
192 h5f.open();
193 auto tab = h5f.getGroup("gr1")->open().getTable("tab1", RecType());
194 EXPECT_EQ(tab->fields()->size(), 3u);
195 EXPECT_EQ(tab->records()->size(), 5u);
196 tab->open();
197 auto cont = tab->read();
198 EXPECT_EQ(cont.size(), mTabA.size());
199 CIndex i(mTabA.range());
200 for(; i.lex() != i.lmax().val(); ++i){
201 EXPECT_EQ( cont[i], mTabA[i] );
202 }
203 auto dtab = h5f.getGroup("gr1")->open().getTable("tab1");
204 auto dcont = dtab->read();
205 EXPECT_EQ(dcont.range()->dim(), 2u);
206 EXPECT_EQ(dcont.range()->sub(0)->size(), 5u);
207 EXPECT_EQ(dcont.range()->sub(1)->size(), 3u);
208 for(auto ai = dcont.begin(); ai != dcont.end(); ++ai){
209 EXPECT_EQ(dcont[ai].str(), mTabD[ai].str());
210 }
211 h5f.close();
212 }
213
214 TEST_F(Group_Test, ReadDataset)
215 {
216 File h5f(mFileName, true);
217 h5f.open();
218 auto dset = h5f.getGroup("gr2")->open().getDataset("dat1", Double{});
219 auto data = dset->read();
220 EXPECT_EQ(data.range()->dim(), 5u);
221 for(SizeT i = 0; i != 5u; ++i){
222 EXPECT_EQ( data.range()->sub(i)->size(), mData.range()->sub(i)->size() );
223 }
224 auto i = std::make_shared<CIndex>(data.range());
225 i->ifor( operation( [](Double a, Double b) { EXPECT_EQ(a,b); }, data(i), mData(i) ), NoF{} )();
226 h5f.close();
227 }
228
229 TEST_F(Group_Test, ReadDatasetPart)
230 {
231 File h5f(mFileName, true);
232 h5f.open();
233 auto dset = h5f.getGroup("gr2")->open().getDataset("dat1", Double{});
234 YIndex beg(dset->dataRange());
235 beg.setSub(0,2);
236 YIndex end = beg - 1;
237 end.setSub(0,2);
238 auto data = dset->read(beg,end);
239 EXPECT_EQ( data.range()->dim(), 5u );
240 EXPECT_EQ( data.range()->sub(0)->size(), 1u );
241 for(SizeT i = 1; i != 5u; ++i){
242 EXPECT_EQ( data.range()->sub(i)->size(), mData.range()->sub(i)->size() );
243 }
244 auto i = std::make_shared<CIndex>(data.range());
245 auto j = std::make_shared<DIndex>( beg.pack().get(0) );
246 i->ifor( operation( [](Double a, Double b) { EXPECT_EQ(a,b); }, data(i), mData(j*i) ), NoF{} )();
247 h5f.close();
248 }
249
250 TEST_F(Group_Test, Read2)
251 {
252 File h5f(mFileName, true);
253 h5f.open();
256
257 auto checkatt = [](const std::map<String,DType>& m,
258 const std::map<String,DType>& cs) {
259 for(const auto& c: cs){
260 if(m.count(c.first)){
261 if(m.at(c.first).str() != c.second.str()){
262 return false;
263 }
264 }
265 else {
266 return false;
267 }
268 }
269 return true;
270 };
271 std::map<String,DType> constr;
272 constr["wex"] = DType(Vector<Int>{7});
273 constr["second"] = DType(static_cast<Int>(-777));
274 h5f.iterRecursive( [&](const auto& c) {
275 if(c->type() == ContentType::TABLE) {
276 c->open();
277 auto av = c->getRecursiveAttributes();
278 auto cx = std::dynamic_pointer_cast<Table>(c);
279 SizeT cnt = 0;
280 cx->iterRecords( [&](const MArray<DType>& r) {
281 auto ax = av;
282 auto fi = UIndex<std::pair<SizeT,String>>(r.range()->sub(0));
283 for(; fi.lex() != fi.lmax().val(); ++fi) { ax[fi.meta().second] = r[fi]; }
284 attrs.push_back(toString(ax));
285 if(checkatt(ax,constr)){
286 paths.push_back(c->path()+"/@"+toString(cnt));
287 }
288 ++cnt;
289 } )();
290 }
291 } )();
292 for(const auto& x: attrs){
293 VCHECK(x);
294 }
295 for(const auto& p: paths){
296 VCHECK(p);
297 }
298 EXPECT_EQ(paths.size(), 1u);
299 EXPECT_EQ(paths[0], "/moregroups/evenmore/need/tab1/@3");
300 h5f.close();
301 }
302}
303
304// check write to new file
305// check read from that file
306// check write to existing file
307// check again read from that file
308
309int main(int argc, char** argv)
310{
311 ::testing::InitGoogleTest(&argc, argv);
312 return RUN_ALL_TESTS();
313}
YIndex & setSub(SizeT ind, SizeT lex)
Definition yrange.cc:507
CNORXZ HDF5 main header.
int main(int argc, char **argv)
#define VCHECK(a)
Definition macros.h:24
std::string String
Definition types.h:42
double Double
Definition types.h:39
uint64_t SizeT
Definition types.h:38
RangePtr yrange(const Vector< RangePtr > &rs)
Definition yrange.cc:666
Sptr< RangeBase > RangePtr
Definition types.h:157
std::vector< T, Allocator< T > > Vector
Definition types.h:310
int32_t Int
Definition types.h:36
Sptr< Range > rangeCast(const RangePtr r)
std::tuple< T... > Tuple
Definition types.h:60
std::array< T, N > Arr
Definition types.h:45
String toString(const T &a)
constexpr decltype(auto) operation(F &&f, const Ops &... ops)
Test numbers utilities.