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 "gtest/gtest.h"
38 class TarWriterTest
: public ::testing::Test
{};
40 static std::vector
<uint8_t> createTar(StringRef Base
, StringRef Filename
) {
41 // Create a temporary file.
42 SmallString
<128> Path
;
44 sys::fs::createTemporaryFile("TarWriterTest", "tar", Path
);
45 EXPECT_FALSE((bool)EC
);
48 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
= TarWriter::create(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
= MemoryBuffer::getFile(Path
);
56 EXPECT_TRUE((bool)MBOrErr
);
57 std::unique_ptr
<MemoryBuffer
> MB
= std::move(*MBOrErr
);
58 std::vector
<uint8_t> Buf((const uint8_t *)MB
->getBufferStart(),
59 (const uint8_t *)MB
->getBufferEnd());
61 // Windows does not allow us to remove a mmap'ed files, so
62 // unmap first and then remove the temporary file.
64 sys::fs::remove(Path
);
69 static UstarHeader
createUstar(StringRef Base
, StringRef Filename
) {
70 std::vector
<uint8_t> Buf
= createTar(Base
, Filename
);
71 EXPECT_TRUE(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 std::string
x154(154, 'x');
85 std::string
x155(155, 'x');
86 std::string
y99(99, 'y');
87 std::string
y100(100, 'y');
89 UstarHeader Hdr1
= createUstar("", x154
+ "/" + y99
);
90 EXPECT_EQ("/" + x154
, StringRef(Hdr1
.Prefix
));
91 EXPECT_EQ(y99
, StringRef(Hdr1
.Name
));
93 UstarHeader Hdr2
= createUstar("", x155
+ "/" + y99
);
94 EXPECT_EQ("", StringRef(Hdr2
.Prefix
));
95 EXPECT_EQ("", StringRef(Hdr2
.Name
));
97 UstarHeader Hdr3
= createUstar("", x154
+ "/" + y100
);
98 EXPECT_EQ("", StringRef(Hdr3
.Prefix
));
99 EXPECT_EQ("", StringRef(Hdr3
.Name
));
101 UstarHeader Hdr4
= createUstar("", x155
+ "/" + y100
);
102 EXPECT_EQ("", StringRef(Hdr4
.Prefix
));
103 EXPECT_EQ("", StringRef(Hdr4
.Name
));
105 std::string yz
= "yyyyyyyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzz";
106 UstarHeader Hdr5
= createUstar("", x154
+ "/" + yz
);
107 EXPECT_EQ("/" + x154
, StringRef(Hdr5
.Prefix
));
108 EXPECT_EQ(yz
, StringRef(Hdr5
.Name
));
111 TEST_F(TarWriterTest
, Pax
) {
112 std::vector
<uint8_t> Buf
= createTar("", std::string(200, 'x'));
113 EXPECT_TRUE(Buf
.size() >= 1024);
115 auto *Hdr
= reinterpret_cast<const UstarHeader
*>(Buf
.data());
116 EXPECT_EQ("", StringRef(Hdr
->Prefix
));
117 EXPECT_EQ("", StringRef(Hdr
->Name
));
119 StringRef Pax
= StringRef((char *)(Buf
.data() + 512), 512);
120 EXPECT_TRUE(Pax
.startswith("211 path=/" + std::string(200, 'x')));
123 TEST_F(TarWriterTest
, SingleFile
) {
124 SmallString
<128> Path
;
126 sys::fs::createTemporaryFile("TarWriterTest", "tar", Path
);
127 EXPECT_FALSE((bool)EC
);
129 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
= TarWriter::create(Path
, "");
130 EXPECT_TRUE((bool)TarOrErr
);
131 std::unique_ptr
<TarWriter
> Tar
= std::move(*TarOrErr
);
132 Tar
->append("FooPath", "foo");
136 EC
= sys::fs::file_size(Path
, TarSize
);
137 EXPECT_FALSE((bool)EC
);
138 EXPECT_EQ(TarSize
, 2048ULL);
141 TEST_F(TarWriterTest
, NoDuplicate
) {
142 SmallString
<128> Path
;
144 sys::fs::createTemporaryFile("TarWriterTest", "tar", Path
);
145 EXPECT_FALSE((bool)EC
);
147 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
= TarWriter::create(Path
, "");
148 EXPECT_TRUE((bool)TarOrErr
);
149 std::unique_ptr
<TarWriter
> Tar
= std::move(*TarOrErr
);
150 Tar
->append("FooPath", "foo");
151 Tar
->append("BarPath", "bar");
155 EC
= sys::fs::file_size(Path
, TarSize
);
156 EXPECT_FALSE((bool)EC
);
157 EXPECT_EQ(TarSize
, 3072ULL);
160 TEST_F(TarWriterTest
, Duplicate
) {
161 SmallString
<128> Path
;
163 sys::fs::createTemporaryFile("TarWriterTest", "tar", Path
);
164 EXPECT_FALSE((bool)EC
);
166 Expected
<std::unique_ptr
<TarWriter
>> TarOrErr
= TarWriter::create(Path
, "");
167 EXPECT_TRUE((bool)TarOrErr
);
168 std::unique_ptr
<TarWriter
> Tar
= std::move(*TarOrErr
);
169 Tar
->append("FooPath", "foo");
170 Tar
->append("FooPath", "bar");
174 EC
= sys::fs::file_size(Path
, TarSize
);
175 EXPECT_FALSE((bool)EC
);
176 EXPECT_EQ(TarSize
, 2048ULL);