Модульный тест для исключения, созданного в пользовательском блоке GNU radio python - PullRequest
0 голосов
/ 14 марта 2020

Я создал пользовательский блок python syn c для использования в потоковой диаграмме gnuradio. Блок проверяет правильность ввода и, если он обнаружен, вызывает исключение ValueError. Я хотел бы создать модульный тест для проверки того, что исключение возникает, когда блок действительно получает неверные входные данные.

В рамках теста qa на основе python для этого блока я создал потоковую диаграмму, так что блок получает недопустимые данные. Когда я запускаю тест, кажется, что блок вызывает исключение, но затем зависает.

Каков подходящий способ проверить это? Вот минимальный рабочий пример:

#!/usr/bin/env python

import numpy as np

from gnuradio import gr, gr_unittest, blocks

class validate_input(gr.sync_block):

    def __init__(self):
        gr.sync_block.__init__(self,
            name="validate_input",
            in_sig=[np.float32],
            out_sig=[np.float32])

        self.max_input = 100

    def work(self, input_items, output_items):
        in0 = input_items[0]

        if (np.max(in0) > self.max_input):
           raise ValueError('input exceeds max.')

        validated_in = output_items[0]
        validated_in[:] = in0

        return len(output_items[0])

class qa_validate_input (gr_unittest.TestCase):

    def setUp (self):
        self.tb = gr.top_block ()

    def tearDown (self):
        self.tb = None

    def test_check_valid_data(self):

        src_data = (0, 201, 92)

        src = blocks.vector_source_f(src_data)
        validate = validate_input()
        snk = blocks.vector_sink_f()

        self.tb.connect (src, validate)
        self.tb.connect (validate, snk)

        self.assertRaises(ValueError, self.tb.run)

if __name__ == '__main__':
    gr_unittest.run(qa_validate_input, "qa_validate_input.xml")

, который производит:

DEPRECATED: Using filename with gr_unittest does no longer have any effect.
handler caught exception: input exceeds max.
Traceback (most recent call last):
  File "/home/xxx/devel/gnuradio3_8/lib/python3.6/dist-packages/gnuradio/gr/gateway.py", line 60, in eval
    try: self._callback()
  File "/home/xxx/devel/gnuradio3_8/lib/python3.6/dist-packages/gnuradio/gr/gateway.py", line 230, in __gr_block_handle
    ) for i in range(noutputs)],
  File "qa_validate_input.py", line 21, in work
    raise ValueError('input exceeds max.')
ValueError: input exceeds max.
thread[thread-per-block[1]: <block validate_input(2)>]: SWIG director method error. Error detected when calling 'feval_ll.eval'
^CF
======================================================================
FAIL: test_check_valid_data (__main__.qa_validate_input)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "qa_validate_input.py", line 47, in test_check_valid_data
    self.assertRaises(ValueError, self.tb.run)
AssertionError: ValueError not raised by run

----------------------------------------------------------------------
Ran 1 test in 1.634s

FAILED (failures=1)

1 Ответ

1 голос
/ 16 марта 2020

Функция run() top_block не вызывает функцию work() блока напрямую, а запускает внутренний планировщик задач и его потоки и ожидает их завершения sh.

Один из способов модульного тестирования ошибки обработка в вашем блоке - вызов функции work() напрямую

    def test_check_valid_data(self):
        src_data = [[0, 201, 92]]
        output_items = [[]]

        validate = validate_input()
        self.assertRaises(ValueError, lambda: validate.work(src_data, output_items))
...