Skip to content

Commit a7853ad

Browse files
committed
CodeBehind tests work across all 3 runtimes
1 parent 2e16109 commit a7853ad

File tree

3 files changed

+74
-39
lines changed

3 files changed

+74
-39
lines changed

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using NUnit.Framework;
1010

1111
using Xamarin.ProjectTools;
12+
using Xamarin.Android.Tasks;
13+
using System.Text;
1214

1315
namespace Xamarin.Android.Build.Tests
1416
{
@@ -111,25 +113,29 @@ sealed class TestProjectInfo
111113
{
112114
public string RootDirectory { get; }
113115
public string OutputDirectory { get; }
116+
public string TestRootDirectory { get; }
114117
public string ObjPath { get; }
115118
public string BinPath { get; }
116119
public string GeneratedPath { get; }
117120
public string ProjectPath { get; }
118121
public string ProjectName { get; }
119122
public string TestName { get; }
123+
public AndroidRuntime Runtime { get; }
120124

121-
public TestProjectInfo (string projectName, string testName, string rootDirectory, string outputRootDir)
125+
public TestProjectInfo (string projectName, string testName, string rootDirectory, string outputRootDir, AndroidRuntime runtime)
122126
{
123127
TestName = testName;
124128
RootDirectory = rootDirectory;
125129
ProjectName = projectName;
130+
Runtime = runtime;
126131

127132
ObjPath = Path.Combine (rootDirectory, "obj");
128133
GeneratedPath = Path.Combine (ObjPath, XABuildPaths.Configuration, "codebehind");
129134
BinPath = Path.Combine (rootDirectory, "bin", XABuildPaths.Configuration);
130135
ProjectPath = Path.Combine (rootDirectory, $"{projectName}.csproj");
131136

132-
OutputDirectory = Path.Combine (outputRootDir, testName, XABuildPaths.Configuration);
137+
TestRootDirectory = Path.Combine (outputRootDir, testName);
138+
OutputDirectory = Path.Combine (TestRootDirectory, XABuildPaths.Configuration);
133139
}
134140
}
135141

@@ -267,37 +273,38 @@ static CodeBehindTests ()
267273
},
268274
};
269275

276+
// TODO: for some reason the tests no longer produce both aab and apk packages, at least locally? Fine? Bug?
270277
produced_binaries = new List <string> {
271278
$"{ProjectName}.dll",
272279
"CommonSampleLibrary.dll",
273-
$"{PackageName}-Signed.apk",
280+
// $"{PackageName}-Signed.apk",
274281
$"{PackageName}.aab",
275282
$"{PackageName}-Signed.aab",
276283
};
277284
}
278285

279286
[Test]
280-
public void SuccessfulBuildFew ()
287+
public void SuccessfulBuildFew ([Values] AndroidRuntime runtime)
281288
{
282-
RunTest ("SuccessfulBuildFew", many: false, dtb: false, runner: SuccessfulBuild_RunTest);
289+
RunTest (TestName, many: false, dtb: false, runner: SuccessfulBuild_RunTest, runtime: runtime);
283290
}
284291

285292
[Test]
286-
public void SuccessfulBuildMany ()
293+
public void SuccessfulBuildMany ([Values] AndroidRuntime runtime)
287294
{
288-
RunTest ("SuccessfulBuildMany", many: true, dtb: false, runner: SuccessfulBuild_RunTest);
295+
RunTest (TestName, many: true, dtb: false, runner: SuccessfulBuild_RunTest, runtime: runtime);
289296
}
290297

291298
[Test]
292-
public void SuccessfulBuildFew_DTB ()
299+
public void SuccessfulBuildFew_DTB ([Values] AndroidRuntime runtime)
293300
{
294-
RunTest ("SuccessfulBuildFew_DTB", many: false, dtb: true, runner: SuccessfulBuild_RunTest);
301+
RunTest (TestName, many: false, dtb: true, runner: SuccessfulBuild_RunTest, runtime: runtime);
295302
}
296303

