Using Fiddler with Windows Store Unit Test - c#

I want to run Fiddler to help debug a portable API client that I'm developing.
In Visual Studio, on the Windows Store Unit Test project property page > Debug tab I have checked the 'Allow Local Network Loopback' option.
Every web request run during a store unit test fails with a System.Net.Sockets.SocketException : A connection attempt failed because the connected party did not properly respond after a period of time or established connection failed because connected host has failed to respond 127.0.0.1:8888.
The Uri I'm connecting to is not local - but another machine on the local network - so this fiddler loopback address is indeed coming from the global proxy setting.
I know that for Windows Store Apps you have to enable the loopback network isolation exemptions and have ticked every app container listed in the UI for that (despite none of them being related to VS or this unit test projects) - to no avail.
I've also tried disabling IPv6 in Fiddler - don't know why I thought that might work, but it was worth a punt - it didn't work either.
Anyone got any ideas!?

Okay - whilst I was on the right track, thinking that there must be some app container registered for the unit test project - what I didn't think was that it might only be active while MSTest is running.
You need to debug the Windows Store unit test (any of the tests in the project) and stick a breakpoint in (to halt execution of the test runner) so it will then appear in the list of AppContainers within Fiddlers' Loopback Extensions tool.
So - given this test:
[TestMethod]
public async Task Example()
{
var result = await GetSomeData(); //<-- breakpoint
Assert.IsNotNull(result);
}
private async string GetSomeData()
{
//TODO something that makes a web request with, say, HttpClient
}
All you do is breakpoint the line shown above - and then launch the 'Win8 Config' option from Fiddler - and you'll see that your unit tests project appears in the list of AppContainers.
Enable loopback for that app container, save the changes and then continue in your unit test - you should see the traffic correctly captured.
After doing this once it would seem that you don't have to do it again - I've closed down fiddler and restarted it and the traffic is still captured correctly.
One word of warning, however, once you do this the Loopback exemptions tool will moan about an exemption being defined for a SID for which there is no AppContainer if it is launched - unless you happen to be running a unit-test again.

Related

How to debug connection to MQTT server using Xamarin System.Net.Mqtt on Android?

I'm trying to build a simple MQTT application using Xamarin, and testing it on both an Android emulator and a phone. Unfortunately, I'm struggling to make a connection with CreateAsync, and at a loss how to debug it.
I've checked I can connect to my RabbitMQ server as follows:
using System.Net.Mqtt;
Console.WriteLine("Trying to connect...");
var configuration = new MqttConfiguration();
var client = MqttClient.CreateAsync("127.0.0.1", configuration).Result;
var sessionState = await client.ConnectAsync(new MqttClientCredentials(clientId: "test", userName:"mqtt", password:"mqtt"));
Console.WriteLine("...it worked.");
Console.Read();
As the code tells me... it worked. :o) RabbitMQ shows the connection. I tried it with "localhost", the hostname and IP of my PC to check they all work, and an incorrect host name to see what exception gets thrown ("Socketexception: No such host is known").
My troubles start when I try to do this in the actual app. The connection code is fundamentally the same, but run in a separate task as I read you shouldn't do it in the GUI thread:
private async Task<SessionState> Connect(string BrokerHostName, Action<MqttApplicationMessage> publishEventHandler)
{
MqttConfiguration config = new MqttConfiguration();
_client = MqttClient.CreateAsync(BrokerHostName, config).Result;
SessionState sessionState = await _client.ConnectAsync(
new MqttClientCredentials(clientId: Id, userName: "mqtt", password: "mqtt")
);
await _client.SubscribeAsync("common", MqttQualityOfService.AtMostOnce);
_client.MessageStream.Subscribe(publishEventHandler);
return sessionState;
}
Called by:
var task = Connect(BrokerHostName, publishEventHandler);
But nothing happens - the code reaches this line and just hangs. If I set a break, continuing just continues to do nothing. I've made sure the INTERNET and ACCESS_NETWORK_STATE permissions are ticked in the Android manifest (though it makes no apparent difference).
This is what I've tried after some hours of Googling:
Using the hostname or IP address of my PC with the Android device, running with and without debug, and also unplugged from PC and run on its own.
Using 10.0.2.2 and running on the emulator, as I understand this is the equivalent of localhost or 127.0.0.1.
Setting the proxy address on the emulator to the same as my PC and port 1883. Even though the 'Apply' button teases with a "Proxy status: success", it still doesn't connect.
It feels like a networking problem since I can put any old rubbish as the host address and it behaves the same, but I've totally run out of ideas for what to try next or how to see what's going on. Any advice very gratefully received!
I now have this working. Here's the steps I took, in case it helps someone else:
I wrote some test apps to check TCP communication. First a client and server in Windows to check they work, then a Xamarin client app. This worked and proved the network connections were OK.
Installed an MQTT Tester on the Android emulator to prove it was possible to connect to RabbitMQ.
Tried a different MQTT framework: MQTTnet.
Similar problem but different symptoms: the code would get stuck on the .Wait() rather than inside the task itself. Then I removed all the asynchronous code and then it connected.
My conclusion is that the problem may be my lack of understanding of asynchronous programming. System.Net.Mqtt seems to require it while MQTTnet does not, so all's well that ends well!

