summaryrefslogtreecommitdiffstats
path: root/test/test_vapi.py
blob: 7bb815d77f3069efcc693cb6abc55a7939962171 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python
""" VAPI test """

import unittest
import os
import signal
from framework import VppTestCase, running_extended_tests, \
    running_on_centos, VppTestRunner, Worker


@unittest.skipUnless(running_extended_tests, "part of extended tests")
class VAPITestCase(VppTestCase):
    """ VAPI test """

    @classmethod
    def setUpClass(cls):
        super(VAPITestCase, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(VAPITestCase, cls).tearDownClass()

    def test_vapi_c(self):
        """ run C VAPI tests """
        var = "TEST_DIR"
        built_root = os.getenv(var, None)
        self.assertIsNotNone(built_root,
                             "Environment variable `%s' not set" % var)
        executable = "%s/build/vapi_test/vapi_c_test" % built_root
        worker = Worker(
            [executable, "vapi client", self.shm_prefix], self.logger)
        worker.start()
        timeout = 60
        worker.join(timeout)
        self.logger.info("Worker result is `%s'" % worker.result)
        error = False
        if worker.result is None:
            try:
                error = True
                self.logger.error(
                    "Timeout! Worker did not finish in %ss" % timeout)
                os.killpg(os.getpgid(worker.process.pid), signal.SIGTERM)
                worker.join()
            except:
                self.logger.debug("Couldn't kill worker-spawned process")
                raise
        if error:
            raise Exception(
                "Timeout! Worker did not finish in %ss" % timeout)
        self.assert_equal(worker.result, 0, "Binary test return code")

    @unittest.skipIf(running_on_centos, "Centos's gcc can't compile our C++")
    def test_vapi_cpp(self):
        """ run C++ VAPI tests """
        var = "TEST_DIR"
        built_root = os.getenv(var, None)
        self.assertIsNotNone(built_root,
                             "Environment variable `%s' not set" % var)
        executable = "%s/build/vapi_test/vapi_cpp_test" % built_root
        worker = Worker(
            [executable, "vapi client", self.shm_prefix], self.logger)
        worker.start()
        timeout = 120
        worker.join(timeout)
        self.logger.info("Worker result is `%s'" % worker.result)
        error = False
        if worker.result is None:
            try:
                error = True
                self.logger.error(
                    "Timeout! Worker did not finish in %ss" % timeout)
                os.killpg(os.getpgid(worker.process.pid), signal.SIGTERM)
                worker.join()
            except:
                raise Exception("Couldn't kill worker-spawned process")
        if error:
            raise Exception(
                "Timeout! Worker did not finish in %ss" % timeout)
        self.assert_equal(worker.result, 0, "Binary test return code")


if __name__ == '__main__':
    unittest.main(testRunner=VppTestRunner)
an> u8 dst_address_bits_of_leaves[256]; /** * Number of non-empty leafs (whether terminal or not). */ i32 n_non_empty_leafs; /** * The length of the ply's covering prefix. Also a measure of its depth * If a leaf in a slot has a mask length longer than this then it is * 'non-empty'. Otherwise it is the value of the cover. */ i32 dst_address_bits_base; /* Pad to cache line boundary. */ u8 pad[CLIB_CACHE_LINE_BYTES - 2 * sizeof (i32)]; } ip4_mtrie_8_ply_t; STATIC_ASSERT (0 == sizeof (ip4_mtrie_8_ply_t) % CLIB_CACHE_LINE_BYTES, "IP4 Mtrie ply cache line"); /** * @brief The mutiway-TRIE with a 16-8-8 stride. * There is no data associated with the mtrie apart from the top PLY */ typedef struct { /** * Embed the PLY with the mtrie struct. This means that the Data-plane * 'get me the mtrie' returns the first ply, and not an indirect 'pointer' * to it. therefore no cacheline misses in the data-path. */ ip4_mtrie_16_ply_t root_ply; } ip4_mtrie_16_t; /** * @brief The mutiway-TRIE with a 8-8-8-8 stride. * There is no data associated with the mtrie apart from the top PLY */ typedef struct { /* pool index of the root ply */ u32 root_ply; } ip4_mtrie_8_t; /** * @brief Initialise an mtrie */ void ip4_mtrie_16_init (ip4_mtrie_16_t *m); void ip4_mtrie_8_init (ip4_mtrie_8_t *m); /** * @brief Free an mtrie, It must be empty when free'd */ void ip4_mtrie_16_free (ip4_mtrie_16_t *m); void ip4_mtrie_8_free (ip4_mtrie_8_t *m); /** * @brief Add a route/entry to the mtrie */ void ip4_mtrie_16_route_add (ip4_mtrie_16_t *m, const ip4_address_t *dst_address, u32 dst_address_length, u32 adj_index); void ip4_mtrie_8_route_add (ip4_mtrie_8_t *m, const ip4_address_t *dst_address, u32 dst_address_length, u32 adj_index); /** * @brief remove a route/entry to the mtrie */ void ip4_mtrie_16_route_del (ip4_mtrie_16_t *m, const ip4_address_t *dst_address, u32 dst_address_length, u32 adj_index, u32 cover_address_length, u32 cover_adj_index); void ip4_mtrie_8_route_del (ip4_mtrie_8_t *m, const ip4_address_t *dst_address, u32 dst_address_length, u32 adj_index, u32 cover_address_length, u32 cover_adj_index); /** * @brief return the memory used by the table */ uword ip4_mtrie_16_memory_usage (ip4_mtrie_16_t *m); uword ip4_mtrie_8_memory_usage (ip4_mtrie_8_t *m); /** * @brief Format/display the contents of the mtrie */ format_function_t format_ip4_mtrie_16; format_function_t format_ip4_mtrie_8; /** * @brief A global pool of 8bit stride plys */ extern ip4_mtrie_8_ply_t *ip4_ply_pool; /** * Is the leaf terminal (i.e. an LB index) or non-terminal (i.e. a PLY index) */ always_inline u32 ip4_mtrie_leaf_is_terminal (ip4_mtrie_leaf_t n) { return n & 1; } /** * From the stored slot value extract the LB index value */ always_inline u32 ip4_mtrie_leaf_get_adj_index (ip4_mtrie_leaf_t n) { ASSERT (ip4_mtrie_leaf_is_terminal (n)); return n >> 1; } /** * @brief Lookup step. Processes 1 byte of 4 byte ip4 address. */ always_inline ip4_mtrie_leaf_t ip4_mtrie_16_lookup_step (ip4_mtrie_leaf_t current_leaf, const ip4_address_t *dst_address, u32 dst_address_byte_index) { ip4_mtrie_8_ply_t *ply; uword current_is_terminal = ip4_mtrie_leaf_is_terminal (current_leaf); if (!current_is_terminal) { ply = ip4_ply_pool + (current_leaf >> 1); return (ply->leaves[dst_address->as_u8[dst_address_byte_index]]); } return current_leaf; } /** * @brief Lookup step number 1. Processes 2 bytes of 4 byte ip4 address. */ always_inline ip4_mtrie_leaf_t ip4_mtrie_16_lookup_step_one (const ip4_mtrie_16_t *m, const ip4_address_t *dst_address) { ip4_mtrie_leaf_t next_leaf; next_leaf = m->root_ply.leaves[dst_address->as_u16[0]]; return next_leaf; } always_inline ip4_mtrie_leaf_t ip4_mtrie_8_lookup_step (ip4_mtrie_leaf_t current_leaf, const ip4_address_t *dst_address, u32 dst_address_byte_index) { ip4_mtrie_8_ply_t *ply; uword current_is_terminal = ip4_mtrie_leaf_is_terminal (current_leaf); if (!current_is_terminal) { ply = ip4_ply_pool + (current_leaf >> 1); return (ply->leaves[dst_address->as_u8[dst_address_byte_index]]); } return current_leaf; } always_inline ip4_mtrie_leaf_t ip4_mtrie_8_lookup_step_one (const ip4_mtrie_8_t *m, const ip4_address_t *dst_address) { ip4_mtrie_leaf_t next_leaf; ip4_mtrie_8_ply_t *ply; ply = pool_elt_at_index (ip4_ply_pool, m->root_ply); next_leaf = ply->leaves[dst_address->as_u8[0]]; return next_leaf; } #endif /* included_ip_ip4_fib_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */