Beispiel #1
0
def assert_supersearch_no_errors():
    """Make sure an uncached SuperSearch query doesn't have any errors"""
    supersearch = SuperSearch()
    # We don't want any caching this time
    supersearch.cache_seconds = 0
    results = supersearch.get(
        product=settings.DEFAULT_PRODUCT,
        _results_number=1,
        _columns=['uuid'],
        _facets_size=1,
    )
    assert not results['errors'], results['errors']
Beispiel #2
0
def assert_supersearch_no_errors():
    """Make sure an uncached SuperSearch query doesn't have any errors"""
    supersearch = SuperSearch()
    # We don't want any caching this time
    supersearch.cache_seconds = 0
    results = supersearch.get(
        product=settings.DEFAULT_PRODUCT,
        _results_number=1,
        _columns=['uuid'],
        _facets_size=1,
    )
    assert not results['errors'], results['errors']
Beispiel #3
0
    def test_topcrasher_modes(self, rpost):
        rpost.side_effect = mocked_post_123

        def mocked_supersearch_get(**params):
            return {'hits': [], 'facets': {'signature': []}, 'total': 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        now = datetime.datetime.utcnow()
        today = now.replace(hour=0, minute=0, second=0, microsecond=0)

        timestr = '%Y-%m-%d %H:%M:%S'
        now = now.strftime(timestr)
        today = today.strftime(timestr)

        with freezegun.freeze_time(now, tz_offset=0):
            # By default, it returns "real-time" data.
            response = self.client.get(self.base_url, {
                'product': 'WaterWolf',
                'version': '19.0',
            })
            eq_(response.status_code, 200)
            ok_(now in response.content, now)
            ok_(today not in response.content)

            # Now test the "day time" data.
            response = self.client.get(self.base_url, {
                'product': 'WaterWolf',
                'version': '19.0',
                '_tcbs_mode': 'byday',
            })
            eq_(response.status_code, 200)
            ok_(today in response.content)
            ok_(now not in response.content)
Beispiel #4
0
    def test_healthcheck(self, mocked_elasticsearch, rget):
        searches = []

        def mocked_supersearch_get(**params):
            searches.append(params)
            eq_(params['product'], [settings.DEFAULT_PRODUCT])
            eq_(params['_results_number'], 1)
            eq_(params['_columns'], ['uuid'])
            return {
                'hits': [
                    {'uuid': '12345'},
                ],
                'facets': [],
                'total': 30002,
                'errors': [],
            }

        SuperSearch.implementation().get.side_effect = (
            mocked_supersearch_get
        )

        def mocked_requests_get(url, **params):
            return Response(True)

        rget.side_effect = mocked_requests_get

        url = reverse('monitoring:healthcheck')
        response = self.client.get(url)
        eq_(response.status_code, 200)
        eq_(json.loads(response.content)['ok'], True)

        assert len(searches) == 1
Beispiel #5
0
    def test_assert_supersearch_errors(self):
        searches = []

        def mocked_supersearch_get(**params):
            searches.append(params)
            eq_(params['product'], [settings.DEFAULT_PRODUCT])
            eq_(params['_results_number'], 1)
            eq_(params['_columns'], ['uuid'])
            return {
                'hits': [
                    {'uuid': '12345'},
                ],
                'facets': [],
                'total': 320,
                'errors': ['bad'],
            }

        SuperSearch.implementation().get.side_effect = (
            mocked_supersearch_get
        )
        assert_raises(
            AssertionError,
            assert_supersearch_no_errors
        )
        assert len(searches) == 1
Beispiel #6
0
    def test_heartbeat(self, mocked_elasticsearch, rget):
        searches = []

        def mocked_supersearch_get(**params):
            searches.append(params)
            assert params["product"] == [settings.DEFAULT_PRODUCT]
            assert params["_results_number"] == 1
            assert params["_columns"] == ["uuid"]
            return {
                "hits": [{
                    "uuid": "12345"
                }],
                "facets": [],
                "total": 30002,
                "errors": [],
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        def mocked_requests_get(url, **params):
            return Response(True)

        rget.side_effect = mocked_requests_get

        # Verify the __heartbeat__ endpoint
        url = reverse("monitoring:dockerflow_heartbeat")
        response = self.client.get(url)
        assert response.status_code == 200
        assert json.loads(response.content)["ok"] is True
        assert len(searches) == 1
Beispiel #7
0
    def test_parameters(self):
        def mocked_supersearch_get(**params):
            # Verify that all expected parameters are in the URL.
            ok_("product" in params)
            ok_("WaterWolf" in params["product"])
            ok_("NightTrain" in params["product"])

            ok_("address" in params)
            ok_("0x0" in params["address"])
            ok_("0xa" in params["address"])

            ok_("reason" in params)
            ok_("^hello" in params["reason"])
            ok_("$thanks" in params["reason"])

            ok_("java_stack_trace" in params)
            ok_("Exception" in params["java_stack_trace"])

            return {"hits": [], "facets": "", "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse("signature:signature_reports")

        response = self.client.get(
            url,
            {
                "signature": DUMB_SIGNATURE,
                "product": ["WaterWolf", "NightTrain"],
                "address": ["0x0", "0xa"],
                "reason": ["^hello", "$thanks"],
                "java_stack_trace": "Exception",
            },
        )
        eq_(response.status_code, 200)
Beispiel #8
0
    def test_parameters(self):
        def mocked_supersearch_get(**params):
            # Verify that all expected parameters are in the URL.
            ok_('product' in params)
            ok_('WaterWolf' in params['product'])
            ok_('NightTrain' in params['product'])

            ok_('address' in params)
            ok_('0x0' in params['address'])
            ok_('0xa' in params['address'])

            ok_('reason' in params)
            ok_('^hello' in params['reason'])
            ok_('$thanks' in params['reason'])

            ok_('java_stack_trace' in params)
            ok_('Exception' in params['java_stack_trace'])

            return {"hits": [], "facets": "", "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_reports')

        response = self.client.get(
            url, {
                'signature': DUMB_SIGNATURE,
                'product': ['WaterWolf', 'NightTrain'],
                'address': ['0x0', '0xa'],
                'reason': ['^hello', '$thanks'],
                'java_stack_trace': 'Exception',
            })
        eq_(response.status_code, 200)
Beispiel #9
0
    def test_healthcheck(self, mocked_elasticsearch, rget):
        searches = []

        def mocked_supersearch_get(**params):
            searches.append(params)
            assert params['product'] == [settings.DEFAULT_PRODUCT]
            assert params['_results_number'] == 1
            assert params['_columns'] == ['uuid']
            return {
                'hits': [
                    {'uuid': '12345'},
                ],
                'facets': [],
                'total': 30002,
                'errors': [],
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        def mocked_requests_get(url, **params):
            return Response(True)

        rget.side_effect = mocked_requests_get

        url = reverse('monitoring:healthcheck')
        response = self.client.get(url)
        assert response.status_code == 200
        assert json.loads(response.content)['ok'] is True

        assert len(searches) == 1
Beispiel #10
0
    def test_topcrasher_modes(self, rpost):
        rpost.side_effect = mocked_post_123

        def mocked_supersearch_get(**params):
            return {"hits": [], "facets": {"signature": []}, "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        now = datetime.datetime.utcnow()
        today = now.replace(hour=0, minute=0, second=0, microsecond=0)

        timestr = "%Y-%m-%d %H:%M:%S"
        now = now.strftime(timestr)
        today = today.strftime(timestr)

        with freezegun.freeze_time(now, tz_offset=0):
            # By default, it returns "real-time" data.
            response = self.client.get(self.base_url, {"product": "WaterWolf", "version": "19.0"})
            eq_(response.status_code, 200)
            ok_(now in response.content, now)
            ok_(today not in response.content)

            # Now test the "day time" data.
            response = self.client.get(
                self.base_url, {"product": "WaterWolf", "version": "19.0", "_tcbs_mode": "byday"}
            )
            eq_(response.status_code, 200)
            ok_(today in response.content)
            ok_(now not in response.content)
Beispiel #11
0
def supersearch_field_update(request):
    field_data = _get_supersearch_field_data(request.POST)

    if isinstance(field_data, basestring):
        return http.HttpResponseBadRequest(field_data)

    api = SuperSearchField()
    api.update_field(**field_data)

    SuperSearch.clear_implementations_cache()

    log(request.user, 'supersearch_field.put', field_data)

    # Refresh the cache for the fields service.
    SuperSearchFields().get(refresh_cache=True)

    return redirect(reverse('manage:supersearch_fields'))
Beispiel #12
0
def supersearch_field_update(request):
    field_data = _get_supersearch_field_data(request.POST)

    if isinstance(field_data, basestring):
        return http.HttpResponseBadRequest(field_data)

    api = SuperSearchField()
    api.update_field(**field_data)

    SuperSearch.clear_implementations_cache()

    log(request.user, 'supersearch_field.put', field_data)

    # Refresh the cache for the fields service.
    SuperSearchFields().get(refresh_cache=True)

    return redirect(reverse('manage:supersearch_fields'))
Beispiel #13
0
    def test_search_results_pagination(self, rpost):
        """Test that the pagination of results works as expected.
        """
        def mocked_post(**options):
            assert 'bugs' in options['url'], options['url']
            return Response("""
                {"hits": [], "total": 0}
            """)

        rpost.side_effect = mocked_post

        def mocked_supersearch_get(**params):
            assert '_columns' in params

            # Make sure a negative page does not lead to negative offset value.
            # But instead it is considered as the page 1 and thus is not added.
            ok_('_results_offset' not in params)

            hits = []
            for i in range(140):
                hits.append({
                    "signature": "nsASDOMWindowEnumerator::GetNext()",
                    "date": "2017-01-31T23:12:57",
                    "uuid": i,
                    "product": "WaterWolf",
                    "version": "1.0",
                    "platform": "Linux",
                    "build_id": 888981
                })
            return {
                "hits": self.only_certain_columns(hits, params['_columns']),
                "facets": "",
                "total": len(hits)
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('supersearch.search_results')

        response = self.client.get(url, {
            '_columns': ['version'],
            '_facets': ['platform']
        })

        eq_(response.status_code, 200)
        ok_('140' in response.content)

        # Check that the pagination URL contains all three expected parameters.
        doc = pyquery.PyQuery(response.content)
        next_page_url = str(doc('.pagination a').eq(0))
        ok_('_facets=platform' in next_page_url)
        ok_('_columns=version' in next_page_url)
        ok_('page=2' in next_page_url)
        ok_('#crash-reports' in next_page_url)

        # Test that a negative page value does not break it.
        response = self.client.get(url, {'page': '-1'})
        eq_(response.status_code, 200)
Beispiel #14
0
def supersearch_field_delete(request):
    field_name = request.GET.get('name')

    if not field_name:
        return http.HttpResponseBadRequest('A "name" is needed')

    api = SuperSearchField()
    api.delete_field(name=field_name)

    SuperSearch.clear_implementations_cache()

    log(request.user, 'supersearch_field.delete', {'name': field_name})

    # Refresh the cache for the fields service.
    SuperSearchFields().get(refresh_cache=True)

    url = reverse('manage:supersearch_fields')
    return redirect(url)
Beispiel #15
0
    def test_signature_reports_pagination(self):
        """Test that the pagination of results works as expected.
        """

        def mocked_supersearch_get(**params):
            assert '_columns' in params

            # Make sure a negative page does not lead to negative offset value.
            # But instead it is considered as the page 1 and thus is not added.
            eq_(params.get('_results_offset'), 0)

            hits = []
            for i in range(140):
                hits.append({
                    "signature": "nsASDOMWindowEnumerator::GetNext()",
                    "date": "2017-01-31T23:12:57",
                    "uuid": i,
                    "product": "WaterWolf",
                    "version": "1.0",
                    "platform": "Linux",
                    "build_id": 888981
                })
            return {
                "hits": self.only_certain_columns(hits, params['_columns']),
                "facets": "",
                "total": len(hits)
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_reports')

        response = self.client.get(
            url,
            {
                'signature': DUMB_SIGNATURE,
                'product': ['WaterWolf'],
                '_columns': ['platform']
            }
        )

        eq_(response.status_code, 200)
        ok_('140' in response.content)

        # Check that the pagination URL contains all three expected parameters.
        doc = pyquery.PyQuery(response.content)
        next_page_url = str(doc('.pagination a').eq(0))
        ok_('product=WaterWolf' in next_page_url)
        ok_('_columns=platform' in next_page_url)
        ok_('page=2' in next_page_url)

        # Test that a negative page value does not break it.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'page': '-1',
        })
        eq_(response.status_code, 200)
Beispiel #16
0
def supersearch_field_delete(request):
    field_name = request.GET.get('name')

    if not field_name:
        return http.HttpResponseBadRequest('A "name" is needed')

    api = SuperSearchField()
    api.delete_field(name=field_name)

    SuperSearch.clear_implementations_cache()

    log(request.user, 'supersearch_field.delete', {'name': field_name})

    # Refresh the cache for the fields service.
    SuperSearchFields().get(refresh_cache=True)

    url = reverse('manage:supersearch_fields')
    return redirect(url)
Beispiel #17
0
    def test_signature_graphs(self):
        def mocked_supersearch_get(**params):
            ok_("signature" in params)
            eq_(params["signature"], ["=" + DUMB_SIGNATURE])

            ok_("_histogram.date" in params)
            ok_("_facets" in params)

            if "product" in params["_facets"]:
                return {
                    "hits": [],
                    "total": 4,
                    "facets": {
                        "product": [{"count": 4, "term": "WaterWolf"}],
                        "histogram_date": [
                            {
                                "count": 2,
                                "term": "2015-08-05T00:00:00+00:00",
                                "facets": {"product": [{"count": 2, "term": "WaterWolf"}]},
                            },
                            {
                                "count": 2,
                                "term": "2015-08-06T00:00:00+00:00",
                                "facets": {"product": [{"count": 2, "term": "WaterWolf"}]},
                            },
                        ],
                    },
                }

            return {"hits": [], "total": 0, "facets": {"platform": [], "signature": [], "histogram_date": []}}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        # Test with no results
        url = reverse("signature:signature_graphs", args=("platform",))

        response = self.client.get(url, {"signature": DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_("application/json" in response["content-type"])
        struct = json.loads(response.content)
        ok_("aggregates" in struct)
        eq_(len(struct["aggregates"]), 0)
        ok_("term_counts" in struct)
        eq_(len(struct["term_counts"]), 0)

        # Test with results
        url = reverse("signature:signature_graphs", args=("product",))

        response = self.client.get(url, {"signature": DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_("application/json" in response["content-type"])
        struct = json.loads(response.content)
        ok_("aggregates" in struct)
        eq_(len(struct["aggregates"]), 2)
        ok_("term_counts" in struct)
        eq_(len(struct["term_counts"]), 1)
Beispiel #18
0
    def test_signature_comments_pagination(self):
        """Test that the pagination of comments works as expected. """

        def mocked_supersearch_get(**params):
            assert '_columns' in params

            if params.get('_results_offset') != 0:
                hits_range = range(100, 140)
            else:
                hits_range = range(100)

            hits = []
            for i in hits_range:
                hits.append({
                    "date": "2017-01-31T23:12:57",
                    "uuid": i,
                    "user_comments": "hi",
                })

            return {
                "hits": self.only_certain_columns(hits, params['_columns']),
                "total": 140
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_comments')

        response = self.client.get(
            url,
            {
                'signature': DUMB_SIGNATURE,
                'product': ['WaterWolf'],
            }
        )

        eq_(response.status_code, 200)
        ok_('140' in response.content)
        ok_('99' in response.content)
        ok_('139' not in response.content)

        # Check that the pagination URL contains all expected parameters.
        doc = pyquery.PyQuery(response.content)
        next_page_url = str(doc('.pagination a').eq(0))
        ok_('product=WaterWolf' in next_page_url)
        ok_('page=2' in next_page_url)

        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'page': '2',
        })
        eq_(response.status_code, 200)
        ok_('140' in response.content)
        ok_('99' not in response.content)
        ok_('139' in response.content)
Beispiel #19
0
def supersearch_field_create(request):
    field_data = _get_supersearch_field_data(request.POST)

    if isinstance(field_data, basestring):
        return http.HttpResponseBadRequest(field_data)

    api = SuperSearchField()
    api.create_field(**field_data)

    log(request.user, 'supersearch_field.post', field_data)

    # Refresh the cache for the fields service.
    SuperSearchFields().get(refresh_cache=True)
    SuperSearch.clear_implementations_cache()

    # The API is using cache to get all fields by a specific namespace
    # for the whitelist lookup, clear that cache too.
    cache.delete('api_supersearch_fields_%s' % field_data['namespace'])

    return redirect(reverse('manage:supersearch_fields'))
Beispiel #20
0
def supersearch_field_create(request):
    field_data = _get_supersearch_field_data(request.POST)

    if isinstance(field_data, basestring):
        return http.HttpResponseBadRequest(field_data)

    api = SuperSearchField()
    api.create_field(**field_data)

    log(request.user, 'supersearch_field.post', field_data)

    # Refresh the cache for the fields service.
    SuperSearchFields().get(refresh_cache=True)
    SuperSearch.clear_implementations_cache()

    # The API is using cache to get all fields by a specific namespace
    # for the whitelist lookup, clear that cache too.
    cache.delete('api_supersearch_fields_%s' % field_data['namespace'])

    return redirect(reverse('manage:supersearch_fields'))
Beispiel #21
0
    def test_search_custom(self):
        def mocked_supersearch_get(**params):
            return None

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        self.create_custom_query_perm()

        url = reverse('supersearch.search_custom')
        response = self.client.get(url)
        eq_(response.status_code, 200)
        ok_('Run a search to get some results' in response.content)
Beispiel #22
0
    def test_signature_aggregation(self):
        def mocked_supersearch_get(**params):
            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            ok_('_facets' in params)

            if 'product' in params['_facets']:
                return {
                    "hits": [],
                    "facets": {
                        "product": [
                            {
                                "term": "windows",
                                "count": 42,
                            },
                            {
                                "term": "linux",
                                "count": 1337,
                            },
                            {
                                "term": "mac",
                                "count": 3,
                            },
                        ]
                    },
                    "total": 1382
                }

            # the default
            return {"hits": [], "facets": {"platform": []}, "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        # Test with no results.
        url = reverse('signature:signature_aggregation', args=('platform', ))

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('Product' not in response.content)
        ok_('No results were found' in response.content)

        # Test with results.
        url = reverse('signature:signature_aggregation', args=('product', ))

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('Product' in response.content)
        ok_('1337' in response.content)
        ok_('linux' in response.content)
        ok_(str(1337 / 1382 * 100) in response.content)
        ok_('windows' in response.content)
        ok_('mac' in response.content)
Beispiel #23
0
    def test_signature_summary_with_many_hexes(self, rget):
        def mocked_get(url, params, **options):
            if '/graphics_devices' in url:
                ok_(len(params['vendor_hex']) <= 50)
                ok_(len(params['adapter_hex']) <= 50)

                return Response({'hits': [], 'total': 0})

            raise NotImplementedError(url)

        rget.side_effect = mocked_get

        def mocked_supersearch_get(**params):
            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            adapters = [{
                'term': '0x{0:0>4}'.format(i),
                'count': 1
            } for i in range(50)]
            vendors = [{
                'term': '0x{0:0>4}'.format(i),
                'count': 50,
                'facets': {
                    'adapter_device_id': adapters
                }
            } for i in range(3)]

            res = {
                'hits': [],
                'total': 4,
                'facets': {
                    'adapter_vendor_id': vendors,
                }
            }

            return res

        SuperSearch.implementation().get.side_effect = (mocked_supersearch_get)

        # Test with no results
        url = reverse('signature:signature_summary')

        response = self.client.get(
            url, {
                'signature': DUMB_SIGNATURE,
                'product': 'WaterWolf',
                'version': '1.0',
            })
        eq_(response.status_code, 200)

        # There are 150 different hexes, there should be 3 calls to the API.
        eq_(rget.call_count, 3)
Beispiel #24
0
    def test_search_custom(self):

        def mocked_supersearch_get(**params):
            return None

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        self.create_custom_query_perm()

        url = reverse('supersearch.search_custom')
        response = self.client.get(url)
        eq_(response.status_code, 200)
        ok_('Run a search to get some results' in response.content)
Beispiel #25
0
    def test_signature_comments_pagination(self):
        """Test that the pagination of comments works as expected. """
        def mocked_supersearch_get(**params):
            assert '_columns' in params

            if '_results_offset' in params:
                hits_range = range(100, 140)
            else:
                hits_range = range(100)

            hits = []
            for i in hits_range:
                hits.append({
                    "date": "2017-01-31T23:12:57",
                    "uuid": i,
                    "user_comments": "hi",
                })

            return {
                "hits": self.only_certain_columns(hits, params['_columns']),
                "total": 140
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_comments')

        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'product': ['WaterWolf'],
        })

        eq_(response.status_code, 200)
        ok_('140' in response.content)
        ok_('99' in response.content)
        ok_('139' not in response.content)

        # Check that the pagination URL contains all expected parameters.
        doc = pyquery.PyQuery(response.content)
        next_page_url = str(doc('.pagination a').eq(0))
        ok_('product=WaterWolf' in next_page_url)
        ok_('page=2' in next_page_url)

        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'page': '2',
        })
        eq_(response.status_code, 200)
        ok_('140' in response.content)
        ok_('99' not in response.content)
        ok_('139' in response.content)
Beispiel #26
0
    def test_search_results_parameters(self, rpost):
        def mocked_post(**options):
            assert 'bugs' in options['url'], options['url']
            return Response({
                "hits": [],
                "total": 0
            })

        rpost.side_effect = mocked_post

        def mocked_supersearch_get(**params):
            # Verify that all expected parameters are in the URL.
            ok_('product' in params)
            ok_('WaterWolf' in params['product'])
            ok_('NightTrain' in params['product'])

            ok_('address' in params)
            ok_('0x0' in params['address'])
            ok_('0xa' in params['address'])

            ok_('reason' in params)
            ok_('^hello' in params['reason'])
            ok_('$thanks' in params['reason'])

            ok_('java_stack_trace' in params)
            ok_('Exception' in params['java_stack_trace'])

            return {
                "hits": [],
                "facets": "",
                "total": 0
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('supersearch.search_results')

        response = self.client.get(
            url, {
                'product': ['WaterWolf', 'NightTrain'],
                'address': ['0x0', '0xa'],
                'reason': ['^hello', '$thanks'],
                'java_stack_trace': 'Exception',
            }
        )
        eq_(response.status_code, 200)
Beispiel #27
0
    def test_topcrasher_without_any_signatures(self, rget, rpost):
        url = self.base_url + '?product=WaterWolf&version=19.0'
        response = self.client.get(self.base_url, {
            'product': 'WaterWolf',
        })
        ok_(url in response['Location'])

        rpost.side_effect = mocked_post_123

        def mocked_get(url, params, **options):
            if '/products' in url:
                return Response("""
                {
                  "hits": [
                    {
                        "is_featured": true,
                        "throttle": 1.0,
                        "end_date": "string",
                        "start_date": "integer",
                        "build_type": "string",
                        "product": "WaterWolf",
                        "version": "19.0",
                        "has_builds": true
                    }],
                    "total": "1"
                }
                """)
            raise NotImplementedError(url)
        rget.side_effect = mocked_get

        def mocked_supersearch_get(**params):
            return {
                'hits': [],
                'facets': {
                    'signature': []
                },
                'total': 0
            }
        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        response = self.client.get(self.base_url, {
            'product': 'WaterWolf',
            'version': '19.0',
        })
        eq_(response.status_code, 200)
Beispiel #28
0
    def test_topcrasher_without_any_signatures(self, rget, rpost):
        url = self.base_url + '?product=WaterWolf&version=19.0'
        response = self.client.get(self.base_url, {
            'product': 'WaterWolf',
        })
        ok_(url in response['Location'])

        rpost.side_effect = mocked_post_123

        def mocked_get(url, params, **options):
            if '/products' in url:
                return Response("""
                {
                  "hits": [
                    {
                        "is_featured": true,
                        "throttle": 1.0,
                        "end_date": "string",
                        "start_date": "integer",
                        "build_type": "string",
                        "product": "WaterWolf",
                        "version": "19.0",
                        "has_builds": true
                    }],
                    "total": "1"
                }
                """)
            raise NotImplementedError(url)
        rget.side_effect = mocked_get

        def mocked_supersearch_get(**params):
            return {
                'hits': [],
                'facets': {
                    'signature': []
                },
                'total': 0
            }
        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        response = self.client.get(self.base_url, {
            'product': 'WaterWolf',
            'version': '19.0',
        })
        eq_(response.status_code, 200)
Beispiel #29
0
    def test_search_results_ratelimited(self):
        def mocked_supersearch_get(**params):
            return {"hits": [], "facets": [], "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('supersearch.search_results')
        limit = int(re.findall('(\d+)', settings.RATELIMIT_SUPERSEARCH)[0])
        params = {'product': 'WaterWolf'}
        # double to avoid https://bugzilla.mozilla.org/show_bug.cgi?id=1148470
        for i in range(limit * 2):
            self.client.get(url, params)
        response = self.client.get(url,
                                   params,
                                   HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        eq_(response.status_code, 429)
        eq_(response.content, 'Too Many Requests')
        eq_(response['content-type'], 'text/plain')
Beispiel #30
0
    def test_signature_aggregation(self):
        def mocked_supersearch_get(**params):
            ok_("signature" in params)
            eq_(params["signature"], ["=" + DUMB_SIGNATURE])

            ok_("_facets" in params)

            if "product" in params["_facets"]:
                return {
                    "hits": [],
                    "facets": {
                        "product": [
                            {"term": "windows", "count": 42},
                            {"term": "linux", "count": 1337},
                            {"term": "mac", "count": 3},
                        ]
                    },
                    "total": 1382,
                }

            # the default
            return {"hits": [], "facets": {"platform": []}, "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        # Test with no results.
        url = reverse("signature:signature_aggregation", args=("platform",))

        response = self.client.get(url, {"signature": DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_("Product" not in response.content)
        ok_("No results were found" in response.content)

        # Test with results.
        url = reverse("signature:signature_aggregation", args=("product",))

        response = self.client.get(url, {"signature": DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_("Product" in response.content)
        ok_("1337" in response.content)
        ok_("linux" in response.content)
        ok_(str(1337 / 1382 * 100) in response.content)
        ok_("windows" in response.content)
        ok_("mac" in response.content)
Beispiel #31
0
    def test_assert_supersearch_errors(self):
        searches = []

        def mocked_supersearch_get(**params):
            searches.append(params)
            assert params["product"] == [settings.DEFAULT_PRODUCT]
            assert params["_results_number"] == 1
            assert params["_columns"] == ["uuid"]
            return {
                "hits": [{"uuid": "12345"}],
                "facets": [],
                "total": 320,
                "errors": ["bad"],
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get
        with pytest.raises(AssertionError):
            assert_supersearch_no_errors()

        assert len(searches) == 1
Beispiel #32
0
    def test_search_results_ratelimited(self):

        def mocked_supersearch_get(**params):
            return {"hits": [], "facets": [], "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('supersearch.search_results')
        limit = int(re.findall('(\d+)', settings.RATELIMIT_SUPERSEARCH)[0])
        params = {'product': 'WaterWolf'}
        # double to avoid https://bugzilla.mozilla.org/show_bug.cgi?id=1148470
        for i in range(limit * 2):
            self.client.get(url, params)
        response = self.client.get(
            url,
            params,
            HTTP_X_REQUESTED_WITH='XMLHttpRequest'
        )
        eq_(response.status_code, 429)
        eq_(response.content, 'Too Many Requests')
        eq_(response['content-type'], 'text/plain')
Beispiel #33
0
    def test_change_certain_exceptions_to_bad_request(self):

        # It actually doesn't matter so much which service we use
        # because we're heavily mocking it.
        # Here we use the SuperSearch model.

        def mocked_supersearch_get(**params):
            if params.get('product'):
                raise MissingArgumentError(params['product'])
            else:
                raise BadArgumentError('That was a bad thing to do')

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('api:model_wrapper', args=('SuperSearch', ))
        response = self.client.get(url)
        assert response.status_code == 400
        assert 'That was a bad thing to do' in response.content
        response = self.client.get(url, {'product': 'foobaz'})
        assert response.status_code == 400
        assert 'foobaz' in response.content
Beispiel #34
0
    def test_change_certain_exceptions_to_bad_request(self):

        # It actually doesn't matter so much which service we use
        # because we're heavily mocking it.
        # Here we use the SuperSearch model.

        def mocked_supersearch_get(**params):
            if params.get('product'):
                raise MissingArgumentError(params['product'])
            else:
                raise BadArgumentError('That was a bad thing to do')

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('api:model_wrapper', args=('SuperSearch',))
        response = self.client.get(url)
        eq_(response.status_code, 400)
        ok_('That was a bad thing to do' in response.content)
        response = self.client.get(url, {'product': 'foobaz'})
        eq_(response.status_code, 400)
        ok_('foobaz' in response.content)
Beispiel #35
0
    def test_topcrasher_modes(self, rpost):
        rpost.side_effect = mocked_post_123

        def mocked_supersearch_get(**params):
            return {
                'hits': [],
                'facets': {
                    'signature': []
                },
                'total': 0
            }
        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        now = datetime.datetime.utcnow()
        today = now.replace(hour=0, minute=0, second=0, microsecond=0)

        timestr = '%Y-%m-%d %H:%M:%S'
        now = now.strftime(timestr)
        today = today.strftime(timestr)

        with freezegun.freeze_time(now, tz_offset=0):
            # By default, it returns "real-time" data.
            response = self.client.get(self.base_url, {
                'product': 'WaterWolf',
                'version': '19.0',
            })
            eq_(response.status_code, 200)
            ok_(now in response.content, now)
            ok_(today not in response.content)

            # Now test the "day time" data.
            response = self.client.get(self.base_url, {
                'product': 'WaterWolf',
                'version': '19.0',
                '_tcbs_mode': 'byday',
            })
            eq_(response.status_code, 200)
            ok_(today in response.content)
            ok_(now not in response.content)
Beispiel #36
0
    def test_parameters(self):

        def mocked_supersearch_get(**params):
            # Verify that all expected parameters are in the URL.
            ok_('product' in params)
            ok_('WaterWolf' in params['product'])
            ok_('NightTrain' in params['product'])

            ok_('address' in params)
            ok_('0x0' in params['address'])
            ok_('0xa' in params['address'])

            ok_('reason' in params)
            ok_('^hello' in params['reason'])
            ok_('$thanks' in params['reason'])

            ok_('java_stack_trace' in params)
            ok_('Exception' in params['java_stack_trace'])

            return {
                "hits": [],
                "facets": "",
                "total": 0
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_reports')

        response = self.client.get(
            url, {
                'signature': DUMB_SIGNATURE,
                'product': ['WaterWolf', 'NightTrain'],
                'address': ['0x0', '0xa'],
                'reason': ['^hello', '$thanks'],
                'java_stack_trace': 'Exception',
            }
        )
        eq_(response.status_code, 200)
Beispiel #37
0
    def test_assert_supersearch_errors(self):
        searches = []

        def mocked_supersearch_get(**params):
            searches.append(params)
            assert params['product'] == [settings.DEFAULT_PRODUCT]
            assert params['_results_number'] == 1
            assert params['_columns'] == ['uuid']
            return {
                'hits': [
                    {'uuid': '12345'},
                ],
                'facets': [],
                'total': 320,
                'errors': ['bad'],
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get
        with pytest.raises(AssertionError):
            assert_supersearch_no_errors()

        assert len(searches) == 1
Beispiel #38
0
    def test_search_custom_parameters(self):
        self.create_custom_query_perm()

        def mocked_supersearch_get(**params):
            ok_('_return_query' in params)
            ok_('signature' in params)
            eq_(params['signature'], ['nsA'])

            return {
                "query": {"query": None},
                "indices": ["socorro200000", "socorro200001"]
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('supersearch.search_custom')
        response = self.client.get(url, {'signature': 'nsA'})
        eq_(response.status_code, 200)
        ok_('Run a search to get some results' in response.content)
        ok_('{&#34;query&#34;: null}' in response.content)
        ok_('socorro200000' in response.content)
        ok_('socorro200001' in response.content)
Beispiel #39
0
    def test_signature_comments_pagination(self):
        """Test that the pagination of comments works as expected. """

        def mocked_supersearch_get(**params):
            assert "_columns" in params

            if params.get("_results_offset") != 0:
                hits_range = range(100, 140)
            else:
                hits_range = range(100)

            hits = []
            for i in hits_range:
                hits.append({"date": "2017-01-31T23:12:57", "uuid": i, "user_comments": "hi"})

            return {"hits": self.only_certain_columns(hits, params["_columns"]), "total": 140}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse("signature:signature_comments")

        response = self.client.get(url, {"signature": DUMB_SIGNATURE, "product": ["WaterWolf"]})

        eq_(response.status_code, 200)
        ok_("140" in response.content)
        ok_("99" in response.content)
        ok_("139" not in response.content)

        # Check that the pagination URL contains all expected parameters.
        doc = pyquery.PyQuery(response.content)
        next_page_url = str(doc(".pagination a").eq(0))
        ok_("product=WaterWolf" in next_page_url)
        ok_("page=2" in next_page_url)

        response = self.client.get(url, {"signature": DUMB_SIGNATURE, "page": "2"})
        eq_(response.status_code, 200)
        ok_("140" in response.content)
        ok_("99" not in response.content)
        ok_("139" in response.content)
Beispiel #40
0
    def test_healthcheck(self, mocked_elasticsearch, rget):
        searches = []

        def mocked_supersearch_get(**params):
            searches.append(params)
            assert params['product'] == [settings.DEFAULT_PRODUCT]
            assert params['_results_number'] == 1
            assert params['_columns'] == ['uuid']
            return {
                'hits': [
                    {'uuid': '12345'},
                ],
                'facets': [],
                'total': 30002,
                'errors': [],
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        def mocked_requests_get(url, **params):
            return Response(True)

        rget.side_effect = mocked_requests_get

        # Verify the __heartbeat__ endpoint
        url = reverse('monitoring:dockerflow_heartbeat')
        response = self.client.get(url)
        assert response.status_code == 200
        assert json.loads(response.content)['ok'] is True
        assert len(searches) == 1

        # Verify the deprecated healthcheck endpoint
        searches = []
        url = reverse('monitoring:healthcheck')
        response = self.client.get(url)
        assert response.status_code == 200
        assert json.loads(response.content)['ok'] is True
        assert len(searches) == 1
Beispiel #41
0
    def test_signature_summary_with_many_hexes(self, rget):
        def mocked_get(url, params, **options):
            if "/graphics_devices" in url:
                ok_(len(params["vendor_hex"]) <= 50)
                ok_(len(params["adapter_hex"]) <= 50)

                return Response({"hits": [], "total": 0})

            raise NotImplementedError(url)

        rget.side_effect = mocked_get

        def mocked_supersearch_get(**params):
            ok_("signature" in params)
            eq_(params["signature"], ["=" + DUMB_SIGNATURE])

            adapters = [{"term": "0x{0:0>4}".format(i), "count": 1} for i in range(50)]
            vendors = [
                {"term": "0x{0:0>4}".format(i), "count": 50, "facets": {"adapter_device_id": adapters}}
                for i in range(3)
            ]

            res = {"hits": [], "total": 4, "facets": {"adapter_vendor_id": vendors}}

            return res

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        # Test with no results
        url = reverse("signature:signature_summary")

        response = self.client.get(url, {"signature": DUMB_SIGNATURE, "product": "WaterWolf", "version": "1.0"})
        eq_(response.status_code, 200)

        # There are 150 different hexes, there should be 3 calls to the API.
        eq_(rget.call_count, 3)
Beispiel #42
0
    def test_signature_graphs(self):

        def mocked_supersearch_get(**params):
            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            ok_('_histogram.date' in params)
            ok_('_facets' in params)

            if 'product' in params['_facets']:
                return {
                    "hits": [],
                    "total": 4,
                    "facets": {
                        "product": [
                            {
                                "count": 4,
                                "term": "WaterWolf"
                            }
                        ],
                        "histogram_date": [
                            {
                                "count": 2,
                                "term": "2015-08-05T00:00:00+00:00",
                                "facets": {
                                    "product": [
                                        {
                                            "count": 2,
                                            "term": "WaterWolf"
                                        }
                                    ]
                                }
                            },
                            {
                                "count": 2,
                                "term": "2015-08-06T00:00:00+00:00",
                                "facets": {
                                    "product": [
                                        {
                                            "count": 2,
                                            "term": "WaterWolf"
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }

            return {
                "hits": [],
                "total": 0,
                "facets": {
                    "platform": [],
                    "signature": [],
                    "histogram_date": []
                }
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        # Test with no results
        url = reverse(
            'signature:signature_graphs',
            args=('platform',)
        )

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('application/json' in response['content-type'])
        struct = json.loads(response.content)
        ok_('aggregates' in struct)
        eq_(len(struct['aggregates']), 0)
        ok_('term_counts' in struct)
        eq_(len(struct['term_counts']), 0)

        # Test with results
        url = reverse(
            'signature:signature_graphs',
            args=('product',)
        )

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('application/json' in response['content-type'])
        struct = json.loads(response.content)
        ok_('aggregates' in struct)
        eq_(len(struct['aggregates']), 2)
        ok_('term_counts' in struct)
        eq_(len(struct['term_counts']), 1)
Beispiel #43
0
    def get(self, **kwargs):
        form = forms.NewSignaturesForm(kwargs)

        if not form.is_valid():
            return http.JsonResponse({"errors": form.errors}, status=400)

        start_date = form.cleaned_data["start_date"]
        end_date = form.cleaned_data["end_date"]
        not_after = form.cleaned_data["not_after"]
        product = form.cleaned_data[
            "product"] or productlib.get_default_product().name

        # Make default values for all dates parameters.
        if not end_date:
            end_date = datetime.datetime.utcnow().date() + datetime.timedelta(
                days=1)

        if not start_date:
            start_date = end_date - datetime.timedelta(days=8)

        if not not_after:
            not_after = start_date - datetime.timedelta(days=14)

        api = SuperSearch()

        signatures_number = 100

        # First let's get a list of the top signatures that appeared during
        # the period we are interested in.
        params = {
            "product": product,
            "version": form.cleaned_data["version"],
            "date":
            [">=" + start_date.isoformat(), "<" + end_date.isoformat()],
            "_facets": "signature",
            "_facets_size": signatures_number,
            "_results_number": 0,
        }
        data = api.get(**params)

        signatures = []
        for signature in data["facets"]["signature"]:
            signatures.append(signature["term"])

        # Now we want to verify whether those signatures appeared or not during
        # some previous period of time.
        params["date"] = [
            ">=" + not_after.isoformat(), "<" + start_date.isoformat()
        ]

        # Filter exactly the signatures that we have.
        params["signature"] = ["=" + x for x in signatures]

        data = api.get(**params)

        # If any of those signatures is in the results, it's that it did not
        # appear during the period of time we are interested in. Let's
        # remove it from the list of new signatures.
        for signature in data["facets"]["signature"]:
            if signature["term"] in signatures:
                signatures.remove(signature["term"])

        # All remaining signatures are "new" ones.
        return {"hits": signatures, "total": len(signatures)}
Beispiel #44
0
    def test_signature_comments(self):

        def mocked_supersearch_get(**params):
            assert '_columns' in params

            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            ok_('user_comments' in params)
            eq_(params['user_comments'], ['!__null__'])

            if 'product' in params:
                results = {
                    "hits": [
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa1",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "user_comments": "hello there people!",
                            "useragent_locale": "locale1"
                        },
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa2",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "user_comments": "I love Mozilla",
                            "useragent_locale": "locale2"
                        },
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa3",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "user_comments": "this product is awesome",
                            "useragent_locale": "locale3"
                        },
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa4",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "user_comments": "WaterWolf Y U SO GOOD?",
                            "useragent_locale": "locale4"
                        }
                    ],
                    "total": 4
                }
                results['hits'] = self.only_certain_columns(
                    results['hits'],
                    params['_columns']
                )
                return results

            return {"hits": [], "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_comments')

        # Test with no results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
        })
        eq_(response.status_code, 200)
        ok_('Crash ID' not in response.content)
        ok_('No comments were found' in response.content)

        # Test with results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'product': 'WaterWolf'
        })
        eq_(response.status_code, 200)
        ok_('aaaaaaaaaaaaa1' in response.content)
        ok_('Crash ID' in response.content)
        ok_('hello there' in response.content)
        ok_('WaterWolf Y U SO GOOD' in response.content)
        ok_('locale1' in response.content)
Beispiel #45
0
    def test_SuperSearch(self):
        def mocked_supersearch_get(**params):
            assert 'exploitability' not in params

            restricted_params = (
                '_facets',
                '_aggs.signature',
                '_histogram.date',
            )
            for key in restricted_params:
                if key in params:
                    assert 'url' not in params[key]
                    assert 'email' not in params[key]
                    assert '_cardinality.email' not in params[key]

            if 'product' in params:
                assert params['product'] == ['WaterWolf', 'NightTrain']

            return {
                'hits': [{
                    'signature': 'abcdef',
                    'product': 'WaterWolf',
                    'version': '1.0',
                    'email': '*****@*****.**',
                    'exploitability': 'high',
                    'url': 'http://embarassing.website.com',
                    'user_comments': 'hey I am [email protected]',
                }],
                'facets': {
                    'signature': []
                },
                'total':
                0
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('api:model_wrapper', args=('SuperSearch', ))
        response = self.client.get(url)
        assert response.status_code == 200
        res = json.loads(response.content)

        assert res['hits']
        assert res['facets']

        # Verify forbidden fields are not exposed.
        assert 'email' not in res['hits']
        assert 'exploitability' not in res['hits']
        assert 'url' not in res['hits']

        # Verify user comments are scrubbed.
        assert '*****@*****.**' not in res['hits'][0]['user_comments']

        # Verify it's not possible to use restricted parameters.
        response = self.client.get(
            url, {
                'exploitability':
                'high',
                '_facets': ['url', 'email', 'product', '_cardinality.email'],
                '_aggs.signature':
                ['url', 'email', 'product', '_cardinality.email'],
                '_histogram.date':
                ['url', 'email', 'product', '_cardinality.email'],
            })
        assert response.status_code == 200

        # Verify values can be lists.
        response = self.client.get(url,
                                   {'product': ['WaterWolf', 'NightTrain']})
        assert response.status_code == 200
Beispiel #46
0
    def test_NewSignatures(self):
        def mocked_supersearch_get(**params):
            assert params['product'] == [settings.DEFAULT_PRODUCT]

            if 'version' in params:
                assert params['version'] == ['1.0', '2.0']

            if 'signature' not in params:
                # Return a list of signatures.
                signatures = [
                    {
                        'term': 'ba',
                        'count': 21
                    },
                    {
                        'term': 'zin',
                        'count': 19
                    },
                    {
                        'term': 'ga',
                        'count': 1
                    },
                ]
            else:
                # Return only some of the above signatures. The missing ones
                # are "new" signatures.
                signatures = [
                    {
                        'term': 'ga',
                        'count': 21
                    },
                ]

            return {
                'hits': [],
                'facets': {
                    'signature': signatures
                },
                'total': 43829,
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('api:model_wrapper', args=('NewSignatures', ))

        # Test we get expected results.
        response = self.client.get(url)
        assert response.status_code == 200

        res_expected = [
            'ba',
            'zin',
        ]
        res = json.loads(response.content)
        assert res['hits'] == res_expected

        # Test with versions.
        response = self.client.get(url, {'version': ['1.0', '2.0']})
        assert response.status_code == 200

        # Test with incorrect arguments.
        response = self.client.get(
            url, {
                'start_date': 'not a date',
                'end_date': 'not a date',
                'not_after': 'not a date',
            })
        assert response.status_code == 400
        assert response['Content-Type'] == 'application/json; charset=UTF-8'
        res = json.loads(response.content)
        assert 'errors' in res
        assert len(res['errors']) == 3
Beispiel #47
0
    def test_signature_summary(self):

        def mocked_supersearch_get(**params):
            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            ok_('_histogram.uptime' in params)
            ok_('_facets' in params)

            res = {
                "hits": [],
                "total": 4,
                "facets": {
                    "platform_pretty_version": [
                        {
                            "count": 4,
                            "term": "WaterWolf"
                        }
                    ],
                    "cpu_name": [
                        {
                            "count": 4,
                            "term": "x86"
                        }
                    ],
                    "process_type": [
                        {
                            "count": 4,
                            "term": "browser"
                        }
                    ],
                    "flash_version": [
                        {
                            "count": 4,
                            "term": "1.1.1.14"
                        }
                    ],
                    "histogram_uptime": [
                        {
                            "count": 2,
                            "term": 0,
                        },
                        {
                            "count": 2,
                            "term": 60,
                        }
                    ],
                }
            }

            if '_histogram.date' in params:
                res['facets']['histogram_date'] = [
                    {
                        "count": 2,
                        "term": "2015-08-05T00:00:00+00:00",
                        "facets": {
                            "exploitability": [
                                {
                                    "count": 2,
                                    "term": "high"
                                }
                            ]
                        }
                    },
                    {
                        "count": 2,
                        "term": "2015-08-06T00:00:00+00:00",
                        "facets": {
                            "exploitability": [
                                {
                                    "count": 2,
                                    "term": "low"
                                }
                            ]
                        }
                    }
                ]

            return res

        SuperSearch.implementation().get.side_effect = (
            mocked_supersearch_get
        )

        # Test with no results
        url = reverse('signature:signature_summary')

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)

        # Make sure all boxes are there.
        ok_('Operating System' in response.content)
        ok_('Uptime Range' in response.content)
        ok_('Architecture' in response.content)
        ok_('Process Type' in response.content)
        ok_('Flash&trade; Version' in response.content)

        # Logged out users can't see no exploitability
        ok_('Exploitability' not in response.content)

        # Check that some of the expected values are there.
        ok_('WaterWolf' in response.content)
        ok_('x86' in response.content)
        ok_('browser' in response.content)
        ok_('1.1.1.14' in response.content)
        ok_('&lt; 1 min' in response.content)
        ok_('1-5 min' in response.content)

        user = self._login()

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)

        # Logged in users without the permission can't see no exploitability
        ok_('Exploitability' not in response.content)

        group = self._create_group_with_permission('view_exploitability')
        user.groups.add(group)
        assert user.has_perm('crashstats.view_exploitability')

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)

        # Logged in users with the permission can see exploitability
        ok_('Exploitability' in response.content)
Beispiel #48
0
    def test_graphics_report(self):
        def mocked_supersearch_get(**params):
            assert params['product'] == [settings.DEFAULT_PRODUCT]
            hits = [
                {
                    'signature': 'my signature',
                    'date': '2015-10-08T23:22:21.1234 +00:00',
                    'cpu_name': 'arm',
                    'cpu_info': 'ARMv7 ARM',
                },
                {
                    'signature': 'other signature',
                    'date': '2015-10-08T13:12:11.1123 +00:00',
                    'cpu_info': 'something',
                    # note! no cpu_name
                },
            ]
            # Value for each of these needs to be in there
            # supplement missing ones from the fixtures we intend to return.
            for hit in hits:
                for head in GRAPHICS_REPORT_HEADER:
                    if head not in hit:
                        hit[head] = None
            return {'hits': hits, 'total': 2}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('graphics:report')

        # viewing this report requires that you're signed in
        response = self.client.get(url)
        assert response.status_code == 403

        # But being signed in isn't good enough, you need the right
        # permissions too.
        user = self._login()
        response = self.client.get(url)
        assert response.status_code == 403

        # Add the user to the Hackers group which has run_long_queries
        # permission
        group = Group.objects.get(name='Hackers')
        user.groups.add(group)

        # But even with the right permissions you still need to
        # provide the right minimal parameters.
        response = self.client.get(url)
        assert response.status_code == 400

        # Let's finally get it right. Permission AND the date parameter.
        data = {'date': datetime.datetime.utcnow().date()}
        response = self.client.get(url, data)
        assert response.status_code == 200
        assert response['Content-Type'] == 'text/csv'
        assert response['Content-Length'] == str(len(response.content))

        # the response content should be parseable
        length = len(response.content)
        inp = StringIO(response.content)
        reader = csv.reader(inp, delimiter='\t')
        lines = list(reader)
        assert len(lines) == 3
        header = lines[0]
        assert header == list(GRAPHICS_REPORT_HEADER)
        first = lines[1]
        assert first[GRAPHICS_REPORT_HEADER.index(
            'signature')] == 'my signature'
        assert first[GRAPHICS_REPORT_HEADER.index(
            'date_processed')] == '201510082322'

        # now fetch it with gzip
        response = self.client.get(url, data, HTTP_ACCEPT_ENCODING='gzip')
        assert response.status_code == 200
        assert response['Content-Type'] == 'text/csv'
        assert response['Content-Length'] == str(len(response.content))
        assert response['Content-Encoding'] == 'gzip'
        assert len(response.content) < length
Beispiel #49
0
    def test_signature_reports(self):
        def mocked_supersearch_get(**params):
            assert '_columns' in params

            ok_('uuid' in params['_columns'])

            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            if 'product' in params:
                results = {
                    "hits": [{
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa1",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "build_id": 888981
                    }, {
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa2",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "build_id": 888981
                    }, {
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa3",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "build_id": None
                    }, {
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa4",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "build_id": None
                    }],
                    "total":
                    4
                }
                results['hits'] = self.only_certain_columns(
                    results['hits'], params['_columns'])
                return results

            return {"hits": [], "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_reports')

        # Test with no results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'date': '2012-01-01',
        })
        eq_(response.status_code, 200)
        ok_('table id="reports-list"' not in response.content)
        ok_('No results were found' in response.content)

        # Test with results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'product': 'WaterWolf'
        })
        eq_(response.status_code, 200)
        ok_('table id="reports-list"' in response.content)
        ok_('aaaaaaaaaaaaa1' in response.content)
        ok_('888981' in response.content)
        ok_('Linux' in response.content)
        ok_('2017-01-31 23:12:57' in response.content)

        # Test with a different columns list.
        response = self.client.get(
            url, {
                'signature': DUMB_SIGNATURE,
                'product': 'WaterWolf',
                '_columns': ['build_id', 'platform'],
            })
        eq_(response.status_code, 200)
        ok_('table id="reports-list"' in response.content)
        # The build and platform appear
        ok_('888981' in response.content)
        ok_('Linux' in response.content)
        # The crash id is always shown
        ok_('aaaaaaaaaaaaa1' in response.content)
        # The version and date do not appear
        ok_('1.0' not in response.content)
        ok_('2017' not in response.content)

        # Test missing parameter.
        response = self.client.get(url)
        eq_(response.status_code, 400)

        response = self.client.get(url, {
            'signature': '',
        })
        eq_(response.status_code, 400)
Beispiel #50
0
    def test_NewSignatures(self):
        def mocked_supersearch_get(**params):
            assert params["product"] == [settings.DEFAULT_PRODUCT]

            if "version" in params:
                assert params["version"] == ["1.0", "2.0"]

            if "signature" not in params:
                # Return a list of signatures.
                signatures = [
                    {
                        "term": "ba",
                        "count": 21
                    },
                    {
                        "term": "zin",
                        "count": 19
                    },
                    {
                        "term": "ga",
                        "count": 1
                    },
                ]
            else:
                # Return only some of the above signatures. The missing ones
                # are "new" signatures.
                signatures = [{"term": "ga", "count": 21}]

            return {
                "hits": [],
                "facets": {
                    "signature": signatures
                },
                "total": 43829
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse("api:model_wrapper", args=("NewSignatures", ))

        # Test we get expected results.
        response = self.client.get(url)
        assert response.status_code == 200

        res_expected = ["ba", "zin"]
        res = json.loads(response.content)
        assert res["hits"] == res_expected

        # Test with versions.
        response = self.client.get(url, {"version": ["1.0", "2.0"]})
        assert response.status_code == 200

        # Test with incorrect arguments.
        response = self.client.get(
            url,
            {
                "start_date": "not a date",
                "end_date": "not a date",
                "not_after": "not a date",
            },
        )
        assert response.status_code == 400
        assert response["Content-Type"] == "application/json; charset=UTF-8"
        res = json.loads(response.content)
        assert "errors" in res
        assert len(res["errors"]) == 3
Beispiel #51
0
    def test_signature_reports(self):

        def mocked_supersearch_get(**params):
            assert '_columns' in params

            ok_('uuid' in params['_columns'])

            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            if 'product' in params:
                results = {
                    "hits": [
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa1",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "build_id": 888981
                        },
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa2",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "build_id": 888981
                        },
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa3",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "build_id": None
                        },
                        {
                            "date": "2017-01-31T23:12:57",
                            "uuid": "aaaaaaaaaaaaa4",
                            "product": "WaterWolf",
                            "version": "1.0",
                            "platform": "Linux",
                            "build_id": None
                        }
                    ],
                    "total": 4
                }
                results['hits'] = self.only_certain_columns(
                    results['hits'],
                    params['_columns']
                )
                return results

            return {"hits": [], "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_reports')

        # Test with no results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'date': '2012-01-01',
        })
        eq_(response.status_code, 200)
        ok_('table id="reports-list"' not in response.content)
        ok_('No results were found' in response.content)

        # Test with results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'product': 'WaterWolf'
        })
        eq_(response.status_code, 200)
        ok_('table id="reports-list"' in response.content)
        ok_('aaaaaaaaaaaaa1' in response.content)
        ok_('888981' in response.content)
        ok_('Linux' in response.content)
        ok_('2017-01-31 23:12:57' in response.content)

        # Test with a different columns list.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'product': 'WaterWolf',
            '_columns': ['build_id', 'platform'],
        })
        eq_(response.status_code, 200)
        ok_('table id="reports-list"' in response.content)
        # The build and platform appear
        ok_('888981' in response.content)
        ok_('Linux' in response.content)
        # The crash id is always shown
        ok_('aaaaaaaaaaaaa1' in response.content)
        # The version and date do not appear
        ok_('1.0' not in response.content)
        ok_('2017' not in response.content)

        # Test missing parameter.
        response = self.client.get(url)
        eq_(response.status_code, 400)

        response = self.client.get(url, {
            'signature': '',
        })
        eq_(response.status_code, 400)
Beispiel #52
0
def graphics_report(request):
    """Return a CSV output of all crashes for a specific date for a
    particular day and a particular product."""
    if (not request.user.is_active
            or not request.user.has_perm('crashstats.run_long_queries')):
        return http.HttpResponseForbidden(
            "You must have the 'Run long queries' permission")
    form = forms.GraphicsReportForm(request.GET, )
    if not form.is_valid():
        return http.HttpResponseBadRequest(str(form.errors))

    batch_size = 1000
    product = form.cleaned_data['product'] or settings.DEFAULT_PRODUCT
    date = form.cleaned_data['date']
    params = {
        'product':
        product,
        'date': [
            '>={}'.format(date.strftime('%Y-%m-%d')), '<{}'.format(
                (date + datetime.timedelta(days=1)).strftime('%Y-%m-%d'))
        ],
        '_columns': (
            'signature',
            'uuid',
            'date',
            'product',
            'version',
            'build_id',
            'platform',
            'platform_version',
            'cpu_name',
            'cpu_info',
            'address',
            'uptime',
            'topmost_filenames',
            'reason',
            'app_notes',
            'release_channel',
        ),
        '_results_number':
        batch_size,
        '_results_offset':
        0,
    }
    api = SuperSearch()
    # Do the first query. That'll give us the total and the first page's
    # worth of crashes.
    data = api.get(**params)
    assert 'hits' in data

    accept_gzip = 'gzip' in request.META.get('HTTP_ACCEPT_ENCODING', '')
    response = http.HttpResponse(content_type='text/csv')
    out = BytesIO()
    writer = utils.UnicodeWriter(out, delimiter='\t')
    writer.writerow(GRAPHICS_REPORT_HEADER)
    pages = data['total'] // batch_size
    # if there is a remainder, add one more page
    if data['total'] % batch_size:
        pages += 1
    alias = {
        'crash_id': 'uuid',
        'os_name': 'platform',
        'os_version': 'platform_version',
        'date_processed': 'date',
        'build': 'build_id',
        'uptime_seconds': 'uptime',
    }
    # Make sure that we don't have an alias for a header we don't need
    alias_excess = set(alias.keys()) - set(GRAPHICS_REPORT_HEADER)
    if alias_excess:
        raise ValueError('Not all keys in the map of aliases are in '
                         'the header ({!r})'.format(alias_excess))

    def get_value(row, key):
        """Return the appropriate output from the row of data, one key
        at a time. The output is what's used in writing the CSV file.

        The reason for doing these "hacks" is to match what used to be
        done with the SELECT statement in SQL in the ancient, but now
        replaced, report.
        """
        value = row.get(alias.get(key, key))
        if key == 'cpu_info':
            value = '{cpu_name} | {cpu_info}'.format(
                cpu_name=row.get('cpu_name', ''),
                cpu_info=row.get('cpu_info', ''),
            )
        if value is None:
            return ''
        if key == 'date_processed':
            value = timezone.make_aware(
                datetime.datetime.strptime(
                    value.split('.')[0], '%Y-%m-%dT%H:%M:%S'))
            value = value.strftime('%Y%m%d%H%M')
        if key == 'uptime_seconds' and value == 0:
            value = ''
        return value

    for page in range(pages):
        if page > 0:
            params['_results_offset'] = batch_size * page
            data = api.get(**params)

        for row in data['hits']:
            # Each row is a dict, we want to turn it into a list of
            # exact order as the `header` tuple above.
            # However, because the csv writer module doesn't "understand"
            # python's None, we'll replace those with '' to make the
            # CSV not have the word 'None' where the data is None.
            writer.writerow(
                [get_value(row, x) for x in GRAPHICS_REPORT_HEADER])

    payload = out.getvalue()
    if accept_gzip:
        zbuffer = BytesIO()
        zfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=zbuffer)
        zfile.write(payload)
        zfile.close()
        compressed_payload = zbuffer.getvalue()
        response.write(compressed_payload)
        response['Content-Length'] = len(compressed_payload)
        response['Content-Encoding'] = 'gzip'
    else:
        response.write(payload)
        response['Content-Length'] = len(payload)
    return response
Beispiel #53
0
    def test_signature_graphs(self):
        def mocked_supersearch_get(**params):
            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            ok_('_histogram.date' in params)
            ok_('_facets' in params)

            if 'product' in params['_facets']:
                return {
                    "hits": [],
                    "total": 4,
                    "facets": {
                        "product": [{
                            "count": 4,
                            "term": "WaterWolf"
                        }],
                        "histogram_date": [{
                            "count": 2,
                            "term": "2015-08-05T00:00:00+00:00",
                            "facets": {
                                "product": [{
                                    "count": 2,
                                    "term": "WaterWolf"
                                }]
                            }
                        }, {
                            "count": 2,
                            "term": "2015-08-06T00:00:00+00:00",
                            "facets": {
                                "product": [{
                                    "count": 2,
                                    "term": "WaterWolf"
                                }]
                            }
                        }]
                    }
                }

            return {
                "hits": [],
                "total": 0,
                "facets": {
                    "platform": [],
                    "signature": [],
                    "histogram_date": []
                }
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        # Test with no results
        url = reverse('signature:signature_graphs', args=('platform', ))

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('application/json' in response['content-type'])
        struct = json.loads(response.content)
        ok_('aggregates' in struct)
        eq_(len(struct['aggregates']), 0)
        ok_('term_counts' in struct)
        eq_(len(struct['term_counts']), 0)

        # Test with results
        url = reverse('signature:signature_graphs', args=('product', ))

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('application/json' in response['content-type'])
        struct = json.loads(response.content)
        ok_('aggregates' in struct)
        eq_(len(struct['aggregates']), 2)
        ok_('term_counts' in struct)
        eq_(len(struct['term_counts']), 1)
Beispiel #54
0
    def test_SuperSearch(self):
        def mocked_supersearch_get(**params):
            assert 'exploitability' not in params

            restricted_params = (
                '_facets',
                '_aggs.signature',
                '_histogram.date',
            )
            for key in restricted_params:
                if key in params:
                    assert 'url' not in params[key]
                    assert 'email' not in params[key]
                    assert '_cardinality.email' not in params[key]

            if 'product' in params:
                assert params['product'] == ['WaterWolf', 'NightTrain']

            return {
                'hits': [
                    {
                        'signature': 'abcdef',
                        'product': 'WaterWolf',
                        'version': '1.0',
                        'email': '*****@*****.**',
                        'exploitability': 'high',
                        'url': 'http://embarassing.website.com',
                        'user_comments': 'hey I am [email protected]',
                    }
                ],
                'facets': {
                    'signature': []
                },
                'total': 0
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('api:model_wrapper', args=('SuperSearch',))
        response = self.client.get(url)
        assert response.status_code == 200
        res = json.loads(response.content)

        assert res['hits']
        assert res['facets']

        # Verify forbidden fields are not exposed.
        assert 'email' not in res['hits']
        assert 'exploitability' not in res['hits']
        assert 'url' not in res['hits']

        # Verify it's not possible to use restricted parameters.
        response = self.client.get(url, {
            'exploitability': 'high',
            '_facets': ['url', 'email', 'product', '_cardinality.email'],
            '_aggs.signature': [
                'url', 'email', 'product', '_cardinality.email'
            ],
            '_histogram.date': [
                'url', 'email', 'product', '_cardinality.email'
            ],
        })
        assert response.status_code == 200

        # Verify values can be lists.
        response = self.client.get(url, {
            'product': ['WaterWolf', 'NightTrain']
        })
        assert response.status_code == 200
Beispiel #55
0
    def test_NewSignatures(self):
        def mocked_supersearch_get(**params):
            assert params['product'] == [settings.DEFAULT_PRODUCT]

            if 'version' in params:
                assert params['version'] == ['1.0', '2.0']

            if 'signature' not in params:
                # Return a list of signatures.
                signatures = [
                    {'term': 'ba', 'count': 21},
                    {'term': 'zin', 'count': 19},
                    {'term': 'ga', 'count': 1},
                ]
            else:
                # Return only some of the above signatures. The missing ones
                # are "new" signatures.
                signatures = [
                    {'term': 'ga', 'count': 21},
                ]

            return {
                'hits': [],
                'facets': {
                    'signature': signatures
                },
                'total': 43829,
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('api:model_wrapper', args=('NewSignatures',))

        # Test we get expected results.
        response = self.client.get(url)
        assert response.status_code == 200

        res_expected = [
            'ba',
            'zin',
        ]
        res = json.loads(response.content)
        assert res['hits'] == res_expected

        # Test with versions.
        response = self.client.get(url, {
            'version': ['1.0', '2.0']
        })
        assert response.status_code == 200

        # Test with incorrect arguments.
        response = self.client.get(url, {
            'start_date': 'not a date',
            'end_date': 'not a date',
            'not_after': 'not a date',
        })
        assert response.status_code == 400
        assert response['Content-Type'] == 'application/json; charset=UTF-8'
        res = json.loads(response.content)
        assert 'errors' in res
        assert len(res['errors']) == 3
Beispiel #56
0
    def test_signature_comments(self):
        def mocked_supersearch_get(**params):
            assert '_columns' in params

            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            ok_('user_comments' in params)
            eq_(params['user_comments'], ['!__null__'])

            if 'product' in params:
                results = {
                    "hits": [{
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa1",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "user_comments": "hello there people!",
                        "useragent_locale": "locale1"
                    }, {
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa2",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "user_comments": "I love Mozilla",
                        "useragent_locale": "locale2"
                    }, {
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa3",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "user_comments": "this product is awesome",
                        "useragent_locale": "locale3"
                    }, {
                        "date": "2017-01-31T23:12:57",
                        "uuid": "aaaaaaaaaaaaa4",
                        "product": "WaterWolf",
                        "version": "1.0",
                        "platform": "Linux",
                        "user_comments": "WaterWolf Y U SO GOOD?",
                        "useragent_locale": "locale4"
                    }],
                    "total":
                    4
                }
                results['hits'] = self.only_certain_columns(
                    results['hits'], params['_columns'])
                return results

            return {"hits": [], "total": 0}

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse('signature:signature_comments')

        # Test with no results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
        })
        eq_(response.status_code, 200)
        ok_('Crash ID' not in response.content)
        ok_('No comments were found' in response.content)

        # Test with results.
        response = self.client.get(url, {
            'signature': DUMB_SIGNATURE,
            'product': 'WaterWolf'
        })
        eq_(response.status_code, 200)
        ok_('aaaaaaaaaaaaa1' in response.content)
        ok_('Crash ID' in response.content)
        ok_('hello there' in response.content)
        ok_('WaterWolf Y U SO GOOD' in response.content)
        ok_('locale1' in response.content)
Beispiel #57
0
    def test_SuperSearch(self):
        def mocked_supersearch_get(**params):
            assert "exploitability" not in params

            restricted_params = ("_facets", "_aggs.signature",
                                 "_histogram.date")
            for key in restricted_params:
                if key in params:
                    assert "url" not in params[key]
                    assert "email" not in params[key]
                    assert "_cardinality.email" not in params[key]

            if "product" in params:
                assert params["product"] == ["WaterWolf", "NightTrain"]

            return {
                "hits": [{
                    "signature": "abcdef",
                    "product": "WaterWolf",
                    "version": "1.0",
                    "email": "*****@*****.**",
                    "exploitability": "high",
                    "url": "http://embarassing.website.com",
                    "user_comments": "hey I am [email protected]",
                }],
                "facets": {
                    "signature": []
                },
                "total":
                0,
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        url = reverse("api:model_wrapper", args=("SuperSearch", ))
        response = self.client.get(url)
        assert response.status_code == 200
        res = json.loads(response.content)

        assert res["hits"]
        assert res["facets"]

        # Verify forbidden fields are not exposed.
        assert "email" not in res["hits"]
        assert "exploitability" not in res["hits"]
        assert "url" not in res["hits"]

        # Verify it's not possible to use restricted parameters.
        response = self.client.get(
            url,
            {
                "exploitability":
                "high",
                "_facets": ["url", "email", "product", "_cardinality.email"],
                "_aggs.signature":
                ["url", "email", "product", "_cardinality.email"],
                "_histogram.date":
                ["url", "email", "product", "_cardinality.email"],
            },
        )
        assert response.status_code == 200

        # Verify values can be lists.
        response = self.client.get(url,
                                   {"product": ["WaterWolf", "NightTrain"]})
        assert response.status_code == 200
Beispiel #58
0
    def test_signature_aggregation(self):

        def mocked_supersearch_get(**params):
            ok_('signature' in params)
            eq_(params['signature'], ['=' + DUMB_SIGNATURE])

            ok_('_facets' in params)

            if 'product' in params['_facets']:
                return {
                    "hits": [],
                    "facets": {
                        "product": [
                            {
                                "term": "windows",
                                "count": 42,
                            },
                            {
                                "term": "linux",
                                "count": 1337,
                            },
                            {
                                "term": "mac",
                                "count": 3,
                            },
                        ]
                    },
                    "total": 1382
                }

            # the default
            return {
                "hits": [],
                "facets": {
                    "platform": []
                },
                "total": 0
            }

        SuperSearch.implementation().get.side_effect = mocked_supersearch_get

        # Test with no results.
        url = reverse(
            'signature:signature_aggregation',
            args=('platform',)
        )

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('Product' not in response.content)
        ok_('No results were found' in response.content)

        # Test with results.
        url = reverse(
            'signature:signature_aggregation',
            args=('product',)
        )

        response = self.client.get(url, {'signature': DUMB_SIGNATURE})
        eq_(response.status_code, 200)
        ok_('Product' in response.content)
        ok_('1337' in response.content)
        ok_('linux' in response.content)
        ok_(str(1337 / 1382 * 100) in response.content)
        ok_('windows' in response.content)
        ok_('mac' in response.content)