Simulating host unreachable - how to achieve/imple

2019-02-04 19:22发布

问题:

Here is my scenario:

A is a provisioning server and B is an client. Whenever there is any change in B's setup, it uploads the appropriate config file to A.

I am working as an automation engineer to automate it. One of the scenario says to disconnect A from network or stop the server A. perform some changes to B and make sure that B failed to upload the files to provisioning server A.

To automate it, the simple way to stop the server A and do the appropriate actions.

Since A and B are also used for other purposes by other parties so I can not either disconnect A or B from network OR stop the server at A.

So, I am looking forward for any solution so that I can simulate the host (provisioning server) unreachable scenario. So when B will send an update to A it will fail but in actual A is running as usual.

Please suggest me some way to achieve it.

I am using Perl as a programming language but I am fine if solution is available in other language.

回答1:

I've done this before using a null route. This is something that best done from the shell with the ip command.

# blackhole all packets destined for 192.168.2.1
ip route add blackhole 192.168.2.1
# to delete the same route, replace add with del
ip route del blackhole 192.168.2.1

Depending on your use case, an unreachable route may work better, as it returns ICMP-unreachable instead of discarding the packets, although they tend to have the same effect.

ip route add unreachable 192.168.2.1

And for thoroughness, if you really wanted to simulate a host-unreachable situation (vs a network-unreachable), you would have to do that at the firewall level.

# resond with icmp-host-unreachable for *any* outbound packet to 192.168.2.1
iptables -I OUTPUT -d 192.168.2.1 -j REJECT --reject-with=icmp-host-unreachable
# delete the same rule (without looking up the rule #)
iptables -D OUTPUT -d 192.168.2.1 -j REJECT --reject-with=icmp-host-unreachable


回答2:

Another, perhaps easier option is to change the configuration on B to have a bogus IP address for A (e.g. 192.0.2.0) when performing the test.



回答3:

Test::MockObject::Extends - great for modifying small parts of modules to create specific testing scenarios. Works great for things that you can't test well because they affect things in production or in places that you don't control.

#!/usr/bin/perl

use strict;
use warnings;
use Test::MockObject::Extends;

#Fake module that has your remote connect subroutine
use Fake::Module;

my $object = Fake::Module->new();

#replace your obj with a copy that Test::MO:E will let us mess with
$object = Test::MockObject::Extends->new( $object )

#replace your connect function with a temp fake version
$object->mock(
    'your_remote_connect_sub' => sub {
        #Whatever data that should returned by your connect function if the server is unavailable
        return undef;
    },
);

#test your sub now
if ( !defined( $object->your_remove_connect_sub() ) ) {
    print "Remote server unavailable\n";
}