LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

RFC: IPVS Unit Tests

To: <lvs-devel@xxxxxxxxxxxxxxx>
Subject: RFC: IPVS Unit Tests
Cc: kernel-team <Kernel-team@xxxxxx>
From: Alex Gartrell <agartrell@xxxxxx>
Date: Wed, 6 Aug 2014 01:19:53 -0700
tl;dr; I've attached the outline of basic unit tests (v4 and v6 tests for round robin, but the sky's the limit) and want feedback

As previously mentioned, we use ipvs /a lot/ at Facebook. We have a bunch of diffs that are pretty hacky to extend it to do stuff we need (mostly the ability to schedule flows at any point, because we ICMP to various ipvs instances and that can shift). Eventually my aim is for that functionality to reach you guys in a more acceptable form, but at the moment that's the state of the world.

Anyway, in the process of forward porting stuff, I wrote a ton of unit tests for the custom functionality, but it's kind of a drag to extend and I don't think any of you are going to be super thrilled about unit tests that require our open source libraries (folly) and c++11. So I started over in python to see how far I could get this afternoon.

These tests transmit over a raw socket and receive over a tun device. I was running it on a 3.2 host, but it should work all the way forward to *-next (the C++ version does). It's pretty easy to extend and mess with.

I've attached the entire script, but here's a simple test

    def do_stickiness_test(self, vip, port, real_servers, src_ip, iph_fn):
        self.tun.add_routes(real_servers)

        # For some reason this is necessary to not break ipv6?
        add_service('192.168.255.38', 999, [])
        add_service(vip, port, real_servers)

        buckets = {}
        base_port = 15000
        for i in xrange(10000):
            src = base_port + (i % 43)
            p = iph_fn(src_ip, vip, payload=TcpHeader(src, port, syn=1))
            send_raw_packet(p)
            dst_ip = parse_packet(self.tun.read()).dst
            if src not in buckets:
                buckets[src] = dst_ip
            else:
                self.assertEqual(buckets[src], dst_ip)

    def test_stickiness_v4(self):
        real_servers = ['1.2.3.%d' % i for i in xrange(5, 32)]
        self.do_stickiness_test(
            '1.2.3.4', 15213, real_servers, '9.9.9.9', Ipv4Header)

The raw socket stuff is just generally useful for other stuff too, if you're into that kind of thing.

Anyway, please let me know what you think

Thanks,

Alex

Attachment: test-ipvs.py
Description: Text Data

<Prev in Thread] Current Thread [Next in Thread>
  • RFC: IPVS Unit Tests, Alex Gartrell <=