mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-04 05:30:32 -05:00 
			
		
		
		
	
		
			
	
	
		
			212 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			212 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								import unittest
							 | 
						||
| 
								 | 
							
								import mock
							 | 
						||
| 
								 | 
							
								import superscanner
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								def print_hex(bytestring):
							 | 
						||
| 
								 | 
							
								    print('\\x' + '\\x'.join('{:02x}'.format(x) for x in bytestring))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								def get_deviceset_info(deviceset_index):
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								        "channelcount": 4,
							 | 
						||
| 
								 | 
							
								        "channels": [
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                "deltaFrequency": 170000,
							 | 
						||
| 
								 | 
							
								                "direction": 0,
							 | 
						||
| 
								 | 
							
								                "id": "NFMDemod",
							 | 
						||
| 
								 | 
							
								                "index": 0,
							 | 
						||
| 
								 | 
							
								                "title": "NFM Demodulator",
							 | 
						||
| 
								 | 
							
								                "uid": 1590355926650308
							 | 
						||
| 
								 | 
							
								            },
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                "deltaFrequency": -155000,
							 | 
						||
| 
								 | 
							
								                "direction": 0,
							 | 
						||
| 
								 | 
							
								                "id": "DSDDemod",
							 | 
						||
| 
								 | 
							
								                "index": 1,
							 | 
						||
| 
								 | 
							
								                "title": "DSD Demodulator",
							 | 
						||
| 
								 | 
							
								                "uid": 1590355926718405
							 | 
						||
| 
								 | 
							
								            },
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                "deltaFrequency": 170000,
							 | 
						||
| 
								 | 
							
								                "direction": 0,
							 | 
						||
| 
								 | 
							
								                "id": "NFMDemod",
							 | 
						||
| 
								 | 
							
								                "index": 2,
							 | 
						||
| 
								 | 
							
								                "title": "NFM Demodulator",
							 | 
						||
| 
								 | 
							
								                "uid": 1590355926939766
							 | 
						||
| 
								 | 
							
								            },
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                "deltaFrequency": -95000,
							 | 
						||
| 
								 | 
							
								                "direction": 0,
							 | 
						||
| 
								 | 
							
								                "id": "NFMDemod",
							 | 
						||
| 
								 | 
							
								                "index": 3,
							 | 
						||
| 
								 | 
							
								                "title": "NFM Demodulator",
							 | 
						||
| 
								 | 
							
								                "uid": 1590355926945674
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        ],
							 | 
						||
