Skip to content

Commit f3d3208

Browse files
Iulian Barbusandreim
authored andcommitted
serial: buffer limit regression test
Signed-off-by: Iulian Barbu <[email protected]>
1 parent b68a78b commit f3d3208

File tree

1 file changed

+59
-7
lines changed

1 file changed

+59
-7
lines changed

tests/integration_tests/functional/test_serial_io.py

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0
33
"""Tests scenario for the Firecracker serial console."""
4+
5+
import fcntl
6+
import os
7+
import termios
48
import time
9+
510
from framework.microvm import Serial
611
from framework.state_machine import TestState
12+
import framework.utils as utils
713

814

9-
class WaitLogin(TestState):
15+
class WaitLogin(TestState): # pylint: disable=too-few-public-methods
1016
"""Initial state when we wait for the login prompt."""
1117

1218
def handle_input(self, serial, input_char) -> TestState:
@@ -18,7 +24,7 @@ def handle_input(self, serial, input_char) -> TestState:
1824
return self
1925

2026

21-
class WaitPasswordPrompt(TestState):
27+
class WaitPasswordPrompt(TestState): # pylint: disable=too-few-public-methods
2228
"""Wait for the password prompt to be shown."""
2329

2430
def handle_input(self, serial, input_char) -> TestState:
@@ -32,7 +38,7 @@ def handle_input(self, serial, input_char) -> TestState:
3238
return self
3339

3440

35-
class WaitIDResult(TestState):
41+
class WaitIDResult(TestState): # pylint: disable=too-few-public-methods
3642
"""Wait for the console to show the result of the 'id' shell command."""
3743

3844
def handle_input(self, unused_serial, input_char) -> TestState:
@@ -42,10 +48,10 @@ def handle_input(self, unused_serial, input_char) -> TestState:
4248
return self
4349

4450

45-
class TestFinished(TestState):
51+
class TestFinished(TestState): # pylint: disable=too-few-public-methods
4652
"""Test complete and successful."""
4753

48-
def handle_input(self, unused_serial, input_char) -> TestState:
54+
def handle_input(self, unused_serial, _) -> TestState:
4955
"""Return self since the test is about to end."""
5056
return self
5157

@@ -68,11 +74,57 @@ def test_serial_console_login(test_microvm_with_ssh):
6874

6975
serial = Serial(microvm)
7076
serial.open()
71-
72-
# Set initial state - wait for 'login:' prompt
7377
current_state = WaitLogin("login:")
7478

7579
while not isinstance(current_state, TestFinished):
7680
output_char = serial.rx_char()
7781
current_state = current_state.handle_input(
7882
serial, output_char)
83+
84+
85+
def get_total_mem_size(pid):
86+
"""Get total memory usage for a process."""
87+
cmd = f"pmap {pid} | tail -n 1 | sed 's/^ //' | tr -s ' ' | cut -d' ' -f2"
88+
rc, stdout, stderr = utils.run_cmd(cmd)
89+
assert rc == 0
90+
assert stderr == ""
91+
92+
return stdout
93+
94+
95+
def send_bytes(tty, bytes_count, timeout=60):
96+
"""Send data to the terminal."""
97+
start = time.time()
98+
for _ in range(bytes_count):
99+
fcntl.ioctl(tty, termios.TIOCSTI, '\n')
100+
current = time.time()
101+
if current - start > timeout:
102+
break
103+
104+
105+
def test_serial_dos(test_microvm_with_ssh):
106+
"""Test serial console behavior under DoS."""
107+
microvm = test_microvm_with_ssh
108+
microvm.jailer.daemonize = False
109+
microvm.spawn()
110+
microvm.memory_events_queue = None
111+
112+
# Set up the microVM with 1 vCPU and a serial console.
113+
microvm.basic_config(vcpu_count=1,
114+
add_root_device=False,
115+
boot_args='console=ttyS0 reboot=k panic=1 pci=off')
116+
microvm.start()
117+
118+
# Open an fd for firecracker process terminal.
119+
tty_path = f"/proc/{microvm.jailer_clone_pid}/fd/0"
120+
tty_fd = os.open(tty_path, os.O_RDWR)
121+
122+
# Check if the total memory size changed.
123+
before_size = get_total_mem_size(microvm.jailer_clone_pid)
124+
send_bytes(tty_fd, 100000000, timeout=1)
125+
after_size = get_total_mem_size(microvm.jailer_clone_pid)
126+
assert before_size == after_size, "The memory size of the " \
127+
"Firecracker process " \
128+
"changed from {} to {}." \
129+
.format(before_size,
130+
after_size)

0 commit comments

Comments
 (0)