Skip to content

Commit d42f3e6

Browse files
pjcollinsjonpryor
authored andcommitted
[tests] Use correct test result for adb hosts (#1365)
Certain deployment targets require us to fix up an external storage path before we can pull it via adb (see `ToAdbPath()` comments for more details). We should only attempt to fix up this path *after* writing our test result, as our application context will not recognize it as a valid file path. Fixes the following error: Error: System.IO.DirectoryNotFoundException: Could not find a part of the path "/mnt/shell/emulated/0/Android/data/Xamarin.Android.Bcl_Tests/files/Documents/TestResults.xUnit.xml". at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x00177] in /Users/builder/jenkins/workspace/xamarin-android-d15-7/xamarin-android/external/mono/mcs/class/corlib/System.IO/FileStream.cs:223 at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.IO.FileOptions options) [0x00000] in /Users/builder/jenkins/workspace/xamarin-android-d15-7/xamarin-android/external/mono/mcs/class/corlib/System.IO/FileStream.cs:106 at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean useAsync) [0x00000] in /Users/builder/jenkins/workspace/xamarin-android-d15-7/xamarin-android/external/mono/mcs/class/corlib/System.IO/FileStream.cs:101 at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int,bool) at System.Xml.XmlWriterSettings.CreateWriter (System.String outputFileName) [0x00051] in /Users/builder/jenkins/workspace/xamarin-android-d15-7/xamarin-android/external/mono/mcs/class/referencesource/System.Xml/System/Xml/Core/XmlWriterSettings.cs:464 at System.Xml.XmlWriter.Create (System.String outputFileName, System.Xml.XmlWriterSettings settings) [0x0000a] in /Users/builder/jenkins/workspace/xamarin-android-d15-7/xamarin-android/external/mono/mcs/class/referencesource/System.Xml/System/Xml/Core/XmlWriter.cs:610 at Xamarin.Android.UnitTests.XUnit.XUnitTestRunner.WriteResultsToFile () at Xamarin.Android.UnitTests.TestInstrumentation`1[TRunner].RunTests (Android.OS.Bundle& results) at Xamarin.Android.UnitTests.TestInstrumentation`1[TRunner].OnStart () UNHANDLED EXCEPTION: Java.Lang.NullPointerException: Exception of type 'Java.Lang.NullPointerException' was thrown. at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/jenkins/workspace/xamarin-android-d15-7/xamarin-android/external/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152 at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00089] in <1c16e67a812b475a9ae6b6e26eed9097>:0 at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0005d] in <1c16e67a812b475a9ae6b6e26eed9097>:0 at Android.App.Instrumentation.Finish (Android.App.Result resultCode, Android.OS.Bundle results) [0x0003a] in /Users/builder/data/lanes/5945/28b08da2/source/monodroid/external/xamarin-android/src/Mono.Android/obj/Release/android-27/mcw/Android.App.Instrumentation.cs:1366 at Xamarin.Android.UnitTests.TestInstrumentation`1[TRunner].OnStart () at Android.App.Instrumentation.n_OnStart (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/builder/data/lanes/5945/28b08da2/source/monodroid/external/xamarin-android/src/Mono.Android/obj/Release/android-27/mcw/Android.App.Instrumentation.cs:1729 at (wrapper dynamic-method) System.Object.60d1c0b0-3a21-410a-9b3a-12e201b965fe(intptr,intptr) --- End of managed Java.Lang.NullPointerException stack trace --- java.lang.NullPointerException at android.app.Instrumentation.finish(Instrumentation.java:213) at md58bfc2187967f55be2f50e366b0d6b91f.TestInstrumentation_1.n_onStart(Native Method) at md58bfc2187967f55be2f50e366b0d6b91f.TestInstrumentation_1.onStart(TestInstrumentation_1.java:35) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1792)
1 parent bcb066c commit d42f3e6

File tree

2 files changed

+23
-23
lines changed

2 files changed

+23
-23
lines changed

tests/TestRunner.Core/TestInstrumentation.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ bool RunTests (ref Bundle results)
257257
results.PutLong (ResultInconclusiveTests, runner.InconclusiveTests);
258258
results.PutLong (ResultTotalTests, runner.TotalTests);
259259
results.PutLong (ResultFilteredTests, runner.FilteredTests);
260-
results.PutString (ResultResultsFilePath, resultsFilePath);
260+
results.PutString (ResultResultsFilePath, ToAdbPath (resultsFilePath));
261261

262262
Log.Info (LogTag, $"Passed: {runner.PassedTests}, Failed: {runner.FailedTests}, Skipped: {runner.SkippedTests}, Inconclusive: {runner.InconclusiveTests}, Total: {runner.TotalTests}, Filtered: {runner.FilteredTests}");
263263

@@ -364,5 +364,26 @@ protected HashSet<string> LoadExcludedTests (TextReader reader)
364364
excludedTestNames.Add (line);
365365
} while (true);
366366
}
367+
368+
// On some Android targets, the external storage directory is "emulated",
369+
// in which case the paths used on-device by the application are *not*
370+
// paths that can be used off-device with `adb pull`.
371+
// For example, `Contxt.GetExternalFilesDir()` may return `/storage/emulated/foo`,
372+
// but `adb pull /storage/emulated/foo` will *fail*; instead, we may need
373+
// `adb pull /mnt/shell/emulated/foo`.
374+
// The `$EMULATED_STORAGE_SOURCE` and `$EMULATED_STORAGE_TARGET` environment
375+
// variables control the "on-device" (`$EMULATED_STORAGE_TARGET`) and
376+
// "off-device" (`$EMULATED_STORAGE_SOURCE`) directory prefixes
377+
string ToAdbPath (string path)
378+
{
379+
string source = global::System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_SOURCE")?.Trim ();
380+
string target = global::System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_TARGET")?.Trim ();
381+
382+
if (!String.IsNullOrEmpty (source) && !String.IsNullOrEmpty (target) && path.StartsWith (target, StringComparison.Ordinal)) {
383+
return path.Replace (target, source);
384+
}
385+
386+
return path;
387+
}
367388
}
368389
}

tests/TestRunner.Core/TestRunner.cs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,28 +107,7 @@ protected virtual string GetResultsFilePath ()
107107
if (!usePathFile && !Directory.Exists (resultsPath))
108108
Directory.CreateDirectory (resultsPath);
109109

110-
return ToAdbPath (Path.Combine (resultsPath, ResultsFileName));
111-
}
112-
113-
// On some Android targets, the external storage directory is "emulated",
114-
// in which case the paths used on-device by the application are *not*
115-
// paths that can be used off-device with `adb pull`.
116-
// For example, `Contxt.GetExternalFilesDir()` may return `/storage/emulated/foo`,
117-
// but `adb pull /storage/emulated/foo` will *fail*; instead, we may need
118-
// `adb pull /mnt/shell/emulated/foo`.
119-
// The `$EMULATED_STORAGE_SOURCE` and `$EMULATED_STORAGE_TARGET` environment
120-
// variables control the "on-device" (`$EMULATED_STORAGE_TARGET`) and
121-
// "off-device" (`$EMULATED_STORAGE_SOURCE`) directory prefixes
122-
string ToAdbPath (string path)
123-
{
124-
string source = global::System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_SOURCE")?.Trim ();
125-
string target = global::System.Environment.GetEnvironmentVariable ("EMULATED_STORAGE_TARGET")?.Trim ();
126-
127-
if (!String.IsNullOrEmpty (source) && !String.IsNullOrEmpty (target) && path.StartsWith (target, StringComparison.Ordinal)) {
128-
return path.Replace (target, source);
129-
}
130-
131-
return path;
110+
return Path.Combine (resultsPath, ResultsFileName);
132111
}
133112
}
134113
}

0 commit comments

Comments
 (0)