Project
Loading...
Searching...
No Matches
test_NavigateToLevel.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <catch_amalgamated.hpp>
13
14#include "../src/DataInputDirector.h"
15
16#include <TFile.h>
17#include <TMap.h>
18#include <TMemFile.h>
19#include <TObjString.h>
20
21using namespace o2::framework;
22
23// Tests for DataInputDirectorContext::levelForOrigin
24
25TEST_CASE("levelForOrigin empty mapping")
26{
28 CHECK(ctx.levelForOrigin("AOD") == -1);
29 CHECK(ctx.levelForOrigin("DYN") == -1);
30}
31
32TEST_CASE("levelForOrigin single entry")
33{
35 ctx.parentLevelToOrigin = {{"DYN", 1}};
36 CHECK(ctx.levelForOrigin("DYN") == 1);
37 CHECK(ctx.levelForOrigin("AOD") == -1);
38}
39
40TEST_CASE("levelForOrigin multiple entries")
41{
43 ctx.parentLevelToOrigin = {{"DYN", 1}, {"EMB", 2}, {"EXT", 1}};
44 CHECK(ctx.levelForOrigin("DYN") == 1);
45 CHECK(ctx.levelForOrigin("EMB") == 2);
46 CHECK(ctx.levelForOrigin("EXT") == 1);
47 CHECK(ctx.levelForOrigin("AOD") == -1);
48 CHECK(ctx.levelForOrigin("") == -1);
49}
50
51// Tests for DataInputDescriptor::navigateToLevel
52
53TEST_CASE("navigateToLevel returns null with no input files")
54{
55 // With no input files setFile fails immediately → {nullptr, -1}
57 ctx.allowedParentLevel = 2;
58 DataInputDescriptor desc(false, 0, ctx);
59
60 auto [parentFile, parentNumTF] = desc.navigateToLevel(0, 0, 1, "DYN");
61 CHECK(parentFile == nullptr);
62 CHECK(parentNumTF == -1);
63}
64
65// ---------------------------------------------------------------------------
66// Helpers: build an AO2D-shaped TMemFile with one DF directory.
67// The AO2D format uses top-level TDirectory entries named DF_<id>.
68// An optional "parentFiles" TMap maps each DF name to its parent file path.
69// ---------------------------------------------------------------------------
70
71static TMemFile* makeAODFile(const char* name)
72{
73 auto* f = new TMemFile(name, "RECREATE");
74 f->mkdir("DF_1");
75 f->Write();
76 return f;
77}
78
79static TMemFile* makeAODFileWithParent(const char* name, const char* parentName)
80{
81 auto* f = new TMemFile(name, "RECREATE");
82 f->mkdir("DF_1");
83 auto* parentMap = new TMap();
84 parentMap->Add(new TObjString("DF_1"), new TObjString(parentName));
85 parentMap->Write("parentFiles", TObject::kSingleKey);
86 f->Write();
87 return f;
88}
89
90TEST_CASE("navigateToLevel finds parent TMemFile")
91{
92 // child.root DF_1 parentFiles: {DF_1 -> parent.root}
93 // parent.root DF_1
94 auto* parentMF = makeAODFile("parent.root");
95 auto* childMF = makeAODFileWithParent("child.root", "parent.root");
96
98 ctx.allowedParentLevel = 2;
99 ctx.openFiles = {{"child.root", childMF}, {"parent.root", parentMF}};
100
101 DataInputDescriptor desc(false, 0, ctx);
102 desc.addFileNameHolder(makeFileNameHolder("child.root"));
103
104 auto [parentDesc, parentNumTF] = desc.navigateToLevel(0, 0, 1, "AOD");
105
106 REQUIRE(parentDesc != nullptr);
107 // DF_1 is the only timeframe in the parent, so its index is 0
108 CHECK(parentNumTF == 0);
109}
110
111TEST_CASE("navigateToLevel returns -1 for missing DF in parent")
112{
113 // child has DF_2 but parent only has DF_1 — findDFNumber returns -1
114 auto* parentMF = makeAODFile("parent2.root");
115
116 auto* childMF = new TMemFile("child2.root", "RECREATE");
117 childMF->mkdir("DF_2");
118 auto* parentMap = new TMap();
119 parentMap->Add(new TObjString("DF_2"), new TObjString("parent2.root"));
120 parentMap->Write("parentFiles", TObject::kSingleKey);
121 childMF->Write();
122
124 ctx.allowedParentLevel = 2;
125 ctx.openFiles = {{"child2.root", childMF}, {"parent2.root", parentMF}};
126
127 DataInputDescriptor desc(false, 0, ctx);
128 desc.addFileNameHolder(makeFileNameHolder("child2.root"));
129
130 auto [parentDesc, parentNumTF] = desc.navigateToLevel(0, 0, 1, "AOD");
131
132 // Parent has DF_1 but child references DF_2 — not found in parent
133 REQUIRE(parentDesc != nullptr);
134 CHECK(parentNumTF == -1);
135}
void addFileNameHolder(FileNameHolder *fn)
std::pair< DataInputDescriptor *, int > navigateToLevel(int counter, int numTF, int wantedParentLevel, std::string_view wantedOrigin)
#define CHECK
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
FileNameHolder * makeFileNameHolder(std::string fileName)
std::vector< std::pair< std::string, int > > parentLevelToOrigin
std::vector< std::pair< std::string, TFile * > > openFiles
int levelForOrigin(std::string_view origin) const
TEST_CASE("levelForOrigin empty mapping")