C#: How to manage Charles Proxy to trace calls from Visual Studio or Rider?

I use Charles Proxy on Mac OS, to debug mobile app: it works well on real devices (iOS/Android), on iOS simulator, but it's a little tricky on Android simulators (several IPs are used for the same URL).
However, I try to debug APIs Integrations Tests, and in this case, I don't see any trace in Charles Proxy...
I've tried to do this with Visual Studio for Mac and with Rider.
When I debug the test, I can see that the call is well done, but I don't see any trace in Charles Proxy, whereas when I use the same URL in the mobile app, I can see the trace easily.
Is there a specific step to do to include calls from console app or Integration Tests calls from any IDE? (Visual Studio for Mac or Rider)
In the same time, I can see all the traces coming from Chrome, Safari, Slack,... So I don't see what I could have forgotten.
After having edited the HttpClientHandler like this, I can see traces in Charles Proxy:
public class TestsHttpMessageHandlerFactory : IHttpMessageHandlerFactory
{
public HttpMessageHandler Create()
{
return new HttpClientHandler
{
Proxy = new WebProxy("http://192.168.86.177:8888"),
UseProxy = true
};
}
}
But now I have the following error details in Charles Proxy:
- Status: Failed Failure: Client closed the connection before a request
was made. Possibly the SSL certificate was rejected.
- Notes: You may need to configure your browser or application to trust the Charles Root Certificate. See SSL Proxying in the Help menu.
- Response Code: 200 Connection established
How to configure the certificate in my app?
Regards,

Remote Desktop, Selenium and SendKeys: WebDriver server timed out after 60 seconds

I have a Selenium test which would fail when run as part of a Jenkins job on a node hosted in vSphere and administered through RDP. The test are run with IE11.
After some troubleshooting it turned out it succeeds if Remote Desktop is connected and focused but fails with an exception if Remote Desktop is disconnected or even minimized:
OneTimeSetUp: OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:56095/session/817b36df-a1b5-484e-b205-d4a0bac8002a/element/0cfa6678-2104-4bc6-bb71-e6d8eac507fb/value timed out after 60 seconds.
----> System.Net.WebException : The operation has timed out
The failing line:
textboxElement.SendKeys("foo").Perform();
As a workaround, I logged through vSphere Console instead of RDP and then even after closing vSphere the test didn't fail anymore. This is a workaround but I would have to be careful never to login through RDP and always to administer only through vSphere Console.
So my questions are:
Is SendKeys() somehow incompatible with an RDP session and is it related to this winapi bug?
Is there an alternative to using SendKeys() in Selenium?
When you execute the selenium script without any UI environment bind to the process the size of the Chrome window may be different from when you execute it when you are logged in with RemoteDesktop.
Try to explicitly set window size in the selenium script prior to the failing command.
1) try some small width/height and execute it where the script usually succeeds, and see what happens
2) set to some large value and execute it on Jenkins, where it usually fails.
Found the culprit - there was a flag RequireWindowFocus = true in InternetExplorerOptions which was causing the issue. After removing it I no longer get the error. This might be related to https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/5431.

