示例#1
0
    def test_nested_tree_missing_child(self):
        """
        MatchesPsTree can detect a missing child process.
        """
        ps_tree = PsTree(PsRow(1, 0, 'root', 'tini -- app'), [
            PsTree(PsRow(2, 1, 'root', 'app --arg'), [
                PsTree(PsRow(3, 2, 'appuser', 'app --child1')),
            ]),
            PsTree(PsRow(5, 1, 'root', 'app2 --arg'), [
                PsTree(PsRow(6, 5, 'root', 'app2 --child')),
            ]),
        ])

        matcher = MatchesPsTree('root', 'tini -- app', pid=1, children=[
            MatchesPsTree('root', 'app --arg', children=[
                MatchesPsTree('appuser', 'app --child1'),
                MatchesPsTree('appuser', 'app --child2'),
            ]),
            MatchesPsTree('root', 'app2 --arg', children=[
                MatchesPsTree('root', 'app2 --child'),
            ]),
        ])
        mm = matcher.match(ps_tree).describe()
        assert "mismatches in children:" in mm
        assert "There was 1 matcher left over:" in mm
示例#2
0
    def test_header_alignment_long_pids(self):
        """
        For some header alignments, the pids may extend beyond the left edge of
        the column headers.
        """
        ps_rows = [
            PsRow(1, 0, 'root', 'tini -- foo'),
            PsRow(10000, 1, 'root', 'foo'),
            PsRow(10001, 10000, 'root', 'bar'),
        ]

        busybox_con = FakePsContainer([
            b'PID   PPID  RUSER    COMMAND',
            b'    1     0 root     tini -- foo',
            b'10000     1 root     foo',
            b'10001 10000 root     bar',
            b'    6     0 root     ps ax -o pid,ppid,ruser,args',
        ])
        self.assertEqual(ps_rows, list_container_processes(busybox_con))

        debian_con = FakePsContainer([
            b'  PID  PPID RUSER    COMMAND',
            b'    1     0 root     tini -- foo',
            b'10000     1 root     foo',
            b'10001 10000 root     bar',
            b'    6     0 root     ps ax -o pid,ppid,ruser,args',
        ])
        self.assertEqual(ps_rows, list_container_processes(debian_con))
示例#3
0
    def test_fields(self):
        """
        A PsRow can be created from field values of various types.
        """
        ps_row = PsRow('1', '0', 'root', 'tini -- true')
        self.assertEqual(
            (ps_row.pid, ps_row.ppid, ps_row.ruser, ps_row.args),
            (1, 0, 'root', 'tini -- true'))

        ps_row = PsRow(1, 0, 'root', 'tini -- true')
        self.assertEqual(
            (ps_row.pid, ps_row.ppid, ps_row.ruser, ps_row.args),
            (1, 0, 'root', 'tini -- true'))
示例#4
0
    def test_single_process(self):
        """
        We can build a PsTree for a single process.
        """
        ps_row = PsRow('1', '0', 'root', 'tini -- echo "hi"')
        ps_tree = build_process_tree([ps_row])

        self.assertEqual(ps_tree, PsTree(ps_row, children=[]))
示例#5
0
 def test_many_processes(self):
     """
     If there are a lot of processes running in a container, we return all
     of them.
     """
     con = FakePsContainer([
         b'  PID  PPID RUSER    COMMAND',
         b'    1     0 root     tini -- django-entrypoint.sh args',
         b'    6     1 django   gunicorn master args',
         b'   17     6 root     nginx master args',
         b'   18     6 django   celery worker args',
         b'   19     6 django   celery beat args',
         b'   26    17 nginx    nginx worker args',
         b'   34     6 django   gunicorn worker args',
         b'   48     0 root     ps ax -o pid,ppid,ruser,args',
     ])
     self.assertEqual(list_container_processes(con), [
         PsRow(1, 0, 'root', 'tini -- django-entrypoint.sh args'),
         PsRow(6, 1, 'django', 'gunicorn master args'),
         PsRow(17, 6, 'root', 'nginx master args'),
         PsRow(18, 6, 'django', 'celery worker args'),
         PsRow(19, 6, 'django', 'celery beat args'),
         PsRow(26, 17, 'nginx', 'nginx worker args'),
         PsRow(34, 6, 'django', 'gunicorn worker args'),
     ])
