How to profile a test in Android Studio? - unit-testing

My Android app has some slow running functionality. A unit test captures it perfectly. The unit test execution shows that it runs way slower than it should be.
Android Studio keeps offering me next to the run method a menu option: "Profile" instead of run. I select that option, but nothing different than run seems to happen. I expected Android Studio to open a window with the timing of all the method calls after the test completes.
I've searched Google and the Android site. Everything I find talks about profiling in Android Studio in general.
How do I profile an Android unit test? (What does that profile option really do?)

I had the same issue and I decided to investigate a solution because I was thinking that it couldn't be too hard. Boy was I wrong.
My original answer which was never posted contained some awkward fiddling around with Thread.sleep and manual timings and hitting the right button at the right time. This was replaced by a more elegant solution using the Debug API from within the code.
Using Android Studio 3.1.3 these were my steps:
I had to copy my actual unit test into androidTest (because I actually was interested in algorithmic complexity (and not time consumption) I found no way to actually profile inside Android Studio without an emulator. For performance tests this makes sense but in my case I wanted to ensure that even in complex scenarios my methods behave in a predictable fashion.)
To avoid the need of fiddling with with Thread.sleep and log output indicating a start/stop you can use combinations of Debug.startMethodTracing("File"); or Debug.startMethodTracingSampling() and Debug.stopMethodTracing(); or similar (See https://developer.android.com/studio/profile/generate-trace-logs). My code now looks like
#Test
public void Test_Something() throws Exception
{
Debug.startMethodTracing("Predict");
// DO YOUR CODE
Debug.stopMethodTracing();
}
When I now execute the profile I can obtain the .trace generated in the mentioned location on the device as stated in the link above:
(again read the linked page because you will need WRITE_EXTERNAL_STORAGE permission, which my app already had, so it wasn't that much of a hassle in my case.
Double clicking the trace opens it in Android Studio. Unlike stated at the link above I am currently unable to import such a trace in the profiler because either 3.1.3 lacks this function or I am unable to locate it.
Edit: After I upgraded to Android Studio 3.2 I now can indeed load and save sessions and display them in the Profiler. This has improved a lot. And interesting fact: When I opened the trace in Android Studio 3.1.3 I saw the hit count for methods (how often methods were called) and not their clock times. In the profiler on the other hand I was not yet able to find the call times but instead have access to wall clock times. Would be great if someone has a hint on how to display those too.

Related

Any way to manually trigger a Test Discovery pass in VS2019 from a VSPackage?

We're currently building an internal apparatus to run unit tests on a large C++ codebase, using Catch2 for the framework and our in-house VS test adapter (using [ITestDiscoverer] and ITestExecutor) to attune them to our code practices. However, we've encountered issues with unit tests not always being discovered after a build.
There's a couple of things we're doing out of the norm that may be contributing. While we're using VS2019 for coding, we use FASTBuild and Sharpmake to build our solutions (which can contain countless projects). When we realised that VS would try to build the tests again using MSBuild before running them (even after a full rebuild), we disabled that behaviour in the VS options. Everything else seems to be running as expected, except that sometimes tests aren't picked up.
After doing some digging (namely outputting a verification message to VS's Tests Output the moment our TestDiscoverer is entered), it seems like a test discovery pass isn't always being invoked when we would expect it, sometimes even with a full solution rebuild. Beyond the usual expectation that building a project with new changes (or rebuilding outright) would cause a pass to start, the methodology VS uses to determine when to invoke all installed test adapters seems to be fairly blackbox in terms of what exact parameters/conditions trigger it.
An alternative seems to be to allow the user to manually execute a TD pass via some means that could be wrapped in a VSPackage. However, initial looks through the VSSDK API for anything that'd do the job has come up short.
Using the VSSDK, are there any means to invoke a Test Discovery pass independently from VS's normal means of detecting whether a pass is required?
You would want to use the ITestContainerDiscoverer.TestContainersUpdated event. The platform should then call into your Container Discoverer to get the latest set of containers (ITestContainerDiscoverer.TestContainers). As long as the containers returned from the discoverer are different(based on ITestContainer.CompareTo()) the platform should trigger a discovery for the changed containers. This blog has been quite helpful in the past: https://matthewmanela.com/blog/anatomy-of-the-chutzpah-test-adapter-for-vs-2012-rc/

Visual Studio 2013 Profiling a Cinder project, not a single function call shows up

I recently upgraded to Visual Studio 2013, and found myself in the unusual position of suddenly needing to make use of a new aspect of VS that I've never worked with before. The profiler!
Long story short - I'm working a with a simple GUI framework I've designed, that recently had gesture support added. To my horror I found what worked more or less fine in one project, bogged down my main app quite horribly. I have a fairly good idea of what's causing it, but I'd still like confirmation - and since I will likely be working quite a bit more on the framework I'm building, it certainly doesn't help to have some profiling tools in place to remove eventual bottlenecks.
I ran the Visual studio performance wizard and was surprised to see (in the 'Call Tree' view) that the output consists of essentially nothing but calls to my TTD.exe (main application) and a bunch to ntdll.dll as well as few other DLLs I'm using.
That's fine and dandy - but I was expecting a much more granular report. As in - which of my functions were being used X percent of the time and the likes. Not a single function is mentioned anywhere...
Googling a bit, I found this particular link:
http://blogs.msdn.com/b/scarroll/archive/2005/04/13/407984.aspx
but I highly doubt that I need to use an additional server just to serve up my - possibly missing - symbols?
I'm a bit at a loss where to begin. Perhaps the issue is that I'm using Cinder and it does a bunch of stuff behind the scenes when starting up the app? To clarify - I'm not running my app from a std. main function. Cinder essentially provides a base framework called through a macro and then my app takes over via a number of setup(), draw() and update() calls. I'd just expect to see these littered all about.
But no... O_o
Has anyone encountered anything similar?
Regards,
Gazoo
You need to link your executable and DLLs with debug symbols.
In Debug builds this is on by default but in Release builds it's off by default.
Project properties->Linker->Debugging->Generate Debug Info = Yes (/DEBUG)

How to disable first-chance exceptions when unit testing Windows Phone 7?

I've been trying to get up to speed with unit testing in Windows Phone 7, and I have a basic test harness working, but when running the tests with the debugger attached, an Assert failure will cause VS to break at the exception:
From what I've read, I should be able to stop this behavior by disabling first chance exceptions. I tried unchecking User-unhandled from the Common Language Runtime Exceptions on the Debug->Exceptions dialog, as described in this blog post. This post was about enabling first chance exceptions, but I expected doing the opposite would disable them.
I tried adding the specific exception names as described in this blog post, and that also did not work:
Other details:
I'm using the Windows Phone SDK 7.1 Beta 2, published 6/29/2011
I'm using the updated Silverlight Unit Testing binaries for the Mango beta
I followed the first section of this cheat sheet to get the test harness running
I'm hoping that someone can point me in the right direction, or at least confirm that this does in fact work on their machine.
Ultimately, this isn't a big problem; I could start without debugging (CTRL+F5), and eventually, shouldn't hit this anyway since all the tests should pass, but it's annoying that I can't get it to run through without breaking into VS.
Have you tried this?
http://sgomez.blogspot.com/2009/12/how-to-disable-assert-dialogs-while.html
Add to your config file:
<system.diagnostics>
<assert assertuienabled="false"/>
</system.diagnostics>

Why does a MFC application behaves mysteriously in encrypted hard drive environment

I'm working on a bug where I have an MFC application that does weird things when installed in when Sophos Safeguard hard drive encryption is installed. I'm sorry to be so vague here, but I'm writing this away from the office so this is all from my (poor) memory.
Three things I've noticed:
AfxGetResourceHandle() doesn't return a consistent resource handle. There is a single case where we try to load a string resource, and for some reason, the resource handle that we get from this method is different to all the other stings.
Can't construct a CDocumentTemplate. There is a trace error which I cant seem to recall. Will edit and post when I'm in tomorrow.
This behaviour appears to manifest in a Visual Studio 2005 version of the project, but not a Visual Studio 2008 version. Unfortunately moving to the 2008 version is not an option.
The bug is not always reproducable if I step through with a debugger. Also, bringing up debug message boxes changes the behaviuor, which leads me to think that either there is some kind of race condition going on with the way MFC events are being handled, but I'm not sure how I'll ever know for sure, or even what I can do about it if I did.
I think there's some underlying reason that the app is behaving weirdly, but what I've posted are more symptoms. Can anyone think of what I should check for?
I've run Windows update on the test environment to ensure everything was up to date, and I've examined the process in procmon to see if the disk encryption stuff was getting in the way and conflicting with files - it didn't appear to be, but it does appear to be involved in some way as our app accesses Sophos related paths in the temp directory.
If your code is multithreaded (which I assume it is, since you mentioned the possibility of a race condition), then the likelihood is that the decryption delays are exposing concurrency flaws. You might want to try running the application off of a network share or similar slow access device to see if it manifests similar problems.
Turned out that the antivirus software was injecting itself in a way where the antivirus' software's resource handles were overridng the app's resource handles. Yuck!

Logging/monitoring all function calls from an application

we have a problem with an application we're developing. Very seldom, like once in a hundred, the application crashes at start up. When the crash happens it brings down the whole system, the computer starts to beep and freezes up completely, the only way to recover is to turn off the power (we're using Windows XP). The rarity of the crash combined with the fact that we can't break into the debugger or even generate a stackdump when it occurs makes it extremely hard to debug.
I'm looking for something that logs all function calls to a file. Does such a tool exist? It shouldn't be impossible to implement, profilers like VTune does something very similar.
We're using visual studio 2008 (C++).
Thanks
A.B.
Logging function entries/exits is a low-level approach to your problem. I would suggest using automatic debugger instrumentation (using Debugger key under Image File Execution Options with regedit or using gflags from the package I provide a link to below) and trying to repro the problem until it crashes. Additionally, you can have the debugger log function call history of suspected module(s) using a script or have collect any other information.
But not knowing the details of your application it is very hard to suggest a solution. Is it a user app, service or a driver? What does "crashes at startup" mean - at windows startup or app's startup?
Use this debugger package to troubleshoot.
The only problem with the logging idea is that when the system crashes, the latest log entries might still be in the cache and have no chance to be written to disk...
If it was me I would try running the program on a different PC - it might be flaky hardware or drivers causing the problem. An application program "shouldn't" be able to bring down the system.
A few Ideas-
There is a good chance that just prior to your crash there is some sort of exception in the application. if you set you handler for all unhandled exceptions using SetUnhandledExceptionFilter() and write a stack trace to your log file, you might have a chance to catch the crash in action.
Just remember to flush the file after every write.
Another option is to use a tool such as strace which logs all of the system calls into the kernel (there are multiple flavors and implementations for that so pick your favorite). if you look at the log just before the crash you might find the culprit
Have you considered using a second machine as a remote debugger (via the network)? When the application (and system) crashes, the second machine should still show some useful information, if not the actual point of the problem. I believe VC++ has that ability, at least in some versions.
For Visual C++ _penter() and _pexit() can be used to instrument your code.
See also Method Call Interception in C++.
GCC (including the version MingGW for Windows development) has a code generation switch called -finstrument-functions that tells the compiler to emit special calls to functions called __cyg_profile_func_enter and __cyg_profile_func_exit around every function call. For Visual C++, there are similar options called /GH and /Gh. These cause the compiler to emit calls to __penter and __pexit around function calls.
These instrumentation modes can be used to implement a logging system, with you implementing the calls that the compiler generates to output to your local filesystem or to another computer on your network.
If possible, I'd also try running your system using valgrind or a similar checking tool. This might catch your problem before it gets out-of-hand.