Connecting to Websphere MQ queue manager works in application A but not in application B

I have two console applications, A and B.
The application A was created for test purposes and works as expected.
The application B does not work although it is basically a copy-paste of A's code:
System.Console.Write("User Name: ");
string username = System.Console.ReadLine();
System.Console.Write("Password: ");
string password = ConsoleReadPassword();
System.Console.WriteLine();
//user and password required because I am also a privileged user
//(member of mqm group)
MQEnvironment.UserId = username;
MQEnvironment.Password = password;
//for application B this line throws exception with code 2538
var queueManager = new MQQueueManager("TEST.QUEUE.MANAGER", "CLIENT.CONN.CHANNEL", "localhost(1414)");
Error code 2538 means "Host not available" which is weird because application A has no problems connecting to the same host.
This is how the MQ Server looks in MQ Explorer:
Queue managers:
Queues:
Listeners:
Channels:
Two server channels
Channel auth records:
Default channel authentication record which prevents MQ admins from connecting to queue managers. It was slightly modified (added ~ prefix) so now it does not block anyone.
The MQ Server and applications are running on the same machine so imho network problems are excluded.
The queue manager error log does not report any errors but the general error log looks like this:
08/02/2016 15:15:23 - Process(13720.10) User([username])
Program(B.EXE) AMQ9202: Remote host 'localhost(1414)' not
available, retry later.
EXPLANATION: The attempt to allocate a conversation using TCP/IP to
host 'localhost(1414)' for channel (Exception) was not successful.
However the error may be a transitory one and it may be possible to
successfully allocate a TCP/IP conversation later.
For both application I use the same version of amqmdnet.dll: 8.0.0.4
Both programs A and B have the same target framework: 4.5
While testing I didn't tried to run the both applications in the same time and I checked in MQ Explorer if the channel is free (Inactive).
I also tried to change the name of resulting assemblies but with no effect.
Does anyone know what could cause application B to be unable to connect?
When using the hostname localhost networking is still involved, it just all happens inside the one machine. If application A is running in the same machine as your queue manager then having application A connect using the connection name localhost(1414) will certainly work but it is not necessary to make the connection like this (i.e. using TCP/IP) you could instead make a local bindings connection.
On the other hand, if you are using TCP/IP because application B is running on a different machine to where the queue manager is running, then using localhost(1414) will not work because localhost on one machine does not connect to localhost on another machine. You should change what is specified in the application's connection name from localhost(1414) to use the IP address (or hostname) of the queue manager's machine (followed as before with the port number).
Although I was unable to find the cause of the problem the solution was to simply
delete and re-create the project.
This is what I tried before and what led me to this action:
In B I removed and then added back the reference to amqmdnet.dll - not working
I created yet another project (let's call it C): console application, same code - working
I renamed* the C project with the same name as B - still working
*The name of the non-working project contained a dot so I thought that this could cause the problem - it was not the case.

Run all tests if one test not fails

I know that all test should be independent and run in the random order.
But here is my situation:
I need to test my library which is working with external web resource. I have one test which checks if the web resource available and I have many tests which check the data I get from this resource.
If the web resource is not available I have all my tests failed and I think it is difficult to interpret this result. Is there any way to run all tests which check the data I get from resource if and only if the first test (which checks resource availability) was not failed?
I think availability of web resource should be a precondition for tests of your library. It should not be a separate test itself.
So, you need to check connection in TestFixtureSetup. If connection fails, all tests from fixture will not run. All tests in this test fixture will be marked as failed (which is true if there is no connection) and you will receive message
TestFixtureSetUp failed in YourLibtraryTests
Unfortunately NUnit will not show additional information if you will fail test with some message
Assert.NotNull(connection, "Cannot establish connection to remote service");
But it will be easy to find the reason if you know that TestFixtureSetUp failed.

Categories

Resources