[lld] r195388 - [test] Add InputGraph tests
Shankar Easwaran
shankare at codeaurora.org
Thu Nov 21 15:37:45 PST 2013
Author: shankare
Date: Thu Nov 21 17:37:45 2013
New Revision: 195388
URL: http://llvm.org/viewvc/llvm-project?rev=195388&view=rev
Log:
[test] Add InputGraph tests
Added:
lld/trunk/unittests/DriverTests/InputGraphTest.cpp
Modified:
lld/trunk/unittests/DriverTests/CMakeLists.txt
Modified: lld/trunk/unittests/DriverTests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/CMakeLists.txt?rev=195388&r1=195387&r2=195388&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/CMakeLists.txt (original)
+++ lld/trunk/unittests/DriverTests/CMakeLists.txt Thu Nov 21 17:37:45 2013
@@ -3,6 +3,7 @@ add_lld_unittest(DriverTests
GnuLdDriverTest.cpp
DarwinLdDriverTest.cpp
WinLinkDriverTest.cpp
+ InputGraphTest.cpp
)
target_link_libraries(DriverTests
Added: lld/trunk/unittests/DriverTests/InputGraphTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/InputGraphTest.cpp?rev=195388&view=auto
==============================================================================
--- lld/trunk/unittests/DriverTests/InputGraphTest.cpp (added)
+++ lld/trunk/unittests/DriverTests/InputGraphTest.cpp Thu Nov 21 17:37:45 2013
@@ -0,0 +1,365 @@
+//===- lld/unittest/InputGraphTest.cpp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief InputGraph Tests
+///
+//===----------------------------------------------------------------------===//
+
+#include <stdarg.h>
+
+#include "gtest/gtest.h"
+
+#include "lld/Core/InputGraph.h"
+#include "lld/Core/Resolver.h"
+#include "lld/ReaderWriter/Simple.h"
+
+using namespace lld;
+
+namespace {
+
+class MyLinkingContext : public LinkingContext {
+public:
+ virtual Reader &getDefaultReader() const { return *_yamlReader; }
+
+ virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const {
+ return make_error_code(YamlReaderError::illegal_value);
+ }
+
+ virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind k) const {
+ return make_error_code(YamlReaderError::illegal_value);
+ }
+
+ virtual Writer &writer() const { llvm_unreachable("no writer!"); }
+
+ virtual bool validateImpl(raw_ostream &) { return true; }
+};
+
+class MyInputGraph : public InputGraph {
+public:
+ MyInputGraph() : InputGraph() {};
+};
+
+class MyFileNode : public FileNode {
+public:
+ MyFileNode(StringRef path, int64_t ordinal) : FileNode(path, ordinal) {}
+
+ bool validate() { return true; }
+
+ bool dump(raw_ostream &) { return true; }
+
+ virtual error_code parse(const LinkingContext &, raw_ostream &) {
+ return error_code::success();
+ }
+
+ virtual ErrorOr<File &> getNextFile() {
+ if (_nextFileIndex == _files.size())
+ return make_error_code(InputGraphError::no_more_files);
+ return *_files[_nextFileIndex++];
+ }
+};
+
+class MyGroupNode : public Group {
+public:
+ MyGroupNode(int64_t ordinal) : Group(ordinal) {}
+
+ bool validate() { return true; }
+
+ bool dump(raw_ostream &) { return true; }
+
+ virtual error_code parse(const LinkingContext &, raw_ostream &) {
+ return error_code::success();
+ }
+};
+
+class MyObjFile : public SimpleFile {
+public:
+ MyObjFile(LinkingContext &context, StringRef path)
+ : SimpleFile(context, path) {}
+};
+
+class InputGraphTest : public testing::Test {
+public:
+ InputGraphTest() {
+ _inputGraph.reset(new MyInputGraph());
+ _context.setInputGraph(std::move(_inputGraph));
+ }
+
+ virtual LinkingContext &linkingContext() { return _context; }
+
+ InputElement &inputElement(unsigned index) {
+ return linkingContext().inputGraph()[index];
+ }
+
+ virtual InputGraph &inputGraph() { return linkingContext().inputGraph(); }
+
+ int inputFileCount() { return linkingContext().inputGraph().size(); }
+
+protected:
+ MyLinkingContext _context;
+ std::unique_ptr<InputGraph> _inputGraph;
+};
+
+TEST_F(InputGraphTest, Basic) {
+ EXPECT_EQ(0, inputFileCount());
+ ErrorOr<InputElement *> nextElement = inputGraph().getNextInputElement();
+ EXPECT_EQ(InputGraphError::no_more_elements, error_code(nextElement));
+}
+
+TEST_F(InputGraphTest, AddAFile) {
+ std::unique_ptr<MyFileNode> myfile(new MyFileNode("file1", 0));
+ EXPECT_EQ(true, inputGraph().addInputElement(std::move(myfile)));
+ EXPECT_EQ(1, inputFileCount());
+ ErrorOr<InputElement *> nextElement = inputGraph().getNextInputElement();
+ EXPECT_NE(InputGraphError::no_more_elements, error_code(nextElement));
+ EXPECT_EQ(InputElement::Kind::File, (*nextElement)->kind());
+ FileNode *fileNode = llvm::dyn_cast<FileNode>(*nextElement);
+ StringRef path = fileNode->getUserPath();
+ EXPECT_EQ(0, path.compare("file1"));
+ nextElement = inputGraph().getNextInputElement();
+ EXPECT_EQ(InputGraphError::no_more_elements, error_code(nextElement));
+}
+
+TEST_F(InputGraphTest, AddAFileWithLLDFiles) {
+ std::unique_ptr<MyFileNode> myfile(new MyFileNode("multi_files", 0));
+ std::vector<std::unique_ptr<File> > objfiles;
+ std::unique_ptr<MyObjFile> obj1(new MyObjFile(_context, "objfile1"));
+ std::unique_ptr<MyObjFile> obj2(new MyObjFile(_context, "objfile2"));
+ objfiles.push_back(std::move(obj1));
+ objfiles.push_back(std::move(obj2));
+ myfile->addFiles(std::move(objfiles));
+ EXPECT_EQ(true, inputGraph().addInputElement(std::move(myfile)));
+ EXPECT_EQ(1, inputFileCount());
+ ErrorOr<InputElement *> nextElement = inputGraph().getNextInputElement();
+ EXPECT_NE(InputGraphError::no_more_elements, error_code(nextElement));
+ EXPECT_EQ(InputElement::Kind::File, (*nextElement)->kind());
+ FileNode *fileNode = llvm::dyn_cast<FileNode>(*nextElement);
+
+ StringRef path = fileNode->getUserPath();
+ EXPECT_EQ(0, path.compare("multi_files"));
+
+ ErrorOr<File &> objfile = fileNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile1", (*objfile).path());
+
+ objfile = fileNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile2", (*objfile).path());
+
+ objfile = fileNode->getNextFile();
+ EXPECT_EQ(InputGraphError::no_more_files, error_code(objfile));
+
+ fileNode->resetNextIndex();
+
+ objfile = fileNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile1", (*objfile).path());
+
+ nextElement = inputGraph().getNextInputElement();
+ EXPECT_EQ(InputGraphError::no_more_elements, error_code(nextElement));
+}
+
+TEST_F(InputGraphTest, AddNodeWithFilesAndGroup) {
+ std::unique_ptr<MyFileNode> myfile(new MyFileNode("multi_files1", 0));
+ std::vector<std::unique_ptr<File> > objfiles;
+ std::unique_ptr<MyObjFile> obj1(new MyObjFile(_context, "objfile1"));
+ std::unique_ptr<MyObjFile> obj2(new MyObjFile(_context, "objfile2"));
+ objfiles.push_back(std::move(obj1));
+ objfiles.push_back(std::move(obj2));
+ myfile->addFiles(std::move(objfiles));
+ EXPECT_EQ(true, inputGraph().addInputElement(std::move(myfile)));
+
+ // Create a group node with two elements
+ // an file node which looks like an archive and
+ // two file nodes
+ std::unique_ptr<MyGroupNode> mygroup(new MyGroupNode(1));
+ std::unique_ptr<MyFileNode> myarchive(new MyFileNode("archive_file", 2));
+ std::vector<std::unique_ptr<File> > objfiles_group;
+ std::unique_ptr<MyObjFile> obj_1(new MyObjFile(_context, "objfile_1"));
+ std::unique_ptr<MyObjFile> obj_2(new MyObjFile(_context, "objfile_2"));
+ objfiles_group.push_back(std::move(obj_1));
+ objfiles_group.push_back(std::move(obj_2));
+ myarchive->addFiles(std::move(objfiles_group));
+ EXPECT_EQ(true, mygroup->processInputElement(std::move(myarchive)));
+
+ std::unique_ptr<MyFileNode> mygroupobjfile_1(
+ new MyFileNode("group_objfile1", 3));
+ std::vector<std::unique_ptr<File> > objfiles_group1;
+ std::unique_ptr<MyObjFile> mygroupobj1(
+ new MyObjFile(_context, "group_objfile1"));
+ objfiles_group1.push_back(std::move(mygroupobj1));
+ mygroupobjfile_1->addFiles(std::move(objfiles_group1));
+ EXPECT_EQ(true, mygroup->processInputElement(std::move(mygroupobjfile_1)));
+
+ std::unique_ptr<MyFileNode> mygroupobjfile_2(
+ new MyFileNode("group_objfile2", 4));
+ std::vector<std::unique_ptr<File> > objfiles_group2;
+ std::unique_ptr<MyObjFile> mygroupobj2(
+ new MyObjFile(_context, "group_objfile2"));
+ objfiles_group2.push_back(std::move(mygroupobj2));
+ mygroupobjfile_2->addFiles(std::move(objfiles_group2));
+ EXPECT_EQ(true, mygroup->processInputElement(std::move(mygroupobjfile_2)));
+
+ // Add the group to the InputGraph.
+ EXPECT_EQ(true, inputGraph().addInputElement(std::move(mygroup)));
+
+ EXPECT_EQ(2, inputFileCount());
+
+ ErrorOr<InputElement *> nextElement = inputGraph().getNextInputElement();
+ EXPECT_NE(InputGraphError::no_more_elements, error_code(nextElement));
+ EXPECT_EQ(InputElement::Kind::File, (*nextElement)->kind());
+ FileNode *fileNode = llvm::dyn_cast<FileNode>(*nextElement);
+
+ StringRef path = fileNode->getUserPath();
+ EXPECT_EQ(0, path.compare("multi_files1"));
+
+ ErrorOr<File &> objfile = fileNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile1", (*objfile).path());
+
+ objfile = fileNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile2", (*objfile).path());
+
+ objfile = fileNode->getNextFile();
+ EXPECT_EQ(InputGraphError::no_more_files, error_code(objfile));
+
+ nextElement = inputGraph().getNextInputElement();
+ EXPECT_EQ(InputElement::Kind::Control, (*nextElement)->kind());
+ ControlNode *controlNode = llvm::dyn_cast<ControlNode>(*nextElement);
+
+ EXPECT_EQ(ControlNode::ControlKind::Group, controlNode->controlKind());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile_1", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile_2", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("group_objfile1", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("group_objfile2", (*objfile).path());
+
+ nextElement = inputGraph().getNextInputElement();
+ EXPECT_EQ(InputGraphError::no_more_elements, error_code(nextElement));
+}
+
+// Iterate through the group
+TEST_F(InputGraphTest, AddNodeWithGroupIteration) {
+ std::unique_ptr<MyFileNode> myfile(new MyFileNode("multi_files1", 0));
+ std::vector<std::unique_ptr<File> > objfiles;
+ std::unique_ptr<MyObjFile> obj1(new MyObjFile(_context, "objfile1"));
+ std::unique_ptr<MyObjFile> obj2(new MyObjFile(_context, "objfile2"));
+ objfiles.push_back(std::move(obj1));
+ objfiles.push_back(std::move(obj2));
+ myfile->addFiles(std::move(objfiles));
+ EXPECT_EQ(true, inputGraph().addInputElement(std::move(myfile)));
+
+ // Create a group node with two elements
+ // an file node which looks like an archive and
+ // two file nodes
+ std::unique_ptr<MyGroupNode> mygroup(new MyGroupNode(1));
+ std::unique_ptr<MyFileNode> myarchive(new MyFileNode("archive_file", 2));
+ std::vector<std::unique_ptr<File> > objfiles_group;
+ std::unique_ptr<MyObjFile> obj_1(new MyObjFile(_context, "objfile_1"));
+ std::unique_ptr<MyObjFile> obj_2(new MyObjFile(_context, "objfile_2"));
+ objfiles_group.push_back(std::move(obj_1));
+ objfiles_group.push_back(std::move(obj_2));
+ myarchive->addFiles(std::move(objfiles_group));
+ EXPECT_EQ(true, mygroup->processInputElement(std::move(myarchive)));
+
+ std::unique_ptr<MyFileNode> mygroupobjfile_1(
+ new MyFileNode("group_objfile1", 3));
+ std::vector<std::unique_ptr<File> > objfiles_group1;
+ std::unique_ptr<MyObjFile> mygroupobj1(
+ new MyObjFile(_context, "group_objfile1"));
+ objfiles_group1.push_back(std::move(mygroupobj1));
+ mygroupobjfile_1->addFiles(std::move(objfiles_group1));
+ EXPECT_EQ(true, mygroup->processInputElement(std::move(mygroupobjfile_1)));
+
+ std::unique_ptr<MyFileNode> mygroupobjfile_2(
+ new MyFileNode("group_objfile2", 4));
+ std::vector<std::unique_ptr<File> > objfiles_group2;
+ std::unique_ptr<MyObjFile> mygroupobj2(
+ new MyObjFile(_context, "group_objfile2"));
+ objfiles_group2.push_back(std::move(mygroupobj2));
+ mygroupobjfile_2->addFiles(std::move(objfiles_group2));
+ EXPECT_EQ(true, mygroup->processInputElement(std::move(mygroupobjfile_2)));
+
+ // Add the group to the InputGraph.
+ EXPECT_EQ(true, inputGraph().addInputElement(std::move(mygroup)));
+
+ EXPECT_EQ(2, inputFileCount());
+
+ ErrorOr<InputElement *> nextElement = inputGraph().getNextInputElement();
+ EXPECT_NE(InputGraphError::no_more_elements, error_code(nextElement));
+ EXPECT_EQ(InputElement::Kind::File, (*nextElement)->kind());
+ FileNode *fileNode = llvm::dyn_cast<FileNode>(*nextElement);
+
+ StringRef path = fileNode->getUserPath();
+ EXPECT_EQ(0, path.compare("multi_files1"));
+
+ ErrorOr<File &> objfile = fileNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile1", (*objfile).path());
+
+ objfile = fileNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile2", (*objfile).path());
+
+ objfile = fileNode->getNextFile();
+ EXPECT_EQ(InputGraphError::no_more_files, error_code(objfile));
+
+ nextElement = inputGraph().getNextInputElement();
+ EXPECT_EQ(InputElement::Kind::Control, (*nextElement)->kind());
+ ControlNode *controlNode = llvm::dyn_cast<ControlNode>(*nextElement);
+
+ EXPECT_EQ(ControlNode::ControlKind::Group, controlNode->controlKind());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile_1", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile_2", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("group_objfile1", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("group_objfile2", (*objfile).path());
+
+ controlNode->setResolveState(Resolver::StateNewDefinedAtoms);
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile_1", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("objfile_2", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("group_objfile1", (*objfile).path());
+
+ objfile = controlNode->getNextFile();
+ EXPECT_NE(InputGraphError::no_more_files, error_code(objfile));
+ EXPECT_EQ("group_objfile2", (*objfile).path());
+}
+}
More information about the llvm-commits
mailing list