297304
[Test]
298-
public void SuccessfulBuildMany_DTB ()
305+
public void SuccessfulBuildMany_DTB ([Values] AndroidRuntime runtime)
299306
{
300-
RunTest ("SuccessfulBuildMany_DTB", many: true, dtb: true, runner: SuccessfulBuild_RunTest);
307+
RunTest (TestName, many: true, dtb: true, runner: SuccessfulBuild_RunTest, runtime: runtime);
301308
}
302309

303310
void SuccessfulBuild_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder)
@@ -328,9 +335,9 @@ void SuccessfulBuild_RunTest (TestProjectInfo testInfo, bool many, bool dtb, Loc
328335
}
329336

330337
[Test]
331-
public void SuccessfulAndroidXApp ()
338+
public void SuccessfulAndroidXApp ([Values] AndroidRuntime runtime)
332339
{
333-
RunTest ("SuccessfulAndroidXApp", many: true, dtb: false, runner: SuccessfulBuild_AndroidX);
340+
RunTest (TestName, many: true, dtb: false, runner: SuccessfulBuild_AndroidX, runtime: runtime);
334341
}
335342

336343
void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder)
@@ -340,7 +347,9 @@ void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, Lo
340347

341348
CopyLogs (testInfo, true);
342349
Assert.That (success, Is.True, "Build should have succeeded");
343-
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings.");
350+
if (testInfo.Runtime != AndroidRuntime.NativeAOT) { // NativeAOT currently (Nov 2025) produces 9 ILC warnings
351+
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings.");
352+
}
344353

345354
CopyGeneratedFiles (testInfo);
346355

@@ -363,15 +372,15 @@ void SuccessfulBuild_AndroidX (TestProjectInfo testInfo, bool many, bool dtb, Lo
363372
}
364373

365374
[Test]
366-
public void FailedBuildFew_ConflictingFragment ()
375+
public void FailedBuildFew_ConflictingFragment ([Values] AndroidRuntime runtime)
367376
{
368-
RunTest ("FailedBuildFew_ConflictingFragment", many: false, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest);
377+
RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest, runtime: runtime);
369378
}
370379

371380
[Test]
372-
public void FailedBuildMany_ConflictingFragment ()
381+
public void FailedBuildMany_ConflictingFragment ([Values] AndroidRuntime runtime)
373382
{
374-
RunTest ("FailedBuildMany_ConflictingFragment", many: true, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest);
383+
RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingFragment_RunTest, runtime: runtime);
375384
}
376385

377386
void FailedBuild_ConflictingFragment_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder)
@@ -391,15 +400,15 @@ void FailedBuild_ConflictingFragment_RunTest (TestProjectInfo testInfo, bool man
391400
}
392401

393402
[Test]
394-
public void FailedBuildFew_ConflictingTextView ()
403+
public void FailedBuildFew_ConflictingTextView ([Values] AndroidRuntime runtime)
395404
{
396-
RunTest ("FailedBuildFew_ConflictingTextView", many: false, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest);
405+
RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest, runtime: runtime);
397406
}
398407

399408
[Test]
400-
public void FailedBuildMany_ConflictingTextView ()
409+
public void FailedBuildMany_ConflictingTextView ([Values] AndroidRuntime runtime)
401410
{
402-
RunTest ("FailedBuildMany_ConflictingTextView", many: true, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest);
411+
RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingTextView_RunTest, runtime: runtime);
403412
}
404413

405414
void FailedBuild_ConflictingTextView_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder)
@@ -419,15 +428,15 @@ void FailedBuild_ConflictingTextView_RunTest (TestProjectInfo testInfo, bool man
419428
}
420429

421430
[Test]
422-
public void FailedBuildFew_ConflictingButton ()
431+
public void FailedBuildFew_ConflictingButton ([Values] AndroidRuntime runtime)
423432
{
424-
RunTest ("FailedBuildFew_ConflictingButton", many: false, dtb: false, runner: FailedBuild_ConflictingButton_RunTest);
433+
RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingButton_RunTest, runtime: runtime);
425434
}
426435

