1 #include <adios2.h>
2 #include <array>
3 #include <condition_variable>
4 #include <future>
5 #include <iostream>
6 #include <numeric>
7 #include <thread>
8 
9 #include <gtest/gtest.h>
10 
11 #include "ParseArgs.h"
12 
13 using dt = long long;
14 
15 int value_errors = 0;
16 
17 std::mutex StdOutMtx;
18 
Read(int ID)19 int Read(int ID)
20 {
21     adios2::ADIOS adios;
22     adios2::IO io = adios.DeclareIO("IO");
23 
24     {
25         std::lock_guard<std::mutex> guard(StdOutMtx);
26         std::cout << "Reader: engine = " << engine << std::endl;
27     }
28     io.SetEngine(engine);
29     io.SetParameters(engineParams);
30 
31     {
32         std::lock_guard<std::mutex> guard(StdOutMtx);
33         std::cout << "Reader: call Open" << std::endl;
34     }
35 
36     try
37     {
38         std::string FName = "File" + std::to_string(ID);
39         adios2::Engine Reader = io.Open(FName, adios2::Mode::Read);
40         {
41             std::lock_guard<std::mutex> guard(StdOutMtx);
42             std::cout << "Reader: passed Open" << std::endl;
43         }
44         std::array<dt, 1000> ar;
45 
46         auto status = Reader.BeginStep();
47         {
48             std::lock_guard<std::mutex> guard(StdOutMtx);
49             std::cout << "Reader: passed BeginStep";
50         }
51         if (status == adios2::StepStatus::EndOfStream)
52         {
53             {
54                 std::lock_guard<std::mutex> guard(StdOutMtx);
55                 std::cout << " with EndOfStream " << std::endl;
56             }
57             return false;
58         }
59         {
60             std::lock_guard<std::mutex> guard(StdOutMtx);
61             std::cout << " with success " << std::endl;
62         }
63 
64         adios2::Variable<dt> var = io.InquireVariable<dt>("data");
65         Reader.Get(var, ar.begin());
66         Reader.EndStep();
67         dt expect = 0;
68         for (auto &val : ar)
69         {
70             if (val != expect)
71             {
72                 value_errors++;
73             }
74             expect++;
75         }
76 
77         Reader.Close();
78         {
79             std::lock_guard<std::mutex> guard(StdOutMtx);
80             std::cout << "Reader got " << expect << " values, " << value_errors
81                       << " were incorrect" << std::endl;
82         }
83     }
84     catch (std::exception &e)
85     {
86         {
87             std::lock_guard<std::mutex> guard(StdOutMtx);
88             std::cout << "Reader: Exception: " << e.what() << std::endl;
89         }
90         return false;
91     }
92     return true;
93 }
94 
Write(int ID)95 bool Write(int ID)
96 {
97     adios2::ADIOS adios;
98     adios2::IO io = adios.DeclareIO("IO");
99     io.SetEngine(engine);
100     io.SetParameters(engineParams);
101     {
102         std::lock_guard<std::mutex> guard(StdOutMtx);
103         std::cout << "Writer: engine = " << engine << std::endl;
104     }
105     auto var = io.DefineVariable<dt>("data", adios2::Dims{100, 10},
106                                      adios2::Dims{0, 0}, adios2::Dims{100, 10});
107 
108     std::array<dt, 1000> ar;
109     std::iota(ar.begin(), ar.end(), 0);
110 
111     try
112     {
113         std::string FName = "File" + std::to_string(ID);
114         adios2::Engine Writer = io.Open(FName, adios2::Mode::Write);
115 
116         {
117             std::lock_guard<std::mutex> guard(StdOutMtx);
118             std::cout << "Writer completed Open() " << std::endl;
119         }
120         Writer.BeginStep();
121         Writer.Put<dt>(var, ar.begin());
122         Writer.EndStep();
123         Writer.Close();
124         {
125             std::lock_guard<std::mutex> guard(StdOutMtx);
126             std::cout << "Writer completed Close() " << std::endl;
127         }
128     }
129     catch (std::exception &e)
130     {
131         {
132             std::lock_guard<std::mutex> guard(StdOutMtx);
133             std::cout << "Writer: Exception: " << e.what() << std::endl;
134         }
135         return false;
136     }
137     return true;
138 }
139 
140 class TestThreads : public ::testing::Test
141 {
142 public:
143     TestThreads() = default;
144 };
145 
TEST_F(TestThreads,Basic)146 TEST_F(TestThreads, Basic)
147 {
148     auto read_fut = std::async(std::launch::async, Read, 0);
149     auto write_fut = std::async(std::launch::async, Write, 0);
150     bool reader_success = read_fut.get();
151     bool writer_success = write_fut.get();
152     EXPECT_TRUE(reader_success);
153     EXPECT_TRUE(writer_success);
154     EXPECT_EQ(value_errors, 0)
155         << "We got " << value_errors << " erroneous values at the reader";
156 }
157 
158 //  This test tries to push up to the limits to see if we're leaking FDs, but it
159 //  runs slowly, commenting it out until needed.
160 //
161 // TEST_F(TestThreads, Repeated)
162 // {
163 //     auto high_write_fut = std::async(std::launch::async, Write, 0);
164 //     for (int i = 0; i < 1024; i++)
165 //     {
166 //         auto read_fut = std::async(std::launch::async, Read, i + 1);
167 //         auto write_fut = std::async(std::launch::async, Write, i + 1);
168 //         bool reader_success = read_fut.get();
169 //         bool writer_success = write_fut.get();
170 //         EXPECT_TRUE(reader_success);
171 //         EXPECT_TRUE(writer_success);
172 //         EXPECT_EQ(value_errors, 0)
173 //             << "We got " << value_errors << " erroneous values at the
174 //             reader";
175 //         std::cout << "finished pair " << i << std::endl;
176 //     }
177 //     auto high_read_fut = std::async(std::launch::async, Read, 0);
178 //     bool reader_success = high_read_fut.get();
179 //     bool writer_success = high_write_fut.get();
180 //     EXPECT_TRUE(reader_success);
181 //     EXPECT_TRUE(writer_success);
182 //     EXPECT_EQ(value_errors, 0);
183 // }
184 
main(int argc,char ** argv)185 int main(int argc, char **argv)
186 {
187     ::testing::InitGoogleTest(&argc, argv);
188     ParseArgs(argc, argv);
189 
190     int result;
191     result = RUN_ALL_TESTS();
192     return result;
193 }
194