Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e6abde0
Reapply "[Mobile] Add BrowserStack Android MAUI Test (#23383)" (#23474)
carzh Jan 28, 2025
0dd42e9
maui csproj that builds into apk successfully
carzh Jan 29, 2025
4011a10
attempt to fix nuget pipeline failure
carzh Jan 29, 2025
0783bb1
target only ort for building c# bindings
carzh Jan 30, 2025
5a5fe4b
removed test projects from sln and updated pipeline yml
carzh Jan 31, 2025
70e3a23
format
carzh Jan 31, 2025
773cbb6
Revert "format"
carzh Jan 31, 2025
657c60d
format again..
carzh Jan 31, 2025
7a51dd5
fixed format again
carzh Jan 31, 2025
ec57836
Merge remote-tracking branch 'msft/main' into carzh/browserstack-andr…
carzh Jan 31, 2025
573e284
removed modifications from sln and commented out the ios and maccatyl…
carzh Feb 3, 2025
15d86f5
added more detailed comment
carzh Feb 4, 2025
2c17720
added test_android yml + added it to nuget pipeline
carzh Feb 4, 2025
fba5416
fixed indent
carzh Feb 4, 2025
a6c9823
Merge remote-tracking branch 'msft/main' into carzh/nuget-test-androi…
carzh Feb 6, 2025
1815b96
fixed curly bracket / ascii processing issue
carzh Feb 7, 2025
e6cd1e8
disable aot compilation for inference sample to see if that resolves …
carzh Feb 7, 2025
d15c053
Merge remote-tracking branch 'msft/main' into carzh/nuget-test-androi…
carzh Feb 21, 2025
a77f4f1
added updated asserts
carzh Feb 21, 2025
7e69c93
made InferenceTest diffs more clear hopefully + removed double feedba…
carzh Feb 22, 2025
24f5b3f
applied formatting suggestions + added second assert method that will…
carzh Feb 25, 2025
90411e9
updated the assertion check for the expected exception message. Added…
carzh Feb 25, 2025
f2e7854
added comment about ep checks, fixed typos, removed aotcompilation
carzh Mar 10, 2025
af28ea3
removed references to the preprocessor directives in the feedback mes…
carzh Mar 10, 2025
a5c7182
added coreml test back in and updated feedback message
carzh Mar 14, 2025
d222d90
updated comment explaining appending ep tests to session options
carzh Mar 19, 2025
26b965e
amended comment
carzh Mar 19, 2025
c70ac90
amended comment
carzh Mar 19, 2025
e7afd4b
Update csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/InferenceTes…
carzh Mar 20, 2025
1dbd060
Merge remote-tracking branch 'msft/main' into carzh/nuget-test-androi…
carzh Mar 21, 2025
644d01c
resolve '
carzh Mar 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

<Compile Include="..\Microsoft.ML.OnnxRuntime.Tests.Common\InferenceTest.cs" />
<Compile Include="..\Microsoft.ML.OnnxRuntime.Tests.Common\EqualityComparers.cs" />
<Compile Include="..\Microsoft.ML.OnnxRuntime.Tests.Common\AssertUtils.cs" />
<Compile Include="..\Microsoft.ML.OnnxRuntime.Tests.Common\OnnxMl.cs" />
<Compile Include="..\Microsoft.ML.OnnxRuntime.Tests.Common\OnnxData.cs" />
<Compile Include="..\Microsoft.ML.OnnxRuntime.Tests.NetCoreApp\InferenceTest.netcore.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public void Dispose()
{
String failureMessage = TestContext.CurrentContext.Result.Message;
String jsonToSendFailure =
String.Format("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": " +
"{\"status\":\"failed\", \"reason\": {0}}}",
String.Format("browserstack_executor: {{\"action\": \"setSessionStatus\", \"arguments\": " +
"{{\"status\":\"failed\", \"reason\": {0}}}}}",
JsonConvert.ToString(failureMessage));

((IJavaScriptExecutor)driver).ExecuteScript(jsonToSendFailure);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public async Task ClickRunAllTest()
await Task.Delay(500);
}

var (numPassed, numFailed) = GetPassFailCount();
(int numPassed, int numFailed) = GetPassFailCount();

if (numFailed == 0)
{
Expand Down
81 changes: 81 additions & 0 deletions csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/AssertUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;

namespace Microsoft.ML.OnnxRuntime.Tests
{
internal static class AssertUtils
{

/// <summary>
/// Check if the action throws the expected exception. If it doesn't, the method passes. If it does, check for
/// the exception type and the expected exception message. More detailed Assert method to be used for unit tests
/// written with XUnit.
/// </summary>
/// <typeparam name="T">Type of exception expected to be thrown.</typeparam>
/// <param name="action">Action to be executed or tested.</param>
/// <param name="feedbackMessage">Feedback message if an unexpected exception happens.</param>
/// <param name="expectedExceptionMessage">Expected exception message. If null, the exception message is not
// checked.</param>
public static void IfThrowsCheckException<T>(Action action, string feedbackMessage, string expectedExceptionMessage = null) where T : Exception
{
try
{
action();
}
catch (T ex)
{
if (expectedExceptionMessage == null)
{
return;
}
else
{
Assert.True(ex.Message.Contains(expectedExceptionMessage),
$"{feedbackMessage}\nExpected exception message to contain '{expectedExceptionMessage}', but got '{ex.Message}'");
}
}
catch (Exception ex)
{
Assert.Fail($"{feedbackMessage}\nExpected {typeof(T).Name} but got {ex.GetType().Name}. ");
}
}


/// <summary>
/// Check if the action throws the expected exception. If it doesn't, the method fails with the feedbackMessage.
/// If it does, check for the exception type and the expected exception message. More detailed Assert method to be
/// used for unit tests written with XUnit.
/// </summary>
/// <typeparam name="T">Type of exception expected to be thrown.</typeparam>
/// <param name="action">Action to be executed or tested. It is expected that the action will throw.</param>
/// <param name="feedbackMessage">Feedback message if an unexpected exception happens.</param>
/// <param name="expectedExceptionMessage">Expected exception message. If null, the exception message is not
// checked.</param>
public static void AssertThrowsCheckException<T>(Action action, string feedbackMessage, string expectedExceptionMessage = null) where T : Exception
{
try
{
action();
Assert.Fail($"{feedbackMessage}\nExpected {typeof(T).Name} but no exception was thrown.");
}
catch (T ex)
{
if (expectedExceptionMessage == null)
{
return;
}
else
{
Assert.True(ex.Message.Contains(expectedExceptionMessage),
$"{feedbackMessage}\nExpected exception message to contain '{expectedExceptionMessage}', but got '{ex.Message}'");
}
}
catch (Exception ex)
{
Assert.Fail($"{feedbackMessage}\nExpected {typeof(T).Name} but got {ex.GetType().Name}. ");
}
}
}
}
70 changes: 38 additions & 32 deletions csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/InferenceTest.cs
Comment thread
edgchen1 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,34 @@ public void TestSessionOptions()
opt.GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_EXTENDED;
Assert.Equal(GraphOptimizationLevel.ORT_ENABLE_EXTENDED, opt.GraphOptimizationLevel);

Assert.Throws<OnnxRuntimeException>(() => { opt.GraphOptimizationLevel = (GraphOptimizationLevel)10; });
AssertUtils.AssertThrowsCheckException<OnnxRuntimeException>(
() => { opt.GraphOptimizationLevel = (GraphOptimizationLevel)10; },
"Set an invalid Graph Optimization Level.");

opt.AddSessionConfigEntry("key", "value");

var ex = Assert.Throws<OnnxRuntimeException>(() => { opt.AddSessionConfigEntry("", "invalid key"); });
Assert.Contains("[ErrorCode:InvalidArgument] Config key is empty", ex.Message);
AssertUtils.AssertThrowsCheckException<OnnxRuntimeException>(
() => { opt.AddSessionConfigEntry("", "invalid key"); },
"Added an invalid config entry.",
"[ErrorCode:InvalidArgument] Config key is empty");

// SessionOptions.RegisterOrtExtensions can be manually tested by referencing the
// Microsoft.ML.OnnxRuntime.Extensions nuget package. After that is done, this should not throw.
ex = Assert.Throws<OnnxRuntimeException>(() => { opt.RegisterOrtExtensions(); });
Assert.Contains("Microsoft.ML.OnnxRuntime.Extensions NuGet package must be referenced", ex.Message);

AssertUtils.AssertThrowsCheckException<OnnxRuntimeException>(
() => { opt.RegisterOrtExtensions(); },
"RegisterOrtExtensions should throw if the Extensions package is not referenced",
"Microsoft.ML.OnnxRuntime.Extensions NuGet package must be referenced");

// The below tests what happens when various execution providers are added
// to the session options. Due to changes in how execution providers are handled,
// only some are expected to throw exceptions.
Comment thread
edgchen1 marked this conversation as resolved.
Outdated

// We can only check what EP's the package was built with for the
// Microsoft.ML.OnnxRuntime.Managed package because those contain the
// C# preprocessor directives (such as USE_CUDA). The Microsoft.ML.OnnxRuntime
Comment thread
edgchen1 marked this conversation as resolved.
Outdated
// package will use the appropriate platform bindings (ie the Android bindings)
// where using the correct ifdefs for the C# preprocessor directives are
// impossible, so we use IfThrowsCheckException instead of using ifdefs.
Comment thread
edgchen1 marked this conversation as resolved.
Outdated
Comment thread
edgchen1 marked this conversation as resolved.
Outdated
#if USE_CUDA
opt.AppendExecutionProvider_CUDA(0);
#endif
Expand Down Expand Up @@ -157,32 +173,22 @@ public void TestSessionOptions()
#if USE_TENSORRT
opt.AppendExecutionProvider_Tensorrt(0);
#endif
#if USE_XNNPACK
opt.AppendExecutionProvider("XNNPACK");
#else
ex = Assert.Throws<OnnxRuntimeException>(() => { opt.AppendExecutionProvider("XNNPACK"); });
Assert.Contains("XNNPACK execution provider is not supported in this build", ex.Message);
#endif
#if USE_SNPE
opt.AppendExecutionProvider("SNPE");
#else
ex = Assert.Throws<OnnxRuntimeException>(() => { opt.AppendExecutionProvider("SNPE"); });
Assert.Contains("SNPE execution provider is not supported in this build", ex.Message);
#endif
#if USE_QNN
opt.AppendExecutionProvider("QNN");
#else
ex = Assert.Throws<OnnxRuntimeException>(() => { opt.AppendExecutionProvider("QNN"); });
Assert.Contains("QNN execution provider is not supported in this build", ex.Message);
#endif
#if USE_COREML
opt.AppendExecutionProvider("CoreML");
Comment thread
carzh marked this conversation as resolved.
#else
ex = Assert.Throws<OnnxRuntimeException>(() => { opt.AppendExecutionProvider("CoreML"); });
Assert.Contains("CoreML execution provider is not supported in this build", ex.Message);
#endif

opt.AppendExecutionProvider_CPU(1);
AssertUtils.IfThrowsCheckException<OnnxRuntimeException>(
Comment thread
edgchen1 marked this conversation as resolved.
() => { opt.AppendExecutionProvider("XNNPACK"); },
"Attempted to add XNNPack execution provider to session options. ",
Comment thread
carzh marked this conversation as resolved.
Outdated
"XNNPACK execution provider is not supported in this build");

AssertUtils.IfThrowsCheckException<OnnxRuntimeException>(
() => { opt.AppendExecutionProvider("SNPE"); },
"Attempted to add SNPE execution provider to session options. ",
"SNPE execution provider is not supported in this build");

AssertUtils.IfThrowsCheckException<OnnxRuntimeException>(
() => { opt.AppendExecutionProvider("QNN"); },
"Attempted to add QNN execution provider to session options. ",
"QNN execution provider is not supported in this build");

opt.AppendExecutionProvider_CPU(1);
Comment thread
edgchen1 marked this conversation as resolved.
Outdated
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
parameters:
AgentPool : 'Win-CPU'
ArtifactSuffix: ''
SpecificArtifact: false
BuildId: ''

stages:
- stage: NuGet_Test_Android
jobs:
- job: NuGet_Test_Android
workspace:
clean: all
pool: "${{ parameters.AgentPool }}"

variables:
- name: OnnxRuntimeBuildDirectory
value: '$(Build.BinariesDirectory)'

steps:
- task: NuGetToolInstaller@0
displayName: Use Nuget 6.10.x
inputs:
versionSpec: 6.10.x

- template: ../../templates/flex-downloadPipelineArtifact.yml
parameters:
StepName: 'Download Pipeline Artifact'
ArtifactName: drop-signed-nuget-${{ parameters.ArtifactSuffix }}
TargetPath: '$(Build.BinariesDirectory)\nuget-artifact'
SpecificArtifact: ${{ parameters.SpecificArtifact }}
BuildId: ${{ parameters.BuildId }}

- template: get-nuget-package-version-as-variable.yml
parameters:
packageFolder: '$(Build.BinariesDirectory)\nuget-artifact'

- task: PowerShell@2
displayName: Install MAUI workloads
inputs:
targetType: 'inline'
script: |
dotnet workload install maui maui-android android
workingDirectory: '$(Build.SourcesDirectory)\csharp'

- task: PowerShell@2
displayName: Publish Android MAUI APK
inputs:
targetType: 'inline'
script: |
dotnet nuget add source $(Build.BinariesDirectory)\nuget-artifact --name local-nuget
dotnet publish -c Release --property:UsePrebuiltNativePackage=true --property:CurrentOnnxRuntimeVersion=$(NuGetPackageVersionNumber) -f net8.0-android
workingDirectory: '$(Build.SourcesDirectory)\csharp\test\Microsoft.ML.OnnxRuntime.Tests.MAUI'

- task: PowerShell@2
displayName: Run BrowserStack test
inputs:
targetType: 'inline'
script: |
dotnet test
workingDirectory: '$(Build.SourcesDirectory)\csharp\test\Microsoft.ML.OnnxRuntime.Tests.BrowserStack.Android'
env:
BROWSERSTACK_USERNAME: $(browserstack_username)
BROWSERSTACK_ACCESS_KEY: $(browserstack_access_key)
7 changes: 7 additions & 0 deletions tools/ci_build/github/azure-pipelines/templates/c-api-cpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,13 @@ stages:
SpecificArtifact: ${{ parameters.SpecificArtifact }}
BuildId: ${{ parameters.BuildId }}

- template: ../nuget/templates/test_android.yml
parameters:
AgentPool : 'onnxruntime-Win-CPU-2022'
ArtifactSuffix: 'CPU'
SpecificArtifact: ${{ parameters.SpecificArtifact }}
BuildId: ${{ parameters.BuildId }}

- template: ../nuget/templates/test_linux.yml
parameters:
AgentPool : onnxruntime-Ubuntu2204-AMD-CPU
Expand Down