| 
								 | 
							
								        "samplingDevice": {
							 | 
						||
| 
								 | 
							
								            "bandwidth": 768000,
							 | 
						||
| 
								 | 
							
								            "centerFrequency": 145480000,
							 | 
						||
| 
								 | 
							
								            "deviceNbStreams": 1,
							 | 
						||
| 
								 | 
							
								            "deviceStreamIndex": 0,
							 | 
						||
| 
								 | 
							
								            "direction": 0,
							 | 
						||
| 
								 | 
							
								            "hwType": "AirspyHF",
							 | 
						||
| 
								 | 
							
								            "index": 0,
							 | 
						||
| 
								 | 
							
								            "sequence": 0,
							 | 
						||
| 
								 | 
							
								            "serial": "c852a98040c73f93",
							 | 
						||
| 
								 | 
							
								            "state": "running"
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								def set_channel_frequency(channel):
							 | 
						||
| 
								 | 
							
								    pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								def set_channel_mute(channel):
							 | 
						||
| 
								 | 
							
								    pass
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								class TestStringMethods(unittest.TestCase):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def test_upper(self):
							 | 
						||
| 
								 | 
							
								        self.assertEqual('foo'.upper(), 'FOO')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def test_isupper(self):
							 | 
						||
| 
								 | 
							
								        self.assertTrue('FOO'.isupper())
							 | 
						||
| 
								 | 
							
								        self.assertFalse('Foo'.isupper())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def test_split(self):
							 | 
						||
| 
								 | 
							
								        s = 'hello world'
							 | 
						||
| 
								 | 
							
								        self.assertEqual(s.split(), ['hello', 'world'])
							 | 
						||
| 
								 | 
							
								        # check that s.split fails when the separator is not a string
							 | 
						||
| 
								 | 
							
								        with self.assertRaises(TypeError):
							 | 
						||
| 
								 | 
							
								            s.split(2)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								class TestSuperScannerOptions(unittest.TestCase):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def test_options_minimal(self):
							 | 
						||
| 
								 | 
							
								        options = superscanner.get_input_options(["-ctoto"])
							 | 
						||
| 
								 | 
							
								        self.assertEqual(options.config_file, 'toto')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								class TestSuperScannerDecode(unittest.TestCase):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def test_decode_bytes(self):
							 | 
						||
| 
								 | 
							
								        msg_bytes = b'\x40\xd9\xab\x08\x00\x00\x00\x00' + \
							 | 
						||
| 
								 | 
							
								            b'\xff\x00\x00\x00\x00\x00\x00\x00' + \
							 | 
						||
| 
								 | 
							
								            b'\x69\x63\xbb\x55\x72\x01\x00\x00' + \
							 | 
						||
| 
								 | 
							
								            b'\x00\x04\x00\x00' + \
							 | 
						||
| 
								 | 
							
								            b'\x00\xb8\x0b\x00' + \
							 | 
						||
| 
								 | 
							
								            b'\x04\x00\x00\x00'
							 | 
						||
| 
								 | 
							
								        for i in range(1024):
							 | 
						||
| 
								 | 
							
								            msg_bytes += b'\x00\x00\x00\x00'
							 | 
						||
| 
								 | 
							
								        msg_struct = superscanner.decode_message(msg_bytes)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(msg_struct['fft_size'], 1024)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								class TestSuperScannerProcessHotspots(unittest.TestCase):
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @mock.patch('superscanner.get_deviceset_info', side_effect=get_deviceset_info)
							 | 
						||
| 
								 | 
							
								    def setUp(self, urandom_function):
							 | 
						||
| 
								 | 
							
								        self.options = type('options', (object,), {})()
							 | 
						||
| 
								 | 
							
								        self.options.address = '127.0.0.1'
							 | 
						||
| 
								 | 
							
								        self.options.passes = 10
							 | 
						||
| 
								 | 
							
								        self.options.api_port =  8091
							 | 
						||
| 
								 | 
							
								        self.options.ws_port  = 8887
							 | 
						||
| 
								 | 
							
								        self.options.config_file = 'toto'
							 | 
						||
| 
								 | 
							
								        self.options.psd_input_file = None
							 | 
						||
| 
								 | 
							
								        self.options.psd_output_file = None
							 | 
						||
| 
								 | 
							
								        self.options.passes = 10
							 | 
						||
| 
								 | 
							
								        self.options.margin = 3
							 | 
						||
| 
								 | 
							
								        self.options.psd_fixed = None
							 | 
						||
| 
								 | 
							
								        self.options.psd_exclude_higher = None
							 | 
						||
| 
								 | 
							
								        self.options.psd_exclude_lower = None
							 | 
						||
| 
								 | 
							
								        self.options.psd_graph = None
							 | 
						||
| 
								 | 
							
								        self.options.group_tolerance = 1
							 | 
						||
| 
								 | 
							
								        self.options.freq_round = 1
							 | 
						||
| 
								 | 
							
								        self.options.freq_offset = 0
							 | 
						||
| 
								 | 
							
								        superscanner.OPTIONS = self.options
							 | 
						||
| 
								 | 
							
								        superscanner.CONFIG = {
							 | 
						||
| 
								 | 
							
								            "deviceset_index": 0,
							 | 
						||
| 
								 | 
							
								            "freqrange_exclusions": [
							 | 
						||
| 
								 | 
							
								                [145290000, 145335000],
							 | 
						||
| 
								 | 
							
								                [145692500, 145707500]
							 | 
						||
| 
								 | 
							
								            ],
							 | 
						||
| 
								 | 
							
								            "freqrange_inclusions": [
							 | 
						||
| 
								 | 
							
								                [145170000, 145800000]
							 | 
						||
| 
								 | 
							
								            ],
							 | 
						||
| 
								 | 
							
								            "channel_info": [
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    "index": 0,
							 | 
						||
| 
								 | 
							
								                    "fc_pos": "center"
							 | 
						||
| 
								 | 
							
								                },
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    "index": 2
							 | 
						||
| 
								 | 
							
								                },
							 | 
						||
| 
								 | 
							
								                {
							 | 
						||
| 
								 | 
							
								                    "index": 3
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            ]
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        superscanner.make_config()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def test_make_config(self):
							 | 
						||
| 
								 | 
							
								        self.assertEqual(superscanner.CONFIG['device_frequency'], 145480000)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @mock.patch('superscanner.set_channel_frequency', side_effect=set_channel_frequency)
							 | 
						||
| 
								 | 
							
								    @mock.patch('superscanner.set_channel_mute', side_effect=set_channel_mute)
							 | 
						||
| 
								 | 
							
								    def test_process_hotspot(self, set_channel_frequency, set_channel_mute):
							 | 
						||
| 
								 | 
							
								        hotspots1 = [
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                'begin': 145550000,
							 | 
						||
| 
								 | 
							
								                'end': 145550000,
							 | 
						||
| 
								 | 
							
								                'power': -50
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        ]
							 | 
						||
| 
								 | 
							
								        superscanner.process_hotspots(hotspots1)
							 | 
						||
| 
								 | 
							
								        channel_info = superscanner.CONFIG['channel_info']
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[0]['usage'], 1)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[1]['usage'], 0)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[2]['usage'], 0)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[0]['frequency'], 145550000)
							 | 
						||
| 
								 | 
							
								        hotspots2 = [
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                'begin': 145200000,
							 | 
						||
| 
								 | 
							
								                'end': 145200000,
							 | 
						||
| 
								 | 
							
								                'power': -35
							 | 
						||
| 
								 | 
							
								            },
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                'begin': 145550000,
							 | 
						||
| 
								 | 
							
								                'end': 145550000,
							 | 
						||
| 
								 | 
							
								                'power': -50
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        ]
							 | 
						||
| 
								 | 
							
								        superscanner.process_hotspots(hotspots2)
							 | 
						||
| 
								 | 
							
								        channel_info = superscanner.CONFIG['channel_info']
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[0]['usage'], 1)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[1]['usage'], 1)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[2]['usage'], 0)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[0]['frequency'], 145550000)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[1]['frequency'], 145200000)
							 | 
						||
| 
								 | 
							
								        hotspots3 = [
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                'begin': 145200000,
							 | 
						||
| 
								 | 
							
								                'end': 145200000,
							 | 
						||
| 
								 | 
							
								                'power': -35
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        ]
							 | 
						||
| 
								 | 
							
								        superscanner.process_hotspots(hotspots3)
							 | 
						||
| 
								 | 
							
								        channel_info = superscanner.CONFIG['channel_info']
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[0]['usage'], 0)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[1]['usage'], 1)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[2]['usage'], 0)
							 | 
						||
| 
								 | 
							
								        self.assertEqual(channel_info[1]['frequency'], 145200000)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# ======================================================================
							 | 
						||
| 
								 | 
							
								if __name__ == '__main__':
							 | 
						||
| 
								 | 
							
								    unittest.main()
							 | 
						||
| 
								 | 
							
								
							 |