def test_set_capture_meta_via_message(self): '''Test that when we send a message to set some metadata it gets set correctly''' src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j)) data_file, json_file = self.temp_file_names() file_sink = sigmf.sink("cf32_le", data_file) sender = msg_sender() tb = gr.top_block() tb.connect(src, file_sink) tb.msg_connect(sender, "out", file_sink, "command") tb.start() sleep(.1) sender.send_msg({ "command": "set_capture_meta", "index": 0, "key": "test:a", "val": 84 }) sleep(.2) tb.stop() tb.wait() with open(json_file, "r") as f: meta = json.load(f) print(meta) assert meta["captures"][0]["test:a"] == 84
def process_func(death_queue): src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j)) file_sink = sigmf.sink("cf32_le", "") sender = msg_sender() eater = sample_eater() tb = gr.top_block() tb.connect(src, eater) tb.msg_connect(sender, "out", file_sink, "command") tb.connect(eater, file_sink) tb.start() sleep(.05) sender.send_msg({"command": "open", "filename": data_file}) # ensure it gets set while True: if file_sink.get_data_path() == "": sleep(.05) else: break # record some data sleep(.05) # eat all the samples so the work function # never gets called again eater.eat_samples = True # wait a bit sleep(.05) # send close, this should close and write the file in # the pmt handler sender.send_msg({"command": "close"}) # signal to outside that this can be killed death_queue.put("KILL") tb.wait()
def test_gps_annotation(self): src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j)) data_file, json_file = self.temp_file_names() file_sink = sigmf.sink("cf32_le", data_file) sender = msg_sender() tb = gr.top_block() tb.connect(src, file_sink) tb.msg_connect(sender, "out", file_sink, "gps") coords = [ (12.345, -67.89), (55.555, -110.111), (33.123, 33.123), ] tb.start() for lat, lon in coords: sender.send_msg({ "latitude": lat, "longitude": lon, }) sleep(.05) tb.stop() tb.wait() metadata = json.load(open(json_file, "r")) # should be 3 annotations self.assertEqual(len(metadata["annotations"]), len(coords)) # And they should be these and in this order for ii, point in enumerate(coords): lat, lon = point annotation = metadata["annotations"][ii] self.assertEqual(annotation["core:latitude"], lat) self.assertEqual(annotation["core:longitude"], lon) self.assertIn("GPS", annotation["core:generator"])
def test_exception_from_open_via_message(self): """Test that if open is called via a message, then an exception is thrown""" src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j)) file_sink = sigmf.sink("cf32_le", "") dirname = uuid.uuid4().hex filename = uuid.uuid4().hex # Make a data file with a weird name that doesn't exist data_file = os.path.join("/tmp", dirname, filename) sender = msg_sender() # eater = sample_eater() tb = gr.top_block() tb.connect(src, file_sink) tb.msg_connect(sender, "out", file_sink, "command") tb.start() sleep(.05) # This should result in an exception beting thrown in the block sender.send_msg({"command": "open", "filename": data_file}) # This is a bit of a hack, once there is better exception handling # behavior in gnuradio, this test will need to be updated. As is, we # can detect that a block has stopped running by checking that it's not # reading new items sleep(.05) items = file_sink.nitems_read(0) sleep(.05) items2 = file_sink.nitems_read(0) diff_items = items2 - items self.assertEqual(diff_items, 0, "Block didn't die from invalid open message!") tb.stop() tb.wait()
def test_pmt_to_annotation(self): src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j)) data_file, json_file = self.temp_file_names() file_sink = sigmf.sink("cf32_le", data_file) injector = simple_tag_injector() sender = msg_sender() counter = sample_counter() tb = gr.top_block() tb.connect(src, injector) tb.connect(injector, counter) tb.connect(counter, file_sink) tb.msg_connect(sender, "out", file_sink, "command") tb.start() # sleep so the streamed annotation isn't the first one sleep(.1) # Inject one tag injector.inject_tag = {"test:a": 1} # Wait again so that we know the tag got processed sleep(.1) # Then tell it to add 2 more via pmts, # one before the injected tag sender.send_msg({ "command": "set_annotation_meta", "sample_start": 1, "sample_count": 10, "key": "test:b", "val": 22 }) # and one after sender.send_msg({ "command": "set_annotation_meta", "sample_start": counter.count + 1, "sample_count": 10, "key": "test:c", "val": True }) sleep(.25) tb.stop() tb.wait() metadata = json.load(open(json_file, "r")) # should be 3 annotations self.assertEqual(len(metadata["annotations"]), 3) # And they should be these and in this order self.assertEqual(metadata["annotations"][0]["test:b"], 22) self.assertEqual(metadata["annotations"][1]["test:a"], 1) self.assertEqual(metadata["annotations"][2]["test:c"], True)
def test_msg_annotation_meta_merging(self): src = analog.sig_source_c(0, analog.GR_CONST_WAVE, 0, 0, (1 + 1j)) data_file, json_file = self.temp_file_names() file_sink = sigmf.sink("cf32_le", data_file) sender = msg_sender() tb = gr.top_block() tb.connect(src, file_sink) tb.msg_connect(sender, "out", file_sink, "command") tb.start() sender.send_msg({ "command": "set_annotation_meta", "sample_start": 1, "sample_count": 10, "key": "test:a", "val": 1 }) sender.send_msg({ "command": "set_annotation_meta", "sample_start": 1, "sample_count": 10, "key": "test:b", "val": 2 }) sender.send_msg({ "command": "set_annotation_meta", "sample_start": 1, "sample_count": 100, "key": "test:c", "val": 3 }) sleep(.25) tb.stop() tb.wait() metadata = json.load(open(json_file, "r")) # should be 2 annotations self.assertEqual(len(metadata["annotations"]), 2) # First should have both test:a and test:b self.assertEqual(metadata["annotations"][0]["core:sample_count"], 10) self.assertEqual(metadata["annotations"][0]["test:a"], 1) self.assertEqual(metadata["annotations"][0]["test:b"], 2) # Second should just have c self.assertEqual(metadata["annotations"][1]["core:sample_count"], 100) self.assertEqual(metadata["annotations"][1]["test:c"], 3)
def test_annotation_sink_time_offsets_no_timebase(self): '''Test of using the annotation sink with time offsets in the case where there is no timebase in the first capture segment to base things off of''' data, json_dict, data_path, json_path = self.make_file( "time_offsets_no_timebase", [ { "core:sample_start": 0, "core:sample_count": 1, }, { "core:sample_start": 100, "core:sample_count": 100, }, ], [{ "core:sample_start": 0 }], { "core:sample_rate": 100 } ) anno_sink = sigmf.annotation_sink( data_path, sigmf.annotation_mode_keep()) sender = msg_sender() tb = gr.top_block() tb.msg_connect(sender, "out", anno_sink, "annotations") tb.start() sender.send_msg({ "time": (0, 0), "duration": (1, .1), "test:foo": 2 }) sender.send_msg({ "time": (1, 0), "duration": (1, 0), "test:foo2": "foo" }) # no such thing as head for messages, so have to sleep here :\ sleep(.1) tb.stop() tb.wait() with open(json_path, "r") as f: meta = json.load(f) print(meta) self.assertEqual(len(meta["annotations"]), 3, "wrong number of annotations") self.assertEqual(len(meta["annotations"][0].keys()), 2, "wrong number of keys in first annotation") self.assertEqual(meta["annotations"][1] ["test:foo"], 2, "Wrong value in annotation") self.assertEqual( meta["annotations"][1]["core:sample_start"], 0, "Wrong value in annotation") self.assertEqual( meta["annotations"][1]["core:sample_count"], 110, "Wrong value in annotation") self.assertEqual( meta["annotations"][2]["core:sample_count"], 100, "Wrong value in annotation") self.assertEqual( meta["annotations"][2]["core:sample_start"], 100, "Wrong value in annotation") self.assertEqual( meta["annotations"][2]["test:foo2"], "foo", "Wrong value in annotation")
def test_annotation_sink_time_offsets(self): '''Test of using the annotation sink with absolute time offsets''' data, json_dict, data_path, json_path = self.make_file( "time_offsets", annotations=[{ "core:sample_start": 0, "core:sample_count": 1, "test:foo": 1, "test:foobar": 2, "test:bar": 3, "test:baz": 4, "blargh:foo": 5 }], captures=[{ "core:sample_start": 0, "core:sample_count": 100, "core:datetime": "2018-04-18T21:41:19" }], global_data={ "core:sample_rate": 100 } ) anno_sink = sigmf.annotation_sink( data_path, sigmf.annotation_mode_clear("test:foo*"), sigmf.sigmf_time_mode_absolute) sender = msg_sender() tb = gr.top_block() tb.msg_connect(sender, "out", anno_sink, "annotations") tb.start() # one second later sender.send_msg({ "time": (1524087680, 0), "duration": (1, 0), "test:foo": 2 }) # one and one half second later sender.send_msg({ "time": (1524087680, .5), "duration": (1, 0), "test:foo2": 3 }) # no such thing as head for messages, so have to sleep here :\ sleep(.2) tb.stop() tb.wait() with open(json_path, "r") as f: meta = json.load(f) self.assertEqual(meta["annotations"][1] ["core:sample_start"], 100, "bad sample start") self.assertEqual(meta["annotations"][1] ["core:sample_count"], 100, "bad sample count") self.assertEqual(meta["annotations"][1] ["test:foo"], 2, "bad anno value") self.assertEqual(meta["annotations"][2] ["core:sample_start"], 150, "bad sample start") self.assertEqual(meta["annotations"][2] ["core:sample_count"], 100, "bad sample count") self.assertEqual(meta["annotations"][2] ["test:foo2"], 3, "bad anno value")
def test_annotation_sink_basics(self): '''Test of actually using the annotation sink''' data, json_dict, data_path, json_path = self.make_file( "basics", annotations=[{ "core:sample_start": 0, "core:sample_count": 1, "test:foo": 1, "test:foobar": 2, "test:bar": 3, "test:baz": 4, "blargh:foo": 5 }] ) anno_sink = sigmf.annotation_sink( data_path, sigmf.annotation_mode_clear("blargh:*")) sender = msg_sender() tb = gr.top_block() tb.msg_connect(sender, "out", anno_sink, "annotations") tb.start() sender.send_msg({ "core:sample_start": 0, "core:sample_count": 1, "test:foo": 2 }) sender.send_msg({ "core:sample_start": 0, "core:sample_count": 1, "test:foo2": "foo2" }) sender.send_msg({ "core:sample_start": 0, "core:sample_count": 3, "test:foo3": True }) sender.send_msg({ "core:sample_start": 1, "core:sample_count": 1, "test:bing": "asdf" }) # no such thing as head for messages, so have to sleep here :\ sleep(.1) tb.stop() tb.wait() with open(json_path, "r") as f: meta = json.load(f) self.assertNotIn( "blargh:foo", meta["annotations"][0], "Clear existing did not work") self.assertEqual(meta["annotations"][0]["test:foo"], 2, "Replacing existing tag didn't work") self.assertEqual(meta["annotations"][0]["test:foo2"], "foo2", "Adding tag to existing segment failure") self.assertEqual(meta["annotations"][1]["test:foo3"], True, "New segment create fail") self.assertEqual(meta["annotations"][2]["test:bing"], "asdf", "New tag add failure") self.assertEqual(meta["annotations"][2]["core:sample_start"], 1, "New tag add failure")