Commit d1d9820a enabled `Xamarin.Android.Bcl-Tests` to build and run
in the Release configuration. This was the right idea, but the wrong
time: [The Jenkins build for xamarin-android/d0d8640b][xad0] reports
68 failures, due to running the `Xamarin.Android.Bcl-Tests` in the
Release configuration, in which the linker is *enabled*.
[xad0]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/666/
Enabling the linker is breaking these tests. :-(
This needs to be addressed -- enabling the linker should *not* break
the BCL unit tests! -- but in the meantime, partially revert commit
d1d9820a and only run the BCL unit tests in the Debug configuration,
removing this source of unit test failures.
Emulator-related failures (3294a50e, db668ba0, c0892674, bc6440bc,
3fa9e9e9, b54f8cd2, 3b893cd4, 7450efcc, and 6358a643) are
unfortunately *still* a fact of life (argh!).
The current set of issues:
* [A never-seen-before failure in `adb uninstall`][xa662]:
Tool …/adb execution started with arguments: -s emulator-5570 uninstall "Mono.Android_Tests"
Failure [DELETE_FAILED_INTERNAL_ERROR]
* [A continuing problem connecting to the Package Manager][xa664]:
Tool …/adb execution started with arguments: uninstall "Mono.Android_Tests"
Error: Could not access the Package Manager. Is the system running?
[xa662]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/662/
[xa664]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/664/
Both of these problems appear related to the emulator being in some
"invalid" state, and poses the question: can we determine that the
emulator is FUBAR *earlier*, so that we can create a new (saner?)
emulator instance?
Take a stab in the dark, and hope that *any* `adb shell pm`-related
command will trigger the same set of errors, and update the
`<CheckAdbTarget/>` task to issue the following command if the
emulator appears to be valid:
adb shell pm path com.android.shell
If the above `pm path` command fails -- ideally with one of the above
messages -- then flag the target as invalid. This will cause the
`AcquireAndroidTarget` target to use the `<CreateAndroidEmulator/>`
and `<StartAndroidEmulator/>` tasks to create a new emulator.
The one downside is that we presumably have these invalid emulators
running around in the first place because the `ReleaseAndroidTarget`
target isn't reliably exiting the emulator instance (b54f8cd2).
Attempt to improve this by following the suggestion from b54f8cd2:
escalate to killing with extreme `kill -KILL` prejudice.
The [Jenkins `xamarin-android` build][xae9] for commit e9daf5ea was
unexpectedly UNSTABLE, because an error was encountered:
[xae9]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/662/
Tool …/adb execution started with arguments: -s emulator-5570 install "…/xamarin-android/tests/../bin/TestRelease/Xamarin.Android.Bcl_Tests-Signed.apk"
adb: error: cannot stat '…/xamarin-android/tests/../bin/TestRelease/Xamarin.Android.Bcl_Tests-Signed.apk':
No such file or directory
The error was encountered because `tests/Xamarin.Android.Bcl-Tests`
wasn't built for the Release configuration, because it wasn't part of
`$(TEST_APK_PROJECTS_RELEASE)` within `Makefile`.
This raises an interesting question: what is the best solution?
1. Make `Xamarin.Android.Bcl-Tests` a Debug-only unit test.
2. Build and run `Xamarin.Android.Bcl-Tests` in both Debug & Release.
...quickly followed by a *second* question:
Why are some tests Debug-only and some aren't?
I don't have a good handle on this second question, other than that it
would "duplicate" unit test execution, thus lengthening build times.
However, I'm not convinced that's a good rationale, either: the
Release runtime has optimizations (`-O0 -fno-omit-frame-pointer` Debug
vs. `-O2` Release), which could theoretically break a great many
things. The Release runtime is also what is used in our commercial
products; the Debug runtime is largely only useful for #runtime
debugging.
We thus should want as many tests as possible to run in Release, not
as few as possible
This allows us to tentatively answer the first question: we should add
`Xamarin.Android.Bcl-Tests` to `$(TEST_APK_PROJECTS_RELEASE)` so that
it's run in *both* Debug *and* Release configurations. This in turn
will ensure that the failing `adb install` command succeeds, which
*should* allow the build to PASS, as desired.
What do we want? (with apologies to 48e3fc26)
**MOAR** Unit tests!
Specifically, we want to run the BCL unit tests which mono generates:
$ cd external/mono/mcs/class/corlib
$ make PROFILE=monodroid test
# creates `monodroid_corlib_test.dll`
Creation of `monodroid_*_test.dll` assemblies and the
`make PROFILE=monodroid test` target is a relatively recent
development, for which I need to buy the #runtime team some beers.
In terms of `mono-runtimes.targets`, we can build *all* of the BCL
unit test assemblies with:
$ cd external/mono/mcs/class
$ make -i do-test PROFILE=monodroid
Now that we can create them, how do we *use* them? That's the trickier
bit: they need to be built within mono, as part of the existing BCL
build process. This in turn means that the BCL unit test assemblies
need to be distributed as part of the mono bundle, as we don't want to
rebuild the mono repo "from scratch" just for the unit tests.
Update `build-tools/mono-runtimes/ProfileAssemblies.projitems` to
include a new `@(MonoTestAssembly)` item group which contains all of
the BCL unit test assemblies and related files which should be
included into `bundle-*.zip`. Additionally, add
`ProfileAssemblies.projitems` to `@(VersionFile)` witihin
`bundle-path.targets`, so that if anything within
`ProfileAssemblies.projitems` changes, we rebuild the bundle.
Once we *have* the BCL unit test assemblies, and their dependencies,
we need to *run* them. The new `Xamarin.Android.Bcl-Tests.csproj`
project is a Xamarin.Android application project which will execute
the unit tests.
There's just one small problem: Xamarin.Android apps want to use
`Xamarin.Android.NUnitLite.dll`. The BCL unit test assemblies instead
build against their own `nunitlite.dll`, which has no Xamarin.Android
integration or support. How do we use the new test assemblies?
*Force* a fix by using `remap-assembly-ref` to "rename" the
`nunitlite` assembly reference to `Xamarin.Android.NUnitLite.dll`.
This *cannot* be done as part of the `mono-runtimes.mdproj` build, as
`Xamarin.Android.NUnitLite.dll` won't yet exist. Instead, remap the
assemblies within `Xamarin.Android.Bcl-Tests.targets`, and distribute
the remapped assemblies with the application.
Finally, address one other "small" problem: not all of the unit tests
pass! Some of these are for reasons we don't know, and others will
require changes to `mono`.
Update `Xamarin.Android.NUnitLite` to allow *filtering* of tests:
namespace Xamarin.Android.NUnitLite {
partial class TestSuiteActivity {
public ITestFilter Filter {get; set;}
public virtual void UpdateFilter ();
}
partial class TestSuiteInstrumentation {
public ITestFilter Filter {get; set;}
public virtual void UpdateFilter ();
}
}
`TestSuiteActivity.UpdateFilter()` is called by
`TestSuiteActivity.OnCreate()`, *after* `GetIncludedCategories()` and
`GetExcludedCategories()` are called, to allow subclasses to alter the
`ITestFilter` which is used to determine which tests are executed.
`TestSuiteInstrumentation.UpdateFilter()` is called by
`TestSuiteInstrumentation.OnStart()`, *after*
`GetIncludedCategories()` and `GetExcludedCategories()` are called, to
allow subclasses to alter the `ITestFilter` which is used to determine
which tests are executed.
`Xamarin.Android.Bcl_Tests` overrides both of these and updates the
`Filter` property so that "known failing" tests are excluded. This
allows us to skip failing tests, giving us time to properly fix them
in time while allowing the rest of this PR to be merged.
The skipped tests include:
* MonoTests.System.Reflection.AssemblyTest.GetReferencedAssemblies
* MonoTests.System.ServiceModel.Description.WebInvokeAttributeTest.RejectTwoParametersWhenNotWrapped
Context: The `Adb` task inherits `PathToolTask`, which inherits
`ToolTask`.
The `Adb` task's `ToolExe` is commonly set to `$(AdbToolExe)`. The
problem with this is that `Microsoft.Build.Utilities.ToolTask` has its
own validation that checks if the file exists. On Windows, a file named
`adb` does not exist, because it is named `adb.exe`.
The solution here is to not set `base.ToolExe` if the incoming value
already matches `ToolBaseName`. This prevents the validation, and
`PathToolTask` can continue to use `Which` appropriately to either find
`adb` or `adb.exe` depending on the platform. This also allows
`$(AdbToolExe)` to be overidden if needed.
Recent versions of the Android Lint tool are now reporting:
obj/Debug/android/src/md5f80e635856c5c6d2b732d9b14f8f2b1f/MainActivity.java(27,13): error XA0103: Overriding method should call super.onCreate [MissingSuperCall]
because we don't call `super.onCreate()` in our JCW genearted code.
This is by design -- *managed* code will perform an equivalent
`base.OnCreate()` call -- so we need to ignore this particular error.
That said we now have 4 issues we ignore, so rather than keep
duplicating code it has been refactored to use a `string[]`.
- `%JAVA_HOME%` needs to be set for `avdmanager.bat`
- Installing apks on the emulator was failing with
`INSTALL_FAILED_INSUFFICIENT_STORAGE` on Windows
- A newer revision of the emulator fixes this, now using
`x86-21_r05.zip`
- `$(JavacFullPath)` was hardcoded to `javac`
- `$(JarFullPath)` was harcoded to `jar`
- Now uses `AndroidSdkInfo` to locate java
- Tests using this should now pass on Windows
Upgrade to use NUnit 3.7, as this version supports running test
methods in parallel, not just test fixtures.
Add `[Parallelizable (ParallelScope.Children)]` where appropriate
so that tests *are* run in parallel. This cuts PR build times from
roughly 1h16min to 52min, a ~32% reduction in build times!
Fix tests so that they *can* be run in parallel. Many of the tests
were using the same folders, which causes problems when the tests are
run in parallel as the tests will conflict with each other --
one test might delete an entire directory causing another to fail.
Many of the tests also take parameters, we usually use
TestContext.CurrentContext.Test.Name
when we want to use the Test method as the name. However
with parameterized tests this can sometimes include invalid
characters for paths/filenames. So a new property has been
introduced in the `BaseTest` class `TestName` which cleans up
and removes problematic characters.
Update the `make run-nunit-tests` target so that it now takes a
`$(TEST)` variable, which allows running a specific test fixture
or method, not all tests:
make run-nunit-tests \
TEST=Xamarin.Android.Build.Tests.BuildTest.BuildBasicApplication \
NUNIT_TESTS=bin/TestDebug/Xamarin.Android.Build.Tests.dll
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=59764
Our regex to pick up error messages from the android tooling is
picking up *warnings*:
obj/Debug/res/drawable-nodpi/background_started.png: libpng warning: iCCP: Not recognizing known sRGB profile that has been edited
This is because the format matches our error regex.
So we need to ignore things that have "warning" in them and log
those as actual warnings, instead of percolating them as errors.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=59651
We were passing ALL the `.class` files in as parameters to the
`dx.jar` invocation. Turns out we can just pass the top level
directory. In this case `$(IntermediateOutputPath)android\bin\classes`
will do fine. Because it's a directory `dx` will pick up any
`.class` file it finds in any subdirectory.
I did try this with the `.jar` files as well, but because a lot
of the libraries have a `lib` folder which contain an internal `.jar`
file it causes problems. This is because it produces duplicate types.
So rather than specifically ignore the `lib` folder (which might change)
we will just stick to the current system.
Somehow the latest class-parse gives more parameter names on api-26
(we have no idea what caused that). That somehow resulted in some
event generation related breakage, which is also fixed in this change.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=59534
When using `@(PackageReference)` with our system it run before
`_SetLatestTargetFrameworkVersion`. As a result it always
uses a `$(TargetFrameworkVersion)` of v2.3 or what ever the
user defined in the project manually.
So we need to make sure that `_SetLatestTargetFrameworkVersion`
runs as part of the `@(PackageReference)` target chain. Fortunately
that chain is run as part of `ResolveNuGetPackageAssetsDependsOn`.
As well as `_GetRestoreTargetFrameworksOutput`.
So we just need to make sure that our target in run as part of
that target chain in order to fix this issue.
We also need to update a few NuGet specific properties to ensure
that it uses the correct `$(TargetPlatformMoniker)`. This is done
via the `NuGetTargetMoniker`.
Our unit tests reliably take over 5 seconds to do a design time
build :(. But that does not happen locally, so we are bumping the
time limit up to 8 seconds.
OK completely forgot when writting this that under VS2017..
`$(DesignTimeBuild)` is NOT set :(. As a result when the old
`<Choose/>` statements run.. we always get a value of `False`
for `$(ManagedDesignTimeBuild)`.
So lets rework the task to make sure we do all the required
calculations in `_SetupDesignTimeBuildForCompile` which does
get run right at the start of the `Compile`.
Context: https://jenkins.mono-project.com/job/xamarin-android-pr-builder/1659/testReport/
I’ve been noticing the Xamarin.Android.Build.Tests are occasionally
failing and reporting zero test results (no failures, no success). This
situation doesn’t break PR builds, and effectively skips
Xamarin.Android.Build.Tests.
Updating NUnit.ConsoleRunner may be the fix as mentioned on this issue:
https://github.com/nunit/nunit/issues/1509
Unfortunately NUnit has some more dependencies now, so there are a few
more packages. I chose version 3.6.0, as I could get a parallel version
number across all NUnit packages.
This resolves several issues:
- `XamarinProject` was not finding NuGet.exe on Windows and the process
is visible
- On Windows, the tests need `libzip.dll` and `zlib.dll` in their output
- `BindingBuildTest` was not using `android-support-multidex.jar` from
VS 2017 installation
- `RunAdbCommand` was using unix-style paths
Changes:
- Run `.nuget/NuGet.exe` on Windows and make it hidden
- Bump LibZipSharp, which better supports `<ProjectReference />`,
`libzip-windows.mdproj` no longer needs to do anything on Windows
- `BindingBuildTest` can use the `FrameworkLibDirectory` property
- `RunAdbCommand` should use `Path.Combine`
- Removed duplicate `FSharp.Compiler.CodeDom` in `packages.config`
Context: https://github.com/jonathanpeppers/xabuild
In creating a prototype `xabuild.exe` that is cross-platform, I’ve
discovered these `*.targets` files are needed on macOS as well as
Windows. Without them, PCL projects (such as a Xamarin.Forms app) do
not build properly when using `xabuild.exe`.
Context: commit e5cc9e2d
Since we are now downloading the bundle to `~/android-archives`, it is
possible that the directory will not exist on a clean machine. We should
be calling `Directory.CreateDirectory()` in the `DownloadUri` task anyway,
as this could easily happen on any destination file.
A case this occured happened on VSTS:
https://devdiv.visualstudio.com/DevDiv/_build/index?buildId=1006149
Previously the bundle was being downloaded to `bin/BuildDebug`, which
would be commonly cleaned for each build on CI systems. We can speed up
our builds by downloading the file to `~/android-archives`, which is
already used for various other downloads. This will persist the file
between builds on the same build agent.
Commit 6fd330df tried to provide a reasonable default for `$(HOME)`
when building on Windows (...years before we could do that):
> I've arbitrary decided to download the files into
> $(HOME)\android-archives and install them into
> $(HOME)\android-toolchain. On windows, this is
> %HOMEDRIVE%%HOMEPATH%\android-archives and
> %HOMEDRIVE%%HOMEPATH%\android-toolchain.
Where did `%HOMEDRIVE%` and `%HOMEPATH%` come from? They came from an
available Windows machine, and otherwise looked sane and useful.
Unfortunately, [when building in the VSTS build agent][0], neither
`%HOMEDRIVE%` nor `%HOMEPATH%` are set, resulting in `$(HOME)`
not being set at all!
[0]: https://devdiv.visualstudio.com/DevDiv/_build/index?buildId=1004861
Instead of setting `$(HOME)` to `%HOMEDRIVE%%HOMEPATH%` on Windows,
set it to `%USERPROFILE`, which appears to be a more useful
environment variable.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=59516
Context: https://bugzilla.xamarin.com/show_bug.cgi?id=59015
The linker requires that the target process contain members such as
`System.Threading.Tasks.Task.NotifyDebuggerOfWaitCompletion()`.
If these members are missing, the runtime may abort:
* Assertion at …xamarin-android/external/mono/mono/mini/debugger-agent.c:4765, condition `array->len == 1' not met
[libc] Fatal signal 6 (SIGABRT), code -6 in tid 11492 (…)
Update the linker so that `async`-related Debugger support
infrastructure is preserved, so that the debugger can rely on them.
*Note*: This commit does *not* fix the assert reported in Bug #59015
on Android as that happens when the linker is disabled as well.
Fixing the assert from Bug #59015 will require another fix.
Commit 73dc058 removed the default for `$(EmbedAssembliesIntoApk)` if
it is blank. This was not the right thing to do :).
This commit adds the a default of 'True' is `$(EmbedAssembliesIntoApk)`
if completely emplty by the time it has gone through all the other
processes.
`Builder.cs` used in the unit tests does not currently use MSBuild from
Visual Studio 2017.
MSBuild is now located by checking the following:
- Check `%XA_MSBUILD_EXE%` environment variable
- Check VS 2017 path
- Check older VS path
- Check .NET path
Also updated `FrameworkLibDirectory` to check VS 2017 path.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=57849
We are sometimes getting duplicate assembly references in the `@(ReferencePath)`
ItemGroup. This is comming from the DesignTime Facade assembly detection.
Looking at the msbuild targets [1], they do duplicate detection by checking the
`%(Filename)` does not exist in the assembly list already. So we should
do the same in our Xamarin.Android.PCLSupport.targets. We use the `CreateItem`
Task rather than `ItemGroup`. This is because it seems xbuild does
NOT like it when you use `%(ItemGroup.MetaData)` when defining additonal
metadata using the `ItemGroup` syntax.. It things its an assembly it
needs to load... weird.
[1] https://github.com/mono/msbuild/blob/xplat-master/src/Tasks/Microsoft.NETFramework.CurrentVersion.targets#L103
Bumps to Java.Interop/master/f3750484.
This fixes JavaNativeTypeManager.PackageNamingPolicy initialization issue
that blocks the entire use of package naming policy customization (one in
Xamarin.Android.Build.Tasks.dll is initialized in GenerateJavaStubs, while
the actual use in Java.Interop.Tools.JavaCallableWrappers.dll never gets
initialized).
Added test for PackageNamingPolicy.Lowercase. Deployed apps work fine too.
The newly added source is positioned at the weird location because
there is a hack around positioning sources:
https://github.com/xamarin/xamarin-android/commit/ada479b
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=57342
Commit 8f2ae248 attempted to fix this issue. However it made the
assumption that `@(ReferenceCopyLocalPaths)` contained the same
items as `@(ReferencePath)`. However it did not. So we should use
a combination of the two to figure out what assmeblies are needed.
We need to disgard reference assemblies though, we do this by
checking for the appropriate attributes before we add the assembly
to the list of items we want to package.
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=51664
The fixes are twofolds:
- Add `GetAction()`/`SetAction()` to alter `Action` property and
add `[Obsolete]` on the `Action` property.
- Add `PerformAccessibilityAction()`/`PerformAction()` overloads
that use Action instead.
In the future we may remove `[Obsolete]`d members so that we can
bring back a sanitized API.
- Needed to `nuget restore Xamarin.Android-Tests.sln`
- Added `$(XAIntegratedTests)` property which defaults to True.
Windows will need to set this property in order to build
`Xamarin.Android-Tests.sln`
- Some project references in `Mono.Android-Tests.csproj` should
be conditional against `$(XAIntegratedTests)`==True
- Usage of `zip -r` is replaced with `jar cf` using `$(JarPath)`
(Windows doesn't have `zip`)
- `Xamarin.Android.Build.Tasks.csproj` had a file-locking issue
similar to `create-vsix.csproj` (2bca09d1): the
`_GenerateXACommonProps` target needs to depend on `ResolveReferences`
Other changes:
- Update README
- Update .gitignore for `.gradle/` and `*.user` files
Commit b16ee559 made `GdbPaths` private. But it is needed/used by
the monodroid repo. This commit makes it `public` and allows
the `Xamarin.Android.Build.Debugging.Tasks` access it.
One annoying thing when developing tests is if you have a failing
test you have to modify the source code to stop it being cleaned up.
This commit checks to see if the Debugger is attached before cleaning
up. If it is attached the source code for the test will not be removed.
This will allow the developer to examine the results.
This commit makes a number of changes to the unit tests to allow us
to handle different behaviour between xamarin-android and monodroid.
Firstly we can now ignore AOT based tests if the compilers or
runtime is not available. This means we can share the test inputs
between repos.
We also split out the Debugger Attribute test inputs into a
`ManifestTest.OSS.cs` file to we can provide different inputs in
monodroid. This is because there is a difference in behaviour between
the two systems. In certain cases in monodroid we *do* want a debug
runtime/attribute where in xamarin-android we never do.
For example in xamarin-android having:
* `$(DebugSymbols)`=None
* `$(EmbedAssembliesIntoApk)`=False
* `$(Optimize)`=False
will result in `//application/@android:debuggable` *not* being added.
This is correct behavior in xamarin-android because we *always*
embed assemblies regardless of the value of `$(EmbedAssembliesIntoApk)`.
In monodroid however that is incorrect, so we need separate test cases.
This commit also moves some of the logic to do with
`$(EmbedAssembliesIntoApk)` into `Xamarin.Android.Common.targets`.
This is protected by the `$(_XASupportsFastDev)` property.
This means the logic is all in one place rather than
being split up across `.targets`. This should make it easier to maintain.
We need to create symbolic links for `Xamarin.Android.Sdk.props` and
`Xamarin.Android.Sdk.targets` so you can test changes to these files on
Windows.
Changes:
- `Xamarin.Android.Sdk.targets` needs to be copied to build output on
Windows
- setup-windows refactored to support both files & directories
- setup-windows now links the additional files
- Updated example output in documentation
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=59473
Commit d079a42e went a bit too far when removing duplicates.
It removed *any* duplicate entry that appeared anywhere in the
document. What we really wanted to remove full duplicates that
exist at the same level as the current element in the document.
For example:
```xml
<foo>
<bar name="bar1">
<bar2 />
</bar>
<bar name="bar2">
<bar2 />
</bar>
<dupe/>
<dupe/>
</foo>
```
`<bar2/>` should *not* be removed but one of the `<dupe/>` values
should. This commit reworks `RemoveDuplicates()` code to handle the
correct logic. It also adds a unit test for this exact senario.
Implement linker's new `ILogger` interface to log linker messages in the
`<LinkAssemblies/>` task. This way we can see the linker messages in the
diagnostic build output, without the need to set the `__XA_LOG_ERRORS__`
environment variable.
This way we can see for example messages from the
`FixAbstractMethodsStep`, so we know whether any assemblies were
modified when the linker mode was set to None. (like we do in default
Debug configuration) That is handy when we are trying to decide
whether a bug is related to or caused by the linker.
The new `versionCode` system introduced in commit 0a2f008c is now on by default.
The default code is
{abi}{versionCode:D6}
For a `versionCode` of `123` the default will produce a code of `123`
for a full .apk and `200123`, `300123`, etc for split abi .apks.
Developers can revert to the existing behaviour by setting
<AndroidUseLegacyVersionCode>true</AndroidUseLegacyVersionCode>
in their `.csproj`. This will revert to the existng behaviour by *not*
setting the default value for `$(AndroidVersionCodePattern)`.
There is some code which is conceptually, if not literally, duplicated
between the xamarin-android and the IDEs (Visual Studio,
Visual Studio for Mac), in particular code that deals with finding the
Android SDK and Java JDK locations.
This code has been split out into a new `xamarin-android-tools` repo
to facilitate sharing, without the IDEs needing to submodule
xamarin-android, which is quite large.
Cleanup the xamarin-android repo to use the new xamarin-android-tools
repo for Android SDK information/etc.