427436
[Test]
428-
public void FailedBuildMany_ConflictingButton ()
437+
public void FailedBuildMany_ConflictingButton ([Values] AndroidRuntime runtime)
429438
{
430-
RunTest ("FailedBuildMany_ConflictingButton", many: true, dtb: false, runner: FailedBuild_ConflictingButton_RunTest);
439+
RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingButton_RunTest, runtime: runtime);
431440
}
432441

433442
void FailedBuild_ConflictingButton_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder)
@@ -447,15 +456,15 @@ void FailedBuild_ConflictingButton_RunTest (TestProjectInfo testInfo, bool many,
447456
}
448457

449458
[Test]
450-
public void FailedBuildFew_ConflictingLinearLayout ()
459+
public void FailedBuildFew_ConflictingLinearLayout ([Values] AndroidRuntime runtime)
451460
{
452-
RunTest ("FailedBuildFew_ConflictingLinearLayout", many: false, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest);
461+
RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest, runtime: runtime);
453462
}
454463

455464
[Test]
456-
public void FailedBuildMany_ConflictingLinearLayout ()
465+
public void FailedBuildMany_ConflictingLinearLayout ([Values] AndroidRuntime runtime)
457466
{
458-
RunTest ("FailedBuildMany_ConflictingLinearLayout", many: true, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest);
467+
RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingLinearLayout_RunTest, runtime: runtime);
459468
}
460469

461470
void FailedBuild_ConflictingLinearLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder)
@@ -475,15 +484,15 @@ void FailedBuild_ConflictingLinearLayout_RunTest (TestProjectInfo testInfo, bool
475484
}
476485

477486
[Test]
478-
public void FailedBuildFew_ConflictingRelativeLayout ()
487+
public void FailedBuildFew_ConflictingRelativeLayout ([Values] AndroidRuntime runtime)
479488
{
480-
RunTest ("FailedBuildFew_ConflictingRelativeLayout", many: false, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest);
489+
RunTest (TestName, many: false, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest, runtime: runtime);
481490
}
482491

483492
[Test]
484-
public void FailedBuildMany_ConflictingRelativeLayout ()
493+
public void FailedBuildMany_ConflictingRelativeLayout ([Values] AndroidRuntime runtime)
485494
{
486-
RunTest ("FailedBuildMany_ConflictingRelativeLayout", many: true, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest);
495+
RunTest (TestName, many: true, dtb: false, runner: FailedBuild_ConflictingRelativeLayout_RunTest, runtime: runtime);
487496
}
488497

489498
void FailedBuild_ConflictingRelativeLayout_RunTest (TestProjectInfo testInfo, bool many, bool dtb, LocalBuilder builder)
@@ -577,12 +586,17 @@ void AssertHaveCompilerError (bool haveError, string fileName, int line)
577586
/// <param name="many">Generate code in parallel if <c>true</c>, serially otherwise</param>
578587
/// <param name="dtb">Test design-time build if <c>true</c>, regular build otherwise</param>
579588
/// <param name="runner">Action consituting the main body of the test. Passed parameters are described above in the remarks section.</param>
580-
void RunTest (string testName, bool many, bool dtb, Action<TestProjectInfo, bool, bool, LocalBuilder> runner)
589+
void RunTest (string testName, bool many, bool dtb, Action<TestProjectInfo, bool, bool, LocalBuilder> runner, AndroidRuntime runtime)
581590
{
582-
string temporaryProjectDir = PrepareProject (testName);
591+
bool isRelease = runtime == AndroidRuntime.NativeAOT;
592+
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
593+
return;
594+
}
595+
596+
string temporaryProjectDir = PrepareProject (testName, isRelease, runtime);
583597
LocalBuilder builder = GetBuilder ($"{ProjectName}.{testName}");
584598
builder.BuildingInsideVisualStudio = dtb;
585-
var testInfo = new TestProjectInfo (ProjectName, testName, temporaryProjectDir, TestOutputDir);
599+
var testInfo = new TestProjectInfo (ProjectName, testName, temporaryProjectDir, TestOutputDir, runtime);
586600

