Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate network failure for test purposes (in C#)?

I'm building what could be called the DAL for a new app. Unfortunately, network connectivity to the database is a real problem.

I'd like to be able to temporarily block network access within the scope of my test so that I can ensure my DAL behaves as expected under those circumstances.

UPDATE: There are many manual ways to disable the network, but it sure would be nice if I could enable/disable within the test itself.

like image 831
Larsenal Avatar asked Jan 23 '09 22:01

Larsenal


People also ask

How do you simulate network failure?

Simulating a hard-down or node failure is fairly easy. All you have to do is turn off the node itself to verify how the system responds (system reconvergence). If high availability is enabled, a secondary/standby node will immediately take over and become the active node, servicing user requests.

How do you simulate packet loss?

To simulate packet loss, you can use an open source tool called tc (traffic control). tc can be installed on any Linux host. With this tool you can introduce packet loss to a network interface, as well as increase in latency and round-trip time.


3 Answers

For the time being, I'm just "disabling" the network by setting a bogus static IP as follows:

using System.Management;

class NetworkController
{

    public static void Disable()
    {
        SetIP("192.168.0.4", "255.255.255.0");
    }

    public static void Enable()
    {
        SetDHCP();
    }


    private static void SetIP(string ip_address, string subnet_mask)
    {
        ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
        ManagementObjectCollection objMOC = objMC.GetInstances();

        foreach (ManagementObject objMO in objMOC) {
            if ((bool)objMO("IPEnabled")) {
                try {
                    ManagementBaseObject setIP = default(ManagementBaseObject);
                    ManagementBaseObject newIP = objMO.GetMethodParameters("EnableStatic");

                    newIP("IPAddress") = new string[] { ip_address };
                    newIP("SubnetMask") = new string[] { subnet_mask };

                    setIP = objMO.InvokeMethod("EnableStatic", newIP, null);
                }
                catch (Exception generatedExceptionName) {
                    throw;
                }
            }


        }
    }

    private static void SetDHCP()
    {
        ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
        ManagementObjectCollection moc = mc.GetInstances();

        foreach (ManagementObject mo in moc) {
            // Make sure this is a IP enabled device. Not something like memory card or VM Ware
            if ((bool)mo("IPEnabled")) {
                ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
                newDNS("DNSServerSearchOrder") = null;
                ManagementBaseObject enableDHCP = mo.InvokeMethod("EnableDHCP", null, null);
                ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
            }
        }
    }
}
like image 129
Larsenal Avatar answered Oct 23 '22 18:10

Larsenal


Write a wrapper to the network class connectivity class you're using (e.g. WebClient) with an on-off switch :)

Either that, or block your application in the firewall.

like image 24
Andrew Rollings Avatar answered Oct 23 '22 20:10

Andrew Rollings


If you are trying a complete network outage for your application unplugging the network cable will work. Sometimes you might have a data access layer with multiple data sources (on different machines) in which case you can simulate an exception in your tests with a Mock Framework like Rhino Mocks. Here is some pseudo-code that you may have in your test

void TestUserDBFailure()
{
    // ***** THIS IS PSEUDO-CODE *******
    //setting up the stage - retrieval of the user info create an exception
    Expect.Call(_userRepository.GetUser(null))
       .IgnoreArguments()
       .Return(new Exception());

    // Call that uses the getuser function, see how it reacts
    User selectedUser = _dataLoader.GetUserData("testuser", "password");        
}
like image 5
Rorzilla Avatar answered Oct 23 '22 18:10

Rorzilla