summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJosh Steadmon <steadmon@google.com>2022-03-08 10:24:43 -0800
committerJosh Steadmon <steadmon@google.com>2022-03-16 17:33:07 +0000
commit244c9a71a689743acea97c6a07ff4dfce4dc6dab (patch)
tree2a52943292478722db03174e577f05ab4ffc1eb7 /tests
parentb308db1e2a982ae4158cb6fedd23d3d547bd09b0 (diff)
downloadgit-repo-244c9a71a689743acea97c6a07ff4dfce4dc6dab.tar.gz
trace: allow writing traces to a socket
Git can write trace2 events to a Unix domain socket [1]. This can be specified via Git's `trace2.eventTarget` config option, which we read to determine where to log our own trace2 events. Currently, if the Git config specifies a socket as the trace2 target, we fail to log any traces. Fix this by adding support for writing to a Unix domain socket, following the same specification that Git supports. [1]: https://git-scm.com/docs/api-trace2#_enabling_a_target Change-Id: I928bc22ba04fba603a9132eb055141845fa48ab2 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/332339 Reviewed-by: Raman Tenneti <rtenneti@google.com> Reviewed-by: Mike Frysinger <vapier@google.com> Tested-by: Josh Steadmon <steadmon@google.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/test_git_trace2_event_log.py62
1 files changed, 62 insertions, 0 deletions
diff --git a/tests/test_git_trace2_event_log.py b/tests/test_git_trace2_event_log.py
index 89dcfb92..0623d32e 100644
--- a/tests/test_git_trace2_event_log.py
+++ b/tests/test_git_trace2_event_log.py
@@ -16,11 +16,42 @@
16 16
17import json 17import json
18import os 18import os
19import socket
19import tempfile 20import tempfile
21import threading
20import unittest 22import unittest
21from unittest import mock 23from unittest import mock
22 24
23import git_trace2_event_log 25import git_trace2_event_log
26import platform_utils
27
28
29def serverLoggingThread(socket_path, server_ready, received_traces):
30 """Helper function to receive logs over a Unix domain socket.
31
32 Appends received messages on the provided socket and appends to received_traces.
33
34 Args:
35 socket_path: path to a Unix domain socket on which to listen for traces
36 server_ready: a threading.Condition used to signal to the caller that this thread is ready to
37 accept connections
38 received_traces: a list to which received traces will be appended (after decoding to a utf-8
39 string).
40 """
41 platform_utils.remove(socket_path, missing_ok=True)
42 data = b''
43 with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
44 sock.bind(socket_path)
45 sock.listen(0)
46 with server_ready:
47 server_ready.notify()
48 with sock.accept()[0] as conn:
49 while True:
50 recved = conn.recv(4096)
51 if not recved:
52 break
53 data += recved
54 received_traces.extend(data.decode('utf-8').splitlines())
24 55
25 56
26class EventLogTestCase(unittest.TestCase): 57class EventLogTestCase(unittest.TestCase):
@@ -324,6 +355,37 @@ class EventLogTestCase(unittest.TestCase):
324 with self.assertRaises(TypeError): 355 with self.assertRaises(TypeError):
325 self._event_log_module.Write(path=1234) 356 self._event_log_module.Write(path=1234)
326 357
358 def test_write_socket(self):
359 """Test Write() with Unix domain socket for |path| and validate received traces."""
360 received_traces = []
361 with tempfile.TemporaryDirectory(prefix='test_server_sockets') as tempdir:
362 socket_path = os.path.join(tempdir, "server.sock")
363 server_ready = threading.Condition()
364 # Start "server" listening on Unix domain socket at socket_path.
365 try:
366 server_thread = threading.Thread(
367 target=serverLoggingThread,
368 args=(socket_path, server_ready, received_traces))
369 server_thread.start()
370
371 with server_ready:
372 server_ready.wait()
373
374 self._event_log_module.StartEvent()
375 path = self._event_log_module.Write(path=f'af_unix:{socket_path}')
376 finally:
377 server_thread.join(timeout=5)
378
379 self.assertEqual(path, f'af_unix:stream:{socket_path}')
380 self.assertEqual(len(received_traces), 2)
381 version_event = json.loads(received_traces[0])
382 start_event = json.loads(received_traces[1])
383 self.verifyCommonKeys(version_event, expected_event_name='version')
384 self.verifyCommonKeys(start_event, expected_event_name='start')
385 # Check for 'start' event specific fields.
386 self.assertIn('argv', start_event)
387 self.assertIsInstance(start_event['argv'], list)
388
327 389
328if __name__ == '__main__': 390if __name__ == '__main__':
329 unittest.main() 391 unittest.main()