Replace JSON-GLib by custom JSON dumper library
[metze/wireshark/wip.git] / test / suite_clopts.py
1 #
2 # -*- coding: utf-8 -*-
3 # Wireshark tests
4 # By Gerald Combs <gerald@wireshark.org>
5 #
6 # Ported from a set of Bash scripts which were copyright 2005 Ulf Lamping
7 #
8 # SPDX-License-Identifier: GPL-2.0-or-later
9 #
10 '''Command line option tests'''
11
12 import json
13 import os.path
14 import subprocess
15 import subprocesstest
16 import fixtures
17
18 #glossaries = ('fields', 'protocols', 'values', 'decodes', 'defaultprefs', 'currentprefs')
19
20 glossaries = ('decodes', 'values')
21 testout_pcap = 'testout.pcap'
22
23
24 @fixtures.uses_fixtures
25 class case_dumpcap_options(subprocesstest.SubprocessTestCase):
26     # XXX Should we generate individual test functions instead of looping?
27     def test_dumpcap_invalid_chars(self, cmd_dumpcap, base_env):
28         '''Invalid dumpcap parameters'''
29         for char_arg in 'CEFGHJKNOQRTUVWXYejloxz':
30             self.assertRun((cmd_dumpcap, '-' + char_arg), env=base_env,
31                            expected_return=self.exit_command_line)
32
33     # XXX Should we generate individual test functions instead of looping?
34     def test_dumpcap_valid_chars(self, cmd_dumpcap, base_env):
35         for char_arg in 'hv':
36             self.assertRun((cmd_dumpcap, '-' + char_arg), env=base_env)
37
38     # XXX Should we generate individual test functions instead of looping?
39     def test_dumpcap_interface_chars(self, cmd_dumpcap, base_env):
40         '''Valid dumpcap parameters requiring capture permissions'''
41         valid_returns = [self.exit_ok, self.exit_error]
42         for char_arg in 'DL':
43             process = self.runProcess((cmd_dumpcap, '-' + char_arg), env=base_env)
44             self.assertIn(process.returncode, valid_returns)
45
46
47 @fixtures.mark_usefixtures('base_env')
48 @fixtures.uses_fixtures
49 class case_dumpcap_capture_clopts(subprocesstest.SubprocessTestCase):
50     def test_dumpcap_invalid_capfilter(self, cmd_dumpcap, capture_interface):
51         '''Invalid capture filter'''
52         invalid_filter = '__invalid_protocol'
53         # $DUMPCAP -f 'jkghg' -w './testout.pcap' > ./testout.txt 2>&1
54         testout_file = self.filename_from_id(testout_pcap)
55         self.runProcess((cmd_dumpcap, '-f', invalid_filter, '-w', testout_file))
56         self.assertTrue(self.grepOutput('Invalid capture filter "' + invalid_filter + '" for interface'))
57
58     def test_dumpcap_invalid_interface_name(self, cmd_dumpcap, capture_interface):
59         '''Invalid capture interface name'''
60         invalid_interface = '__invalid_interface'
61         # $DUMPCAP -i invalid_interface -w './testout.pcap' > ./testout.txt 2>&1
62         testout_file = self.filename_from_id(testout_pcap)
63         self.runProcess((cmd_dumpcap, '-i', invalid_interface, '-w', testout_file))
64         self.assertTrue(self.grepOutput('The capture session could not be initiated'))
65
66     def test_dumpcap_invalid_interface_index(self, cmd_dumpcap, capture_interface):
67         '''Invalid capture interface index'''
68         invalid_index = '0'
69         # $DUMPCAP -i 0 -w './testout.pcap' > ./testout.txt 2>&1
70         testout_file = self.filename_from_id(testout_pcap)
71         self.runProcess((cmd_dumpcap, '-i', invalid_index, '-w', testout_file))
72         self.assertTrue(self.grepOutput('There is no interface with that adapter index'))
73
74
75 @fixtures.mark_usefixtures('test_env')
76 @fixtures.uses_fixtures
77 class case_basic_clopts(subprocesstest.SubprocessTestCase):
78     def test_existing_file(self, cmd_tshark, capture_file):
79         # $TSHARK -r "${CAPTURE_DIR}dhcp.pcap" > ./testout.txt 2>&1
80         self.assertRun((cmd_tshark, '-r', capture_file('dhcp.pcap')))
81
82     def test_nonexistent_file(self, cmd_tshark, capture_file):
83         # $TSHARK - r ThisFileDontExist.pcap > ./testout.txt 2 > &1
84         self.assertRun((cmd_tshark, '-r', capture_file('__ceci_nest_pas_une.pcap')),
85                        expected_return=self.exit_error)
86
87
88 @fixtures.mark_usefixtures('test_env')
89 @fixtures.uses_fixtures
90 class case_tshark_options(subprocesstest.SubprocessTestCase):
91     # XXX Should we generate individual test functions instead of looping?
92     def test_tshark_invalid_chars(self, cmd_tshark):
93         '''Invalid tshark parameters'''
94         for char_arg in 'ABCEFHJKMNORTUWXYZabcdefijkmorstuwyz':
95             self.assertRun((cmd_tshark, '-' + char_arg),
96                            expected_return=self.exit_command_line)
97
98     # XXX Should we generate individual test functions instead of looping?
99     def test_tshark_valid_chars(self, cmd_tshark):
100         for char_arg in 'Ghv':
101             self.assertRun((cmd_tshark, '-' + char_arg))
102
103     # XXX Should we generate individual test functions instead of looping?
104     def test_tshark_interface_chars(self, cmd_tshark, cmd_dumpcap):
105         '''Valid tshark parameters requiring capture permissions'''
106         # These options require dumpcap
107         valid_returns = [self.exit_ok, self.exit_error]
108         for char_arg in 'DL':
109             process = self.runProcess((cmd_tshark, '-' + char_arg))
110             self.assertIn(process.returncode, valid_returns)
111
112
113 @fixtures.mark_usefixtures('test_env')
114 @fixtures.uses_fixtures
115 class case_tshark_capture_clopts(subprocesstest.SubprocessTestCase):
116     def test_tshark_invalid_capfilter(self, cmd_tshark, capture_interface):
117         '''Invalid capture filter'''
118         invalid_filter = '__invalid_protocol'
119         # $TSHARK -f 'jkghg' -w './testout.pcap' > ./testout.txt 2>&1
120         testout_file = self.filename_from_id(testout_pcap)
121         self.runProcess((cmd_tshark, '-f', invalid_filter, '-w', testout_file ))
122         self.assertTrue(self.grepOutput('Invalid capture filter "' + invalid_filter + '" for interface'))
123
124     def test_tshark_invalid_interface_name(self, cmd_tshark, capture_interface):
125         '''Invalid capture interface name'''
126         invalid_interface = '__invalid_interface'
127         # $TSHARK -i invalid_interface -w './testout.pcap' > ./testout.txt 2>&1
128         testout_file = self.filename_from_id(testout_pcap)
129         self.runProcess((cmd_tshark, '-i', invalid_interface, '-w', testout_file))
130         self.assertTrue(self.grepOutput('The capture session could not be initiated'))
131
132     def test_tshark_invalid_interface_index(self, cmd_tshark, capture_interface):
133         '''Invalid capture interface index'''
134         invalid_index = '0'
135         # $TSHARK -i 0 -w './testout.pcap' > ./testout.txt 2>&1
136         testout_file = self.filename_from_id(testout_pcap)
137         self.runProcess((cmd_tshark, '-i', invalid_index, '-w', testout_file))
138         self.assertTrue(self.grepOutput('There is no interface with that adapter index'))
139
140
141 @fixtures.mark_usefixtures('test_env')
142 @fixtures.uses_fixtures
143 class case_tshark_name_resolution_clopts(subprocesstest.SubprocessTestCase):
144     def test_tshark_valid_name_resolution(self, cmd_tshark, capture_interface):
145         # $TSHARK -N mnNtdv -a duration:1 > ./testout.txt 2>&1
146         self.assertRun((cmd_tshark, '-N', 'mnNtdv', '-a', 'duration: 1'))
147
148     # XXX Add invalid name resolution.
149
150 @fixtures.mark_usefixtures('test_env')
151 @fixtures.uses_fixtures
152 class case_tshark_unicode_clopts(subprocesstest.SubprocessTestCase):
153     def test_tshark_unicode_display_filter(self, cmd_tshark, capture_file):
154         '''Unicode (UTF-8) display filter'''
155         self.runProcess((cmd_tshark, '-r', capture_file('http.pcap'), '-Y', 'tcp.flags.str == "·······AP···"'))
156         self.assertTrue(self.grepOutput('HEAD.*/v4/iuident.cab'))
157
158
159 @fixtures.uses_fixtures
160 class case_tshark_dump_glossaries(subprocesstest.SubprocessTestCase):
161     def test_tshark_dump_glossary(self, cmd_tshark, base_env):
162         for glossary in glossaries:
163             try:
164                 self.log_fd.truncate()
165             except:
166                 pass
167             self.assertRun((cmd_tshark, '-G', glossary), env=base_env)
168             self.assertEqual(self.countOutput(count_stdout=False, count_stderr=True), 0, 'Found error output while printing glossary ' + glossary)
169
170     def test_tshark_glossary_valid_utf8(self, cmd_tshark, base_env):
171         for glossary in glossaries:
172             env = base_env
173             env['LANG'] = 'en_US.UTF-8'
174             g_contents = subprocess.check_output((cmd_tshark, '-G', glossary), env=env, stderr=subprocess.PIPE)
175             decoded = True
176             try:
177                 g_contents.decode('UTF-8')
178             except UnicodeDecodeError:
179                 decoded = False
180             self.assertTrue(decoded, '{} is not valid UTF-8'.format(glossary))
181
182     def test_tshark_glossary_plugin_count(self, cmd_tshark, base_env):
183         self.runProcess((cmd_tshark, '-G', 'plugins'), env=base_env)
184         self.assertGreaterEqual(self.countOutput('dissector'), 10, 'Fewer than 10 dissector plugins found')
185
186     def test_tshark_elastic_mapping(self, cmd_tshark, dirs, base_env):
187         def get_ip_props(obj):
188             return obj['mappings']['pcap_file']['properties']['layers']['properties']['ip']['properties']
189         baseline_file = os.path.join(dirs.baseline_dir, 'elastic-mapping-ip-subset.json')
190         with open(baseline_file) as f:
191             expected_obj = json.load(f)
192         keys_to_check = get_ip_props(expected_obj).keys()
193         proc = self.assertRun((cmd_tshark, '-G', 'elastic-mapping', '--elastic-mapping-filter', 'ip'))
194         actual_obj = json.loads(proc.stdout_str)
195         ip_props = get_ip_props(actual_obj)
196         for key in list(ip_props.keys()):
197             if key not in keys_to_check:
198                 del ip_props[key]
199         self.assertEqual(actual_obj, expected_obj)
200
201
202 @fixtures.mark_usefixtures('test_env')
203 @fixtures.uses_fixtures
204 class case_tshark_z_expert(subprocesstest.SubprocessTestCase):
205     def test_tshark_z_expert_all(self, cmd_tshark, capture_file):
206         self.assertRun((cmd_tshark, '-q', '-z', 'expert',
207             '-r', capture_file('http-ooo.pcap')))
208         self.assertTrue(self.grepOutput('Errors'))
209         self.assertTrue(self.grepOutput('Warns'))
210         self.assertTrue(self.grepOutput('Chats'))
211
212     def test_tshark_z_expert_error(self, cmd_tshark, capture_file):
213         self.assertRun((cmd_tshark, '-q', '-z', 'expert,error',
214             '-r', capture_file('http-ooo.pcap')))
215         self.assertTrue(self.grepOutput('Errors'))
216         self.assertFalse(self.grepOutput('Warns'))
217         self.assertFalse(self.grepOutput('Chats'))
218
219     def test_tshark_z_expert_warn(self, cmd_tshark, capture_file):
220         self.assertRun((cmd_tshark, '-q', '-z', 'expert,warn',
221             '-r', capture_file('http-ooo.pcap')))
222         self.assertTrue(self.grepOutput('Errors'))
223         self.assertTrue(self.grepOutput('Warns'))
224         self.assertFalse(self.grepOutput('Chats'))
225
226     def test_tshark_z_expert_note(self, cmd_tshark, capture_file):
227         self.assertRun((cmd_tshark, '-q', '-z', 'expert,note',
228             '-r', capture_file('http2-data-reassembly.pcap')))
229         self.assertTrue(self.grepOutput('Warns'))
230         self.assertTrue(self.grepOutput('Notes'))
231         self.assertFalse(self.grepOutput('Chats'))
232
233     def test_tshark_z_expert_chat(self, cmd_tshark, capture_file):
234         self.assertRun((cmd_tshark, '-q', '-z', 'expert,chat',
235             '-r', capture_file('http-ooo.pcap')))
236         self.assertTrue(self.grepOutput('Errors'))
237         self.assertTrue(self.grepOutput('Warns'))
238         self.assertTrue(self.grepOutput('Chats'))
239
240     def test_tshark_z_expert_comment(self, cmd_tshark, capture_file):
241         self.assertRun((cmd_tshark, '-q', '-z', 'expert,comment',
242             '-r', capture_file('sip.pcapng')))
243         self.assertTrue(self.grepOutput('Notes'))
244         self.assertTrue(self.grepOutput('Comments'))
245
246     def test_tshark_z_expert_invalid_filter(self, cmd_tshark, capture_file):
247         invalid_filter = '__invalid_protocol'
248         self.assertRun((cmd_tshark, '-q', '-z', 'expert,' + invalid_filter,
249             '-r', capture_file('http-ooo.pcap')),
250             expected_return=self.exit_command_line)
251         self.assertTrue(self.grepOutput('Filter "' + invalid_filter + '" is invalid'))
252
253     def test_tshark_z_expert_error_invalid_filter(self, cmd_tshark, capture_file):
254         invalid_filter = '__invalid_protocol'
255         self.assertRun((cmd_tshark, '-q', '-z', 'expert,error,' + invalid_filter,
256             '-r', capture_file('http-ooo.pcap')),
257             expected_return=self.exit_command_line)
258         self.assertTrue(self.grepOutput('Filter "' + invalid_filter + '" is invalid'))
259
260     def test_tshark_z_expert_filter(self, cmd_tshark, capture_file):
261         self.assertRun((cmd_tshark, '-q', '-z', 'expert,udp',  # udp is a filter
262             '-r', capture_file('http-ooo.pcap')))
263         self.assertFalse(self.grepOutput('Errors'))
264         self.assertFalse(self.grepOutput('Warns'))
265         self.assertFalse(self.grepOutput('Chats'))
266
267     def test_tshark_z_expert_error_filter(self, cmd_tshark, capture_file):
268         self.assertRun((cmd_tshark, '-q', '-z', 'expert,error,udp',  # udp is a filter
269             '-r', capture_file('http-ooo.pcap')))
270         self.assertFalse(self.grepOutput('Errors'))
271         self.assertFalse(self.grepOutput('Warns'))
272         self.assertFalse(self.grepOutput('Chats'))