1e471ba3dSJoseph Huber #include "llvm/Object/OffloadBinary.h"
2e471ba3dSJoseph Huber
3e471ba3dSJoseph Huber #include "llvm/Testing/Support/Error.h"
4e471ba3dSJoseph Huber #include "gtest/gtest.h"
5e471ba3dSJoseph Huber #include <random>
6e471ba3dSJoseph Huber
7afd2f7e9SJoseph Huber using namespace llvm;
8afd2f7e9SJoseph Huber using namespace llvm::object;
9afd2f7e9SJoseph Huber
TEST(OffloadingTest,checkOffloadingBinary)10e471ba3dSJoseph Huber TEST(OffloadingTest, checkOffloadingBinary) {
11e471ba3dSJoseph Huber // Create random data to fill the image.
12e471ba3dSJoseph Huber std::mt19937 Rng(std::random_device{}());
13e471ba3dSJoseph Huber std::uniform_int_distribution<uint64_t> SizeDist(0, 256);
14e471ba3dSJoseph Huber std::uniform_int_distribution<uint16_t> KindDist(0);
15e471ba3dSJoseph Huber std::uniform_int_distribution<uint16_t> BinaryDist(
16e471ba3dSJoseph Huber std::numeric_limits<uint8_t>::min(), std::numeric_limits<uint8_t>::max());
17e471ba3dSJoseph Huber std::uniform_int_distribution<int16_t> StringDist('!', '~');
18e471ba3dSJoseph Huber std::vector<uint8_t> Image(SizeDist(Rng));
19e471ba3dSJoseph Huber std::generate(Image.begin(), Image.end(), [&]() { return BinaryDist(Rng); });
20e471ba3dSJoseph Huber std::vector<std::pair<std::string, std::string>> Strings(SizeDist(Rng));
21e471ba3dSJoseph Huber for (auto &KeyAndValue : Strings) {
22e471ba3dSJoseph Huber std::string Key(SizeDist(Rng), '\0');
23e471ba3dSJoseph Huber std::string Value(SizeDist(Rng), '\0');
24e471ba3dSJoseph Huber
25e471ba3dSJoseph Huber std::generate(Key.begin(), Key.end(), [&]() { return StringDist(Rng); });
26e471ba3dSJoseph Huber std::generate(Value.begin(), Value.end(),
27e471ba3dSJoseph Huber [&]() { return StringDist(Rng); });
28e471ba3dSJoseph Huber
29e471ba3dSJoseph Huber KeyAndValue = std::make_pair(Key, Value);
30e471ba3dSJoseph Huber }
31e471ba3dSJoseph Huber
32e471ba3dSJoseph Huber // Create the image.
33ecb1d844SFangrui Song MapVector<StringRef, StringRef> StringData;
34e471ba3dSJoseph Huber for (auto &KeyAndValue : Strings)
35e471ba3dSJoseph Huber StringData[KeyAndValue.first] = KeyAndValue.second;
36afd2f7e9SJoseph Huber std::unique_ptr<MemoryBuffer> ImageData = MemoryBuffer::getMemBuffer(
37e471ba3dSJoseph Huber {reinterpret_cast<char *>(Image.data()), Image.size()}, "", false);
38e471ba3dSJoseph Huber
39afd2f7e9SJoseph Huber OffloadBinary::OffloadingImage Data;
40afd2f7e9SJoseph Huber Data.TheImageKind = static_cast<ImageKind>(KindDist(Rng));
41afd2f7e9SJoseph Huber Data.TheOffloadKind = static_cast<OffloadKind>(KindDist(Rng));
42e471ba3dSJoseph Huber Data.Flags = KindDist(Rng);
43e471ba3dSJoseph Huber Data.StringData = StringData;
44f06731e3SJoseph Huber Data.Image = std::move(ImageData);
45e471ba3dSJoseph Huber
46*f93c271dSFangrui Song auto BinaryBuffer =
47*f93c271dSFangrui Song MemoryBuffer::getMemBufferCopy(OffloadBinary::write(Data));
48afd2f7e9SJoseph Huber auto BinaryOrErr = OffloadBinary::create(*BinaryBuffer);
49e471ba3dSJoseph Huber if (!BinaryOrErr)
50e471ba3dSJoseph Huber FAIL();
51e471ba3dSJoseph Huber
52e471ba3dSJoseph Huber // Make sure we get the same data out.
53e471ba3dSJoseph Huber auto &Binary = **BinaryOrErr;
54e471ba3dSJoseph Huber ASSERT_EQ(Data.TheImageKind, Binary.getImageKind());
55e471ba3dSJoseph Huber ASSERT_EQ(Data.TheOffloadKind, Binary.getOffloadKind());
56e471ba3dSJoseph Huber ASSERT_EQ(Data.Flags, Binary.getFlags());
57e471ba3dSJoseph Huber
58e471ba3dSJoseph Huber for (auto &KeyAndValue : Strings)
59e471ba3dSJoseph Huber ASSERT_TRUE(StringData[KeyAndValue.first] ==
60e471ba3dSJoseph Huber Binary.getString(KeyAndValue.first));
61e471ba3dSJoseph Huber
62f06731e3SJoseph Huber EXPECT_TRUE(Data.Image->getBuffer() == Binary.getImage());
63e471ba3dSJoseph Huber
64e471ba3dSJoseph Huber // Ensure the size and alignment of the data is correct.
65afd2f7e9SJoseph Huber EXPECT_TRUE(Binary.getSize() % OffloadBinary::getAlignment() == 0);
66e471ba3dSJoseph Huber EXPECT_TRUE(Binary.getSize() == BinaryBuffer->getBuffer().size());
67e471ba3dSJoseph Huber }
68