1 //===- ArchiveTest.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Object/Archive.h"
10 #include "llvm/Testing/Support/Error.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 using namespace object;
15 using namespace testing;
16 
17 static const char ArchiveWithMember[] = "!<arch>\n"        // Global header
18                                         "test/           " // Member name
19                                         "0           "     // Timestamp
20                                         "0     "           // Owner ID
21                                         "0     "           // Group ID
22                                         "0       "         // File mode
23                                         "9999999999"       // Size
24                                         "`\n";
25 
26 static const char ThinArchiveWithMember[] = "!<thin>\n"        // Global header
27                                             "test/           " // Member name
28                                             "0           "     // Timestamp
29                                             "0     "           // Owner ID
30                                             "0     "           // Group ID
31                                             "0       "         // File mode
32                                             "9999999999"       // Size
33                                             "`\n";
34 
35 static const uint64_t MemberSize = 9999999999ull;
36 
37 struct ArchiveTestsFixture : Test {
createChildArchiveTestsFixture38   Expected<Archive::child_iterator> createChild(StringRef Src) {
39     MemoryBufferRef Source(Src, "archive");
40     Expected<std::unique_ptr<Archive>> AOrErr = Archive::create(Source);
41     if (!AOrErr)
42       return AOrErr.takeError();
43     A = std::move(*AOrErr);
44 
45     Error ChildErr = Error::success();
46     auto Child = A->child_begin(ChildErr);
47     if (ChildErr)
48       return std::move(ChildErr);
49     return Child;
50   }
51 
52   std::unique_ptr<Archive> A;
53 };
54 
TEST_F(ArchiveTestsFixture,ArchiveChildGetSizeRegularArchive)55 TEST_F(ArchiveTestsFixture, ArchiveChildGetSizeRegularArchive) {
56   // This test relies on a StringRef being able to hold the appropriate amount
57   // of data.
58   if (std::numeric_limits<StringRef::size_type>::max() < MemberSize)
59     return;
60 
61   auto Child = createChild(ArchiveWithMember);
62   ASSERT_THAT_EXPECTED(Child, Succeeded());
63 
64   Expected<uint64_t> Size = (*Child)->getSize();
65   ASSERT_THAT_EXPECTED(Size, Succeeded());
66   EXPECT_EQ(MemberSize, *Size);
67 }
68 
TEST_F(ArchiveTestsFixture,ArchiveChildGetSizeThinArchive)69 TEST_F(ArchiveTestsFixture, ArchiveChildGetSizeThinArchive) {
70   auto Child = createChild(ThinArchiveWithMember);
71   ASSERT_THAT_EXPECTED(Child, Succeeded());
72 
73   Expected<uint64_t> Size = (*Child)->getSize();
74   ASSERT_THAT_EXPECTED(Size, Succeeded());
75   EXPECT_EQ(MemberSize, *Size);
76 }
77 
TEST_F(ArchiveTestsFixture,ArchiveChildGetBuffer)78 TEST_F(ArchiveTestsFixture, ArchiveChildGetBuffer) {
79   // This test relies on a StringRef being able to hold the appropriate amount
80   // of data.
81   if (std::numeric_limits<StringRef::size_type>::max() < MemberSize)
82     return;
83 
84   auto Child = createChild(ArchiveWithMember);
85   ASSERT_THAT_EXPECTED(Child, Succeeded());
86 
87   Expected<StringRef> Buffer = (*Child)->getBuffer();
88   // Cannot use ASSERT_THAT_EXPECTED, as that will attempt to print the
89   // StringRef (which has an invalid size).
90   ASSERT_TRUE((bool)Buffer);
91   EXPECT_EQ(MemberSize, Buffer->size());
92   EXPECT_EQ(ArchiveWithMember + sizeof(ArchiveWithMember) - 1, Buffer->data());
93 }
94