def test_merge_group_environments(self): group1 = self.create_group(self.project) GroupEnvironment.objects.create( group_id=group1.id, environment_id=1, ) group2 = self.create_group(self.project) GroupEnvironment.objects.create( group_id=group2.id, environment_id=1, ) GroupEnvironment.objects.create( group_id=group2.id, environment_id=2, ) with self.tasks(): merge_groups([group1.id], group2.id) assert list(GroupEnvironment.objects.filter( group_id=group2.id, ).order_by('environment_id').values_list( 'environment_id', flat=True, )) == [1, 2]
def test_group_refresh(self, mock_processor): event = self.store_event(data={"message": "testing"}, project_id=self.project.id) cache_key = write_event_to_cache(event) group1 = event.group group2 = self.create_group(project=self.project) assert event.group_id == group1.id assert event.group == group1 with self.tasks(): merge_groups([group1.id], group2.id) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [(mock_callback, mock_futures)] post_process_group( is_new=True, is_regression=False, is_new_group_environment=True, cache_key=cache_key, group_id=event.group_id, ) # Ensure that rule processing sees the merged group. mock_processor.assert_called_with(EventMatcher(event, group=group2), True, False, True, False)
def test_merge_with_event_integrity(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event('a' * 32, group=group1, data={'extra': { 'foo': 'bar' }}) project2 = self.create_project() group2 = self.create_group(project2) event2 = self.create_event('b' * 32, group=group2, data={'extra': { 'foo': 'baz' }}) with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() # this previously would error with NodeIntegrityError due to the # reference check being bound to a group event1 = Event.objects.get(id=event1.id) assert event1.group_id == group2.id Event.objects.bind_nodes([event1], 'data') assert event1.data['extra']['foo'] == 'bar' event2 = Event.objects.get(id=event2.id) assert event2.group_id == group2.id Event.objects.bind_nodes([event2], 'data') assert event2.data['extra']['foo'] == 'baz'
def test_group_refresh(self, mock_processor): group1 = self.create_group(project=self.project) group2 = self.create_group(project=self.project) event = self.create_event(group=group1) assert event.group_id == group1.id assert event.group == group1 with self.tasks(): merge_groups([group1.id], group2.id) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [ (mock_callback, mock_futures), ] post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, is_new_group_environment=True, ) assert event.group == group2 assert event.group_id == group2.id
def test_group_refresh(self, mock_processor): group1 = self.create_group(project=self.project) group2 = self.create_group(project=self.project) event = self.create_event(group=group1) assert event.group_id == group1.id assert event.group == group1 with self.tasks(): merge_groups([group1.id], group2.id) mock_callback = Mock() mock_futures = [Mock()] mock_processor.return_value.apply.return_value = [ (mock_callback, mock_futures), ] post_process_group( event=event, is_new=True, is_regression=False, is_sample=False, is_new_group_environment=True, ) assert event.group == group2 assert event.group_id == group2.id
def test_merge_with_group_meta(self): project1 = self.create_project() event1 = self.store_event(data={}, project_id=project1.id) group1 = event1.group project2 = self.create_project() event2 = self.store_event(data={}, project_id=project2.id) group2 = event2.group GroupMeta.objects.create(group=event1.group, key="github:tid", value="134") GroupMeta.objects.create(group=event1.group, key="other:tid", value="567") GroupMeta.objects.create(group=event2.group, key="other:tid", value="abc") GroupMeta.objects.populate_cache([group1, group2]) assert GroupMeta.objects.get_value(group1, "github:tid") == "134" assert GroupMeta.objects.get_value(group2, "other:tid") == "abc" assert not GroupMeta.objects.get_value(group2, "github:tid") assert GroupMeta.objects.get_value(group1, "other:tid") == "567" with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() GroupMeta.objects.clear_local_cache() GroupMeta.objects.populate_cache([group1, group2]) assert not GroupMeta.objects.get_value(group1, "github:tid") assert not GroupMeta.objects.get_value(group1, "other:tid") assert GroupMeta.objects.get_value(group2, "github:tid") == "134" assert GroupMeta.objects.get_value(group2, "other:tid") == "abc"
def test_merge_with_event_integrity(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event("a" * 32, group=group1, data={"extra": { "foo": "bar" }}) project2 = self.create_project() group2 = self.create_group(project2) event2 = self.create_event("b" * 32, group=group2, data={"extra": { "foo": "baz" }}) with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() # this previously would error with NodeIntegrityError due to the # reference check being bound to a group event1 = Event.objects.get(id=event1.id) assert event1.group_id == group2.id Event.objects.bind_nodes([event1], "data") assert event1.data["extra"]["foo"] == "bar" event2 = Event.objects.get(id=event2.id) assert event2.group_id == group2.id Event.objects.bind_nodes([event2], "data") assert event2.data["extra"]["foo"] == "baz"
def test_merge_updates_tag_values_seen(self): project = self.create_project() event1 = self.store_event( data={ "event_id": "a" * 32, "timestamp": iso_format(before_now(seconds=1)), "fingerprint": ["group-1"], "tags": {"foo": "bar"}, "environment": self.environment.name, }, project_id=project.id, ) event2 = self.store_event( data={ "event_id": "b" * 32, "timestamp": iso_format(before_now(seconds=1)), "fingerprint": ["group-2"], "tags": {"foo": "bar"}, "environment": self.environment.name, }, project_id=project.id, ) target = event1.group other = event2.group with self.tasks(): merge_groups([other.id], target.id) assert not Group.objects.filter(id=other.id).exists()
def test_merge_group_environments(self): group1 = self.create_group(self.project) GroupEnvironment.objects.create( group_id=group1.id, environment_id=1, ) group2 = self.create_group(self.project) GroupEnvironment.objects.create( group_id=group2.id, environment_id=1, ) GroupEnvironment.objects.create( group_id=group2.id, environment_id=2, ) with self.tasks(): merge_groups([group1.id], group2.id) assert list( GroupEnvironment.objects.filter( group_id=group2.id, ).order_by('environment_id').values_list( 'environment_id', flat=True, )) == [1, 2]
def test_merge_with_group_meta(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event("a" * 32, group=group1, data={"foo": "bar"}) project2 = self.create_project() group2 = self.create_group(project2) event2 = self.create_event("b" * 32, group=group2, data={"foo": "baz"}) GroupMeta.objects.create(group=event1.group, key="github:tid", value="134") GroupMeta.objects.create(group=event1.group, key="other:tid", value="567") GroupMeta.objects.create(group=event2.group, key="other:tid", value="abc") GroupMeta.objects.populate_cache([group1, group2]) assert GroupMeta.objects.get_value(group1, "github:tid") == "134" assert GroupMeta.objects.get_value(group2, "other:tid") == "abc" assert not GroupMeta.objects.get_value(group2, "github:tid") assert GroupMeta.objects.get_value(group1, "other:tid") == "567" with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() GroupMeta.objects.clear_local_cache() GroupMeta.objects.populate_cache([group1, group2]) assert not GroupMeta.objects.get_value(group1, "github:tid") assert not GroupMeta.objects.get_value(group1, "other:tid") assert GroupMeta.objects.get_value(group2, "github:tid") == "134" assert GroupMeta.objects.get_value(group2, "other:tid") == "abc"
def test_merge_calls_eventstream(self, mock_eventstream): group1 = self.create_group(self.project) group2 = self.create_group(self.project) eventstream_state = object() with self.tasks(): merge_groups([group1.id], group2.id, eventstream_state=eventstream_state) mock_eventstream.end_merge.assert_called_once_with(eventstream_state)
def test_merge_calls_eventstream(self, mock_eventstream): group1 = self.create_group(self.project) group2 = self.create_group(self.project) eventstream_state = object() with self.tasks(): merge_groups([group1.id], group2.id, eventstream_state=eventstream_state) mock_eventstream.end_merge.assert_called_once_with(eventstream_state)
def test_user_report_merge(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event('a' * 32, group=group1, data={'foo': 'bar'}) project2 = self.create_project() group2 = self.create_group(project2) ur = UserReport.objects.create(project=project1, group=group1, event_id=event1.event_id) with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() assert UserReport.objects.get(id=ur.id).group_id == group2.id
def test_user_report_merge(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event('a' * 32, group=group1, data={'foo': 'bar'}) project2 = self.create_project() group2 = self.create_group(project2) ur = UserReport.objects.create(project=project1, group=group1, event_id=event1.event_id) with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() assert UserReport.objects.get(id=ur.id).group_id == group2.id
def test_merge_creates_redirect(self): groups = [self.create_group() for _ in range(0, 3)] with self.tasks(): merge_groups([groups[0].id], groups[1].id) assert not Group.objects.filter(id=groups[0].id).exists() assert (GroupRedirect.objects.filter( group_id=groups[1].id, previous_group_id=groups[0].id).count() == 1) with self.tasks(): merge_groups([groups[1].id], groups[2].id) assert not Group.objects.filter(id=groups[1].id).exists() assert GroupRedirect.objects.filter(group_id=groups[2].id).count() == 2
def test_user_report_merge(self): project1 = self.create_project() event1 = self.store_event(data={}, project_id=project1.id) group1 = event1.group project2 = self.create_project() group2 = self.create_group(project2) ur = UserReport.objects.create(project_id=project1.id, group_id=group1.id, event_id=event1.event_id) with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() assert UserReport.objects.get(id=ur.id).group_id == group2.id
def test_merge_with_group_meta(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event('a' * 32, group=group1, data={'foo': 'bar'}) project2 = self.create_project() group2 = self.create_group(project2) event2 = self.create_event('b' * 32, group=group2, data={'foo': 'baz'}) GroupMeta.objects.create( group=event1.group, key='github:tid', value='134', ) GroupMeta.objects.create( group=event1.group, key='other:tid', value='567', ) GroupMeta.objects.create( group=event2.group, key='other:tid', value='abc', ) GroupMeta.objects.populate_cache([group1, group2]) assert GroupMeta.objects.get_value(group1, 'github:tid') == '134' assert GroupMeta.objects.get_value(group2, 'other:tid') == 'abc' assert not GroupMeta.objects.get_value(group2, 'github:tid') assert GroupMeta.objects.get_value(group1, 'other:tid') == '567' with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() GroupMeta.objects.clear_local_cache() GroupMeta.objects.populate_cache([group1, group2]) assert not GroupMeta.objects.get_value(group1, 'github:tid') assert not GroupMeta.objects.get_value(group1, 'other:tid') assert GroupMeta.objects.get_value(group2, 'github:tid') == '134' assert GroupMeta.objects.get_value(group2, 'other:tid') == 'abc'
def test_merge_with_group_meta(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event('a' * 32, group=group1, data={'foo': 'bar'}) project2 = self.create_project() group2 = self.create_group(project2) event2 = self.create_event('b' * 32, group=group2, data={'foo': 'baz'}) GroupMeta.objects.create( group=event1.group, key='github:tid', value='134', ) GroupMeta.objects.create( group=event1.group, key='other:tid', value='567', ) GroupMeta.objects.create( group=event2.group, key='other:tid', value='abc', ) GroupMeta.objects.populate_cache([group1, group2]) assert GroupMeta.objects.get_value(group1, 'github:tid') == '134' assert GroupMeta.objects.get_value(group2, 'other:tid') == 'abc' assert not GroupMeta.objects.get_value(group2, 'github:tid') assert GroupMeta.objects.get_value(group1, 'other:tid') == '567' with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() GroupMeta.objects.clear_local_cache() GroupMeta.objects.populate_cache([group1, group2]) assert not GroupMeta.objects.get_value(group1, 'github:tid') assert not GroupMeta.objects.get_value(group1, 'other:tid') assert GroupMeta.objects.get_value(group2, 'github:tid') == '134' assert GroupMeta.objects.get_value(group2, 'other:tid') == 'abc'
def test_merge_with_event_integrity(self): project = self.create_project() event1 = self.store_event( data={ "event_id": "a" * 32, "timestamp": iso_format(before_now(seconds=1)), "fingerprint": ["group-1"], "extra": { "foo": "bar" }, }, project_id=project.id, ) group1 = event1.group event2 = self.store_event( data={ "event_id": "b" * 32, "timestamp": iso_format(before_now(seconds=1)), "fingerprint": ["group-2"], "extra": { "foo": "baz" }, }, project_id=project.id, ) group2 = event2.group with self.tasks(): eventstream_state = eventstream.start_merge( project.id, [group1.id], group2.id) merge_groups([group1.id], group2.id) eventstream.end_merge(eventstream_state) assert not Group.objects.filter(id=group1.id).exists() event1 = eventstore.get_event_by_id(project.id, event1.event_id) assert event1.group_id == group2.id Event.objects.bind_nodes([event1], "data") assert event1.data["extra"]["foo"] == "bar" event2 = eventstore.get_event_by_id(project.id, event2.event_id) assert event2.group_id == group2.id Event.objects.bind_nodes([event2], "data") assert event2.data["extra"]["foo"] == "baz"
def test_merge_creates_redirect(self): groups = [self.create_group() for _ in range(0, 3)] with self.tasks(): merge_groups([groups[0].id], groups[1].id) assert not Group.objects.filter(id=groups[0].id).exists() assert GroupRedirect.objects.filter( group_id=groups[1].id, previous_group_id=groups[0].id, ).count() == 1 with self.tasks(): merge_groups([groups[1].id], groups[2].id) assert not Group.objects.filter(id=groups[1].id).exists() assert GroupRedirect.objects.filter( group_id=groups[2].id, ).count() == 2
def test_merge_with_event_integrity(self): project1 = self.create_project() group1 = self.create_group(project1) event1 = self.create_event('a' * 32, group=group1, data={'extra': {'foo': 'bar'}}) project2 = self.create_project() group2 = self.create_group(project2) event2 = self.create_event('b' * 32, group=group2, data={'extra': {'foo': 'baz'}}) with self.tasks(): merge_groups([group1.id], group2.id) assert not Group.objects.filter(id=group1.id).exists() # this previously would error with NodeIntegrityError due to the # reference check being bound to a group event1 = Event.objects.get(id=event1.id) assert event1.group_id == group2.id Event.objects.bind_nodes([event1], 'data') assert event1.data['extra']['foo'] == 'bar' event2 = Event.objects.get(id=event2.id) assert event2.group_id == group2.id Event.objects.bind_nodes([event2], 'data') assert event2.data['extra']['foo'] == 'baz'
def test_merge_updates_tag_values_seen(self): project = self.create_project() target, other = [self.create_group(project) for _ in range(0, 2)] data = { 'sentry:user': { 'id:1': { target: 2, }, 'id:2': { other: 3, }, 'id:3': { target: 1, other: 2, }, }, 'key': { 'foo': { other: 3, }, }, } input_group_tag_keys = defaultdict(int) # [(group, key)] = values_seen input_group_tag_values = defaultdict(int) # [(group, key, value)] = times_seen output_group_tag_keys = defaultdict(int) # [key] = values_seen output_group_tag_values = defaultdict(int) # [(key, value)] = times_seen for key, values in data.items(): output_group_tag_keys[key] = len(values) for value, groups in values.items(): for group, count in groups.items(): input_group_tag_keys[(group, key)] += 1 input_group_tag_values[(group, key, value)] += count output_group_tag_values[(key, value)] += count for ((group, key), values_seen) in input_group_tag_keys.items(): tagstore.create_group_tag_key( project_id=project.id, group_id=group.id, environment_id=self.environment.id, key=key, values_seen=values_seen, ) for ((group, key, value), times_seen) in input_group_tag_values.items(): tagstore.create_group_tag_value( project_id=project.id, group_id=group.id, environment_id=self.environment.id, key=key, value=value, times_seen=times_seen, ) with self.tasks(): merge_groups([other.id], target.id) assert not Group.objects.filter(id=other.id).exists() assert len( tagstore.get_group_tag_keys( other.project_id, other.id, environment_id=self.environment.id)) == 0 assert len( GroupTagValue.objects.filter( project_id=other.project_id, group_id=other.id, )) == 0 for key, values_seen in output_group_tag_keys.items(): assert tagstore.get_group_tag_key( target.project_id, target.id, environment_id=self.environment.id, key=key).values_seen == values_seen for (key, value), times_seen in output_group_tag_values.items(): assert tagstore.get_group_tag_value( project_id=target.project_id, group_id=target.id, environment_id=self.environment.id, key=key, value=value, ).times_seen == times_seen
def test_merge_updates_tag_values_seen(self): project = self.create_project() target, other = [self.create_group(project) for _ in range(0, 2)] data = { "sentry:user": { "id:1": { target: 2 }, "id:2": { other: 3 }, "id:3": { target: 1, other: 2 } }, "key": { "foo": { other: 3 } }, } input_group_tag_keys = defaultdict(int) # [(group, key)] = values_seen input_group_tag_values = defaultdict( int) # [(group, key, value)] = times_seen output_group_tag_keys = defaultdict(int) # [key] = values_seen output_group_tag_values = defaultdict( int) # [(key, value)] = times_seen for key, values in data.items(): output_group_tag_keys[key] = len(values) for value, groups in values.items(): for group, count in groups.items(): input_group_tag_keys[(group, key)] += 1 input_group_tag_values[(group, key, value)] += count output_group_tag_values[(key, value)] += count for ((group, key), values_seen) in input_group_tag_keys.items(): tagstore.create_group_tag_key( project_id=project.id, group_id=group.id, environment_id=self.environment.id, key=key, values_seen=values_seen, ) for ((group, key, value), times_seen) in input_group_tag_values.items(): tagstore.create_group_tag_value( project_id=project.id, group_id=group.id, environment_id=self.environment.id, key=key, value=value, times_seen=times_seen, ) with self.tasks(): merge_groups([other.id], target.id) assert not Group.objects.filter(id=other.id).exists() assert (len( tagstore.get_group_tag_keys(other.project_id, other.id, environment_ids=[self.environment.id ])) == 0) assert (len( GroupTagValue.objects.filter(project_id=other.project_id, group_id=other.id)) == 0) for key, values_seen in output_group_tag_keys.items(): assert (tagstore.get_group_tag_key( target.project_id, target.id, environment_id=self.environment.id, key=key).values_seen == values_seen) for (key, value), times_seen in output_group_tag_values.items(): assert (tagstore.get_group_tag_value( project_id=target.project_id, group_id=target.id, environment_id=self.environment.id, key=key, value=value, ).times_seen == times_seen)