Skip to content

Commit 081a32c

Browse files
authored
PYSCAN-28: Refactor scanner to use the application logger (#11)
1 parent 55ab7c5 commit 081a32c

File tree

3 files changed

+47
-22
lines changed

3 files changed

+47
-22
lines changed

src/py_sonar_scanner/logger.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,4 @@ def get_logger(cls) -> Logger:
3636
def _setup_logger(log: Logger):
3737
log.setLevel(logging.INFO)
3838
handler = logging.StreamHandler()
39-
handler.terminator = ""
4039
log.addHandler(handler)

src/py_sonar_scanner/scanner.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@
1818
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
#
2020
from __future__ import annotations
21-
import logging
2221
from logging import Logger
23-
import threading
2422
from threading import Thread
2523
from subprocess import Popen, PIPE
2624

25+
from py_sonar_scanner.logger import ApplicationLogger
2726
from py_sonar_scanner.configuration import Configuration
2827

2928

@@ -33,19 +32,12 @@ class Scanner:
3332

3433
def __init__(self, cfg: Configuration):
3534
self.cfg = cfg
36-
self.log = logging.getLogger(__name__)
37-
self._setup_logger(self.log)
38-
39-
def _setup_logger(self, log: Logger):
40-
log.setLevel(logging.INFO)
41-
handler = logging.StreamHandler()
42-
handler.terminator = ""
43-
log.addHandler(handler)
35+
self.log = ApplicationLogger.get_logger()
4436

4537
def scan(self):
4638
process = self.execute_command()
47-
output_thread = threading.Thread(target=self._log_output, args=(process.stdout,))
48-
error_thread = threading.Thread(target=self._log_output, args=(process.stderr,))
39+
output_thread = Thread(target=self._log_output, args=(process.stdout,))
40+
error_thread = Thread(target=self._log_output, args=(process.stderr,))
4941
return self.process_output(output_thread, error_thread, process)
5042

5143
def process_output(self, output_thread: Thread, error_thread: Thread, process: Popen) -> int:
@@ -68,5 +60,5 @@ def compute_command(self) -> list[str]:
6860

6961
def _log_output(self, stream: list[bytes]):
7062
for line in stream:
71-
decoded_line = line.decode("utf-8")
63+
decoded_line = line.decode("utf-8").rstrip()
7264
self.log.info(decoded_line)

tests/test_scanner.py

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
#
2020
import unittest
21-
from unittest.mock import Mock
21+
from unittest.mock import Mock, patch, call
2222
import threading
2323
from py_sonar_scanner.scanner import Scanner
2424
from py_sonar_scanner.configuration import Configuration
@@ -31,13 +31,13 @@ def test_scanner_compute_command(self):
3131
cfg.scan_arguments = ["a", "b"]
3232
scanner = Scanner(cfg)
3333

34-
assert scanner.compute_command() == ["test", "a", "b"]
34+
self.assertEqual(scanner.compute_command(), ["test", "a", "b"])
3535

3636
cfg.sonar_scanner_executable_path = "test"
3737
cfg.scan_arguments = []
3838
scanner = Scanner(cfg)
3939

40-
assert scanner.compute_command() == ["test"]
40+
self.assertEqual(scanner.compute_command(), ["test"])
4141

4242
cfg.sonar_scanner_executable_path = ""
4343
cfg.scan_arguments = []
@@ -49,8 +49,8 @@ def test_process_output(self):
4949
scanner = Scanner(Configuration())
5050
output_thread = threading.Thread()
5151
error_thread = threading.Thread()
52-
53-
process = Mock()
52+
success_code = 0
53+
process = Mock(returncode=success_code)
5454
output_thread.start = Mock()
5555
error_thread.start = Mock()
5656
output_thread.join = Mock()
@@ -64,14 +64,48 @@ def test_process_output(self):
6464
output_thread.join.assert_called_once()
6565
error_thread.join.assert_called_once()
6666
process.wait.assert_called_once()
67+
self.assertEqual(return_code, success_code)
6768

68-
def test_scan(self):
69+
@patch("py_sonar_scanner.scanner.Thread")
70+
def test_scan(self, mock_thread):
6971
scanner = Scanner(Configuration())
70-
71-
scanner.execute_command = Mock()
72+
process = Mock()
73+
scanner.execute_command = Mock(return_value=process)
7274
scanner.process_output = Mock()
7375

7476
scanner.scan()
7577

7678
scanner.execute_command.assert_called_once()
79+
call_thread_stdout = call(target=scanner._log_output, args=(process.stdout,))
80+
call_thread_stderr = call(target=scanner._log_output, args=(process.stderr,))
81+
mock_thread.assert_has_calls([call_thread_stdout, call_thread_stderr])
82+
self.assertEqual(mock_thread.call_count, 2)
7783
scanner.process_output.assert_called_once()
84+
85+
@patch("py_sonar_scanner.scanner.Popen")
86+
def test_execute_command(self, mock_popen):
87+
from subprocess import PIPE
88+
89+
scanner = Scanner(Configuration())
90+
command = "test"
91+
scanner.compute_command = Mock(return_value=command)
92+
93+
scanner.execute_command()
94+
95+
scanner.compute_command.assert_called_once()
96+
mock_popen.assert_called_once_with(command, stdout=PIPE, stderr=PIPE)
97+
98+
def test_log_output(self):
99+
scanner = Scanner(Configuration())
100+
input_lines = [
101+
bytes("test\n", encoding="utf-8"),
102+
bytes("\nother line\n\n", encoding="utf-8"),
103+
bytes("", encoding="utf-8"),
104+
bytes("last \n line", encoding="utf-8"),
105+
]
106+
with self.assertLogs(scanner.log) as log:
107+
scanner._log_output(input_lines)
108+
self.assertEqual(log.records[0].getMessage(), "test")
109+
self.assertEqual(log.records[1].getMessage(), "\nother line")
110+
self.assertEqual(log.records[2].getMessage(), "")
111+
self.assertEqual(log.records[3].getMessage(), "last \n line")

0 commit comments

Comments
 (0)