示例#6
0
    def test_using_assert_that(self):
        """
        MatchesPsTree can be used with assert_that() from testtools.
        """
        pst = PsTree(PsRow(1, 0, 'root', 'tini -- app'), [
            PsTree(PsRow(2, 1, 'root', 'app --arg'), [
                PsTree(PsRow(3, 2, 'appuser', 'app --child1')),
                PsTree(PsRow(4, 2, 'appuser', 'app --child2')),
            ]),
            PsTree(PsRow(5, 1, 'root', 'app2 --arg'), [
                PsTree(PsRow(6, 5, 'root', 'app2 --child')),
            ]),
        ])

        # This passes if the MatchesPsTree matcher matches.
        assert_that(pst, MatchesPsTree('root', 'tini -- app', children=[
            MatchesPsTree('root', 'app --arg', children=[
                MatchesPsTree('appuser', 'app --child1'),
                MatchesPsTree('appuser', 'app --child2'),
            ]),
            MatchesPsTree('root', 'app2 --arg', children=[
                MatchesPsTree('root', 'app2 --child'),
            ]),
        ]))

        # This passes if the MatchesPsTree matcher does not match.
        assert_that(pst, Not(MatchesPsTree('root', 'tini -- app', children=[
            MatchesPsTree('root', 'app --arg', children=[
                MatchesPsTree('appuser', 'app --child1'),
            ]),
            MatchesPsTree('root', 'app2 --arg', children=[
                MatchesPsTree('root', 'app2 --child'),
                MatchesPsTree('appuser', 'app --child2'),
            ]),
        ])))
示例#7
0
    def test_nested_tree_different_child(self):
        """
        MatchesPsTree can detect a child process that is different.
        """
        ps_tree = PsTree(PsRow(1, 0, 'root', 'tini -- app'), [
            PsTree(PsRow(2, 1, 'root', 'app --arg'), [
                PsTree(PsRow(3, 2, 'appuser', 'app --child1')),
                PsTree(PsRow(4, 2, 'appuser', 'app --child3')),
            ]),
            PsTree(PsRow(5, 1, 'root', 'app2 --arg'), [
                PsTree(PsRow(6, 5, 'root', 'app2 --child')),
            ]),
        ])

        matcher = MatchesPsTree('root', 'tini -- app', pid=1, children=[
            MatchesPsTree('root', 'app --arg', children=[
                MatchesPsTree('appuser', 'app --child1'),
                MatchesPsTree('appuser', 'app --child2'),
            ]),
            MatchesPsTree('root', 'app2 --arg', children=[
                MatchesPsTree('root', 'app2 --child'),
            ]),
        ])
        mm = matcher.match(ps_tree).describe()
        assert "mismatches in children:" in mm
        assert "'app --child3' != 'app --child2': args" in mm
示例#8
0
    def test_header_alignment(self):
        """
        Different ps implementations use different alignments for the column
        headers.
        """
        ps_rows = [PsRow(1, 0, 'root', 'sleep 2')]

        busybox_con = FakePsContainer([
            b'PID   PPID  RUSER    COMMAND',
            b'    1     0 root     sleep 2',
            b'    6     0 root     ps ax -o pid,ppid,ruser,args',
        ])
        self.assertEqual(ps_rows, list_container_processes(busybox_con))

        debian_con = FakePsContainer([
            b'  PID  PPID RUSER    COMMAND',
            b'    1     0 root     sleep 2',
            b'    6     0 root     ps ax -o pid,ppid,ruser,args',
        ])
        self.assertEqual(ps_rows, list_container_processes(debian_con))
