Как имитировать отказ сети для целей тестирования (на С#)?
Я создаю то, что можно назвать DAL для нового приложения. К сожалению, сетевая связь с базой данных является реальной проблемой.
Я хотел бы временно заблокировать доступ к сети в рамках моего теста, чтобы я мог гарантировать, что мой DAL будет вести себя так, как ожидалось в этих обстоятельствах.
UPDATE: существует много ручных способов отключения сети, но было бы неплохо, если бы я мог включить/отключить в самом тесте.
Ответы
Ответ 1
В настоящее время я просто отключу сеть, установив фиктивный статический IP-адрес следующим образом:
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);
}
}
}
}
Ответ 2
Напишите оболочку в класс подключения класса сетевого класса, который вы используете (например, WebClient), с помощью переключателя on-off:)
Либо это, либо заблокируйте ваше приложение в брандмауэре.
Ответ 3
Если вы пытаетесь полностью отключить сеть для своего приложения, отключите сетевой кабель. Иногда у вас может быть уровень доступа к данным с несколькими источниками данных (на разных компьютерах), и в этом случае вы можете имитировать исключение в своих тестах с помощью Mock Framework, например Rhino Mocks. Вот какой-то псевдокод, который у вас может быть в вашем тесте
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");
}
Ответ 4
Попробуйте заблокировать соединение с брандмауэром на полпути через сеанс, возможно?
Мне нравится идея обертки, но это как бы абстрагирование проблемы, и вы, возможно, не сможете получить точное поведение в реальном мире. Кроме того, вставка слоя обертки, а затем удаление его может быть более сложной, чем ее ценность.
Изменить. Запустите script, который включает/отключает сетевой адаптер в случайном порядке или с установленными интервалами?
Ответ 5
Попробуйте Toxiproxi, он может имитировать отказ сети.
У них есть API REST и даже .NET Client API для программной модификации сети (из вашего тестового кода)
https://github.com/shopify/toxiproxy
Ответ 6
Ищите симулятор WAN, который позволит вам ограничить пропускную способность (и полностью отключить его). Мне всегда интересно узнать, как меняется пользовательский интерфейс, когда мои приложения запускаются в среде с ограниченной пропускной способностью. Посмотрите здесь для получения некоторой информации.
Ответ 7
Существует инструмент, который можно использовать для моделирования высокой латентности и низкой пропускной способности при тестировании приложений баз данных, как описано в этой записи в блоге.
Ответ 8
Вероятно, не полезно для имитации "реальных" сетевых проблем, но вы можете просто указать строку подключения к DB на несуществующий компьютер, находясь в пределах вашего теста.
Ответ 9
Зависит от конкретной сетевой проблемы, которую вы хотите имитировать. Для большинства людей это так же просто, как "сервер недоступен", и в этом случае вы просто попытаетесь подключиться к несуществующему серверу. Однако будьте осторожны, потому что вы хотите что-то маршрутизируемое, но не отвечаете. Пытаться подключиться к dkjdsjk.com не удастся немедленно (поиск DNS), но попытка подключения к www.google.com:1433 будет (вероятно) тайм-аут из-за брандмауэра - как ваше приложение будет вести себя, когда ваш сервер БД вниз.
Ответ 10
Только что нашел альтернативу, которая позволяет напрямую закрыть TCP-соединения:
http://lamahashim.blogspot.ch/2010/03/disabling-network-using-c.html
Он основан на API-интерфейсе Windows IP Helper (использует DllImport):
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366073(v=vs.85).aspx
Ответ 11
Использование макетных объектов для создания настраиваемых, разрушаемых версий реальной вещи - в данном случае базы данных.