/* * Copyright 2024 Intel Corporation * SPDX-License-Identifier: MIT */ #include "tar.h" #include #include #include class TarTest : public testing::Test { protected: TarTest() : f{std::tmpfile()} {}; ~TarTest() { std::fclose(f); } FILE *f; }; TEST_F(TarTest, RoundtripSmallFile) { const char *test = "TEST TEST TEST"; { tar_writer tw; tar_writer_init(&tw, f); tar_writer_start_file(&tw, "test"); fwrite(test, strlen(test), 1, f); tar_writer_finish_file(&tw); } fseek(f, 0, SEEK_END); long size = ftell(f); ASSERT_TRUE(size > 0); ASSERT_TRUE(size % 512 == 0); std::vector contents(size); fseek(f, 0, SEEK_SET); ASSERT_EQ(fread(contents.data(), size, 1, f), 1); { tar_reader ar; tar_reader_init_from_bytes(&ar, contents.data(), size); tar_reader_entry entry; bool first_read = tar_reader_next(&ar, &entry); ASSERT_TRUE(first_read); ASSERT_EQ(entry.name.len, 4); ASSERT_TRUE(memcmp(entry.name.data, "test", 4) == 0); ASSERT_EQ(entry.contents.len, strlen(test)); ASSERT_TRUE(memcmp(entry.contents.data, test, entry.contents.len) == 0); bool second_read = tar_reader_next(&ar, &entry); ASSERT_FALSE(second_read); } } TEST_F(TarTest, RoundtripContentsWithRecordSize) { uint8_t test[512]; for (unsigned i = 0; i < sizeof(test); i++) { test[i] = 'A' + (i % 26); } { tar_writer tw; tar_writer_init(&tw, f); tar_writer_file_from_bytes(&tw, "test", (const char*)test, sizeof(test)); ASSERT_FALSE(tw.error); } fseek(f, 0, SEEK_END); long size = ftell(f); ASSERT_TRUE(size > 0); ASSERT_TRUE(size % 512 == 0); std::vector contents(size); fseek(f, 0, SEEK_SET); ASSERT_EQ(fread(contents.data(), size, 1, f), 1); { tar_reader ar; tar_reader_init_from_bytes(&ar, contents.data(), size); ASSERT_FALSE(ar.error); tar_reader_entry entry; bool first_read = tar_reader_next(&ar, &entry); ASSERT_TRUE(first_read); ASSERT_EQ(entry.name.len, 4); ASSERT_TRUE(memcmp(entry.name.data, "test", 4) == 0); ASSERT_EQ(entry.contents.len, sizeof(test)); ASSERT_TRUE(memcmp(entry.contents.data, test, sizeof(test)) == 0); bool second_read = tar_reader_next(&ar, &entry); ASSERT_FALSE(second_read); } } TEST_F(TarTest, TimestampRoundtrip) { const char *test = "TEST TIMESTAMP"; const time_t test_timestamp = 1234567890; // Known timestamp (February 13, 2009) { tar_writer tw; tar_writer_init(&tw, f); tw.timestamp = test_timestamp; tar_writer_file_from_bytes(&tw, "timestamp_test", test, strlen(test)); ASSERT_FALSE(tw.error); } fseek(f, 0, SEEK_END); long size = ftell(f); ASSERT_TRUE(size > 0); ASSERT_TRUE(size % 512 == 0); std::vector contents(size); fseek(f, 0, SEEK_SET); ASSERT_EQ(fread(contents.data(), size, 1, f), 1); { tar_reader ar; tar_reader_init_from_bytes(&ar, contents.data(), size); ASSERT_FALSE(ar.error); tar_reader_entry entry; bool first_read = tar_reader_next(&ar, &entry); ASSERT_TRUE(first_read); ASSERT_EQ(entry.name.len, strlen("timestamp_test")); ASSERT_TRUE(memcmp(entry.name.data, "timestamp_test", strlen("timestamp_test")) == 0); ASSERT_EQ(entry.contents.len, strlen(test)); ASSERT_TRUE(memcmp(entry.contents.data, test, strlen(test)) == 0); // Verify the timestamp matches ASSERT_EQ(entry.mtime, test_timestamp); bool second_read = tar_reader_next(&ar, &entry); ASSERT_FALSE(second_read); } }