| #!/usr/bin/env python3 |
| # Copyright (C) 2023 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 a |
| # |
| # 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. |
| |
| from python.generators.diff_tests.testing import Path, DataPath, Metric |
| from python.generators.diff_tests.testing import Csv, Json, TextProto |
| from python.generators.diff_tests.testing import DiffTestBlueprint |
| from python.generators.diff_tests.testing import TestSuite |
| |
| |
| class ProcessTracking(TestSuite): |
| # Tests for the core process and thread tracking logic. Smoke tests |
| def test_process_tracking(self): |
| return DiffTestBlueprint( |
| trace=Path('synth_process_tracking.py'), |
| query=""" |
| SELECT tid, pid, process.name AS pname, thread.name AS tname |
| FROM thread |
| LEFT JOIN process USING(upid) |
| WHERE tid > 0 |
| ORDER BY tid; |
| """, |
| out=Csv(""" |
| "tid","pid","pname","tname" |
| 10,10,"process1","p1-t0" |
| 11,"[NULL]","[NULL]","p1-t1" |
| 12,10,"process1","p1-t2" |
| 20,20,"process_2","p2-t0" |
| 21,20,"process_2","p2-t1" |
| 22,20,"process_2","p2-t2" |
| 30,30,"process_3","p3-t0" |
| 31,30,"process_3","p3-t1" |
| 31,40,"process_4","p4-t1" |
| 32,30,"process_3","p3-t2" |
| 33,30,"process_3","p3-t3" |
| 34,30,"process_3","p3-t4" |
| 40,40,"process_4","p4-t0" |
| """)) |
| |
| # Short lived threads/processes |
| def test_process_tracking_process_tracking_short_lived_1(self): |
| return DiffTestBlueprint( |
| trace=Path('process_tracking_short_lived_1.py'), |
| query=""" |
| SELECT tid, pid, process.name AS pname, thread.name AS tname |
| FROM thread |
| LEFT JOIN process USING(upid) |
| WHERE tid > 0 |
| ORDER BY tid; |
| """, |
| out=Csv(""" |
| "tid","pid","pname","tname" |
| 10,10,"parent","parent" |
| 11,11,"child","child" |
| """)) |
| |
| def test_process_tracking_process_tracking_short_lived_2(self): |
| return DiffTestBlueprint( |
| trace=Path('process_tracking_short_lived_2.py'), |
| query=""" |
| SELECT tid, pid, process.name AS pname, thread.name AS tname |
| FROM thread |
| LEFT JOIN process USING(upid) |
| WHERE tid > 0 |
| ORDER BY tid; |
| """, |
| out=Csv(""" |
| "tid","pid","pname","tname" |
| 10,10,"parent","parent" |
| 11,11,"true_name","true_name" |
| """)) |
| |
| # Process uid handling |
| def test_process_tracking_uid(self): |
| return DiffTestBlueprint( |
| trace=Path('synth_process_tracking.py'), |
| query=""" |
| SELECT pid, uid |
| FROM process |
| ORDER BY pid; |
| """, |
| out=Csv(""" |
| "pid","uid" |
| 0,"[NULL]" |
| 10,1001 |
| 20,1002 |
| 30,"[NULL]" |
| 40,"[NULL]" |
| """)) |
| |
| # Tracking across execs |
| def test_process_tracking_process_tracking_exec(self): |
| return DiffTestBlueprint( |
| trace=Path('process_tracking_exec.py'), |
| query=""" |
| SELECT tid, pid, process.name AS pname, thread.name AS tname |
| FROM thread |
| LEFT JOIN process USING(upid) |
| WHERE tid > 0 |
| ORDER BY tid; |
| """, |
| out=Csv(""" |
| "tid","pid","pname","tname" |
| 10,10,"parent","parent" |
| 11,11,"true_process_name","true_name" |
| """)) |
| |
| # Tracking parent threads |
| def test_process_parent_pid_process_parent_pid_tracking_1(self): |
| return DiffTestBlueprint( |
| trace=Path('process_parent_pid_tracking_1.py'), |
| query=""" |
| SELECT |
| child.pid AS child_pid, |
| parent.pid AS parent_pid |
| FROM process AS child |
| JOIN process AS parent |
| ON child.parent_upid = parent.upid |
| ORDER BY child_pid; |
| """, |
| out=Csv(""" |
| "child_pid","parent_pid" |
| 10,0 |
| 20,10 |
| """)) |
| |
| def test_process_parent_pid_process_parent_pid_tracking_2(self): |
| return DiffTestBlueprint( |
| trace=Path('process_parent_pid_tracking_2.py'), |
| query=""" |
| SELECT |
| child.pid AS child_pid, |
| parent.pid AS parent_pid |
| FROM process AS child |
| JOIN process AS parent |
| ON child.parent_upid = parent.upid |
| ORDER BY child_pid; |
| """, |
| out=Csv(""" |
| "child_pid","parent_pid" |
| 10,0 |
| 20,10 |
| """)) |
| |
| # Tracking thread reuse |
| def test_process_tracking_reused_thread_print(self): |
| return DiffTestBlueprint( |
| trace=Path('reused_thread_print.py'), |
| query=""" |
| SELECT tid, pid, process.name AS pname, thread.name AS tname |
| FROM thread |
| LEFT JOIN process USING(upid) |
| WHERE tid > 0 |
| ORDER BY tid; |
| """, |
| out=Csv(""" |
| "tid","pid","pname","tname" |
| 10,10,"parent","[NULL]" |
| 11,11,"short_lived","[NULL]" |
| 11,10,"parent","true_name" |
| """)) |
| |
| # TODO(lalitm): move this out of this folder. |
| def test_slice_with_pid_sde_tracing_mark_write(self): |
| return DiffTestBlueprint( |
| trace=TextProto(r""" |
| packet { |
| ftrace_events { |
| cpu: 0 |
| event { |
| timestamp: 100 |
| pid: 403 |
| sde_tracing_mark_write { |
| pid: 403 |
| trace_name: "test_event" |
| trace_begin: 1 |
| } |
| } |
| event { |
| timestamp: 101 |
| pid: 403 |
| sde_tracing_mark_write { |
| pid: 403 |
| trace_name: "test_event" |
| trace_begin: 0 |
| } |
| } |
| } |
| } |
| """), |
| query=""" |
| SELECT s.name, dur, tid, pid |
| FROM slice s |
| JOIN thread_track t ON s.track_id = t.id |
| JOIN thread USING(utid) |
| LEFT JOIN process USING(upid); |
| """, |
| out=Csv(""" |
| "name","dur","tid","pid" |
| "test_event",1,403,403 |
| """)) |
| |
| # Check that a <...> thread name doesn't overwrite a useful thread name |
| def test_unknown_thread_name_tracking(self): |
| return DiffTestBlueprint( |
| trace=Path('unknown_thread_name.systrace'), |
| query=""" |
| SELECT tid, pid, process.name AS pname, thread.name AS tname |
| FROM thread |
| LEFT JOIN process USING(upid) |
| WHERE tid > 0 |
| ORDER BY tid; |
| """, |
| out=Csv(""" |
| "tid","pid","pname","tname" |
| 19999,"[NULL]","[NULL]","real_name" |
| """)) |