aboutsummaryrefslogtreecommitdiff
path: root/src/dctv/test_event_parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/dctv/test_event_parser.py')
-rw-r--r--src/dctv/test_event_parser.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/dctv/test_event_parser.py b/src/dctv/test_event_parser.py
new file mode 100644
index 0000000..ed95303
--- /dev/null
+++ b/src/dctv/test_event_parser.py
@@ -0,0 +1,170 @@
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http:#www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Test event parser routines"""
+
+# pylint: disable=missing-docstring
+
+import logging
+from tempfile import NamedTemporaryFile
+from contextlib import contextmanager
+
+import numpy as np
+from cytoolz import valmap
+import pytest
+
+from .trace_file_util import (
+ BadTraceFileError,
+ ParseFailureError,
+)
+
+from .util import (
+ INT64,
+)
+
+from .model import TraceAnalysisSession, FileTraceContext
+from .test_query import TestQueryTable
+
+log = logging.getLogger(__name__)
+
+@contextmanager
+def trace_in_ntf(string):
+ with NamedTemporaryFile(prefix="dctv-ep-test-", suffix=".trace") as ntf:
+ ntf.write(string.encode("UTF-8"))
+ ntf.flush()
+ yield ntf
+
+@contextmanager
+def trace_session(string, time_basis_override=None, threads=False):
+ with trace_in_ntf(string) as ntf, \
+ TraceAnalysisSession(threads=threads) as session:
+ session.mount_trace(["trace"],
+ FileTraceContext(
+ ntf.name,
+ force_ftrace=True,
+ time_basis_override=time_basis_override),
+ temp_hack_lenient_metadata=True)
+ yield session
+
+TEST_TRACE_BASIC = """\
+ trace-cmd-12196 [005] d..3 276946.285107: sched_switch: prev_comm=trace-cmd prev_pid=12196 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+ <idle>-0 [005] d..3 276946.285115: sched_waking: comm=trace-cmd pid=12203 prio=120 target_cpu=006
+ <idle>-0 [005] d..3 276946.285121: sched_wakeup: comm=trace-cmd pid=12203 prio=120 target_cpu=004
+ <idle>-0 [004] d..3 276946.285124: cpu_idle: state=4294967295 cpu_id=4
+ <idle>-0 [004] d..3 276946.285128: sched_waking: comm=trace-cmd pid=12202 prio=120 target_cpu=004
+ <idle>-0 [005] d..3 276946.285129: cpu_idle: state=0 cpu_id=5
+ <idle>-0 [004] d..3 276946.285131: sched_wakeup: comm=trace-cmd pid=12202 prio=120 target_cpu=004
+ <idle>-0 [004] d..3 276946.285134: sched_switch: prev_comm=swapper/4 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=trace-cmd next_pid=12202 next_prio=120
+ trace-cmd-12202 [004] d..3 276946.285141: sched_switch: prev_comm=trace-cmd prev_pid=12202 prev_prio=120 prev_state=S ==> next_comm=trace-cmd next_pid=12203 next_prio=120
+"""
+
+def _array2str(array, st):
+ return [b.decode("UTF-8") for b in st.vlookup(array)]
+
+def _sessionq(session, sql, *, as_raw_array=False):
+ result = dict(session.sql_query(sql))
+ if not as_raw_array:
+ result = valmap(lambda x: x.tolist(), result)
+ return result
+
+@pytest.mark.parametrize("threads", ["threads", "nothreads"])
+def test_parse_events_basic(threads):
+ # pylint: disable=bad-whitespace
+ with trace_session(TEST_TRACE_BASIC,
+ threads=(threads=="threads")) as session:
+ assert _sessionq(session, """
+ SELECT event_type, COUNT(*) AS count FROM trace.raw_event_index
+ GROUP BY event_type""") == TestQueryTable(
+ names=["event_type", "count"],
+ rows=[
+ ["sched_switch", 3],
+ ["sched_waking", 2],
+ ["sched_wakeup", 2],
+ ["cpu_idle", 2],
+ ]).as_dict()
+ assert _sessionq(session, """
+ SELECT prev_tid, cpu, comm FROM trace.raw_events.sched_switch
+ """) == TestQueryTable(
+ names=["prev_tid", "cpu", "comm"],
+ rows=[
+ [12196, 5, "trace-cmd"],
+ [0, 4, "<idle>"],
+ [12202, 4, "trace-cmd"],
+ ]).as_dict()
+
+def test_parse_events_ts():
+ with trace_session(TEST_TRACE_BASIC, time_basis_override=0) as session:
+ assert _sessionq(session, """
+ SELECT _ts FROM trace.raw_events.sched_switch""") == \
+ TestQueryTable(
+ names=["_ts"],
+ rows=[
+ [276946285107000],
+ [276946285134000],
+ [276946285141000],
+ ]).as_dict()
+
+def test_parse_events_time_basis():
+ with trace_session(TEST_TRACE_BASIC) as session:
+ assert _sessionq(session, """
+ SELECT _ts FROM trace.raw_events.sched_switch""") == \
+ TestQueryTable(
+ names=["_ts"],
+ rows=[
+ [0],
+ [27000],
+ [34000],
+ ]).as_dict()
+
+def test_fake_empty_event_list():
+ with trace_session(TEST_TRACE_BASIC) as session:
+ result = _sessionq(session, """
+ SELECT _ts, handler_name FROM trace.raw_events.irq_handler_entry
+ """, as_raw_array=True)
+ assert result["_ts"].dtype == INT64
+ assert result["handler_name"].dtype == np.dtype("O")
+
+def test_last_ts():
+ with trace_session(TEST_TRACE_BASIC) as session:
+ assert _sessionq(session, "SELECT EVENT * FROM trace.last_ts") == \
+ dict(_ts=[34000])
+
+TEST_TRACE_BAD_PAYLOAD_SS = """\
+ TRACE-cmd-12196 [005] d..3 276946.285107: sched_switch: prev_comm=trace-cmd prev_pid=12196 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+ trace-cmd-12202 [004] d..3 276946.285141: sched_switch: prev_comm=trace-cmd INVALID_FIELD=12202 prev_prio=120 prev_state=S ==> next_comm=trace-cmd next_pid=12203 next_prio=120
+"""
+
+def test_parse_event_error():
+ with trace_session(TEST_TRACE_BAD_PAYLOAD_SS) as session:
+ with pytest.raises(BadTraceFileError) as ex:
+ _sessionq(session,
+ "SELECT prev_tid FROM trace.raw_events.sched_switch")
+ assert "INVALID_FIELD" in str(ex)
+ cause = ex.value.__cause__
+ assert isinstance(cause, ParseFailureError)
+ assert cause.offset == 182
+
+TEST_TRACE_BAD_INDEX = """\
+ TRACE-cmd-12196 [005] d..3 276946.285107: sched_switch: prev_comm=trace-cmd prev_pid=12196 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+ dsfaadfsfasf
+"""
+
+def test_index_error():
+ with trace_session(TEST_TRACE_BAD_INDEX) as session:
+ with pytest.raises(BadTraceFileError) as ex:
+ _sessionq(session,
+ "SELECT prev_tid FROM trace.raw_events.sched_switch")
+ assert "index error" in str(ex)
+ cause = ex.value.__cause__
+ assert isinstance(cause, ParseFailureError)
+ assert 182 <= cause.offset < len(TEST_TRACE_BAD_INDEX)