1 //===- llvm/unittest/Support/TarWriterTest.cpp ----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/TarWriter.h"
10 #include "llvm/Support/FileSystem.h"
11 #include "llvm/Support/MemoryBuffer.h"
12 #include "llvm/Testing/Support/SupportHelpers.h"
13 #include "gtest/gtest.h"
17 using llvm::unittest::TempFile
;
41 class TarWriterTest
: public ::testing::Test
{};
43 static std::vector
<uint8_t> createTar(StringRef Base
, StringRef Filename
) {
44 TempFile
TarWriterTest("TarWriterTest", "tar", "", /*Unique*/ true);
47 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
=
48 TarWriter::create(TarWriterTest
.path(), Base
);
49 EXPECT_TRUE((bool)TarOrErr
);
50 std::unique_ptr
<TarWriter
> Tar
= std::move(*TarOrErr
);
51 Tar
->append(Filename
, "contents");
55 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> MBOrErr
=
56 MemoryBuffer::getFile(TarWriterTest
.path());
57 EXPECT_TRUE((bool)MBOrErr
);
58 std::unique_ptr
<MemoryBuffer
> MB
= std::move(*MBOrErr
);
59 std::vector
<uint8_t> Buf((const uint8_t *)MB
->getBufferStart(),
60 (const uint8_t *)MB
->getBufferEnd());
62 // Windows does not allow us to remove a mmap'ed files, so
63 // unmap first and then remove the temporary file.
69 static UstarHeader
createUstar(StringRef Base
, StringRef Filename
) {
70 std::vector
<uint8_t> Buf
= createTar(Base
, Filename
);
71 EXPECT_GE(Buf
.size(), sizeof(UstarHeader
));
72 return *reinterpret_cast<const UstarHeader
*>(Buf
.data());
75 TEST_F(TarWriterTest
, Basics
) {
76 UstarHeader Hdr
= createUstar("base", "file");
77 EXPECT_EQ("ustar", StringRef(Hdr
.Magic
));
78 EXPECT_EQ("00", StringRef(Hdr
.Version
, 2));
79 EXPECT_EQ("base/file", StringRef(Hdr
.Name
));
80 EXPECT_EQ("00000000010", StringRef(Hdr
.Size
));
83 TEST_F(TarWriterTest
, LongFilename
) {
84 // The prefix is prefixed by an additional '/' so it's one longer than the
85 // number of x's here.
86 std::string
x136(136, 'x');
87 std::string
x137(137, 'x');
88 std::string
y99(99, 'y');
89 std::string
y100(100, 'y');
91 UstarHeader Hdr1
= createUstar("", x136
+ "/" + y99
);
92 EXPECT_EQ("/" + x136
, StringRef(Hdr1
.Prefix
));
93 EXPECT_EQ(y99
, StringRef(Hdr1
.Name
));
95 UstarHeader Hdr2
= createUstar("", x137
+ "/" + y99
);
96 EXPECT_EQ("", StringRef(Hdr2
.Prefix
));
97 EXPECT_EQ("", StringRef(Hdr2
.Name
));
99 UstarHeader Hdr3
= createUstar("", x136
+ "/" + y100
);
100 EXPECT_EQ("", StringRef(Hdr3
.Prefix
));
101 EXPECT_EQ("", StringRef(Hdr3
.Name
));
103 UstarHeader Hdr4
= createUstar("", x137
+ "/" + y100
);
104 EXPECT_EQ("", StringRef(Hdr4
.Prefix
));
105 EXPECT_EQ("", StringRef(Hdr4
.Name
));
107 std::string yz
= "yyyyyyyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzz";
108 UstarHeader Hdr5
= createUstar("", x136
+ "/" + yz
);
109 EXPECT_EQ("/" + x136
, StringRef(Hdr5
.Prefix
));
110 EXPECT_EQ(yz
, StringRef(Hdr5
.Name
));
113 TEST_F(TarWriterTest
, Pax
) {
114 std::vector
<uint8_t> Buf
= createTar("", std::string(200, 'x'));
115 EXPECT_GE(Buf
.size(), 1024u);
117 auto *Hdr
= reinterpret_cast<const UstarHeader
*>(Buf
.data());
118 EXPECT_EQ("", StringRef(Hdr
->Prefix
));
119 EXPECT_EQ("", StringRef(Hdr
->Name
));
121 StringRef Pax
= StringRef((char *)(Buf
.data() + 512), 512);
122 EXPECT_TRUE(Pax
.starts_with("211 path=/" + std::string(200, 'x')));
125 TEST_F(TarWriterTest
, SingleFile
) {
126 TempFile
TarWriterTest("TarWriterTest", "tar", "", /*Unique*/ true);
128 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
=
129 TarWriter::create(TarWriterTest
.path(), "");
130 EXPECT_TRUE((bool)TarOrErr
);
131 std::unique_ptr
<TarWriter
> Tar
= std::move(*TarOrErr
);
132 Tar
->append("FooPath", "foo");
136 std::error_code EC
= sys::fs::file_size(TarWriterTest
.path(), TarSize
);
137 EXPECT_FALSE((bool)EC
);
138 EXPECT_EQ(TarSize
, 2048ULL);
141 TEST_F(TarWriterTest
, NoDuplicate
) {
142 TempFile
TarWriterTest("TarWriterTest", "tar", "", /*Unique*/ true);
144 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
=
145 TarWriter::create(TarWriterTest
.path(), "");
146 EXPECT_TRUE((bool)TarOrErr
);
147 std::unique_ptr
<TarWriter
> Tar
= std::move(*TarOrErr
);
148 Tar
->append("FooPath", "foo");
149 Tar
->append("BarPath", "bar");
153 std::error_code EC
= sys::fs::file_size(TarWriterTest
.path(), TarSize
);
154 EXPECT_FALSE((bool)EC
);
155 EXPECT_EQ(TarSize
, 3072ULL);
158 TEST_F(TarWriterTest
, Duplicate
) {
159 TempFile
TarWriterTest("TarWriterTest", "tar", "", /*Unique*/ true);
161 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
=
162 TarWriter::create(TarWriterTest
.path(), "");
163 EXPECT_TRUE((bool)TarOrErr
);
164 std::unique_ptr
<TarWriter
> Tar
= std::move(*TarOrErr
);
165 Tar
->append("FooPath", "foo");
166 Tar
->append("FooPath", "bar");
170 std::error_code EC
= sys::fs::file_size(TarWriterTest
.path(), TarSize
);
171 EXPECT_FALSE((bool)EC
);
172 EXPECT_EQ(TarSize
, 2048ULL);