xref: /aosp_15_r20/external/grpc-grpc/src/csharp/Grpc.Tools.Tests/DepFileUtilTest.cs (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 #region Copyright notice and license
2 
3 // Copyright 2018 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #endregion
18 
19 using System.IO;
20 using Microsoft.Build.Framework;
21 using Microsoft.Build.Utilities;
22 using NUnit.Framework;
23 
24 namespace Grpc.Tools.Tests
25 {
26     public class DepFileUtilTest
27     {
28 
29         [Test]
HashString64Hex_IsSane()30         public void HashString64Hex_IsSane()
31         {
32             string hashFoo1 = DepFileUtil.HashString64Hex("foo");
33             string hashEmpty = DepFileUtil.HashString64Hex("");
34             string hashFoo2 = DepFileUtil.HashString64Hex("foo");
35 
36             StringAssert.IsMatch("^[a-f0-9]{16}$", hashFoo1);
37             Assert.AreEqual(hashFoo1, hashFoo2);
38             Assert.AreNotEqual(hashFoo1, hashEmpty);
39         }
40 
41         [Test]
GetDepFilenameForProto_IsSane()42         public void GetDepFilenameForProto_IsSane()
43         {
44             StringAssert.IsMatch(@"^out[\\/][a-f0-9]{16}_foo.protodep$",
45                 DepFileUtil.GetDepFilenameForProto("out", "foo.proto"));
46             StringAssert.IsMatch(@"^[a-f0-9]{16}_foo.protodep$",
47                 DepFileUtil.GetDepFilenameForProto("", "foo.proto"));
48         }
49 
50         [Test]
GetDepFilenameForProto_HashesDir()51         public void GetDepFilenameForProto_HashesDir()
52         {
53             string PickHash(string fname) =>
54                 DepFileUtil.GetDepFilenameForProto("", fname).Substring(0, 16);
55 
56             string same1 = PickHash("dir1/dir2/foo.proto");
57             string same2 = PickHash("dir1/dir2/proto.foo");
58             string same3 = PickHash("dir1/dir2/proto");
59             string same4 = PickHash("dir1/dir2/.proto");
60             string unsame1 = PickHash("dir2/foo.proto");
61             string unsame2 = PickHash("/dir2/foo.proto");
62 
63             Assert.AreEqual(same1, same2);
64             Assert.AreEqual(same1, same3);
65             Assert.AreEqual(same1, same4);
66             Assert.AreNotEqual(same1, unsame1);
67             Assert.AreNotEqual(unsame1, unsame2);
68         }
69 
70         [Test]
GetOutputDirWithHash_IsSane()71         public void GetOutputDirWithHash_IsSane()
72         {
73             StringAssert.IsMatch(@"^out[\\/][a-f0-9]{16}$",
74                 DepFileUtil.GetOutputDirWithHash("out", "foo.proto"));
75             StringAssert.IsMatch(@"^[a-f0-9]{16}$",
76                 DepFileUtil.GetOutputDirWithHash("", "foo.proto"));
77         }
78 
79         [Test]
GetOutputDirWithHash_HashesDir()80         public void GetOutputDirWithHash_HashesDir()
81         {
82             string PickHash(string fname) => DepFileUtil.GetOutputDirWithHash("", fname);
83 
84             string same1 = PickHash("dir1/dir2/foo.proto");
85             string same2 = PickHash("dir1/dir2/proto.foo");
86             string same3 = PickHash("dir1/dir2/proto");
87             string same4 = PickHash("dir1/dir2/.proto");
88             string unsame1 = PickHash("dir2/foo.proto");
89             string unsame2 = PickHash("/dir2/foo.proto");
90 
91             Assert.AreEqual(same1, same2);
92             Assert.AreEqual(same1, same3);
93             Assert.AreEqual(same1, same4);
94             Assert.AreNotEqual(same1, unsame1);
95             Assert.AreNotEqual(unsame1, unsame2);
96         }
97 
98         //////////////////////////////////////////////////////////////////////////
99         // Full file reading tests
100 
101         // Generated by protoc on Windows. Slashes vary.
102         const string depFile1 =
103     @"C:\projects\foo\src\./foo.grpc.pb.cc \
104 C:\projects\foo\src\./foo.grpc.pb.h \
105 C:\projects\foo\src\./foo.pb.cc \
106  C:\projects\foo\src\./foo.pb.h: C:/usr/include/google/protobuf/wrappers.proto\
107    C:/usr/include/google/protobuf/any.proto\
108 C:/usr/include/google/protobuf/source_context.proto\
109    C:/usr/include/google/protobuf/type.proto\
110    foo.proto";
111 
112         // This has a nasty output directory with a space.
113         const string depFile2 =
114     @"obj\Release x64\net45\/Foo.cs \
115 obj\Release x64\net45\/FooGrpc.cs: C:/usr/include/google/protobuf/wrappers.proto\
116  C:/projects/foo/src//foo.proto";
117 
118         [Test]
ReadDependencyInput_FullFile1()119         public void ReadDependencyInput_FullFile1()
120         {
121             string[] deps = ReadDependencyInputFromFileData(depFile1, "foo.proto");
122 
123             Assert.NotNull(deps);
124             Assert.That(deps, Has.Length.InRange(4, 5));  // foo.proto may or may not be listed.
125             Assert.That(deps, Has.One.EndsWith("wrappers.proto"));
126             Assert.That(deps, Has.One.EndsWith("type.proto"));
127             Assert.That(deps, Has.None.StartWith(" "));
128         }
129 
130         [Test]
ReadDependencyInput_FullFile2()131         public void ReadDependencyInput_FullFile2()
132         {
133             string[] deps = ReadDependencyInputFromFileData(depFile2, "C:/projects/foo/src/foo.proto");
134 
135             Assert.NotNull(deps);
136             Assert.That(deps, Has.Length.InRange(1, 2));
137             Assert.That(deps, Has.One.EndsWith("wrappers.proto"));
138             Assert.That(deps, Has.None.StartWith(" "));
139         }
140 
141         [Test]
ReadDependencyInput_FullFileUnparsable()142         public void ReadDependencyInput_FullFileUnparsable()
143         {
144             string[] deps = ReadDependencyInputFromFileData("a:/foo.proto", "/foo.proto");
145             Assert.NotNull(deps);
146             Assert.Zero(deps.Length);
147         }
148 
ReadDependencyInputFromFileData(string fileData, string protoName)149         private string[] ReadDependencyInputFromFileData(string fileData, string protoName)
150         {
151             string randomTempDir = Path.GetTempPath() + '/' + Path.GetRandomFileName();
152             Directory.CreateDirectory(randomTempDir);
153             string tempfile = DepFileUtil.GetDepFilenameForProto(randomTempDir, protoName);
154             try
155             {
156                 File.WriteAllText(tempfile, fileData);
157                 var mockEng = new Moq.Mock<IBuildEngine>();
158                 var log = new TaskLoggingHelper(mockEng.Object, "x");
159                 return DepFileUtil.ReadDependencyInputs(randomTempDir, protoName, log);
160             }
161             finally
162             {
163                 try
164                 {
165                     File.Delete(tempfile);
166                 }
167                 catch { }
168             }
169         }
170     };
171 }
172