示例#9
0
    def test_nested_tree_matches(self):
        """
        MatchesPsTree can match a multi-process tree.
        """
        ps_tree = PsTree(PsRow(1, 0, 'root', 'tini -- app'), [
            PsTree(PsRow(2, 1, 'root', 'app --arg'), [
                PsTree(PsRow(3, 2, 'appuser', 'app --child1')),
                PsTree(PsRow(4, 2, 'appuser', 'app --child2')),
            ]),
            PsTree(PsRow(5, 1, 'root', 'app2 --arg'), [
                PsTree(PsRow(6, 5, 'root', 'app2 --child')),
            ]),
        ])

        # Check children in the same order.
        matcher = MatchesPsTree('root', 'tini -- app', pid=1, children=[
            MatchesPsTree('root', 'app --arg', children=[
                MatchesPsTree('appuser', 'app --child1'),
                MatchesPsTree('appuser', 'app --child2'),
            ]),
            MatchesPsTree('root', 'app2 --arg', children=[
                MatchesPsTree('root', 'app2 --child'),
            ]),
        ])
        assert matcher.match(ps_tree) is None

        # Check children in a different order.
        matcher = MatchesPsTree('root', 'tini -- app', pid=1, children=[
            MatchesPsTree('root', 'app --arg', children=[
                MatchesPsTree('appuser', 'app --child2'),
                MatchesPsTree('appuser', 'app --child1'),
            ]),
            MatchesPsTree('root', 'app2 --arg', children=[
                MatchesPsTree('root', 'app2 --child'),
            ]),
        ])
        assert matcher.match(ps_tree) is None

        # Check different children in a different order.
        matcher = MatchesPsTree('root', 'tini -- app', pid=1, children=[
            MatchesPsTree('root', 'app2 --arg', children=[
                MatchesPsTree('root', 'app2 --child'),
            ]),
            MatchesPsTree('root', 'app --arg', children=[
                MatchesPsTree('appuser', 'app --child1'),
                MatchesPsTree('appuser', 'app --child2'),
            ]),
        ])
        assert matcher.match(ps_tree) is None
示例#10
0
    def test_minimal_tree_matches(self):
        """
        MatchesPsTree can match a single-process tree.
        """
        ps_tree = PsTree(PsRow(1, 0, 'root', 'tini -- echo "hi"'))

        matcher = MatchesPsTree('root', 'tini -- echo "hi"')
        assert matcher.match(ps_tree) is None

        matcher = MatchesPsTree('root', 'tini -- echo "hi"', 1)
        assert matcher.match(ps_tree) is None

        matcher = MatchesPsTree('root', 'tini -- echo "hi"', ppid=0)
        assert matcher.match(ps_tree) is None

        matcher = MatchesPsTree('root', 'tini -- echo "hi"', 1, 0)
        assert matcher.match(ps_tree) is None

        matcher = MatchesPsTree('root', 'tini -- echo "hi"', 1, 0, children=[])
        assert matcher.match(ps_tree) is None
示例#11
0
    def test_minimal_tree_mismatches(self):
        """
        MatchesPsTree can detect a non-matching single-process tree.
        """
        ps_tree = PsTree(PsRow(1, 0, 'root', 'tini -- true'))

        matcher = MatchesPsTree('tuber', 'tini -- true')
        mismatch = matcher.match(ps_tree)
        assert "'root' != 'tuber': ruser" in mismatch.describe()

        matcher = MatchesPsTree('root', 'tini -- false')
        mismatch = matcher.match(ps_tree)
        assert "'tini -- true' != 'tini -- false': args" in mismatch.describe()

        matcher = MatchesPsTree('tuber', 'tini -- true', pid=7)
        mismatch = matcher.match(ps_tree)
        assert "1 != 7: pid" in mismatch.describe()

        matcher = MatchesPsTree('tuber', 'tini -- true', ppid=7)
        mismatch = matcher.match(ps_tree)
        assert "0 != 7: ppid" in mismatch.describe()
示例#12
0
 def test_columns(self):
     """
     The PsRow class knows what columns it requires from ps.
     """
     self.assertEqual(PsRow.columns(), ['pid', 'ppid', 'ruser', 'args'])
示例#13
0
def mkrow(pid, ppid, ruser='******', args=None):
    if args is None:
        args = 'args for pid {}'.format(pid)
    return PsRow(pid, ppid, ruser, args)