Introduce VPP-IPsec container tests.
[csit.git] / resources / libraries / robot / shared / container.robot
1 # Copyright (c) 2019 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 *** Settings ***
15 | Documentation | Keywords related to linux containers
16 |
17 | Library | resources.libraries.python.CpuUtils
18 | Library | resources.libraries.python.topology.Topology
19 | Variables | resources/libraries/python/Constants.py
20
21 *** Keywords ***
22 | Construct container on all DUTs
23 | | [Documentation] | Construct 1 CNF of specific technology on all DUT nodes.
24 | |
25 | | ... | *Arguments:*
26 | | ... | - nf_chains: Total number of chains (Optional). Type: integer, default
27 | | ... | value: ${1}
28 | | ... | - nf_nodes: Total number of nodes per chain (Optional). Type: integer,
29 | | ... | default value: ${1}
30 | | ... | - nf_chain: Chain ID (Optional). Type: integer, default value: ${1}
31 | | ... | - nf_node: Node ID (Optional). Type: integer, default value: ${1}
32 | | ... | - auto_scale - If True, use same amount of Dataplane threads for
33 | | ... | network function as DUT, otherwise use single physical core for
34 | | ... | every network function. Type: boolean
35 | | ... | - pinning: Set True if CPU pinning should be done on starting
36 | | ... | containers. Type: boolean, default value: ${False}
37 | |
38 | | ... | *Example:*
39 | |
40 | | ... | \| Construct container on all DUTs \| 1 \| 1 \| 1 \| 1 \| ${True} \|
41 | |
42 | | [Arguments] | ${nf_chains}=${1} | ${nf_nodes}=${1} | ${nf_chain}=${1}
43 | | ... | ${nf_node}=${1} | ${auto_scale}=${True} | ${pinning}=${True}
44 | |
45 | | ${duts}= | Get Matches | ${nodes} | DUT*
46 | | FOR | ${dut} | IN | @{duts}
47 | | | Run Keyword | Construct container on DUT | ${dut}
48 | | | ... | ${nf_chains} | ${nf_nodes} | ${nf_chain}
49 | | | ... | ${nf_node} | ${auto_scale} | ${pinning}
50 | | END
51
52 | Construct container on DUT
53 | | [Documentation] | Construct 1 CNF of specific technology on specific DUT.
54 | |
55 | | ... | *Arguments:*
56 | | ... | - dut: DUT node to construct the CNF on. Type: string
57 | | ... | - nf_chains: Total number of chains (Optional). Type: integer, default
58 | | ... | value: ${1}
59 | | ... | - nf_nodes: Total number of nodes per chain (Optional). Type: integer,
60 | | ... | default value: ${1}
61 | | ... | - nf_chain: Chain ID (Optional). Type: integer, default value: ${1}
62 | | ... | - nf_node: Node ID (Optional). Type: integer, default value: ${1}
63 | | ... | - auto_scale - If True, use same amount of Dataplane threads for
64 | | ... | network function as DUT, otherwise use single physical core for
65 | | ... | every network function. Type: boolean
66 | | ... | - pinning: Set True if CPU pinning should be done on starting
67 | | ... | containers. Type: boolean, default value: ${False}
68 | |
69 | | ... | *Example:*
70 | |
71 | | ... | \| Construct container on DUT \| DUT1 \| 1 \| 1 \| 1 \| 1 \|
72 | | ... | \| ${True} \|
73 | |
74 | | [Arguments] | ${dut}
75 | | ... | ${nf_chains}=${1} | ${nf_nodes}=${1} | ${nf_chain}=${1}
76 | | ... | ${nf_node}=${1} | ${auto_scale}=${True} | ${pinning}=${True}
77 | |
78 | | ${nf_dtcr_status} | ${value}= | Run Keyword And Ignore Error
79 | | ... | Variable Should Exist | ${nf_dtcr}
80 | | ${nf_dtcr}= | Run Keyword If | '${nf_dtcr_status}' == 'PASS'
81 | | ... | Set Variable | ${nf_dtcr} | ELSE | Set Variable | ${1}
82 | | ${nf_dtc}= | Run Keyword If | ${pinning}
83 | | ... | Set Variable If | ${auto_scale} | ${cpu_count_int}
84 | | ... | ${nf_dtc}
85 | | ${nf_id}= | Evaluate | (${nf_chain} - ${1}) * ${nf_nodes} + ${nf_node}
86 | | ${env}= | Create List | DEBIAN_FRONTEND=noninteractive
87 | | ${dut1_uuid_length} = | Get Length | ${DUT1_UUID}
88 | | ${root}= | Run Keyword If | ${dut1_uuid_length}
89 | | ... | Get Docker Mergeddir | ${nodes['DUT1']} | ${DUT1_UUID}
90 | | ... | ELSE | Set Variable | ${EMPTY}
91 | | ${node_arch}= | Get Node Arch | ${nodes['${dut}']}
92 | | ${name}= | Set Variable | ${dut}_${container_group}${nf_id}${DUT1_UUID}
93 | | ${mnt}= | Create List
94 | | ... | ${root}/tmp/:/mnt/host/
95 | | ... | ${root}/tmp/vpp_sockets/${name}/:/run/vpp/
96 | | ... | ${root}/dev/vfio/:/dev/vfio/
97 | | ... | ${root}/usr/bin/vpp:/usr/bin/vpp
98 | | ... | ${root}/usr/bin/vppctl:/usr/bin/vppctl
99 | | ... | ${root}/usr/lib/${node_arch}-linux-gnu/:/usr/lib/${node_arch}-linux-gnu/
100 | | ... | ${root}/usr/share/vpp/:/usr/share/vpp/
101 | | ${nf_cpus}= | Set Variable | ${None}
102 | | ${nf_cpus}= | Run Keyword If | ${pinning}
103 | | ... | Get Affinity NF | ${nodes} | ${dut}
104 | | ... | nf_chains=${nf_chains} | nf_nodes=${nf_nodes}
105 | | ... | nf_chain=${nf_chain} | nf_node=${nf_node}
106 | | ... | vs_dtc=${cpu_count_int} | nf_dtc=${nf_dtc} | nf_dtcr=${nf_dtcr}
107 | | &{cont_args}= | Create Dictionary
108 | | ... | name=${name} | node=${nodes['${dut}']} | mnt=${mnt} | env=${env}
109 | | ... | root=${root}
110 | | Run Keyword If | ${pinning}
111 | | ... | Set To Dictionary | ${cont_args} | cpuset_cpus=${nf_cpus}
112 | | Run Keyword | ${container_group}.Construct container | &{cont_args}
113
114 | Construct chain of containers
115 | | [Documentation] | Construct 1 chain of 1..N CNFs on selected/all DUT nodes.
116 | |
117 | | ... | *Arguments:*
118 | | ... | - dut: DUT node to start the containers on. Run on all nodes if None.
119 | | ... | Type: string or None
120 | | ... | - nf_chains: Total number of chains. Type: integer
121 | | ... | - nf_nodes: Total number of nodes per chain. Type: integer
122 | | ... | - nf_chain: Chain ID. Type: integer
123 | | ... | - auto_scale - If True, use same amount of Dataplane threads for
124 | | ... | network function as DUT, otherwise use single physical core for
125 | | ... | every network function. Type: boolean
126 | | ... | - pinning: Set True if CPU pinning should be done on starting
127 | | ... | containers. Type: boolean, default value: ${False}
128 | |
129 | | ... | *Example:*
130 | |
131 | | ... | \| Construct chain of containers \| 1 \| 1 \| 1 \| ${True} \|
132 | |
133 | | [Arguments] | ${dut}=${None} | ${nf_chains}=${1} | ${nf_nodes}=${1}
134 | | ... | ${nf_chain}=${1} | ${auto_scale}=${True} | ${pinning}=${True}
135 | |
136 | | FOR | ${nf_node} | IN RANGE | 1 | ${nf_nodes}+1
137 | | | Run Keyword If | '${dut}' == '${None}'
138 | | | ... | Construct container on all DUTs
139 | | | ... | nf_chains=${nf_chains} | nf_nodes=${nf_nodes} | nf_chain=${nf_chain}
140 | | | ... | nf_node=${nf_node} | auto_scale=${auto_scale} | pinning=${pinning}
141 | | | ... | ELSE
142 | | | ... | Construct container on DUT | ${dut}
143 | | | ... | nf_chains=${nf_chains} | nf_nodes=${nf_nodes} | nf_chain=${nf_chain}
144 | | | ... | nf_node=${nf_node} | auto_scale=${auto_scale} | pinning=${pinning}
145 | | END
146
147 | Construct chains of containers
148 | | [Documentation] | Construct 1..N chains of 1..N CNFs on selected/all DUT
149 | | ... | nodes.
150 | |
151 | | ... | *Arguments:*
152 | | ... | - dut: DUT node to start the containers on. Run on all nodes if None.
153 | | ... | Type: string or None
154 | | ... | - nf_chains: Total number of chains (Optional). Type: integer, default
155 | | ... | value: ${1}
156 | | ... | - nf_nodes: Total number of nodes per chain (Optional). Type: integer,
157 | | ... | default value: ${1}
158 | | ... | - auto_scale - If True, use same amount of Dataplane threads for
159 | | ... | network function as DUT, otherwise use single physical core for
160 | | ... | every network function. Type: boolean
161 | | ... | - pinning: Set True if CPU pinning should be done on starting
162 | | ... | containers. Type: boolean, default value: ${True}
163 | |
164 | | ... | *Example:*
165 | |
166 | | ... | \| Construct chains of containers \| 1 \| 1 \|
167 | |
168 | | [Arguments] | ${dut}=${None} | ${nf_chains}=${1} | ${nf_nodes}=${1}
169 | | ... | ${auto_scale}=${True} | ${pinning}=${True}
170 | |
171 | | FOR | ${nf_chain} | IN RANGE | 1 | ${nf_chains}+1
172 | | | Construct chain of containers
173 | | | ... | dut=${dut} | nf_chains=${nf_chains} | nf_nodes=${nf_nodes}
174 | | | ... | nf_chain=${nf_chain} | auto_scale=${auto_scale} | pinning=${pinning}
175 | | END
176
177 | Acquire all '${group}' containers
178 | | [Documentation] | Acquire all container(s) in specific container group on
179 | | ... | all DUT nodes.
180 | |
181 | | Run Keyword | ${group}.Acquire all containers
182
183 | Create all '${group}' containers
184 | | [Documentation] | Create/deploy all container(s) in specific container group
185 | | ... | on all DUT nodes.
186 | |
187 | | Run Keyword | ${group}.Create all containers
188
189 | Start VPP in all '${group}' containers
190 | | [Documentation] | Start VPP on all container(s) in specific container
191 | | ... | group on all DUT nodes.
192 | |
193 | | Run Keyword | ${group}.Start VPP In All Containers
194
195 | Restart VPP in all '${group}' containers
196 | | [Documentation] | Restart VPP on all container(s) in specific container
197 | | ... | group on all DUT nodes.
198 | |
199 | | Run Keyword | ${group}.Restart VPP In All Containers
200
201 | Configure VPP in all '${group}' containers
202 | | [Documentation] | Configure VPP on all container(s) in specific container
203 | | ... | group on all DUT nodes.
204 | |
205 | | ... | *Test (or broader scope) variables read:*
206 | | ... | - container_chain_topology - Topology type used for configuring CNF
207 | | ... | (VPP) in container. Type: string
208 | |
209 | | ${dut1_if2} = | Get Variable Value | \${dut1_if2} | ${None}
210 | | ${dut2_if2} = | Get Variable Value | \${dut2_if2} | ${None}
211 | | Run Keyword If | '${container_chain_topology}' == 'chain_ip4'
212 | | ... | ${group}.Configure VPP In All Containers | ${container_chain_topology}
213 | | ... | tg_if1_mac=${tg_if1_mac} | tg_if2_mac=${tg_if2_mac}
214 | | ... | nodes=${nf_nodes}
215 | | ... | ELSE IF | '${container_chain_topology}' == 'chain_ipsec'
216 | | ... | ${group}.Configure VPP In All Containers | ${container_chain_topology}
217 | | ... | tg_if1_ip4=${tg_if1_ip4} | tg_if1_mac=${tg_if1_mac}
218 | | ... | tg_if2_ip4=${tg_if2_ip4} | tg_if2_mac=${tg_if2_mac}
219 | | ... | dut1_if1_ip4=${dut1_if1_ip4} | dut1_if2_ip4=${dut1_if2_ip4}
220 | | ... | dut2_if1_ip4=${dut2_if1_ip4} | dut2_if2_ip4=${dut2_if2_ip4}
221 | | ... | raddr_ip4=${raddr_ip4} | laddr_ip4=${laddr_ip4}
222 | | ... | nodes=${nodes} | nf_nodes=${nf_nodes}
223 | | ... | ELSE IF | '${container_chain_topology}' == 'pipeline_ip4'
224 | | ... | ${group}.Configure VPP In All Containers | ${container_chain_topology}
225 | | ... | tg_if1_mac=${tg_if1_mac} | tg_if2_mac=${tg_if2_mac}
226 | | ... | nodes=${nf_nodes}
227 | | ... | ELSE IF | '${container_chain_topology}' == 'cross_horiz'
228 | | ... | ${group}.Configure VPP In All Containers | ${container_chain_topology}
229 | | ... | dut1_if=${dut1_if2} | dut2_if=${dut2_if2}
230 | | ... | ELSE
231 | | ... | ${group}.Configure VPP In All Containers | ${container_chain_topology}
232
233 | Stop all '${group}' containers
234 | | [Documentation] | Stop all container(s) in specific container group on all
235 | | ... | DUT nodes.
236 | |
237 | | Run Keyword | ${group}.Stop all containers
238
239 | Destroy all '${group}' containers
240 | | [Documentation] | Destroy all container(s) in specific container group on
241 | | ... | all DUT nodes.
242 | |
243 | | Run Keyword | ${group}.Destroy all containers
244
245 | Verify VPP in all '${group}' containers
246 | | [Documentation] | Verify that VPP is running inside containers in specific
247 | | ... | container group on all DUT nodes. Does 120 retries with one second
248 | | ... | between retries.
249 | |
250 | | Run Keyword | ${group}.Verify VPP in all containers
251
252 | Start containers for test
253 | | [Documentation]
254 | | ... | Start containers for test.
255 | |
256 | | ... | *Arguments:*
257 | | ... | - dut: DUT node to start the containers on. Run on all nodes if None.
258 | | ... | Type: string or None
259 | | ... | - nf_chains: Total number of chains. Type: integer
260 | | ... | - nf_nodes: Total number of nodes per chain. Type: integer
261 | | ... | - auto_scale - If True, use same amount of Dataplane threads for
262 | | ... | network function as DUT, otherwise use single physical core for
263 | | ... | every network function. Type: boolean
264 | | ... | - pinning: Set True if CPU pinning should be done on starting
265 | | ... | containers. Type: boolean, default value: ${False}
266 | |
267 | | ... | *Example:*
268 | |
269 | | ... | \| Start containers for test \| 1 \| 1 \|
270 | |
271 | | [Arguments] | ${dut}=${None} | ${nf_chains}=${1} | ${nf_nodes}=${1}
272 | | ... | ${auto_scale}=${True} | ${pinning}=${True}
273 | |
274 | | Set Test Variable | @{container_groups} | @{EMPTY}
275 | | Set Test Variable | ${container_group} | CNF
276 | | Set Test Variable | ${nf_nodes}
277 | | Import Library | resources.libraries.python.ContainerUtils.ContainerManager
278 | | ... | engine=${container_engine} | WITH NAME | ${container_group}
279 | | Construct chains of containers
280 | | ... | dut=${dut} | nf_chains=${nf_chains} | nf_nodes=${nf_nodes}
281 | | ... | auto_scale=${auto_scale} | pinning=${pinning}
282 | | Acquire all '${container_group}' containers
283 | | Create all '${container_group}' containers
284 | | Configure VPP in all '${container_group}' containers
285 | | Start VPP in all '${container_group}' containers
286 | | Append To List | ${container_groups} | ${container_group}
287 | | Save VPP PIDs
288
289 # TODO: Remove the vswitch startup.conf and read the host configuration instead.
290 | Start vswitch in container on DUT
291 | | [Documentation]
292 | | ... | Configure and start vswitch in container.
293 | |
294 | | ... | *Arguments:*
295 | | ... | - dut: DUT node on which to install vswitch. Type: string
296 | | ... | - phy_cores - Number of physical cores to use. Type: integer
297 | | ... | - rx_queues: Number of RX queues. Type: integer
298 | |
299 | | ... | *Example:*
300 | |
301 | | ... | \| Start vswitch in container on DUT \| DUT1 \| 1 \| 1 \|
302 | |
303 | | [Arguments] | ${dut} | ${phy_cores} | ${rx_queues}=${None}
304 | |
305 | | Set Test Variable | ${container_group} | VSWITCH
306 | | Import Library | resources.libraries.python.ContainerUtils.ContainerManager
307 | | ... | engine=${container_engine} | WITH NAME | VSWITCH
308 | | Construct container on DUT | ${dut}
309 | | ... | nf_chains=${1} | nf_nodes=${1} | nf_chain=${1}
310 | | ... | nf_node=${1} | auto_scale=${False} | pinning=${False}
311 | | Acquire all '${container_group}' containers
312 | | Create all '${container_group}' containers
313 | | ${cpu_count_int} | Convert to Integer | ${phy_cores}
314 | | ${thr_count_int} | Convert to Integer | ${phy_cores}
315 | | ${smt_used}= | Is SMT enabled | ${nodes['${dut}']['cpuinfo']}
316 | | ${thr_count_int}= | Run keyword if | ${smt_used}
317 | | ... | Evaluate | int(${cpu_count_int}*2)
318 | | ... | ELSE | Set variable | ${thr_count_int}
319 | | ${rxq_count_int}= | Run keyword if | ${rx_queues}
320 | | ... | Set variable | ${rx_queues}
321 | | ... | ELSE | Evaluate | int(${thr_count_int}/2)
322 | | ${rxq_count_int}= | Run keyword if | ${rxq_count_int} == 0
323 | | ... | Set variable | ${1}
324 | | ... | ELSE | Set variable | ${rxq_count_int}
325 | | VSWITCH.Configure VPP in all containers | chain_vswitch
326 | | ... | rxq=${rxq_count_int} | n_instances=${n_instances}
327 | | ... | buffers=${215040} | node=${dut}
328 | | ... | dut1_if1=${dut1_if1} | dut1_if2=${dut1_if2}
329 | | ... | dut2_if1=${dut2_if1} | dut2_if2=${dut2_if2}
330 | | ... | dut2_if2_ip4=${dut2_if2_ip4}
331 | | ... | tg_if1_ip4=${tg_if1_ip4} | tg_if1_mac=${tg_if1_mac}
332 | | ... | tg_if2_ip4=${tg_if2_ip4} | tg_if2_mac=${tg_if2_mac}
333 | | ... | nodes=${nodes}
334 | | Start VPP in all '${container_group}' containers
335 | | Verify VPP in all '${container_group}' containers
336
337 | Start vswitch in container
338 | | [Documentation]
339 | | ... | Configure and start vswitch in container on all DUTs.
340 | |
341 | | ... | *Arguments:*
342 | | ... | - phy_cores - Number of physical cores to use. Type: integer
343 | | ... | - rx_queues: Number of RX queues. Type: integer
344 | |
345 | | ... | *Example:*
346 | |
347 | | ... | \| Start vswitch in container \| 1 \| 1 \|
348 | |
349 | | [Arguments] | ${phy_cores} | ${rx_queues}=${None}
350 | |
351 | | FOR | ${dut} | IN | @{duts}
352 | | | Run Keyword | Start vswitch in container on DUT
353 | | | ... | ${dut} | ${phy_cores} | ${rx_queues}
354 | | END
355 | | Append To List | ${container_groups} | ${container_group}
356 | | Save VPP PIDs