def generate_data(send_batch, make_data_args, samples_count, batch_size, resources_count, topic): make_data_args.interval = 1 make_data_args.start = (datetime.datetime.utcnow() - datetime.timedelta(minutes=samples_count)) make_data_args.end = datetime.datetime.utcnow() make_data_args.resource_id = None resources_list = [str(uuid.uuid4()) for _ in moves.xrange(resources_count)] resource_samples = {resource: 0 for resource in resources_list} batch = [] count = 0 for sample in make_test_data.make_test_data(**make_data_args.__dict__): count += 1 resource = resources_list[random.randint(0, len(resources_list) - 1)] resource_samples[resource] += 1 sample['resource_id'] = resource # need to change the timestamp from datetime.datetime type to iso # format (unicode type), because collector will change iso format # timestamp to datetime.datetime type before recording to db. sample['timestamp'] = sample['timestamp'].isoformat() # need to recalculate signature because of the resource_id change sig = utils.compute_signature(sample, cfg.CONF.publisher.telemetry_secret) sample['message_signature'] = sig batch.append(sample) if len(batch) == batch_size: send_batch(topic, batch) batch = [] if count == samples_count: send_batch(topic, batch) return resource_samples send_batch(topic, batch) return resource_samples
def test_event_pipeline_endpoint_requeue_on_failure(self): self.CONF.set_override("ack_on_event_error", False, group="notification") self.CONF.set_override("telemetry_secret", "not-so-secret", group="publisher") test_data = { "message_id": uuid.uuid4(), "event_type": "a", "generated": "2013-08-08 21:06:37.803826", "traits": [{"name": "t_text", "value": 1, "dtype": "text_trait"}], "raw": {"status": "started"}, } message_sign = utils.compute_signature(test_data, "not-so-secret") test_data["message_signature"] = message_sign fake_publisher = mock.Mock() self.useFixture(mockpatch.Patch("ceilometer.publisher.test.TestPublisher", return_value=fake_publisher)) pipeline_manager = pipeline.PipelineManager(self.CONF, self.pipeline_cfg, self.transformer_manager, self.p_type) event_pipeline_endpoint = pipeline.EventPipelineEndpoint(pipeline_manager.pipelines[0]) fake_publisher.publish_events.side_effect = Exception ret = event_pipeline_endpoint.sample( [ { "ctxt": {}, "publisher_id": "compute.vagrant-precise", "event_type": "a", "payload": [test_data], "metadata": {}, } ] ) self.assertEqual(oslo_messaging.NotificationResult.REQUEUE, ret)
def setUp(self): super(DispatcherWorkflowTest, self).setUp() self.conf = self.useFixture(config_fixture.Config()) # Set this explicitly to avoid conflicts with any existing # configuration. self.conf.config(url='http://localhost:8041', group='dispatcher_gnocchi') ks_client = mock.Mock() ks_client.projects.find.return_value = mock.Mock( name='gnocchi', id='a2d42c23-d518-46b6-96ab-3fba2e146859') self.useFixture(mockpatch.Patch( 'ceilometer.keystone_client.get_client', return_value=ks_client)) self.ks_client = ks_client ceilometer_service.prepare_service(argv=[], config_files=[]) self.conf.config( resources_definition_file=self.path_get( 'etc/ceilometer/gnocchi_resources.yaml'), group="dispatcher_gnocchi" ) self.sample['resource_id'] = str(uuid.uuid4()) + "/foobar" self.sample['message_signature'] = utils.compute_signature( self.sample, self.conf.conf.publisher.telemetry_secret)
def test_file_dispatcher_with_path_only(self): # Create a temporaryFile to get a file name tf = tempfile.NamedTemporaryFile('r') filename = tf.name tf.close() self.CONF.dispatcher_file.file_path = filename self.CONF.dispatcher_file.max_bytes = None self.CONF.dispatcher_file.backup_count = None dispatcher = file.FileDispatcher(self.CONF) # The number of the handlers should be 1 self.assertEqual(1, len(dispatcher.log.handlers)) # The handler should be RotatingFileHandler handler = dispatcher.log.handlers[0] self.assertIsInstance(handler, logging.FileHandler) msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, } msg['message_signature'] = utils.compute_signature( msg, self.CONF.publisher.telemetry_secret, ) # The record_metering_data method should exist and not produce errors. dispatcher.record_metering_data(msg) # After the method call above, the file should have been created. self.assertTrue(os.path.exists(handler.baseFilename))
def test_valid_message(self): msg = {"counter_name": "test", "resource_id": self.id(), "counter_volume": 1} msg["message_signature"] = utils.compute_signature(msg, self.CONF.publisher.metering_secret) with mock.patch.object(self.dispatcher.storage_conn, "record_metering_data") as record_metering_data: self.dispatcher.record_metering_data(msg) record_metering_data.assert_called_once_with(msg)
def test_verify_unicode_symbols(self): data = {u'a\xe9\u0437': 'A', 'b': u'B\xe9\u0437' } data['message_signature'] = utils.compute_signature( data, 'not-so-secret') jsondata = json.loads(json.dumps(data)) self.assertTrue(utils.verify_signature(jsondata, 'not-so-secret'))
def setUp(self): super(DispatcherTest, self).setUp() conf = ceilometer_service.prepare_service(argv=[], config_files=[]) self.conf = self.useFixture(config_fixture.Config(conf)) self.conf.config( resources_definition_file=self.path_get( 'etc/ceilometer/gnocchi_resources.yaml'), group="dispatcher_gnocchi" ) self.resource_id = str(uuid.uuid4()) self.samples = [{ 'counter_name': 'disk.root.size', 'counter_unit': 'GB', 'counter_type': 'gauge', 'counter_volume': '2', 'user_id': 'test_user', 'project_id': 'test_project', 'source': 'openstack', 'timestamp': '2012-05-08 20:23:48.028195', 'resource_id': self.resource_id, 'resource_metadata': { 'host': 'foo', 'image_ref': 'imageref!', 'instance_flavor_id': 1234, 'display_name': 'myinstance', } }, { 'counter_name': 'disk.root.size', 'counter_unit': 'GB', 'counter_type': 'gauge', 'counter_volume': '2', 'user_id': 'test_user', 'project_id': 'test_project', 'source': 'openstack', 'timestamp': '2014-05-08 20:23:48.028195', 'resource_id': self.resource_id, 'resource_metadata': { 'host': 'foo', 'image_ref': 'imageref!', 'instance_flavor_id': 1234, 'display_name': 'myinstance', } }] for sample in self.samples: sample['message_signature'] = utils.compute_signature( sample, self.conf.conf.publisher.telemetry_secret) ks_client = mock.Mock(auth_token='fake_token') ks_client.projects.find.return_value = mock.Mock( name='gnocchi', id='a2d42c23-d518-46b6-96ab-3fba2e146859') self.useFixture(mockpatch.Patch( 'ceilometer.keystone_client.get_client', return_value=ks_client)) self.ks_client = ks_client self.conf.conf.dispatcher_gnocchi.filter_service_activity = True
def setUp(self): super(TestDispatcherHttp, self).setUp() self.CONF = self.useFixture(fixture_config.Config()).conf self.msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, } self.msg['message_signature'] = utils.compute_signature( self.msg, self.CONF.publisher.telemetry_secret, )
def test_verify_signature_nested(self): data = {'a': 'A', 'b': 'B', 'nested': {'a': 'A', 'b': 'B', }, } data['message_signature'] = utils.compute_signature( data, 'not-so-secret') self.assertTrue(utils.verify_signature(data, 'not-so-secret'))
def test_valid_message(self): msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, } msg['message_signature'] = utils.compute_signature( msg, self.CONF.publisher.telemetry_secret, ) with mock.patch.object(self.dispatcher.meter_conn, 'record_metering_data') as record_metering_data: self.dispatcher.verify_and_record_metering_data(msg) record_metering_data.assert_called_once_with(msg)
def test_valid_message(self): msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, } msg['message_signature'] = utils.compute_signature( msg, self.CONF.publisher.telemetry_secret, ) with mock.patch.object(self.meter_dispatcher.conn, 'record_metering_data') as record_metering_data: self.meter_dispatcher.record_metering_data(msg) record_metering_data.assert_called_once_with(msg)
def test_verify_signature_nested_json(self): data = {'a': 'A', 'b': 'B', 'nested': {'a': 'A', 'b': 'B', 'c': ('c',), 'd': ['d'] }, } data['message_signature'] = utils.compute_signature( data, 'not-so-secret') jsondata = jsonutils.loads(jsonutils.dumps(data)) self.assertTrue(utils.verify_signature(jsondata, 'not-so-secret'))
def test_sample_with_bad_signature(self, mocked_verify): def _fake_verify(ev, secret): return ev.get('message_signature') != 'bad_signature' mocked_verify.side_effect = _fake_verify sample = {"payload": [{"message_signature": "bad_signature"}]} manager = dispatcher.load_dispatcher_manager()[0] v = collector.EventEndpoint("secret", manager) v.sample([sample]) self.assertEqual([], manager['database'].obj.events) del sample['payload'][0]['message_signature'] sample['payload'][0]['message_signature'] = utils.compute_signature( sample['payload'][0], "secret") v.sample([sample]) self.assertEqual(sample['payload'], manager['database'].obj.events)
def test_http_dispatcher_with_cadf_event(self): self.CONF.dispatcher_http.target = 'fake' self.CONF.dispatcher_http.cadf_only = True dispatcher = http.HttpDispatcher(self.CONF) self.msg['resource_metadata'] = {'request': {'CADF_EVENT': { 'q1': 'v1', 'q2': 'v2'}, }, } self.msg['message_signature'] = utils.compute_signature( self.msg, self.CONF.publisher.telemetry_secret, ) with mock.patch.object(requests, 'post') as post: dispatcher.record_metering_data(self.msg) self.assertEqual(1, post.call_count)
def test_http_dispatcher_with_none_cadf_event(self): self.CONF.dispatcher_http.target = 'fake' self.CONF.dispatcher_http.cadf_only = False dispatcher = http.HttpDispatcher(self.CONF) self.msg['resource_metadata'] = {'any': {'thing1': 'v1', 'thing2': 'v2', }, } self.msg['message_signature'] = utils.compute_signature( self.msg, self.CONF.publisher.metering_secret, ) with mock.patch.object(requests, 'post') as post: dispatcher.record_metering_data(self.msg) self.assertEqual(1, post.call_count)
def generate_random_sample(): sample = {'source': rand_source(), 'counter_name': rand_counter_name(), 'counter_type': random_counter_type(), 'counter_unit': rand_counter_unit(), 'counter_volume': rand_counter_volume(), 'user_id': rand_user_id(), 'project_id': rand_project_id(), 'resource_id': rand_resource_id(), 'timestamp': datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ"), 'resource_metadata': random_resource_metadata(), 'message_id': rand_message_id() } sample['message_signature'] = utils.compute_signature( sample, '0680372fc6a43c4339cd') return sample
def test_timestamp_conversion(self): msg = { "counter_name": "test", "resource_id": self.id(), "counter_volume": 1, "timestamp": "2012-07-02T13:53:40Z", } msg["message_signature"] = utils.compute_signature(msg, self.CONF.publisher.metering_secret) expected = msg.copy() expected["timestamp"] = datetime.datetime(2012, 7, 2, 13, 53, 40) with mock.patch.object(self.dispatcher.storage_conn, "record_metering_data") as record_metering_data: self.dispatcher.record_metering_data(msg) record_metering_data.assert_called_once_with(expected)
def test_timestamp_tzinfo_conversion(self): msg = { "counter_name": "test", "resource_id": self.id(), "counter_volume": 1, "timestamp": "2012-09-30T15:31:50.262-08:00", } msg["message_signature"] = utils.compute_signature(msg, self.CONF.publisher.metering_secret) expected = msg.copy() expected["timestamp"] = datetime.datetime(2012, 9, 30, 23, 31, 50, 262000) with mock.patch.object(self.dispatcher.storage_conn, "record_metering_data") as record_metering_data: self.dispatcher.record_metering_data(msg) record_metering_data.assert_called_once_with(expected)
def test_event_pipeline_endpoint_requeue_on_failure(self): self.CONF.set_override("ack_on_event_error", False, group="notification") self.CONF.set_override("telemetry_secret", "not-so-secret", group="publisher") test_data = { 'message_id': uuid.uuid4(), 'event_type': 'a', 'generated': '2013-08-08 21:06:37.803826', 'traits': [{ 'name': 't_text', 'value': 1, 'dtype': 'text_trait' }], 'raw': { 'status': 'started' } } message_sign = utils.compute_signature(test_data, 'not-so-secret') test_data['message_signature'] = message_sign fake_publisher = mock.Mock() self.useFixture( mockpatch.Patch('ceilometer.publisher.test.TestPublisher', return_value=fake_publisher)) pipeline_manager = pipeline.PipelineManager(self.CONF, self.pipeline_cfg, self.transformer_manager, self.p_type) event_pipeline_endpoint = pipeline.EventPipelineEndpoint( pipeline_manager.pipelines[0]) fake_publisher.publish_events.side_effect = Exception ret = event_pipeline_endpoint.sample([{ 'ctxt': {}, 'publisher_id': 'compute.vagrant-precise', 'event_type': 'a', 'payload': [test_data], 'metadata': {} }]) self.assertEqual(oslo_messaging.NotificationResult.REQUEUE, ret)
def test_http_dispatcher_without_cadf_event(self): self.CONF.dispatcher_http.target = 'fake' self.CONF.dispatcher_http.cadf_only = True dispatcher = http.HttpDispatcher(self.CONF) self.msg['resource_metadata'] = {'request': {'NONE_CADF_EVENT': { 'q1': 'v1', 'q2': 'v2'}, }, } self.msg['message_signature'] = utils.compute_signature( self.msg, self.CONF.publisher.metering_secret, ) with mock.patch.object(requests, 'post') as post: dispatcher.record_metering_data(self.msg) # Since the meter does not have metadata or CADF_EVENT, the method # call count should be zero self.assertEqual(0, post.call_count)
def test_timestamp_conversion(self): msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, 'timestamp': '2012-07-02T13:53:40Z', } msg['message_signature'] = utils.compute_signature( msg, self.CONF.publisher.telemetry_secret, ) expected = msg.copy() expected['timestamp'] = datetime.datetime(2012, 7, 2, 13, 53, 40) with mock.patch.object(self.meter_dispatcher.conn, 'record_metering_data') as record_metering_data: self.meter_dispatcher.record_metering_data(msg) record_metering_data.assert_called_once_with(expected)
def test_timestamp_conversion(self): msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, 'timestamp': '2012-07-02T13:53:40Z', } msg['message_signature'] = utils.compute_signature( msg, self.CONF.publisher.telemetry_secret, ) expected = msg.copy() expected['timestamp'] = datetime.datetime(2012, 7, 2, 13, 53, 40) with mock.patch.object(self.dispatcher.meter_conn, 'record_metering_data') as record_metering_data: self.dispatcher.verify_and_record_metering_data(msg) record_metering_data.assert_called_once_with(expected)
def test_timestamp_tzinfo_conversion(self): msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, 'timestamp': '2012-09-30T15:31:50.262-08:00', } msg['message_signature'] = utils.compute_signature( msg, self.CONF.publisher.telemetry_secret, ) expected = msg.copy() expected['timestamp'] = datetime.datetime(2012, 9, 30, 23, 31, 50, 262000) with mock.patch.object(self.meter_dispatcher.conn, 'record_metering_data') as record_metering_data: self.meter_dispatcher.record_metering_data(msg) record_metering_data.assert_called_once_with(expected)
def test_timestamp_tzinfo_conversion(self): msg = {'counter_name': 'test', 'resource_id': self.id(), 'counter_volume': 1, 'timestamp': '2012-09-30T15:31:50.262-08:00', } msg['message_signature'] = utils.compute_signature( msg, self.CONF.publisher.telemetry_secret, ) expected = msg.copy() expected['timestamp'] = datetime.datetime(2012, 9, 30, 23, 31, 50, 262000) with mock.patch.object(self.dispatcher.meter_conn, 'record_metering_data') as record_metering_data: self.dispatcher.verify_and_record_metering_data(msg) record_metering_data.assert_called_once_with(expected)
def setUp(self): super(DispatcherWorkflowTest, self).setUp() conf = ceilometer_service.prepare_service(argv=[], config_files=[]) self.conf = self.useFixture(config_fixture.Config(conf)) ks_client = mock.Mock() ks_client.projects.find.return_value = mock.Mock( name='gnocchi', id='a2d42c23-d518-46b6-96ab-3fba2e146859') self.useFixture( fixtures.MockPatch('ceilometer.keystone_client.get_client', return_value=ks_client)) self.ks_client = ks_client self.conf.config(resources_definition_file=self.path_get( 'etc/ceilometer/gnocchi_resources.yaml'), group="dispatcher_gnocchi") self.sample['resource_id'] = str(uuid.uuid4()) + "_foobar" self.sample['message_signature'] = utils.compute_signature( self.sample, self.conf.conf.publisher.telemetry_secret)
def test_event_with_bad_signature(self, mocked_verify): event = event_models.Event(uuid.uuid4(), 'test', datetime.datetime(2012, 7, 2, 13, 53, 40), [], {}).serialize() def _fake_verify(ev, secret): if ev.get('message_signature') == 'bad_signature': return False return True mocked_verify.side_effect = _fake_verify with mock.patch.object(self.dispatcher.event_conn, 'record_events') as record_events: event['message_signature'] = 'bad_signature' self.dispatcher.verify_and_record_events([event]) self.assertEqual([], record_events.call_args_list[0][0][0]) del event['message_signature'] event['message_signature'] = utils.compute_signature( event, self.CONF.publisher.telemetry_secret) self.dispatcher.verify_and_record_events([event]) self.assertEqual(1, len(record_events.call_args_list[1][0][0]))
def test_http_dispatcher_with_none_cadf_event(self): self.CONF.dispatcher_http.target = 'fake' self.CONF.dispatcher_http.cadf_only = False dispatcher = http.HttpDispatcher(self.CONF) self.msg['resource_metadata'] = { 'any': { 'thing1': 'v1', 'thing2': 'v2', }, } self.msg['message_signature'] = utils.compute_signature( self.msg, self.CONF.publisher.metering_secret, ) with mock.patch.object(requests, 'post') as post: dispatcher.record_metering_data(self.msg) self.assertEqual(1, post.call_count)
def setUp(self): super(DispatcherWorkflowTest, self).setUp() conf = ceilometer_service.prepare_service(argv=[], config_files=[]) self.conf = self.useFixture(config_fixture.Config(conf)) ks_client = mock.Mock() ks_client.projects.find.return_value = mock.Mock( name='gnocchi', id='a2d42c23-d518-46b6-96ab-3fba2e146859') self.useFixture(mockpatch.Patch( 'ceilometer.keystone_client.get_client', return_value=ks_client)) self.ks_client = ks_client self.conf.config( resources_definition_file=self.path_get( 'etc/ceilometer/gnocchi_resources.yaml'), group="dispatcher_gnocchi" ) self.sample['resource_id'] = str(uuid.uuid4()) + "_foobar" self.sample['message_signature'] = utils.compute_signature( self.sample, self.conf.conf.publisher.telemetry_secret)
def test_event_pipeline_endpoint_requeue_on_failure(self): self.CONF.set_override("ack_on_event_error", False, group="notification") self.CONF.set_override("telemetry_secret", "not-so-secret", group="publisher") test_data = { 'message_id': uuid.uuid4(), 'event_type': 'a', 'generated': '2013-08-08 21:06:37.803826', 'traits': [ {'name': 't_text', 'value': 1, 'dtype': 'text_trait' } ], 'raw': {'status': 'started'} } message_sign = utils.compute_signature(test_data, 'not-so-secret') test_data['message_signature'] = message_sign fake_publisher = mock.Mock() self.useFixture(mockpatch.Patch( 'ceilometer.publisher.test.TestPublisher', return_value=fake_publisher)) pipeline_manager = pipeline.PipelineManager( self.CONF, self.cfg2file(self.pipeline_cfg), self.transformer_manager, self.p_type) event_pipeline_endpoint = pipeline.EventPipelineEndpoint( pipeline_manager.pipelines[0]) fake_publisher.publish_events.side_effect = Exception ret = event_pipeline_endpoint.sample([ {'ctxt': {}, 'publisher_id': 'compute.vagrant-precise', 'event_type': 'a', 'payload': [test_data], 'metadata': {}}]) self.assertEqual(oslo_messaging.NotificationResult.REQUEUE, ret)
def setUp(self): super(DispatcherWorkflowTest, self).setUp() self.conf = self.useFixture(config_fixture.Config()) # Set this explicitly to avoid conflicts with any existing # configuration. self.conf.config(url='http://localhost:8041', group='dispatcher_gnocchi') ks_client = mock.Mock() ks_client.projects.find.return_value = mock.Mock( name='gnocchi', id='a2d42c23-d518-46b6-96ab-3fba2e146859') self.useFixture( mockpatch.Patch('ceilometer.keystone_client.get_client', return_value=ks_client)) self.ks_client = ks_client ceilometer_service.prepare_service(argv=[], config_files=[]) self.conf.config(resources_definition_file=self.path_get( 'etc/ceilometer/gnocchi_resources.yaml'), group="dispatcher_gnocchi") self.sample['resource_id'] = str(uuid.uuid4()) + "/foobar" self.sample['message_signature'] = utils.compute_signature( self.sample, self.conf.conf.publisher.telemetry_secret)
def test_http_dispatcher_without_cadf_event(self): self.CONF.dispatcher_http.target = 'fake' self.CONF.dispatcher_http.cadf_only = True dispatcher = http.HttpDispatcher(self.CONF) self.msg['resource_metadata'] = { 'request': { 'NONE_CADF_EVENT': { 'q1': 'v1', 'q2': 'v2' }, }, } self.msg['message_signature'] = utils.compute_signature( self.msg, self.CONF.publisher.metering_secret, ) with mock.patch.object(requests, 'post') as post: dispatcher.record_metering_data(self.msg) # Since the meter does not have metadata or CADF_EVENT, the method # call count should be zero self.assertEqual(0, post.call_count)
def test_verify_unicode_symbols(self): data = {u'a\xe9\u0437': 'A', 'b': u'B\xe9\u0437'} data['message_signature'] = utils.compute_signature( data, 'not-so-secret') jsondata = json.loads(json.dumps(data)) self.assertTrue(utils.verify_signature(jsondata, 'not-so-secret'))
def test_compute_signature_same(self): sig1 = utils.compute_signature({'a': 'A', 'b': 'B'}, 'not-so-secret') sig2 = utils.compute_signature({'a': 'A', 'b': 'B'}, 'not-so-secret') self.assertEqual(sig1, sig2)
def test_compute_signature_signed(self): data = {'a': 'A', 'b': 'B'} sig1 = utils.compute_signature(data, 'not-so-secret') data['message_signature'] = sig1 sig2 = utils.compute_signature(data, 'not-so-secret') self.assertEqual(sig1, sig2)
def test_compute_signature_use_configured_secret(self): data = {'a': 'A', 'b': 'B'} sig1 = utils.compute_signature(data, 'not-so-secret') sig2 = utils.compute_signature(data, 'different-value') self.assertNotEqual(sig1, sig2)
def test_verify_signature_nested(self): data = {"a": "A", "b": "B", "nested": {"a": "A", "b": "B"}} data["message_signature"] = utils.compute_signature(data, "not-so-secret") self.assertTrue(utils.verify_signature(data, "not-so-secret"))
def test_verify_signature_nested_json(self): data = {"a": "A", "b": "B", "nested": {"a": "A", "b": "B", "c": ("c",), "d": ["d"]}} data["message_signature"] = utils.compute_signature(data, "not-so-secret") jsondata = jsonutils.loads(jsonutils.dumps(data)) self.assertTrue(utils.verify_signature(jsondata, "not-so-secret"))
def test_verify_unicode_symbols(self): data = {u"a\xe9\u0437": "A", "b": u"B\xe9\u0437"} data["message_signature"] = utils.compute_signature(data, "not-so-secret") jsondata = jsonutils.loads(jsonutils.dumps(data)) self.assertTrue(utils.verify_signature(jsondata, "not-so-secret"))
def test_verify_signature_signed(self): data = {'a': 'A', 'b': 'B'} sig1 = utils.compute_signature(data, 'not-so-secret') data['message_signature'] = sig1 self.assertTrue(utils.verify_signature(data, 'not-so-secret'))