Skip to content

Commit b292711

Browse files
nh13claude
andcommitted
fix: add file open error handling with tests (#21)
- Add error handling for file open failures in caller.cpp - Add Google Test framework and test infrastructure - Add tests for file handling (non-existent and valid files) - Use unique temp filenames and RAII cleanup in tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 50c42dc commit b292711

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

src/caller.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,11 @@ int main(int argc, char** argv) {
325325
}
326326
else {
327327
in.open(opt->input.c_str(), std::ifstream::in);
328+
if (!in.is_open()) {
329+
fprintf(stderr, "Error: cannot open file '%s'\n", opt->input.c_str());
330+
free(opt);
331+
return 1;
332+
}
328333
stream = &in;
329334
}
330335

tests/test_caller.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
#include <gtest/gtest.h>
2+
#include <cstdlib>
3+
#include <ctime>
4+
#include <fstream>
5+
#include <sys/wait.h>
6+
#include <unistd.h>
27

38
// Placeholder test to verify Google Test infrastructure works
49
TEST(InfrastructureTest, PlaceholderTest) {
@@ -10,3 +15,36 @@ TEST(InfrastructureTest, BasicAssertions) {
1015
EXPECT_EQ(1 + 1, 2);
1116
EXPECT_NE(1, 2);
1217
}
18+
19+
// Test file open error handling
20+
TEST(FileHandlingTest, NonExistentFileReturnsError) {
21+
std::string nonexistent = "/tmp/nonexistent_" + std::to_string(getpid()) + "_" + std::to_string(time(nullptr)) + ".fa";
22+
std::string cmd = "./bin/callerpp -i " + nonexistent + " 2>/dev/null";
23+
int result = std::system(cmd.c_str());
24+
ASSERT_NE(result, -1) << "std::system() failed to execute";
25+
ASSERT_TRUE(WIFEXITED(result)) << "Process did not exit normally";
26+
EXPECT_NE(WEXITSTATUS(result), 0);
27+
}
28+
29+
TEST(FileHandlingTest, ValidFileWorks) {
30+
// Use unique filename with process ID to avoid race conditions
31+
std::string temp_path = "/tmp/test_callerpp_" + std::to_string(getpid()) + ".fa";
32+
33+
// RAII cleanup guard ensures file is removed even if assertions fail
34+
struct FileGuard {
35+
std::string path;
36+
~FileGuard() { std::remove(path.c_str()); }
37+
} guard{temp_path};
38+
39+
// Create a temporary test file
40+
std::ofstream testfile(temp_path);
41+
ASSERT_TRUE(testfile.is_open()) << "Failed to create temporary test file";
42+
testfile << ">test\nACGT\nACGT\n";
43+
testfile.close();
44+
45+
std::string cmd = "./bin/callerpp -i " + temp_path + " >/dev/null 2>&1";
46+
int result = std::system(cmd.c_str());
47+
ASSERT_NE(result, -1) << "std::system() failed to execute";
48+
ASSERT_TRUE(WIFEXITED(result)) << "Process did not exit normally";
49+
EXPECT_EQ(WEXITSTATUS(result), 0);
50+
}

0 commit comments

Comments
 (0)