1c6b2b784SKirill Bobyrev //===--- MarshallingTests.cpp ------------------------------------*- C++-*-===//
2c6b2b784SKirill Bobyrev //
3c6b2b784SKirill Bobyrev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c6b2b784SKirill Bobyrev // See https://llvm.org/LICENSE.txt for license information.
5c6b2b784SKirill Bobyrev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c6b2b784SKirill Bobyrev //
7c6b2b784SKirill Bobyrev //===----------------------------------------------------------------------===//
8c6b2b784SKirill Bobyrev
9c6b2b784SKirill Bobyrev #include "../TestTU.h"
10fb5588b0SKirill Bobyrev #include "Index.pb.h"
1193bb9944SKirill Bobyrev #include "TestFS.h"
1293bb9944SKirill Bobyrev #include "index/Index.h"
1393bb9944SKirill Bobyrev #include "index/Ref.h"
14a262f0feSKirill Bobyrev #include "index/Relation.h"
15c6b2b784SKirill Bobyrev #include "index/Serialization.h"
1693bb9944SKirill Bobyrev #include "index/Symbol.h"
1793bb9944SKirill Bobyrev #include "index/SymbolID.h"
18eef162c3SKirill Bobyrev #include "index/SymbolLocation.h"
194169c520SKirill Bobyrev #include "index/SymbolOrigin.h"
20c6b2b784SKirill Bobyrev #include "index/remote/marshalling/Marshalling.h"
2193bb9944SKirill Bobyrev #include "clang/Index/IndexSymbol.h"
2293bb9944SKirill Bobyrev #include "llvm/ADT/SmallString.h"
2393bb9944SKirill Bobyrev #include "llvm/ADT/StringRef.h"
24a262f0feSKirill Bobyrev #include "llvm/ADT/Twine.h"
25f49a7ad8SKirill Bobyrev #include "llvm/Support/Error.h"
2693bb9944SKirill Bobyrev #include "llvm/Support/Path.h"
27c6b2b784SKirill Bobyrev #include "llvm/Support/StringSaver.h"
2893bb9944SKirill Bobyrev #include "gmock/gmock.h"
29c6b2b784SKirill Bobyrev #include "gtest/gtest.h"
3093bb9944SKirill Bobyrev #include <cstring>
31c6b2b784SKirill Bobyrev
32c6b2b784SKirill Bobyrev namespace clang {
33c6b2b784SKirill Bobyrev namespace clangd {
34c6b2b784SKirill Bobyrev namespace remote {
35c6b2b784SKirill Bobyrev namespace {
36c6b2b784SKirill Bobyrev
3793bb9944SKirill Bobyrev using llvm::sys::path::convert_to_slash;
3893bb9944SKirill Bobyrev
testPathURI(llvm::StringRef Path,llvm::UniqueStringSaver & Strings)3993bb9944SKirill Bobyrev const char *testPathURI(llvm::StringRef Path,
4093bb9944SKirill Bobyrev llvm::UniqueStringSaver &Strings) {
4193bb9944SKirill Bobyrev auto URI = URI::createFile(testPath(Path));
4293bb9944SKirill Bobyrev return Strings.save(URI.toString()).begin();
4393bb9944SKirill Bobyrev }
4493bb9944SKirill Bobyrev
createSymbol(llvm::StringRef PathPrefix,llvm::UniqueStringSaver & Strings)45a262f0feSKirill Bobyrev clangd::Symbol createSymbol(llvm::StringRef PathPrefix,
46a262f0feSKirill Bobyrev llvm::UniqueStringSaver &Strings) {
47a262f0feSKirill Bobyrev clangd::Symbol Sym;
48a262f0feSKirill Bobyrev Sym.ID = llvm::cantFail(SymbolID::fromStr("057557CEBF6E6B2D"));
49a262f0feSKirill Bobyrev
50a262f0feSKirill Bobyrev index::SymbolInfo Info;
51a262f0feSKirill Bobyrev Info.Kind = index::SymbolKind::Function;
52a262f0feSKirill Bobyrev Info.SubKind = index::SymbolSubKind::AccessorGetter;
53a262f0feSKirill Bobyrev Info.Lang = index::SymbolLanguage::CXX;
54a262f0feSKirill Bobyrev Info.Properties = static_cast<index::SymbolPropertySet>(
55a262f0feSKirill Bobyrev index::SymbolProperty::TemplateSpecialization);
56a262f0feSKirill Bobyrev Sym.SymInfo = Info;
57a262f0feSKirill Bobyrev
58a262f0feSKirill Bobyrev Sym.Name = Strings.save("Foo");
59a262f0feSKirill Bobyrev Sym.Scope = Strings.save("llvm::foo::bar::");
60a262f0feSKirill Bobyrev
61a262f0feSKirill Bobyrev clangd::SymbolLocation Location;
62a262f0feSKirill Bobyrev Location.Start.setLine(1);
63a262f0feSKirill Bobyrev Location.Start.setColumn(15);
64a262f0feSKirill Bobyrev Location.End.setLine(3);
65a262f0feSKirill Bobyrev Location.End.setColumn(121);
66a262f0feSKirill Bobyrev Location.FileURI = testPathURI(PathPrefix.str() + "Definition.cpp", Strings);
67a262f0feSKirill Bobyrev Sym.Definition = Location;
68a262f0feSKirill Bobyrev
69a262f0feSKirill Bobyrev Location.Start.setLine(42);
70a262f0feSKirill Bobyrev Location.Start.setColumn(31);
71a262f0feSKirill Bobyrev Location.End.setLine(20);
72a262f0feSKirill Bobyrev Location.End.setColumn(400);
73a262f0feSKirill Bobyrev Location.FileURI = testPathURI(PathPrefix.str() + "Declaration.h", Strings);
74a262f0feSKirill Bobyrev Sym.CanonicalDeclaration = Location;
75a262f0feSKirill Bobyrev
76a262f0feSKirill Bobyrev Sym.References = 9000;
77a262f0feSKirill Bobyrev Sym.Origin = clangd::SymbolOrigin::Static;
78a262f0feSKirill Bobyrev Sym.Signature = Strings.save("(int X, char Y, Type T)");
79a262f0feSKirill Bobyrev Sym.TemplateSpecializationArgs = Strings.save("<int, char, bool, Type>");
80a262f0feSKirill Bobyrev Sym.CompletionSnippetSuffix =
81a262f0feSKirill Bobyrev Strings.save("({1: int X}, {2: char Y}, {3: Type T})");
82a262f0feSKirill Bobyrev Sym.Documentation = Strings.save("This is my amazing Foo constructor!");
83a262f0feSKirill Bobyrev Sym.ReturnType = Strings.save("Foo");
84a262f0feSKirill Bobyrev
85a262f0feSKirill Bobyrev Sym.Flags = clangd::Symbol::SymbolFlag::IndexedForCodeCompletion;
86a262f0feSKirill Bobyrev
87a262f0feSKirill Bobyrev return Sym;
88a262f0feSKirill Bobyrev }
89a262f0feSKirill Bobyrev
TEST(RemoteMarshallingTest,URITranslation)9093bb9944SKirill Bobyrev TEST(RemoteMarshallingTest, URITranslation) {
9193bb9944SKirill Bobyrev llvm::BumpPtrAllocator Arena;
9293bb9944SKirill Bobyrev llvm::UniqueStringSaver Strings(Arena);
93eef162c3SKirill Bobyrev Marshaller ProtobufMarshaller(
94eef162c3SKirill Bobyrev testPath("remote/machine/projects/llvm-project/"),
95eef162c3SKirill Bobyrev testPath("home/my-projects/llvm-project/"));
9693bb9944SKirill Bobyrev clangd::Ref Original;
9793bb9944SKirill Bobyrev Original.Location.FileURI =
9893bb9944SKirill Bobyrev testPathURI("remote/machine/projects/llvm-project/clang-tools-extra/"
9993bb9944SKirill Bobyrev "clangd/unittests/remote/MarshallingTests.cpp",
10093bb9944SKirill Bobyrev Strings);
101eef162c3SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Original);
102fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
103eef162c3SKirill Bobyrev EXPECT_EQ(Serialized->location().file_path(),
10493bb9944SKirill Bobyrev "clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp");
105eef162c3SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
106fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
107eef162c3SKirill Bobyrev EXPECT_STREQ(Deserialized->Location.FileURI,
10893bb9944SKirill Bobyrev testPathURI("home/my-projects/llvm-project/clang-tools-extra/"
10993bb9944SKirill Bobyrev "clangd/unittests/remote/MarshallingTests.cpp",
11093bb9944SKirill Bobyrev Strings));
11193bb9944SKirill Bobyrev
112eef162c3SKirill Bobyrev // Can't have empty paths.
113eef162c3SKirill Bobyrev *Serialized->mutable_location()->mutable_file_path() = std::string();
114fb5588b0SKirill Bobyrev Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
115fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Deserialized));
116fb5588b0SKirill Bobyrev llvm::consumeError(Deserialized.takeError());
117eef162c3SKirill Bobyrev
11893bb9944SKirill Bobyrev clangd::Ref WithInvalidURI;
119eef162c3SKirill Bobyrev // Invalid URI results in serialization failure.
12093bb9944SKirill Bobyrev WithInvalidURI.Location.FileURI = "This is not a URI";
121fb5588b0SKirill Bobyrev auto DeserializedRef = ProtobufMarshaller.toProtobuf(WithInvalidURI);
122fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(DeserializedRef));
123fb5588b0SKirill Bobyrev llvm::consumeError(DeserializedRef.takeError());
12493bb9944SKirill Bobyrev
12593bb9944SKirill Bobyrev // Can not use URIs with scheme different from "file".
12693bb9944SKirill Bobyrev auto UnittestURI =
12793bb9944SKirill Bobyrev URI::create(testPath("project/lib/HelloWorld.cpp"), "unittest");
128974ffee9SKirill Bobyrev ASSERT_TRUE(bool(UnittestURI));
12993bb9944SKirill Bobyrev WithInvalidURI.Location.FileURI =
13093bb9944SKirill Bobyrev Strings.save(UnittestURI->toString()).begin();
131fb5588b0SKirill Bobyrev auto DeserializedSymbol = ProtobufMarshaller.toProtobuf(WithInvalidURI);
132fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(DeserializedSymbol));
133fb5588b0SKirill Bobyrev llvm::consumeError(DeserializedSymbol.takeError());
13493bb9944SKirill Bobyrev
135eef162c3SKirill Bobyrev // Paths transmitted over the wire can not be absolute, they have to be
136eef162c3SKirill Bobyrev // relative.
137ce63383eSSam McCall Ref WithAbsolutePath;
13893bb9944SKirill Bobyrev *WithAbsolutePath.mutable_location()->mutable_file_path() =
13993bb9944SKirill Bobyrev "/usr/local/user/home/HelloWorld.cpp";
140fb5588b0SKirill Bobyrev Deserialized = ProtobufMarshaller.fromProtobuf(WithAbsolutePath);
141fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Deserialized));
142fb5588b0SKirill Bobyrev llvm::consumeError(Deserialized.takeError());
14393bb9944SKirill Bobyrev }
14493bb9944SKirill Bobyrev
TEST(RemoteMarshallingTest,SymbolSerialization)145c6b2b784SKirill Bobyrev TEST(RemoteMarshallingTest, SymbolSerialization) {
146c6b2b784SKirill Bobyrev llvm::BumpPtrAllocator Arena;
147c6b2b784SKirill Bobyrev llvm::UniqueStringSaver Strings(Arena);
14893bb9944SKirill Bobyrev
149a262f0feSKirill Bobyrev clangd::Symbol Sym = createSymbol("home/", Strings);
150eef162c3SKirill Bobyrev Marshaller ProtobufMarshaller(testPath("home/"), testPath("home/"));
151eef162c3SKirill Bobyrev
15293bb9944SKirill Bobyrev // Check that symbols are exactly the same if the path to indexed project is
15393bb9944SKirill Bobyrev // the same on indexing machine and the client.
154eef162c3SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Sym);
155fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
156eef162c3SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
157fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
1584169c520SKirill Bobyrev // Origin is overwritten when deserializing.
1594169c520SKirill Bobyrev Sym.Origin = SymbolOrigin::Remote;
16093bb9944SKirill Bobyrev EXPECT_EQ(toYAML(Sym), toYAML(*Deserialized));
16193bb9944SKirill Bobyrev // Serialized paths are relative and have UNIX slashes.
162eef162c3SKirill Bobyrev EXPECT_EQ(convert_to_slash(Serialized->definition().file_path(),
16393bb9944SKirill Bobyrev llvm::sys::path::Style::posix),
164eef162c3SKirill Bobyrev Serialized->definition().file_path());
16593bb9944SKirill Bobyrev EXPECT_TRUE(
166eef162c3SKirill Bobyrev llvm::sys::path::is_relative(Serialized->definition().file_path()));
167eef162c3SKirill Bobyrev
168eef162c3SKirill Bobyrev // Missing definition is OK.
169eef162c3SKirill Bobyrev Sym.Definition = clangd::SymbolLocation();
170eef162c3SKirill Bobyrev Serialized = ProtobufMarshaller.toProtobuf(Sym);
171fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
172fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(ProtobufMarshaller.fromProtobuf(*Serialized)));
173eef162c3SKirill Bobyrev
174eef162c3SKirill Bobyrev // Relative path is absolute.
175eef162c3SKirill Bobyrev *Serialized->mutable_canonical_declaration()->mutable_file_path() =
176eef162c3SKirill Bobyrev convert_to_slash("/path/to/Declaration.h");
177fb5588b0SKirill Bobyrev Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
178fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Deserialized));
179fb5588b0SKirill Bobyrev llvm::consumeError(Deserialized.takeError());
18093bb9944SKirill Bobyrev
18193bb9944SKirill Bobyrev // Fail with an invalid URI.
182a262f0feSKirill Bobyrev Sym.Definition.FileURI = "Not A URI";
183fb5588b0SKirill Bobyrev Serialized = ProtobufMarshaller.toProtobuf(Sym);
184fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Serialized));
185fb5588b0SKirill Bobyrev llvm::consumeError(Serialized.takeError());
18693bb9944SKirill Bobyrev
18793bb9944SKirill Bobyrev // Schemes other than "file" can not be used.
18893bb9944SKirill Bobyrev auto UnittestURI = URI::create(testPath("home/SomePath.h"), "unittest");
189974ffee9SKirill Bobyrev ASSERT_TRUE(bool(UnittestURI));
190a262f0feSKirill Bobyrev Sym.Definition.FileURI = Strings.save(UnittestURI->toString()).begin();
191fb5588b0SKirill Bobyrev Serialized = ProtobufMarshaller.toProtobuf(Sym);
192fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Serialized));
193fb5588b0SKirill Bobyrev llvm::consumeError(Serialized.takeError());
19493bb9944SKirill Bobyrev
19593bb9944SKirill Bobyrev // Passing root that is not prefix of the original file path.
196a262f0feSKirill Bobyrev Sym.Definition.FileURI = testPathURI("home/File.h", Strings);
19793bb9944SKirill Bobyrev // Check that the symbol is valid and passing the correct path works.
198eef162c3SKirill Bobyrev Serialized = ProtobufMarshaller.toProtobuf(Sym);
199fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
200eef162c3SKirill Bobyrev Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
201fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
202eef162c3SKirill Bobyrev EXPECT_STREQ(Deserialized->Definition.FileURI,
20393bb9944SKirill Bobyrev testPathURI("home/File.h", Strings));
20493bb9944SKirill Bobyrev // Fail with a wrong root.
205eef162c3SKirill Bobyrev Marshaller WrongMarshaller(testPath("nothome/"), testPath("home/"));
206fb5588b0SKirill Bobyrev Serialized = WrongMarshaller.toProtobuf(Sym);
207fb5588b0SKirill Bobyrev EXPECT_FALSE(Serialized);
208fb5588b0SKirill Bobyrev llvm::consumeError(Serialized.takeError());
209c6b2b784SKirill Bobyrev }
210c6b2b784SKirill Bobyrev
TEST(RemoteMarshallingTest,RefSerialization)21193bb9944SKirill Bobyrev TEST(RemoteMarshallingTest, RefSerialization) {
21293bb9944SKirill Bobyrev clangd::Ref Ref;
21393bb9944SKirill Bobyrev Ref.Kind = clangd::RefKind::Spelled | clangd::RefKind::Declaration;
214c6b2b784SKirill Bobyrev
215c6b2b784SKirill Bobyrev llvm::BumpPtrAllocator Arena;
216c6b2b784SKirill Bobyrev llvm::UniqueStringSaver Strings(Arena);
21793bb9944SKirill Bobyrev
21893bb9944SKirill Bobyrev clangd::SymbolLocation Location;
21993bb9944SKirill Bobyrev Location.Start.setLine(124);
22093bb9944SKirill Bobyrev Location.Start.setColumn(21);
22193bb9944SKirill Bobyrev Location.End.setLine(3213);
22293bb9944SKirill Bobyrev Location.End.setColumn(541);
22393bb9944SKirill Bobyrev Location.FileURI = testPathURI(
22493bb9944SKirill Bobyrev "llvm-project/llvm/clang-tools-extra/clangd/Protocol.h", Strings);
22593bb9944SKirill Bobyrev Ref.Location = Location;
22693bb9944SKirill Bobyrev
227eef162c3SKirill Bobyrev Marshaller ProtobufMarshaller(testPath("llvm-project/"),
228eef162c3SKirill Bobyrev testPath("llvm-project/"));
229eef162c3SKirill Bobyrev
230eef162c3SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Ref);
231fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
232eef162c3SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
233fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
23493bb9944SKirill Bobyrev EXPECT_EQ(toYAML(Ref), toYAML(*Deserialized));
235c6b2b784SKirill Bobyrev }
23693bb9944SKirill Bobyrev
TEST(RemoteMarshallingTest,IncludeHeaderURIs)23793bb9944SKirill Bobyrev TEST(RemoteMarshallingTest, IncludeHeaderURIs) {
23893bb9944SKirill Bobyrev llvm::BumpPtrAllocator Arena;
23993bb9944SKirill Bobyrev llvm::UniqueStringSaver Strings(Arena);
24093bb9944SKirill Bobyrev
241fb5588b0SKirill Bobyrev clangd::Symbol Sym = createSymbol("remote/", Strings);
242fb5588b0SKirill Bobyrev
24393bb9944SKirill Bobyrev clangd::Symbol::IncludeHeaderWithReferences Header;
244fb5588b0SKirill Bobyrev // Add only valid headers.
245d99b2a97SAleksandr Platonov Header.IncludeHeader =
246d99b2a97SAleksandr Platonov Strings.save(URI::createFile(testPath("project/Header.h")).toString());
24793bb9944SKirill Bobyrev Header.References = 21;
248fb5588b0SKirill Bobyrev Sym.IncludeHeaders.push_back(Header);
24993bb9944SKirill Bobyrev Header.IncludeHeader = Strings.save("<iostream>");
25093bb9944SKirill Bobyrev Header.References = 100;
251fb5588b0SKirill Bobyrev Sym.IncludeHeaders.push_back(Header);
25293bb9944SKirill Bobyrev Header.IncludeHeader = Strings.save("\"cstdio\"");
25393bb9944SKirill Bobyrev Header.References = 200;
254fb5588b0SKirill Bobyrev Sym.IncludeHeaders.push_back(Header);
25593bb9944SKirill Bobyrev
256d99b2a97SAleksandr Platonov Marshaller ProtobufMarshaller(testPath(""), testPath(""));
257eef162c3SKirill Bobyrev
258eef162c3SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Sym);
259fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
260eef162c3SKirill Bobyrev EXPECT_EQ(static_cast<size_t>(Serialized->headers_size()),
261fb5588b0SKirill Bobyrev Sym.IncludeHeaders.size());
262eef162c3SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
263fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
2644169c520SKirill Bobyrev Sym.Origin = SymbolOrigin::Remote;
26593bb9944SKirill Bobyrev EXPECT_EQ(toYAML(Sym), toYAML(*Deserialized));
266fb5588b0SKirill Bobyrev
267fb5588b0SKirill Bobyrev // This is an absolute path to a header: can not be transmitted over the wire.
268fb5588b0SKirill Bobyrev Header.IncludeHeader = Strings.save(testPath("project/include/Common.h"));
269fb5588b0SKirill Bobyrev Header.References = 42;
270fb5588b0SKirill Bobyrev Sym.IncludeHeaders.push_back(Header);
271fb5588b0SKirill Bobyrev Serialized = ProtobufMarshaller.toProtobuf(Sym);
272fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Serialized));
273fb5588b0SKirill Bobyrev llvm::consumeError(Serialized.takeError());
274fb5588b0SKirill Bobyrev
275fb5588b0SKirill Bobyrev // Remove last invalid header.
276fb5588b0SKirill Bobyrev Sym.IncludeHeaders.pop_back();
277fb5588b0SKirill Bobyrev // This is not a valid header: can not be transmitted over the wire;
278fb5588b0SKirill Bobyrev Header.IncludeHeader = Strings.save("NotAHeader");
279fb5588b0SKirill Bobyrev Header.References = 5;
280fb5588b0SKirill Bobyrev Sym.IncludeHeaders.push_back(Header);
281fb5588b0SKirill Bobyrev Serialized = ProtobufMarshaller.toProtobuf(Sym);
282fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Serialized));
283fb5588b0SKirill Bobyrev llvm::consumeError(Serialized.takeError());
284fb5588b0SKirill Bobyrev
285fb5588b0SKirill Bobyrev // Try putting an invalid header into already serialized symbol.
286fb5588b0SKirill Bobyrev Sym.IncludeHeaders.pop_back();
287fb5588b0SKirill Bobyrev Serialized = ProtobufMarshaller.toProtobuf(Sym);
288fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
289ce63383eSSam McCall HeaderWithReferences InvalidHeader;
290fb5588b0SKirill Bobyrev InvalidHeader.set_header(convert_to_slash("/absolute/path/Header.h"));
291fb5588b0SKirill Bobyrev InvalidHeader.set_references(9000);
292fb5588b0SKirill Bobyrev *Serialized->add_headers() = InvalidHeader;
293fb5588b0SKirill Bobyrev Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
294fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Deserialized));
295fb5588b0SKirill Bobyrev llvm::consumeError(Deserialized.takeError());
296c6b2b784SKirill Bobyrev }
29793bb9944SKirill Bobyrev
TEST(RemoteMarshallingTest,LookupRequestSerialization)298f49a7ad8SKirill Bobyrev TEST(RemoteMarshallingTest, LookupRequestSerialization) {
299f49a7ad8SKirill Bobyrev clangd::LookupRequest Request;
300f49a7ad8SKirill Bobyrev Request.IDs.insert(llvm::cantFail(SymbolID::fromStr("0000000000000001")));
301f49a7ad8SKirill Bobyrev Request.IDs.insert(llvm::cantFail(SymbolID::fromStr("0000000000000002")));
302f49a7ad8SKirill Bobyrev
303f49a7ad8SKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
304f49a7ad8SKirill Bobyrev
305f49a7ad8SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Request);
306f49a7ad8SKirill Bobyrev EXPECT_EQ(static_cast<unsigned>(Serialized.ids_size()), Request.IDs.size());
307f49a7ad8SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized);
308f49a7ad8SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
309f49a7ad8SKirill Bobyrev EXPECT_EQ(Deserialized->IDs, Request.IDs);
310f49a7ad8SKirill Bobyrev }
311f49a7ad8SKirill Bobyrev
TEST(RemoteMarshallingTest,LookupRequestFailingSerialization)312f49a7ad8SKirill Bobyrev TEST(RemoteMarshallingTest, LookupRequestFailingSerialization) {
313f49a7ad8SKirill Bobyrev clangd::LookupRequest Request;
314f49a7ad8SKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
315f49a7ad8SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Request);
316f49a7ad8SKirill Bobyrev Serialized.add_ids("Invalid Symbol ID");
317f49a7ad8SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized);
318fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Deserialized));
319f49a7ad8SKirill Bobyrev llvm::consumeError(Deserialized.takeError());
320f49a7ad8SKirill Bobyrev }
321f49a7ad8SKirill Bobyrev
TEST(RemoteMarshallingTest,FuzzyFindRequestSerialization)32293bb9944SKirill Bobyrev TEST(RemoteMarshallingTest, FuzzyFindRequestSerialization) {
32393bb9944SKirill Bobyrev clangd::FuzzyFindRequest Request;
3247d591e12SKirill Bobyrev Request.ProximityPaths = {testPath("local/Header.h"),
3257d591e12SKirill Bobyrev testPath("local/subdir/OtherHeader.h"),
3267d591e12SKirill Bobyrev testPath("remote/File.h"), "Not a Path."};
3277d591e12SKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
328eef162c3SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Request);
32993bb9944SKirill Bobyrev EXPECT_EQ(Serialized.proximity_paths_size(), 2);
330eef162c3SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized);
331f49a7ad8SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
332f49a7ad8SKirill Bobyrev EXPECT_THAT(Deserialized->ProximityPaths,
3337d591e12SKirill Bobyrev testing::ElementsAre(testPath("remote/Header.h"),
3347d591e12SKirill Bobyrev testPath("remote/subdir/OtherHeader.h")));
33593bb9944SKirill Bobyrev }
33693bb9944SKirill Bobyrev
TEST(RemoteMarshallingTest,RefsRequestSerialization)337f49a7ad8SKirill Bobyrev TEST(RemoteMarshallingTest, RefsRequestSerialization) {
338f49a7ad8SKirill Bobyrev clangd::RefsRequest Request;
339f49a7ad8SKirill Bobyrev Request.IDs.insert(llvm::cantFail(SymbolID::fromStr("0000000000000001")));
340f49a7ad8SKirill Bobyrev Request.IDs.insert(llvm::cantFail(SymbolID::fromStr("0000000000000002")));
341f49a7ad8SKirill Bobyrev
342f49a7ad8SKirill Bobyrev Request.Limit = 9000;
343f49a7ad8SKirill Bobyrev Request.Filter = RefKind::Spelled | RefKind::Declaration;
344f49a7ad8SKirill Bobyrev
345f49a7ad8SKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
346f49a7ad8SKirill Bobyrev
347f49a7ad8SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Request);
348f49a7ad8SKirill Bobyrev EXPECT_EQ(static_cast<unsigned>(Serialized.ids_size()), Request.IDs.size());
349f49a7ad8SKirill Bobyrev EXPECT_EQ(Serialized.limit(), Request.Limit);
350f49a7ad8SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized);
351f49a7ad8SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
352f49a7ad8SKirill Bobyrev EXPECT_EQ(Deserialized->IDs, Request.IDs);
353f49a7ad8SKirill Bobyrev ASSERT_TRUE(Deserialized->Limit);
354f49a7ad8SKirill Bobyrev EXPECT_EQ(*Deserialized->Limit, Request.Limit);
355f49a7ad8SKirill Bobyrev EXPECT_EQ(Deserialized->Filter, Request.Filter);
356f49a7ad8SKirill Bobyrev }
357f49a7ad8SKirill Bobyrev
TEST(RemoteMarshallingTest,RefsRequestFailingSerialization)358f49a7ad8SKirill Bobyrev TEST(RemoteMarshallingTest, RefsRequestFailingSerialization) {
359f49a7ad8SKirill Bobyrev clangd::RefsRequest Request;
360f49a7ad8SKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
361f49a7ad8SKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Request);
362f49a7ad8SKirill Bobyrev Serialized.add_ids("Invalid Symbol ID");
363f49a7ad8SKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized);
364fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Deserialized));
365f49a7ad8SKirill Bobyrev llvm::consumeError(Deserialized.takeError());
366f49a7ad8SKirill Bobyrev }
367f49a7ad8SKirill Bobyrev
TEST(RemoteMarshallingTest,RelationsRequestSerialization)368a262f0feSKirill Bobyrev TEST(RemoteMarshallingTest, RelationsRequestSerialization) {
369a262f0feSKirill Bobyrev clangd::RelationsRequest Request;
370a262f0feSKirill Bobyrev Request.Subjects.insert(
371a262f0feSKirill Bobyrev llvm::cantFail(SymbolID::fromStr("0000000000000001")));
372a262f0feSKirill Bobyrev Request.Subjects.insert(
373a262f0feSKirill Bobyrev llvm::cantFail(SymbolID::fromStr("0000000000000002")));
374a262f0feSKirill Bobyrev
375a262f0feSKirill Bobyrev Request.Limit = 9000;
376a262f0feSKirill Bobyrev Request.Predicate = RelationKind::BaseOf;
377a262f0feSKirill Bobyrev
378a262f0feSKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
379a262f0feSKirill Bobyrev
380a262f0feSKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(Request);
381a262f0feSKirill Bobyrev EXPECT_EQ(static_cast<unsigned>(Serialized.subjects_size()),
382a262f0feSKirill Bobyrev Request.Subjects.size());
383a262f0feSKirill Bobyrev EXPECT_EQ(Serialized.limit(), Request.Limit);
384a262f0feSKirill Bobyrev EXPECT_EQ(static_cast<RelationKind>(Serialized.predicate()),
385a262f0feSKirill Bobyrev Request.Predicate);
386a262f0feSKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized);
387a262f0feSKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
388a262f0feSKirill Bobyrev EXPECT_EQ(Deserialized->Subjects, Request.Subjects);
389a262f0feSKirill Bobyrev ASSERT_TRUE(Deserialized->Limit);
390a262f0feSKirill Bobyrev EXPECT_EQ(*Deserialized->Limit, Request.Limit);
391a262f0feSKirill Bobyrev EXPECT_EQ(Deserialized->Predicate, Request.Predicate);
392a262f0feSKirill Bobyrev }
393a262f0feSKirill Bobyrev
TEST(RemoteMarshallingTest,RelationsRequestFailingSerialization)394a262f0feSKirill Bobyrev TEST(RemoteMarshallingTest, RelationsRequestFailingSerialization) {
395ce63383eSSam McCall RelationsRequest Serialized;
396a262f0feSKirill Bobyrev Serialized.add_subjects("ZZZZZZZZZZZZZZZZ");
397a262f0feSKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
398a262f0feSKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(&Serialized);
399fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(Deserialized));
400a262f0feSKirill Bobyrev llvm::consumeError(Deserialized.takeError());
401a262f0feSKirill Bobyrev }
402a262f0feSKirill Bobyrev
TEST(RemoteMarshallingTest,RelationsSerializion)403a262f0feSKirill Bobyrev TEST(RemoteMarshallingTest, RelationsSerializion) {
404a262f0feSKirill Bobyrev llvm::BumpPtrAllocator Arena;
405a262f0feSKirill Bobyrev llvm::UniqueStringSaver Strings(Arena);
406a262f0feSKirill Bobyrev
407a262f0feSKirill Bobyrev clangd::Symbol Sym = createSymbol("remote/", Strings);
408a262f0feSKirill Bobyrev SymbolID ID = llvm::cantFail(SymbolID::fromStr("0000000000000002"));
409a262f0feSKirill Bobyrev Marshaller ProtobufMarshaller(testPath("remote/"), testPath("local/"));
410a262f0feSKirill Bobyrev auto Serialized = ProtobufMarshaller.toProtobuf(ID, Sym);
411fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Serialized));
412a262f0feSKirill Bobyrev auto Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
413fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(Deserialized));
414a262f0feSKirill Bobyrev EXPECT_THAT(Deserialized->first, ID);
415a262f0feSKirill Bobyrev EXPECT_THAT(Deserialized->second.ID, Sym.ID);
416a262f0feSKirill Bobyrev }
417a262f0feSKirill Bobyrev
TEST(RemoteMarshallingTest,RelativePathToURITranslation)41893bb9944SKirill Bobyrev TEST(RemoteMarshallingTest, RelativePathToURITranslation) {
419eef162c3SKirill Bobyrev Marshaller ProtobufMarshaller(/*RemoteIndexRoot=*/"",
420eef162c3SKirill Bobyrev /*LocalIndexRoot=*/testPath("home/project/"));
421fb5588b0SKirill Bobyrev auto URIString = ProtobufMarshaller.relativePathToURI("lib/File.cpp");
422fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(URIString));
42393bb9944SKirill Bobyrev // RelativePath can not be absolute.
424fb5588b0SKirill Bobyrev URIString = ProtobufMarshaller.relativePathToURI("/lib/File.cpp");
425fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(URIString));
426fb5588b0SKirill Bobyrev llvm::consumeError(URIString.takeError());
427eef162c3SKirill Bobyrev // RelativePath can not be empty.
428fb5588b0SKirill Bobyrev URIString = ProtobufMarshaller.relativePathToURI(std::string());
429fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(URIString));
430fb5588b0SKirill Bobyrev llvm::consumeError(URIString.takeError());
43193bb9944SKirill Bobyrev }
43293bb9944SKirill Bobyrev
TEST(RemoteMarshallingTest,URIToRelativePathTranslation)43393bb9944SKirill Bobyrev TEST(RemoteMarshallingTest, URIToRelativePathTranslation) {
43493bb9944SKirill Bobyrev llvm::BumpPtrAllocator Arena;
43593bb9944SKirill Bobyrev llvm::UniqueStringSaver Strings(Arena);
436eef162c3SKirill Bobyrev Marshaller ProtobufMarshaller(/*RemoteIndexRoot=*/testPath("remote/project/"),
437eef162c3SKirill Bobyrev /*LocalIndexRoot=*/"");
438fb5588b0SKirill Bobyrev auto RelativePath = ProtobufMarshaller.uriToRelativePath(
439fb5588b0SKirill Bobyrev testPathURI("remote/project/lib/File.cpp", Strings));
440fb5588b0SKirill Bobyrev ASSERT_TRUE(bool(RelativePath));
441*c8f47925SRageking8 // RemoteIndexRoot has to be a prefix of the file path.
442eef162c3SKirill Bobyrev Marshaller WrongMarshaller(
443eef162c3SKirill Bobyrev /*RemoteIndexRoot=*/testPath("remote/other/project/"),
444eef162c3SKirill Bobyrev /*LocalIndexRoot=*/"");
445fb5588b0SKirill Bobyrev RelativePath = WrongMarshaller.uriToRelativePath(
446fb5588b0SKirill Bobyrev testPathURI("remote/project/lib/File.cpp", Strings));
447fb5588b0SKirill Bobyrev EXPECT_FALSE(bool(RelativePath));
448fb5588b0SKirill Bobyrev llvm::consumeError(RelativePath.takeError());
44993bb9944SKirill Bobyrev }
450c6b2b784SKirill Bobyrev
451c6b2b784SKirill Bobyrev } // namespace
452c6b2b784SKirill Bobyrev } // namespace remote
453c6b2b784SKirill Bobyrev } // namespace clangd
454c6b2b784SKirill Bobyrev } // namespace clang
455