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