Skip to content

Commit 830e1b3

Browse files
committed
Add test for feature flags
1 parent 84876ff commit 830e1b3

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

structure/feature_flag/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Unknown feature flag set
2+
3+
An empty RNTuple with feature flag 137 (>62) set in the header. Reading should fail accordingly.
4+
The error message should indicate the feature flag.
5+
6+
A later version of this test should set the flag in the footer.

structure/feature_flag/read.C

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "../read_structure.hxx"
2+
3+
void read(std::string_view input = "structure.feature_flag.root",
4+
std::string_view output = "structure.feature_flag.json") {
5+
read_structure(input, output);
6+
}

structure/feature_flag/write.C

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <ROOT/RField.hxx>
2+
#include <ROOT/RMiniFile.hxx>
3+
#include <ROOT/RNTupleDescriptor.hxx>
4+
#include <ROOT/RNTupleSerialize.hxx>
5+
#include <ROOT/RNTupleWriteOptions.hxx>
6+
7+
#include <memory>
8+
#include <string_view>
9+
#include <utility>
10+
11+
using ROOT::Experimental::RFieldZero;
12+
using ROOT::Experimental::RNTupleDescriptor;
13+
using ROOT::Experimental::RNTupleWriteOptions;
14+
using ROOT::Experimental::Internal::RFieldDescriptorBuilder;
15+
using ROOT::Experimental::Internal::RNTupleDescriptorBuilder;
16+
using ROOT::Experimental::Internal::RNTupleFileWriter;
17+
using ROOT::Experimental::Internal::RNTupleSerializer;
18+
19+
void write(std::string_view filename = "structure.feature_flag.root") {
20+
// Note that we are writing a file with a so-far unused feature flag. This cannot use the regular
21+
// production API but we have to use the internal, low-level classes to create the file.
22+
23+
RNTupleDescriptorBuilder descBuilder;
24+
// The following line will be required as of ROOT v6.36
25+
// descBuilder.SetVersionForWriting();
26+
descBuilder.SetNTuple("ntpl", "");
27+
descBuilder.SetFeature(RNTupleDescriptor::kFeatureFlagTest);
28+
descBuilder.AddField(RFieldDescriptorBuilder::FromField(RFieldZero()).FieldId(0).MakeDescriptor().Unwrap());
29+
30+
RNTupleWriteOptions options;
31+
auto writer =
32+
RNTupleFileWriter::Recreate("ntpl", filename, RNTupleFileWriter::EContainerFormat::kTFile, RNTupleWriteOptions());
33+
34+
RNTupleSerializer serializer;
35+
36+
auto ctx = serializer.SerializeHeader(nullptr, descBuilder.GetDescriptor());
37+
auto buffer = std::make_unique<unsigned char[]>(ctx.GetHeaderSize());
38+
ctx = serializer.SerializeHeader(buffer.get(), descBuilder.GetDescriptor());
39+
writer->WriteNTupleHeader(buffer.get(), ctx.GetHeaderSize(), ctx.GetHeaderSize());
40+
41+
auto szFooter = serializer.SerializeFooter(nullptr, descBuilder.GetDescriptor(), ctx);
42+
buffer = std::make_unique<unsigned char[]>(szFooter);
43+
serializer.SerializeFooter(buffer.get(), descBuilder.GetDescriptor(), ctx);
44+
writer->WriteNTupleFooter(buffer.get(), szFooter, szFooter);
45+
46+
writer->Commit();
47+
// Call destructor to flush data to disk
48+
writer.reset();
49+
}

structure/read_structure.hxx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include <ROOT/REntry.hxx>
2+
#include <ROOT/RError.hxx>
23
#include <ROOT/RNTupleReader.hxx>
34

5+
using ROOT::Experimental::RException;
46
using ROOT::Experimental::RNTupleReader;
57

68
#include <cstdint>
@@ -11,9 +13,20 @@ using ROOT::Experimental::RNTupleReader;
1113

1214
void read_structure(std::string_view input, std::string_view output) {
1315
std::ofstream os(std::string{output});
14-
os << "[\n";
1516

16-
auto reader = RNTupleReader::Open("ntpl", input);
17+
std::unique_ptr<RNTupleReader> reader;
18+
try {
19+
reader = RNTupleReader::Open("ntpl", input);
20+
} catch (const RException &e) {
21+
std::string msgWithoutStacktrace;
22+
std::getline(std::istringstream(e.what()), msgWithoutStacktrace);
23+
os << "{\n";
24+
os << " \"error\": \"" << msgWithoutStacktrace << "\"\n";
25+
os << "}\n";
26+
return;
27+
}
28+
29+
os << "[\n";
1730
auto Int32 =
1831
reader->GetModel().GetDefaultEntry().GetPtr<std::int32_t>("Int32");
1932
bool first = true;

0 commit comments

Comments
 (0)