587601
try {
588602
runner (testInfo, many, dtb, builder);
@@ -604,7 +618,7 @@ void RunTest (string testName, bool many, bool dtb, Action<TestProjectInfo, bool
604618

605619
// Clean up successful tests
606620
FileSystemUtils.SetDirectoryWriteable (testInfo.OutputDirectory);
607-
Directory.Delete (testInfo.OutputDirectory, recursive: true);
621+
Directory.Delete (testInfo.TestRootDirectory, recursive: true);
608622
}
609623

610624
bool WasParsedInParallel (TestProjectInfo testInfo)
@@ -675,7 +689,7 @@ string Regexify (string input)
675689
.Replace ("}", "\\}");
676690
}
677691

678-
string PrepareProject (string testName)
692+
string PrepareProject (string testName, bool isRelease, AndroidRuntime runtime)
679693
{
680694
string tempRoot = Path.Combine (TestOutputDir, testName, XABuildPaths.Configuration);
681695
string temporaryProjectPath = Path.Combine (tempRoot, "project");
@@ -692,7 +706,21 @@ string PrepareProject (string testName)
692706
CopyFile (Path.Combine (XABuildPaths.TopDirectory, "Directory.Build.props"), Path.Combine (tempRoot, "Directory.Build.props" ));
693707
var project = new XamarinAndroidApplicationProject ();
694708
project.CopyNuGetConfig (Path.Combine (tempRoot, "NuGet.config"));
709+
710+
PatchProject (Path.Combine (tempRoot, CommonSampleLibraryName, $"{CommonSampleLibraryName}.NET.csproj"));
711+
PatchProject (Path.Combine (temporaryProjectPath, $"{ProjectName}.csproj"));
712+
695713
return temporaryProjectPath;
714+
715+
void PatchProject (string csprojPath)
716+
{
717+
AssertExists (testName, csprojPath);
718+
var sb = new StringBuilder (File.ReadAllText (csprojPath));
719+
sb.Replace ("@UseMonoRuntime@", (runtime == AndroidRuntime.MonoVM).ToString ())
720+
.Replace ("@PublishAot@", (runtime == AndroidRuntime.NativeAOT).ToString ())
721+
.Replace ("@Configuration@", isRelease ? "Release" : "Debug");
722+
File.WriteAllText (csprojPath, sb.ToString ());
723+
}
696724
}
697725

698726
void CopyRecursively (string fromDir, string toDir, HashSet <string> ignoreDirs)

tests/CodeBehind/BuildTests/CodeBehindBuildTests.NET.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
1212
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
1313
<AppendTargetFrameworkToIntermediateOutputPath>false</AppendTargetFrameworkToIntermediateOutputPath>
14+
<AndroidPackageFormat>aab</AndroidPackageFormat>
15+
<UseMonoRuntime>@UseMonoRuntime@</UseMonoRuntime>
16+
<PublishAot>@PublishAot@</PublishAot>
17+
<Configuration>@Configuration@</Configuration>
1418
</PropertyGroup>
1519
<PropertyGroup>
1620
<DefineConstants Condition=" '$(ExtraConstants)' != '' ">$(DefineConstants);$(ExtraConstants)</DefineConstants>

tests/CodeBehind/CommonSampleLibrary/CommonSampleLibrary.NET.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<RootNamespace>CommonSampleLibrary</RootNamespace>
55
<AssemblyName>CommonSampleLibrary</AssemblyName>
66
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
7+
<UseMonoRuntime>@UseMonoRuntime@</UseMonoRuntime>
8+
<PublishAot>@PublishAot@</PublishAot>
9+
<Configuration>@Configuration@</Configuration>
710
</PropertyGroup>
811
<PropertyGroup>
912
<DefineConstants Condition=" '$(ExtraConstants)' != '' ">$(DefineConstants);$(ExtraConstants)</DefineConstants>

0 commit comments

Comments
 (0)