Skip to content

Commit 4dfb07a

Browse files
authored
Test/writer test matrix3d size (#106)
* check that dir exists in writer and Matrix3d is in bounds * formatting * formatting again * fixed includes
1 parent 05c9c8a commit 4dfb07a

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

src/data_ops/writer.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
// Created Date: 2025-01-17 //
55
// Author: Matthew Carroll //
66
// ----- //
7-
// Last Modified: 2025-06-05 //
8-
// Modified By: Matthew Carroll //
7+
// Last Modified: 2025-07-24 //
8+
// Modified By: Andrew Clark //
99
// ----- //
1010
// Copyright (c) 2025 Syndemics Lab at Boston Medical Center //
1111
////////////////////////////////////////////////////////////////////////////////
@@ -237,6 +237,17 @@ std::string WriterImpl::WriteTimedMatrix3d(
237237
index[static_cast<int>(Dimension::kIntervention)] = i;
238238
index[static_cast<int>(Dimension::kOud)] = b;
239239
index[static_cast<int>(Dimension::kDemographicCombo)] = d;
240+
const auto &dims = kv.second.dimensions();
241+
if (index[0] >= dims[0] || index[1] >= dims[1] ||
242+
index[2] >= dims[2]) {
243+
std::stringstream msg;
244+
msg << "Out of bounds matrix access at: [" << kv.first
245+
<< ", " << "(" << i << ", " << b << ", " << d
246+
<< ")]";
247+
respond::utils::LogError(logger_name, msg.str());
248+
throw std::runtime_error(
249+
"Out of bounds Matrix3d access.");
250+
}
240251
double value = kv.second(index[0], index[1], index[2]);
241252
if (pivot) {
242253
stream << interventions[i] << "," << behaviors[b] << ","
@@ -526,8 +537,15 @@ std::string WriterImpl::WriteContents(std::stringstream &stream,
526537
const std::string &path,
527538
OutputType output_type) const {
528539
if (output_type == OutputType::kFile) {
529-
std::filesystem::path p = (path.empty()) ? "temp.csv" : path;
530540
try {
541+
std::filesystem::path p = (path.empty()) ? "temp.csv" : path;
542+
std::filesystem::path dir = p.parent_path();
543+
if (!dir.empty() && !std::filesystem::exists(dir)) {
544+
respond::utils::LogWarning(
545+
logger_name, "Unable to write contents, directory: " +
546+
dir.string() + " does not exist...");
547+
throw std::invalid_argument("Directory does not exist.");
548+
}
531549
std::ofstream file(p.string());
532550
file << stream.rdbuf();
533551
file.close();

tests/src/writer_test.cpp

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
// Created Date: 2025-01-14 //
55
// Author: Matthew Carroll //
66
// ----- //
7-
// Last Modified: 2025-06-06 //
8-
// Modified By: Matthew Carroll //
7+
// Last Modified: 2025-07-24 //
8+
// Modified By: Andrew Clark //
99
// ----- //
1010
// Copyright (c) 2025 Syndemics Lab at Boston Medical Center //
1111
////////////////////////////////////////////////////////////////////////////////
@@ -246,3 +246,54 @@ TEST_F(WriterTest, WriteTotalsData) {
246246
writer->WriteTotalsData(totals, "", OutputType::kString);
247247
ASSERT_EQ(expected, result);
248248
}
249+
250+
TEST_F(WriterTest, WriteTimedMatrix3dOutOfBoundsMatrixAccess) {
251+
TimedMatrix3d utilities;
252+
Matrix3d mat3d(1, 1, 1);
253+
mat3d.setConstant(0.9);
254+
utilities[0] = mat3d;
255+
256+
ASSERT_THROW(writer->WriteUtilityData(utilities, "", OutputType::kString),
257+
std::runtime_error);
258+
}
259+
260+
TEST_F(WriterTest, WriteDirectoryDoesNotExist) {
261+
std::string fake_dir = "FakeDir";
262+
std::string expected = "failure\n\nfailure\n\nfailure\n\n"
263+
"failure\n\nfailure";
264+
265+
MockDataLoader data_loader;
266+
Matrix3d behavior(9, 16, 1);
267+
behavior.setConstant(0.9);
268+
269+
Matrix3d intervention(81, 4, 1);
270+
intervention.setConstant(0.8);
271+
272+
Matrix3d standard(9, 4, 1);
273+
standard.setConstant(0.7);
274+
275+
// WriteOUDTransitionRates
276+
EXPECT_CALL(data_loader, GetOUDTransitionRates())
277+
.WillRepeatedly(Return(behavior));
278+
279+
// WriteInterventionTransitionRates
280+
EXPECT_CALL(data_loader, GetInterventionTransitionRates(_))
281+
.WillRepeatedly(Return(intervention));
282+
283+
// WriteInterventionInitRates
284+
EXPECT_CALL(data_loader, GetInterventionInitRates())
285+
.WillRepeatedly(Return(behavior));
286+
287+
// WriteOverdoseRates
288+
EXPECT_CALL(data_loader, GetOverdoseRates(_))
289+
.WillRepeatedly(Return(standard));
290+
291+
// WriteFatalOverdoseRates
292+
EXPECT_CALL(data_loader, GetFatalOverdoseRates(_))
293+
.WillRepeatedly(Return(standard));
294+
295+
std::string result =
296+
writer->WriteInputData(data_loader, fake_dir, OutputType::kFile);
297+
298+
ASSERT_EQ(expected, result);
299+
}

0 commit comments

Comments
 (0)