diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f758249..230ff37 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -91,6 +91,7 @@ add_executable(tests_run open_image.cpp create_image.cpp verify_image.cpp + identify.cpp ps3_aes.cpp ps3_crypto.cpp ps3_encryption_map.cpp diff --git a/tests/identify.cpp b/tests/identify.cpp new file mode 100644 index 0000000..0c76ce3 --- /dev/null +++ b/tests/identify.cpp @@ -0,0 +1,188 @@ +/* + * This file is part of the Aaru Data Preservation Suite. + * Copyright (c) 2019-2026 Natalia Portillo. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include +#include +#include +#include + +#include "../include/aaruformat.h" +#include "gtest/gtest.h" + +// Helper: create a tmpfile containing a crafted AaruHeader with the given magic and version. +// Returns the FILE* rewound to position 0. Caller must fclose(). +static FILE *make_header_stream(uint64_t magic, uint8_t major_version) +{ + FILE *f = tmpfile(); + EXPECT_NE(f, nullptr); + if(f == nullptr) return nullptr; + + AaruHeader hdr; + memset(&hdr, 0, sizeof(hdr)); + hdr.identifier = magic; + hdr.imageMajorVersion = major_version; + fwrite(&hdr, sizeof(hdr), 1, f); + rewind(f); + return f; +} + +class IdentifyFixture : public testing::Test +{ +public: + IdentifyFixture() = default; + +protected: + char path[PATH_MAX]; + char filename[PATH_MAX]; + + void SetUp() override { getcwd(path, PATH_MAX); } +}; + +// --------------------------------------------------------------------------- +// aaruf_identify_stream() tests +// --------------------------------------------------------------------------- + +TEST_F(IdentifyFixture, StreamValidV2) +{ + snprintf(filename, PATH_MAX, "%s/data/mf2hd.aif", path); + FILE *f = fopen(filename, "rb"); + ASSERT_NE(f, nullptr) << "Failed to open mf2hd.aif"; + + EXPECT_EQ(aaruf_identify_stream(f), 100); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamValidV1) +{ + snprintf(filename, PATH_MAX, "%s/data/mf2hd_v1.aif", path); + FILE *f = fopen(filename, "rb"); + ASSERT_NE(f, nullptr) << "Failed to open mf2hd_v1.aif"; + + EXPECT_EQ(aaruf_identify_stream(f), 100); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamNull) +{ + EXPECT_EQ(aaruf_identify_stream(nullptr), 0); +} + +TEST_F(IdentifyFixture, StreamNonAaru) +{ + snprintf(filename, PATH_MAX, "%s/data/random", path); + FILE *f = fopen(filename, "rb"); + ASSERT_NE(f, nullptr) << "Failed to open random data file"; + + EXPECT_EQ(aaruf_identify_stream(f), 0); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamEmptyFile) +{ + FILE *f = tmpfile(); + ASSERT_NE(f, nullptr); + + EXPECT_EQ(aaruf_identify_stream(f), 0); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamTruncatedHeader) +{ + // Write only the 8-byte magic — not enough for a full AaruHeader (104 bytes) + FILE *f = tmpfile(); + ASSERT_NE(f, nullptr); + + const uint64_t magic = AARU_MAGIC; + fwrite(&magic, sizeof(magic), 1, f); + rewind(f); + + EXPECT_EQ(aaruf_identify_stream(f), 0); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamInvalidMagic) +{ + FILE *f = make_header_stream(0xDEADBEEFDEADBEEFULL, 2); + ASSERT_NE(f, nullptr); + + EXPECT_EQ(aaruf_identify_stream(f), 0); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamFutureVersion) +{ + FILE *f = make_header_stream(AARU_MAGIC, 255); + ASSERT_NE(f, nullptr); + + EXPECT_EQ(aaruf_identify_stream(f), 0); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamDicMagic) +{ + FILE *f = make_header_stream(DIC_MAGIC, 1); + ASSERT_NE(f, nullptr); + + EXPECT_EQ(aaruf_identify_stream(f), 100); + fclose(f); +} + +TEST_F(IdentifyFixture, StreamMidPosition) +{ + // Verify identify_stream seeks to 0 even when stream is positioned elsewhere + snprintf(filename, PATH_MAX, "%s/data/mf2hd.aif", path); + FILE *f = fopen(filename, "rb"); + ASSERT_NE(f, nullptr) << "Failed to open mf2hd.aif"; + + fseek(f, 50, SEEK_SET); + EXPECT_EQ(aaruf_identify_stream(f), 100); + fclose(f); +} + +// --------------------------------------------------------------------------- +// aaruf_identify() tests +// --------------------------------------------------------------------------- + +TEST_F(IdentifyFixture, FileValidV2) +{ + snprintf(filename, PATH_MAX, "%s/data/mf2hd.aif", path); + EXPECT_EQ(aaruf_identify(filename), 100); +} + +TEST_F(IdentifyFixture, FileValidV1) +{ + snprintf(filename, PATH_MAX, "%s/data/mf2hd_v1.aif", path); + EXPECT_EQ(aaruf_identify(filename), 100); +} + +TEST_F(IdentifyFixture, FileNull) +{ + EXPECT_EQ(aaruf_identify(nullptr), EINVAL); +} + +TEST_F(IdentifyFixture, FileNonExistent) +{ + EXPECT_EQ(aaruf_identify("/tmp/aaruf_test_nonexistent_identify.aif"), ENOENT); +} + +TEST_F(IdentifyFixture, FileNonAaru) +{ + snprintf(filename, PATH_MAX, "%s/data/random", path); + EXPECT_EQ(aaruf_identify(filename), 0); +}