Skip to content

[fix-finder] Add unit tests for EnvironmentFilesParser utility #11372

@github-actions

Description

@github-actions

Problem

The EnvironmentFilesParser class in src/Xamarin.Android.Build.Tasks/Utilities/EnvironmentFilesParser.cs has no unit tests. It contains non-trivial parsing logic for Android environment configuration files — detecting log levels, GC params, mono debug settings, HTTP handlers, assembly preload, and broken exception transitions — that should be covered by tests to prevent regressions.

Location

  • File: src/Xamarin.Android.Build.Tasks/Utilities/EnvironmentFilesParser.cs
  • Test directory: src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/

Current Code

The class parses environment variable files line by line, setting boolean flags and collecting lines:

class EnvironmentFilesParser
{
	public bool BrokenExceptionTransitions       { get; set; }
	public bool HaveHttpMessageHandler           { get; private set; }
	public bool HaveLogLevel                     { get; private set; }
	public bool HaveMonoDebug                    { get; private set; }
	public bool HaveMonoGCParams                 { get; private set; }
	public bool HaveTlsProvider                  { get; private set; }
	public bool UsesAssemblyPreload              { get; set; }
	public List<string> EnvironmentVariableLines { get; } = new List<string> ();

	public bool AreBrokenExceptionTransitionsEnabled (ITaskItem[] environments) { ... }
	public void Parse (ITaskItem[]? environments, SequencePointsMode sequencePointsMode, TaskLoggingHelper log) { ... }
}

Suggested Fix

Create a new test file src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/EnvironmentFilesParserTests.cs with tests covering the following behaviors. The class is internal but accessible via [InternalsVisibleTo("Xamarin.Android.Build.Tests")] in Properties/AssemblyInfo.cs.

Tests should create temporary files with specific environment variable content and verify the parser sets the correct flags.

Test cases to cover:

  1. MONO_LOG_LEVEL= detection — Verify HaveLogLevel is set to true when a line starts with MONO_LOG_LEVEL=
  2. MONO_GC_PARAMS= detection — Verify HaveMonoGCParams is set to true
  3. MONO_GC_PARAMS= with old bridge warning — Verify that when the line contains bridge-implementation=old, the parser logs coded warning XA2000
  4. MONO_DEBUG= detection — Verify HaveMonoDebug is set to true
  5. MONO_DEBUG= with sequence points — When sequencePointsMode != SequencePointsMode.None and the line does not contain gen-compact-seq-points, verify that gen-compact-seq-points is appended to the line in EnvironmentVariableLines
  6. XA_HTTP_CLIENT_HANDLER_TYPE= detection — Verify HaveHttpMessageHandler is set to true
  7. mono.enable_assembly_preload= handling — Verify UsesAssemblyPreload is set; note this line should NOT appear in EnvironmentVariableLines (it's filtered via continue)
  8. XA_BROKEN_EXCEPTION_TRANSITIONS= handling — Verify BrokenExceptionTransitions is set; note this line should NOT appear in EnvironmentVariableLines (it's filtered via continue)
  9. AreBrokenExceptionTransitionsEnabled — Verify it returns true when a file contains a XA_BROKEN_EXCEPTION_TRANSITIONS= line, and false otherwise
  10. Empty/null environments — Verify Parse handles null environments parameter without throwing
  11. Multiple files — Verify flags are accumulated across multiple environment files

Example structure:

using System.Collections.Generic;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using NUnit.Framework;
using Xamarin.Android.Tasks;

namespace Xamarin.Android.Build.Tests
{
	[TestFixture]
	[Parallelizable (ParallelScope.Self)]
	public class EnvironmentFilesParserTests : BaseTest
	{
		string? tempDirectory;

		[SetUp]
		public void Setup ()
		{
			tempDirectory = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName ());
			Directory.CreateDirectory (tempDirectory);
		}

		[TearDown]
		public void TearDown ()
		{
			if (tempDirectory != null && Directory.Exists (tempDirectory))
				Directory.Delete (tempDirectory, recursive: true);
		}

		ITaskItem CreateEnvFile (string content)
		{
			var path = Path.Combine (tempDirectory!, Path.GetRandomFileName () + ".env");
			File.WriteAllText (path, content);
			return new TaskItem (path);
		}

		[Test]
		public void DetectsMonoLogLevel ()
		{
			var envFile = CreateEnvFile ("MONO_LOG_LEVEL=debug");
			var parser = new EnvironmentFilesParser ();
			var engine = new MockBuildEngine (TestContext.Out);
			var log = new TaskLoggingHelper (engine, "Test");

			parser.Parse (new [] { envFile }, SequencePointsMode.None, log);

			Assert.IsTrue (parser.HaveLogLevel);
		}

		[Test]
		public void MonoGCParams_OldBridgeWarning ()
		{
			var envFile = CreateEnvFile ("MONO_GC_PARAMS=bridge-implementation=old");
			var warnings = new List<BuildWarningEventArgs> ();
			var engine = new MockBuildEngine (TestContext.Out, warnings: warnings);
			var log = new TaskLoggingHelper (engine, "Test");
			var parser = new EnvironmentFilesParser ();

			parser.Parse (new [] { envFile }, SequencePointsMode.None, log);

			Assert.IsTrue (parser.HaveMonoGCParams);
			Assert.AreEqual (1, warnings.Count);
			Assert.AreEqual ("XA2000", warnings [0].Code);
		}

		// ... additional tests for each behavior listed above
	}
}

Guidelines

  • Follow existing test patterns in src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ (e.g., AndroidComputeResPathsTests.cs)
  • Extend BaseTest, use MockBuildEngine — note: MockBuildEngine constructor accepts (TextWriter output, IList<BuildErrorEventArgs> errors = null, IList<BuildWarningEventArgs> warnings = null, IList<BuildMessageEventArgs> messages = null)
  • TaskLoggingHelper needs a IBuildEngine and a task name string: new TaskLoggingHelper (engine, "Test")
  • Use tabs for indentation, space before ( and [ (Mono style)
  • No ! (null-forgiving operator) — declare temp fields as nullable instead
  • SequencePointsMode enum is defined in Xamarin.Android.Tasks namespace (in Tasks/Aot.cs): None, Normal, Offline
  • Create and clean up temp files for each test using [SetUp] / [TearDown]

Acceptance Criteria

  • New file EnvironmentFilesParserTests.cs added in the Tasks test directory
  • MONO_LOG_LEVEL detection tested
  • MONO_GC_PARAMS detection tested, including XA2000 warning for old bridge
  • MONO_DEBUG detection and sequence-points appending tested
  • XA_HTTP_CLIENT_HANDLER_TYPE detection tested
  • XA_BROKEN_EXCEPTION_TRANSITIONS filtering tested (flag set, line excluded from EnvironmentVariableLines)
  • mono.enable_assembly_preload filtering tested (flag set, line excluded from EnvironmentVariableLines)
  • AreBrokenExceptionTransitionsEnabled tested
  • Null environments handled gracefully
  • All existing tests still pass
  • No new warnings introduced

Generated by Nightly Fix Finder for issue #11352 · ● 5.4M ·

  • expires on May 22, 2026, 5:28 PM UTC

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions