Skip to content

Commit 81d37a1

Browse files
authored
[Xamarin.Android.Tools.Aidl-Tests] Add unit tests (#5756)
Context: #5726 We have someone willing to contribute fixes for `Xamarin.Android.Tools.Aidl.dll` (yay!). However, we no longer have any expertise with AIDL available on the team, and there are no unit tests for this area. This makes us very reluctant to make changes which could potentially break the currently working aspects of AIDL. Add a new `tests/Xamarin.Android.Tools.Aidl-Tests` unit test project and seed it with a few examples from our repo and a few large examples from other OSS repos. Note: this does *not* mean that the behavior tested by these tests is necessarily *correct*. It simply reflects what the code does *today*, in order that we can see any changes made by future PR's. ~~ Note ~~ The format for test data files is delimited by 4 pound signs as: <input> #### <output> Test results can be generated by: - Placing the input in a test file - Enabling the `GENERATE_OUTPUT` define at the top of `AidlCompilerTestBase.cs` - Running the test - The test file in `bin/TestData` will now contain the test output which can be copied back to the original test data file.
1 parent 4e37293 commit 81d37a1

File tree

15 files changed

+16648
-0
lines changed

15 files changed

+16648
-0
lines changed

Xamarin.Android-Tests.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Java.Interop-Tests", "tests
9090
EndProject
9191
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop", "external\Java.Interop\src\Java.Interop\Java.Interop.csproj", "{94BD81F7-B06F-4295-9636-F8A3B6BDC762}"
9292
EndProject
93+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.Android.Tools.Aidl-Tests", "tests\Xamarin.Android.Tools.Aidl-Tests\Xamarin.Android.Tools.Aidl-Tests.csproj", "{883941C8-C4ED-428D-A7D2-26F2EEA23F92}"
94+
EndProject
95+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.Android.Tools.Aidl", "src\Xamarin.Android.Tools.Aidl\Xamarin.Android.Tools.Aidl.csproj", "{302D9D2E-1F98-4374-9B6B-922F78620C4B}"
96+
EndProject
9397
Global
9498
GlobalSection(SharedMSBuildProjectFiles) = preSolution
9599
tests\Mono.Android-Tests\Mono.Android-Test.Shared.projitems*{0ab4956e-6fb9-4da0-9d49-ab65a3ff403a}*SharedItemsImports = 13
@@ -241,6 +245,14 @@ Global
241245
{94BD81F7-B06F-4295-9636-F8A3B6BDC762}.Debug|Any CPU.Build.0 = Debug|Any CPU
242246
{94BD81F7-B06F-4295-9636-F8A3B6BDC762}.Release|Any CPU.ActiveCfg = Release|Any CPU
243247
{94BD81F7-B06F-4295-9636-F8A3B6BDC762}.Release|Any CPU.Build.0 = Release|Any CPU
248+
{883941C8-C4ED-428D-A7D2-26F2EEA23F92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
249+
{883941C8-C4ED-428D-A7D2-26F2EEA23F92}.Debug|Any CPU.Build.0 = Debug|Any CPU
250+
{883941C8-C4ED-428D-A7D2-26F2EEA23F92}.Release|Any CPU.ActiveCfg = Release|Any CPU
251+
{883941C8-C4ED-428D-A7D2-26F2EEA23F92}.Release|Any CPU.Build.0 = Release|Any CPU
252+
{302D9D2E-1F98-4374-9B6B-922F78620C4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
253+
{302D9D2E-1F98-4374-9B6B-922F78620C4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
254+
{302D9D2E-1F98-4374-9B6B-922F78620C4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
255+
{302D9D2E-1F98-4374-9B6B-922F78620C4B}.Release|Any CPU.Build.0 = Release|Any CPU
244256
EndGlobalSection
245257
GlobalSection(SolutionProperties) = preSolution
246258
HideSolutionNode = FALSE
@@ -278,6 +290,8 @@ Global
278290
{D1243BAB-23CA-4566-A2A3-3ADA2C2DC3AF} = {EFBC4DC0-DBFF-4DAA-B0B8-6D0CB02A25F5}
279291
{6CB00820-A66B-43E5-8785-ED456C6E9F39} = {EFBC4DC0-DBFF-4DAA-B0B8-6D0CB02A25F5}
280292
{94BD81F7-B06F-4295-9636-F8A3B6BDC762} = {EFBC4DC0-DBFF-4DAA-B0B8-6D0CB02A25F5}
293+
{883941C8-C4ED-428D-A7D2-26F2EEA23F92} = {EFBC4DC0-DBFF-4DAA-B0B8-6D0CB02A25F5}
294+
{302D9D2E-1F98-4374-9B6B-922F78620C4B} = {EFBC4DC0-DBFF-4DAA-B0B8-6D0CB02A25F5}
281295
EndGlobalSection
282296
GlobalSection(ExtensibilityGlobals) = postSolution
283297
SolutionGuid = {8643CD20-B195-4919-8135-27549488237E}

build-tools/automation/yaml-templates/run-msbuild-mac-tests.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ jobs:
5656
dotNetTestExtraArgs: --filter "TestCategory != Node-1 & TestCategory != Node-2 & TestCategory != Node-3"
5757
testResultsFile: TestResult-MSBuildTests-macOS-NoNode-$(XA.Build.Configuration).xml
5858

59+
# Only run these tests on node 2
60+
- ${{ if eq(parameters.run_extra_tests, true) }}:
61+
- template: run-nunit-tests.yaml
62+
parameters:
63+
useDotNet: $(UseDotNet)
64+
testRunTitle: Xamarin.Android.Tools.Aidl-Tests - macOS
65+
testAssembly: $(System.DefaultWorkingDirectory)/bin/Test$(XA.Build.Configuration)/${{ parameters.target_framework }}/Xamarin.Android.Tools.Aidl-Tests.dll
66+
testResultsFile: TestResult-Aidl-Tests-macOS-$(XA.Build.Configuration).xml
67+
5968
- template: upload-results.yaml
6069
parameters:
6170
artifactName: Test Results - MSBuild ${{ parameters.job_suffix }} - macOS-${{ parameters.node_id }}

build-tools/automation/yaml-templates/run-msbuild-win-tests.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ jobs:
6363
dotNetTestExtraArgs: --filter "TestCategory != Node-1 & TestCategory != Node-2 & TestCategory != Node-3"
6464
testResultsFile: TestResult-MSBuildTests-Windows-NoNode-$(XA.Build.Configuration).xml
6565

66+
# Only run these tests on node 2
67+
- ${{ if eq(parameters.run_extra_tests, true) }}:
68+
- template: run-nunit-tests.yaml
69+
parameters:
70+
useDotNet: $(UseDotNet)
71+
testRunTitle: Xamarin.Android.Tools.Aidl-Tests - Windows
72+
testAssembly: $(System.DefaultWorkingDirectory)\bin\Test$(XA.Build.Configuration)\${{ parameters.target_framework }}\Xamarin.Android.Tools.Aidl-Tests.dll
73+
testResultsFile: TestResult-Aidl-Tests-Windows-$(XA.Build.Configuration).xml
74+
6675
- template: upload-results.yaml
6776
parameters:
6877
artifactName: Test Results - MSBuild ${{ parameters.job_suffix }} - Windows-${{ parameters.node_id }}

build-tools/scripts/RunTests.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
</PropertyGroup>
1717
<ItemGroup>
1818
<_TestAssembly Include="$(_TopDir)\bin\Test$(Configuration)\net472\Xamarin.Android.Build.Tests.dll" />
19+
<_TestAssembly Include="$(_TopDir)\bin\Test$(Configuration)\net472\Xamarin.Android.Tools.Aidl-Tests.dll" />
1920
<_ApkTestProject Include="$(_TopDir)\tests\Mono.Android-Tests\Mono.Android-Tests.csproj" />
2021
<_ApkTestProject Include="$(_TopDir)\tests\CodeGen-Binding\Xamarin.Android.JcwGen-Tests\Xamarin.Android.JcwGen-Tests.csproj" />
2122
<_ApkTestProject Include="$(_TopDir)\tests\CodeGen-MkBundle\Xamarin.Android.MakeBundle-Tests\Xamarin.Android.MakeBundle-Tests.csproj" />

src/Xamarin.Android.Tools.Aidl/AidlCompiler.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,41 @@ public Result Run (ConverterOptions opts, Func<string,AssemblyDefinition> resolv
7777

7878
return result;
7979
}
80+
81+
// This overload is primarily for unit tests.
82+
public Result Run (string input, out string output, AssemblyDefinition[] references = null, ParcelableHandling parcelableHandling = ParcelableHandling.Ignore)
83+
{
84+
var result = new Result ();
85+
var database = new BindingDatabase (references ?? Array.Empty<AssemblyDefinition> ());
86+
var lang = new LanguageData (new AidlGrammar () { LanguageFlags = LanguageFlags.Default | LanguageFlags.CreateAst });
87+
var parser = new Parser (lang);
88+
89+
var pt = parser.Parse (input);
90+
91+
if (pt.HasErrors ()) {
92+
foreach (var l in pt.ParserMessages)
93+
result.LogMessages.Add ("input.aidl", l);
94+
95+
output = null;
96+
return result;
97+
}
98+
99+
var unit = (CompilationUnit) pt.Root.AstNode;
100+
101+
var parcelables = new List<TypeName> ();
102+
103+
foreach (Parcelable t in unit.Types.Where (t => t is Parcelable))
104+
parcelables.Add (unit.Package == null ? t.Name : new TypeName (unit.Package.Identifiers.Concat (t.Name.Identifiers).ToArray ()));
105+
106+
var sw = new StringWriter ();
107+
var opts = new ConverterOptions { ParcelableHandling = parcelableHandling };
108+
109+
new CSharpCodeGenerator (sw, database).GenerateCode (unit, parcelables, opts);
110+
111+
output = sw.ToString ();
112+
113+
return result;
114+
}
80115
}
81116
}
82117

src/Xamarin.Android.Tools.Aidl/BindingDatabase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public BindingDatabase (IEnumerable<string> assemblies, Func<string,AssemblyDefi
2525
public BindingDatabase (IEnumerable<AssemblyDefinition> asses)
2626
{
2727
this.asses.AddRange (asses);
28+
Initialize (null, null);
2829
}
2930

3031
public IDictionary<string,string> NamespaceMappings {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//#define GENERATE_OUTPUT
2+
// This define will overwrite the files in /bin/TestData.
3+
// You will still need to copy them back to the original /TestData.
4+
5+
using System;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Reflection;
9+
using NUnit.Framework;
10+
using Xamarin.Android.Tools.Aidl;
11+
12+
namespace Xamarin.Android.Tools.Aidl_Tests
13+
{
14+
public class AidlCompilerTestBase
15+
{
16+
protected void RunTest (string name)
17+
{
18+
var root = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
19+
var file = Path.Combine (root, "TestData", name + ".txt");
20+
var text = File.ReadAllText (file);
21+
22+
(var input, var expected_output) = SplitTestFile (text);
23+
24+
var compiler = new AidlCompiler ();
25+
var results = compiler.Run (input, out var output);
26+
27+
Assert.False (results.LogMessages.Any ());
28+
29+
#if GENERATE_OUTPUT
30+
using (var sw = new StreamWriter (file)) {
31+
sw.WriteLine (input);
32+
sw.WriteLine ();
33+
sw.WriteLine ("####");
34+
sw.WriteLine ();
35+
sw.WriteLine (output);
36+
}
37+
38+
Assert.Ignore ("Generating output for this test.");
39+
#endif // GENERATE_OUTPUT
40+
41+
Assert.AreEqual (StripLineEndings (expected_output), StripLineEndings (output));
42+
}
43+
44+
(string input, string output) SplitTestFile (string text)
45+
{
46+
var index = text.IndexOf ("####");
47+
48+
if (index < 0) {
49+
#if GENERATE_OUTPUT
50+
return (text, null);
51+
#endif // GENERATE_OUTPUT
52+
throw new Exception ("No expected output found.");
53+
}
54+
55+
var input = text.Substring (0, index).Trim ();
56+
var output = text.Substring (index + 4).Trim ();
57+
58+
return (input, output);
59+
}
60+
61+
string StripLineEndings (string input) => input.Replace ("\n", "").Replace ("\r", "").Trim ();
62+
}
63+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using NUnit.Framework;
7+
8+
namespace Xamarin.Android.Tools.Aidl_Tests
9+
{
10+
[TestFixture]
11+
public class AidlCompilerTests : AidlCompilerTestBase
12+
{
13+
[Test]
14+
public void ListAndMap () => RunTest (nameof (ListAndMap));
15+
16+
[Test]
17+
public void NamespaceResolution () => RunTest (nameof (NamespaceResolution));
18+
19+
[Test]
20+
public void PrimitiveTypes () => RunTest (nameof (PrimitiveTypes));
21+
22+
[Test]
23+
public void FaceService () => RunTest (nameof (FaceService));
24+
25+
[Test]
26+
public void IUpdateEngine () => RunTest (nameof (IUpdateEngine));
27+
28+
[Test]
29+
public void ITelephony () => RunTest (nameof (ITelephony));
30+
}
31+
}

0 commit comments

Comments
 (0)