def test_find_nodes_cached(self, http_request, cache_get):
      finder = RemoteFinder('127.0.0.1')

      startTime = 1496262000
      endTime   = 1496262060

      data = [
        {
          'path': 'a.b.c',
          'is_leaf': False,
        },
        {
          'path': 'a.b.c.d',
          'is_leaf': True,
        },
      ]
      cache_get.return_value = data

      query = FindQuery('a.b.c', startTime, endTime)
      nodes = finder.find_nodes(query)

      self.assertEqual(http_request.call_count, 0)

      self.assertEqual(cache_get.call_count, 1)
      self.assertEqual(cache_get.call_args[0], (
        'find:127.0.0.1:553f764f7b436175c0387e22b4a19213:1496262000:1496262000',
      ))

      self.assertEqual(len(nodes), 2)

      self.assertIsInstance(nodes[0], BranchNode)
      self.assertEqual(nodes[0].path, 'a.b.c')

      self.assertIsInstance(nodes[1], LeafNode)
      self.assertEqual(nodes[1].path, 'a.b.c.d')
    def test_find_nodes_cached(self, http_request, cache_get):
      finder = RemoteFinder('127.0.0.1')

      startTime = 1496262000
      endTime   = 1496262060

      data = [
        {
          'path': 'a.b.c',
          'is_leaf': False,
        },
        {
          'path': 'a.b.c.d',
          'is_leaf': True,
        },
      ]
      cache_get.return_value = data

      query = FindQuery('a.b.c', startTime, endTime)
      nodes = finder.find_nodes(query)

      self.assertEqual(http_request.call_count, 0)

      self.assertEqual(cache_get.call_count, 1)
      self.assertEqual(cache_get.call_args[0], (
        'find:127.0.0.1:553f764f7b436175c0387e22b4a19213:1496262000:1496262000',
      ))

      self.assertEqual(len(nodes), 2)

      self.assertIsInstance(nodes[0], BranchNode)
      self.assertEqual(nodes[0].path, 'a.b.c')

      self.assertIsInstance(nodes[1], LeafNode)
      self.assertEqual(nodes[1].path, 'a.b.c.d')
    def test_remote_stores(self):
        # Save settings
        old_cluster_servers = settings.CLUSTER_SERVERS
        old_remote_exclude_local = settings.REMOTE_EXCLUDE_LOCAL

        # Set test cluster servers
        settings.CLUSTER_SERVERS = ['127.0.0.1', '8.8.8.8']

        # Test REMOTE_EXCLUDE_LOCAL = False
        settings.REMOTE_EXCLUDE_LOCAL = False
        test_finder = RemoteFinder()
        remote_hosts = [
            remote_store.host for remote_store in test_finder.remote_stores
        ]
        self.assertTrue('127.0.0.1' in remote_hosts)
        self.assertTrue('8.8.8.8' in remote_hosts)

        # Test REMOTE_EXCLUDE_LOCAL = True
        settings.REMOTE_EXCLUDE_LOCAL = True
        test_finder = RemoteFinder()
        remote_hosts = [
            remote_store.host for remote_store in test_finder.remote_stores
        ]
        self.assertTrue('127.0.0.1' not in remote_hosts)
        self.assertTrue('8.8.8.8' in remote_hosts)

        # Restore original settings
        settings.CLUSTER_SERVERS = old_cluster_servers
        settings.REMOTE_EXCLUDE_LOCAL = old_remote_exclude_local
    def test_remote_stores(self):
      # Test REMOTE_EXCLUDE_LOCAL = False
      with self.settings(REMOTE_EXCLUDE_LOCAL=False):
        test_finders = RemoteFinder.factory()
        remote_hosts = [finder.host for finder in test_finders]
        self.assertTrue('127.0.0.1' in remote_hosts)
        self.assertTrue('8.8.8.8' in remote_hosts)

      # Test REMOTE_EXCLUDE_LOCAL = True
      with self.settings(REMOTE_EXCLUDE_LOCAL=True):
        test_finders = RemoteFinder.factory()
        remote_hosts = [finder.host for finder in test_finders]
        self.assertTrue('127.0.0.1' not in remote_hosts)
        self.assertTrue('8.8.8.8' in remote_hosts)
Beispiel #5
0
    def test_remote_stores(self):
        # Test REMOTE_EXCLUDE_LOCAL = False
        with self.settings(REMOTE_EXCLUDE_LOCAL=False):
            test_finders = RemoteFinder.factory()
            remote_hosts = [finder.host for finder in test_finders]
            self.assertTrue('127.0.0.1' in remote_hosts)
            self.assertTrue('8.8.8.8' in remote_hosts)

        # Test REMOTE_EXCLUDE_LOCAL = True
        with self.settings(REMOTE_EXCLUDE_LOCAL=True):
            test_finders = RemoteFinder.factory()
            remote_hosts = [finder.host for finder in test_finders]
            self.assertTrue('127.0.0.1' not in remote_hosts)
            self.assertTrue('8.8.8.8' in remote_hosts)
    def test_fail(self):
      finder = RemoteFinder('127.0.0.1')

      self.assertEqual(finder.last_failure, 0)
      self.assertFalse(finder.disabled)

      with patch('graphite.finders.remote.time.time', lambda: 100):
        finder.fail()
        self.assertEqual(finder.last_failure, 100)
        self.assertTrue(finder.disabled)

      with patch('graphite.finders.remote.time.time', lambda: 109):
        self.assertTrue(finder.disabled)

      with patch('graphite.finders.remote.time.time', lambda: 110):
        self.assertFalse(finder.disabled)
Beispiel #7
0
    def test_fail(self):
        finder = RemoteFinder('127.0.0.1')

        self.assertEqual(finder.last_failure, 0)
        self.assertFalse(finder.disabled)

        with patch('graphite.finders.remote.time.time', lambda: 100):
            finder.fail()
            self.assertEqual(finder.last_failure, 100)
            self.assertTrue(finder.disabled)

        with patch('graphite.finders.remote.time.time', lambda: 109):
            self.assertTrue(finder.disabled)

        with patch('graphite.finders.remote.time.time', lambda: 110):
            self.assertFalse(finder.disabled)
 def test_RemoteReader_get_intervals(self):
     test_finder = RemoteFinder()
     finder = test_finder.remote_stores[0]
     reader = RemoteReader(finder,
                           {'intervals': []},
                           bulk_query='a.b.c.d')
     self.assertEqual(reader.get_intervals(), [])
Beispiel #9
0
    def test_RemoteReader_fetch(self, http_request):
        test_finders = RemoteFinder.factory()
        finder = test_finders[0]

        startTime = 1496262000
        endTime = 1496262060

        # no path or bulk_query
        reader = RemoteReader(finder, {})
        self.assertEqual(reader.bulk_query, [])
        result = reader.fetch(startTime, endTime)
        self.assertEqual(result, None)
        self.assertEqual(http_request.call_count, 0)

        # path & bulk_query
        reader = RemoteReader(finder, {
            'intervals': [],
            'path': 'a.b.c.d'
        },
                              bulk_query=['a.b.c.*'])

        data = [{
            'start': startTime,
            'step': 60,
            'end': endTime,
            'values': [1.0, 0.0, 1.0, 0.0, 1.0],
            'name': 'a.b.c.c'
        }, {
            'start': startTime,
            'step': 60,
            'end': endTime,
            'values': [1.0, 0.0, 1.0, 0.0, 1.0],
            'name': 'a.b.c.d'
        }]
        responseObject = HTTPResponse(body=StringIO(pickle.dumps(data)),
                                      status=200)
        http_request.return_value = responseObject
        result = reader.fetch(startTime, endTime)
        expected_response = ((1496262000, 1496262060, 60),
                             [1.0, 0.0, 1.0, 0.0, 1.0])
        self.assertEqual(result, expected_response)
        self.assertEqual(http_request.call_args[0], (
            'GET',
            'http://127.0.0.1/render/',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('format', 'pickle'),
                    ('local', '1'),
                    ('noCache', '1'),
                    ('from', startTime),
                    ('until', endTime),
                    ('target', 'a.b.c.*'),
                ],
                'headers':
                None,
                'timeout':
                10,
            })
    def test_get_index(self, http_request):
        finder = RemoteFinder('127.0.0.1')

        data = [
            'a.b.c',
            'a.b.c.d',
        ]
        responseObject = HTTPResponse(body=BytesIO(
            json.dumps(data).encode('utf-8')),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        result = finder.get_index({})

        self.assertIsInstance(result, list)

        self.assertEqual(http_request.call_args[0], (
            'POST',
            'http://127.0.0.1/metrics/index.json',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('local', '1'),
                ],
                'headers': None,
                'preload_content': False,
                'timeout': 10,
            })

        self.assertEqual(len(result), 2)

        self.assertEqual(result[0], 'a.b.c')
        self.assertEqual(result[1], 'a.b.c.d')

        # non-json response
        responseObject = HTTPResponse(body=BytesIO(b'error'),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        with self.assertRaisesRegexp(
                Exception,
                'Error decoding index response from http://[^ ]+: .+'):
            result = finder.get_index({})
Beispiel #11
0
    def test_RemoteReader_init(self):
        test_finder = RemoteFinder()
        finder = test_finder.remote_stores[0]
        reader = RemoteReader(finder,
                              {'intervals': []},
                              bulk_query='a.b.c.d')

        self.assertIsNotNone(reader)
Beispiel #12
0
    def test_RemoteReader_repr(self):
        test_finder = RemoteFinder()
        finder = test_finder.remote_stores[0]
        reader = RemoteReader(finder,
                              {'intervals': []},
                              bulk_query='a.b.c.d')

        self.assertIsNotNone(reader)
        self.assertRegexpMatches(str(reader), "<RemoteReader\[.*\]: 127.0.0.1>")
Beispiel #13
0
    def test_RemoteReader_fetch_list_empty_bulk_query(self):
        test_finder = RemoteFinder()
        finder = test_finder.remote_stores[0]
        reader = RemoteReader(finder,
                              {'intervals': []},
                              bulk_query='')
        startTime = 1496262000
        endTime   = 1496262060

        ret = reader.fetch_list(startTime, endTime)
        self.assertEqual(ret, [])
    def test_RemoteReader_fetch(self, http_request):
        test_finders = RemoteFinder.factory()
        finder = test_finders[0]

        startTime = 1496262000
        endTime   = 1496262060

        # no path or bulk_query
        reader = RemoteReader(finder,{})
        self.assertEqual(reader.bulk_query, [])
        result = reader.fetch(startTime, endTime)
        self.assertEqual(result, None)
        self.assertEqual(http_request.call_count, 0)

        # path & bulk_query
        reader = RemoteReader(finder, {'intervals': [], 'path': 'a.b.c.d'}, bulk_query=['a.b.c.*'])

        data = [
                {'start': startTime,
                 'step': 60,
                 'end': endTime,
                 'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                 'name': 'a.b.c.c'
                },
                {'start': startTime,
                 'step': 60,
                 'end': endTime,
                 'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                 'name': 'a.b.c.d'
                }
               ]
        responseObject = HTTPResponse(body=BytesIO(pickle.dumps(data)), status=200, preload_content=False)
        http_request.return_value = responseObject
        result = reader.fetch(startTime, endTime)
        expected_response = ((1496262000, 1496262060, 60), [1.0, 0.0, 1.0, 0.0, 1.0])
        self.assertEqual(result, expected_response)
        self.assertEqual(http_request.call_args[0], (
          'GET',
          'http://127.0.0.1/render/',
        ))
        self.assertEqual(http_request.call_args[1], {
          'fields': [
            ('format', 'pickle'),
            ('local', '1'),
            ('noCache', '1'),
            ('from', startTime),
            ('until', endTime),
            ('target', 'a.b.c.*'),
          ],
          'headers': None,
          'preload_content': False,
          'timeout': 10,
        })
    def test_RemoteFinder_fetch(self, http_request):
        test_finders = RemoteFinder.factory()
        finder = test_finders[0]
        startTime = 1496262000
        endTime = 1496262060

        data = [
            {
                'start': startTime,
                'step': 60,
                'end': endTime,
                'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                'name': 'a.b.c.d',
            },
        ]
        responseObject = HTTPResponse(body=BytesIO(pickle.dumps(data)),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        result = finder.fetch(['a.b.c.d'], startTime, endTime)
        expected_response = [
            {
                'pathExpression': 'a.b.c.d',
                'name': 'a.b.c.d',
                'time_info': (1496262000, 1496262060, 60),
                'values': [1.0, 0.0, 1.0, 0.0, 1.0],
            },
        ]
        self.assertEqual(result, expected_response)
        self.assertEqual(http_request.call_args[0], (
            'POST',
            'https://127.0.0.1/render/',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('format', 'pickle'),
                    ('local', '1'),
                    ('noCache', '1'),
                    ('from', startTime),
                    ('until', endTime),
                    ('target', 'a.b.c.d'),
                ],
                'headers':
                None,
                'preload_content':
                False,
                'timeout':
                10,
            })
    def test_get_index(self, http_request):
      finder = RemoteFinder('127.0.0.1')

      data = [
        'a.b.c',
        'a.b.c.d',
      ]
      responseObject = HTTPResponse(body=BytesIO(json.dumps(data).encode('utf-8')), status=200, preload_content=False)
      http_request.return_value = responseObject

      result = finder.get_index({})

      self.assertIsInstance(result, list)

      self.assertEqual(http_request.call_args[0], (
        'POST',
        'http://127.0.0.1/metrics/index.json',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('local', '1'),
        ],
        'headers': None,
        'preload_content': False,
        'timeout': 10,
      })

      self.assertEqual(len(result), 2)

      self.assertEqual(result[0], 'a.b.c')
      self.assertEqual(result[1], 'a.b.c.d')

      # non-json response
      responseObject = HTTPResponse(body=BytesIO(b'error'), status=200, preload_content=False)
      http_request.return_value = responseObject

      with self.assertRaisesRegexp(Exception, 'Error decoding index response from http://[^ ]+: .+'):
        result = finder.get_index({})
    def test_RemoteReader_init_repr_get_intervals(self):
        finders = RemoteFinder.factory()
        self.assertEqual(len(finders), 2)
        self.assertEqual(finders[0].host, '127.0.0.1')
        self.assertEqual(finders[1].host, '8.8.8.8')

        finder = finders[0]
        reader = RemoteReader(finder, {'intervals': []},
                              bulk_query=['a.b.c.d'])

        self.assertIsNotNone(reader)
        self.assertRegexpMatches(str(reader),
                                 "<RemoteReader\[.*\]: 127.0.0.1 a.b.c.d>")
        self.assertEqual(reader.get_intervals(), [])
    def test_RemoteReader_init_repr_get_intervals(self):
        finders = RemoteFinder.factory()
        self.assertEqual(len(finders), 2)
        self.assertEqual(finders[0].host, '127.0.0.1')
        self.assertEqual(finders[1].host, '8.8.8.8')

        finder = finders[0]
        reader = RemoteReader(finder,
                              {'intervals': []},
                              bulk_query=['a.b.c.d'])

        self.assertIsNotNone(reader)
        self.assertRegexpMatches(str(reader), "<RemoteReader\[.*\]: 127.0.0.1 a.b.c.d>")
        self.assertEqual(reader.get_intervals(), [])
    def test_RemoteFinder_fetch(self, http_request):
      test_finders = RemoteFinder.factory()
      finder = test_finders[0]
      startTime = 1496262000
      endTime   = 1496262060

      data = [
        {
          'start': startTime,
          'step': 60,
          'end': endTime,
          'values': [1.0, 0.0, 1.0, 0.0, 1.0],
          'name': 'a.b.c.d',
        },
      ]
      responseObject = HTTPResponse(body=BytesIO(pickle.dumps(data)), status=200, preload_content=False)
      http_request.return_value = responseObject

      result = finder.fetch(['a.b.c.d'], startTime, endTime)
      expected_response = [
        {
          'pathExpression': 'a.b.c.d',
          'name': 'a.b.c.d',
          'time_info': (1496262000, 1496262060, 60),
          'values': [1.0, 0.0, 1.0, 0.0, 1.0],
        },
      ]
      self.assertEqual(result, expected_response)
      self.assertEqual(http_request.call_args[0], (
        'POST',
        'https://127.0.0.1/render/',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('format', 'pickle'),
          ('local', '1'),
          ('noCache', '1'),
          ('from', startTime),
          ('until', endTime),
          ('target', 'a.b.c.d'),
        ],
        'headers': None,
        'preload_content': False,
        'timeout': 10,
      })
Beispiel #20
0
    def test_RemoteReader_fetch(self, http_request):
        test_finder = RemoteFinder()
        finder = test_finder.remote_stores[0]
        reader = RemoteReader(finder,
                              {'intervals': [], 'path': 'a.b.c.d'},
                              bulk_query='a.b.c.d')
        startTime = 1496262000
        endTime   = 1496262060

        data = [
                {'start': startTime,
                 'step': 60,
                 'end': endTime,
                 'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                 'name': 'a.b.c.d'
                }
               ]
        responseObject = HTTPResponse(body=StringIO(pickle.dumps(data)), status=200)
        http_request.return_value = responseObject
        ret = reader.fetch(startTime, endTime)
        expected_response = ((1496262000, 1496262060, 60), [1.0, 0.0, 1.0, 0.0, 1.0])
        self.assertEqual(ret.waitForResults(), expected_response)
Beispiel #21
0
    def test_RemoteReader__fetch(self, http_request):
        startTime = 1496262000
        endTime   = 1496262060

        url = 'http://127.0.0.1/render/'
        query_string = 'a.b.c.d'
        query_params = [
            ('format', 'pickle'),
            ('local', '1'),
            ('noCache', '1'),
            ('from', str(int(startTime))),
            ('until', str(int(endTime)))
        ]
        headers = ''

        test_finder = RemoteFinder()
        finder = test_finder.remote_stores[0]
        reader = RemoteReader(finder,
                              {'intervals': [], 'path': 'a.b.c.d'},
                              bulk_query='a.b.c.d')

        # Response was an error
        responseObject = HTTPResponse(status=400)
        http_request.return_value = responseObject
        ret = reader._fetch(url, query_string, query_params, headers)
        self.assertEqual(ret, [])

        # 200 response with bad result.data
        responseObject = HTTPResponse(status=200)
        http_request.return_value = responseObject
        ret = reader._fetch(url, query_string, query_params, headers)
        self.assertEqual(ret, [])

        # 200 response with good result.data
        responseObject = HTTPResponse(body=StringIO(pickle.dumps(['a'])), status=200)
        http_request.return_value = responseObject
        ret = reader._fetch(url, query_string, query_params, headers)
        self.assertEqual(ret, ['a'])
Beispiel #22
0
    def test_RemoteFinder_fetch(self, http_request):
        finder = test_finder = RemoteFinder()
        store = test_finder.remote_stores[0]
        reader = RemoteReader(store,
                              {'intervals': [], 'path': 'a.b.c.d'},
                              bulk_query='a.b.c.d')
        node = LeafNode('a.b.c.d', reader)
        startTime = 1496262000
        endTime   = 1496262060

        data = [
                {'start': startTime,
                 'step': 60,
                 'end': endTime,
                 'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                 'name': 'a.b.c.d'
                }
               ]
        responseObject = HTTPResponse(body=StringIO(pickle.dumps(data)), status=200)
        http_request.return_value = responseObject

        ret = finder.fetch(['a.b.c.d'], startTime, endTime)
        expected_response = ((1496262000, 1496262060, 60), [1.0, 0.0, 1.0, 0.0, 1.0])
        expected_response = [
            {
                'name': 'a.b.c.d',
                'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                'pathExpression': 'a.b.c.d',
                'time_info': (1496262000, 1496262060, 60)
            }, {
                'name': 'a.b.c.d',
                'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                'pathExpression': 'a.b.c.d',
                'time_info': (1496262000, 1496262060, 60)
            }
        ]
        result = list(ret.waitForResults())
        self.assertEqual(result, expected_response)
Beispiel #23
0
    def test_RemoteReader_fetch_list_no_worker_pool(self, http_request):
        test_finder = RemoteFinder()
        finder = test_finder.remote_stores[0]
        reader = RemoteReader(finder,
                              {'intervals': []},
                              bulk_query='a.b.c.d')
        startTime = 1496262000
        endTime   = 1496262060

        data = [
                {'start': startTime,
                 'step': 60,
                 'end': endTime,
                 'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                 'name': 'a.b.c.d'
                }
               ]

        # 200 response with good result.data
        responseObject = HTTPResponse(body=StringIO(pickle.dumps(data)), status=200)
        http_request.return_value = responseObject
        ret = reader.fetch_list(startTime, endTime)
        data[0]['path'] = 'a.b.c.d'
        self.assertEqual(ret.waitForResults(), data)
    def test_RemoteReader_fetch_multi(self, http_request):
        test_finders = RemoteFinder.factory()
        finder = test_finders[0]

        startTime = 1496262000
        endTime   = 1496262060

        # no path or bulk_query
        reader = RemoteReader(finder,{})
        self.assertEqual(reader.bulk_query, [])
        result = reader.fetch_multi(startTime, endTime)
        self.assertEqual(result, [])
        self.assertEqual(http_request.call_count, 0)

        # path
        reader = RemoteReader(finder, {'intervals': [], 'path': 'a.b.c.d'})

        data = [
                {'start': startTime,
                 'step': 60,
                 'end': endTime,
                 'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                 'name': 'a.b.c.d'
                }
               ]
        responseObject = HTTPResponse(body=BytesIO(pickle.dumps(data)), status=200, preload_content=False)
        http_request.return_value = responseObject

        result = reader.fetch_multi(startTime, endTime)
        expected_response = [
            {
                'pathExpression': 'a.b.c.d',
                'name': 'a.b.c.d',
                'time_info': (1496262000, 1496262060, 60),
                'values': [1.0, 0.0, 1.0, 0.0, 1.0],
            }
        ]
        self.assertEqual(result, expected_response)
        self.assertEqual(http_request.call_args[0], (
          'GET',
          'http://127.0.0.1/render/',
        ))
        self.assertEqual(http_request.call_args[1], {
          'fields': [
            ('format', 'pickle'),
            ('local', '1'),
            ('noCache', '1'),
            ('from', startTime),
            ('until', endTime),
            ('target', 'a.b.c.d'),
          ],
          'headers': None,
          'preload_content': False,
          'timeout': 10,
        })

        # bulk_query & now
        finder = test_finders[1]
        reader = RemoteReader(finder, {'intervals': [], 'path': 'a.b.c.d'}, bulk_query=['a.b.c.d'])

        data = [
                {'start': startTime,
                 'step': 60,
                 'end': endTime,
                 'values': [1.0, 0.0, 1.0, 0.0, 1.0],
                 'name': 'a.b.c.d'
                }
               ]
        responseObject = HTTPResponse(
          body=BytesIO(msgpack.dumps(data, use_bin_type=True)),
          status=200,
          preload_content=False,
          headers={'Content-Type': 'application/x-msgpack'}
        )
        http_request.return_value = responseObject

        result = reader.fetch_multi(startTime, endTime, now=endTime, requestContext={'forwardHeaders': {'Authorization': 'Basic xxxx'}})
        expected_response = [
            {
                'pathExpression': 'a.b.c.d',
                'name': 'a.b.c.d',
                'time_info': (1496262000, 1496262060, 60),
                'values': [1.0, 0.0, 1.0, 0.0, 1.0],
            }
        ]
        self.assertEqual(result, expected_response)
        self.assertEqual(http_request.call_args[0], (
          'GET',
          'http://8.8.8.8/graphite/render/',
        ))
        self.assertEqual(http_request.call_args[1], {
          'fields': [
            ('format', 'msgpack'),
            ('local', '0'),
            ('noCache', '1'),
            ('from', startTime),
            ('until', endTime),
            ('target', 'a.b.c.d'),
            ('now', endTime),
          ],
          'headers': {'Authorization': 'Basic xxxx'},
          'preload_content': False,
          'timeout': 10,
        })

        # non-pickle response
        responseObject = HTTPResponse(body=BytesIO(b'error'), status=200, preload_content=False)
        http_request.return_value = responseObject

        with self.assertRaisesRegexp(Exception, 'Error decoding response from http://[^ ]+: .+'):
          reader.fetch(startTime, endTime)

        # invalid response data
        data = [
          {},
        ]
        responseObject = HTTPResponse(
          body=BytesIO(msgpack.dumps(data, use_bin_type=True)),
          status=200,
          preload_content=False,
          headers={'Content-Type': 'application/x-msgpack'}
        )
        http_request.return_value = responseObject

        with self.assertRaisesRegexp(Exception, 'Invalid render response from http://[^ ]+: KeyError\(\'name\',?\)'):
          reader.fetch(startTime, endTime)

        # non-200 response
        responseObject = HTTPResponse(body=BytesIO(b'error'), status=500, preload_content=False)
        http_request.return_value = responseObject

        with self.assertRaisesRegexp(Exception, 'Error response 500 from http://[^ ]+'):
          reader.fetch(startTime, endTime)

        # exception raised by request()
        http_request.side_effect = Exception('error')

        with self.assertRaisesRegexp(Exception, 'Error requesting http://[^ ]+: error'):
          reader.fetch(startTime, endTime)
    def test_RemoteReader_fetch_multi(self, http_request):
        test_finders = RemoteFinder.factory()
        finder = test_finders[0]

        startTime = 1496262000
        endTime = 1496262060

        # no path or bulk_query
        reader = RemoteReader(finder, {})
        self.assertEqual(reader.bulk_query, [])
        result = reader.fetch_multi(startTime, endTime)
        self.assertEqual(result, [])
        self.assertEqual(http_request.call_count, 0)

        # path
        reader = RemoteReader(finder, {'intervals': [], 'path': 'a.b.c.d'})

        data = [{
            'start': startTime,
            'step': 60,
            'end': endTime,
            'values': [1.0, 0.0, 1.0, 0.0, 1.0],
            'name': 'a.b.c.d'
        }]
        responseObject = HTTPResponse(body=StringIO(pickle.dumps(data)),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        result = reader.fetch_multi(startTime, endTime)
        expected_response = [{
            'pathExpression': 'a.b.c.d',
            'name': 'a.b.c.d',
            'time_info': (1496262000, 1496262060, 60),
            'values': [1.0, 0.0, 1.0, 0.0, 1.0],
        }]
        self.assertEqual(result, expected_response)
        self.assertEqual(http_request.call_args[0], (
            'GET',
            'http://127.0.0.1/render/',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('format', 'pickle'),
                    ('local', '1'),
                    ('noCache', '1'),
                    ('from', startTime),
                    ('until', endTime),
                    ('target', 'a.b.c.d'),
                ],
                'headers':
                None,
                'preload_content':
                False,
                'timeout':
                10,
            })

        # bulk_query & now
        finder = test_finders[1]
        reader = RemoteReader(finder, {
            'intervals': [],
            'path': 'a.b.c.d'
        },
                              bulk_query=['a.b.c.d'])

        data = [{
            'start': startTime,
            'step': 60,
            'end': endTime,
            'values': [1.0, 0.0, 1.0, 0.0, 1.0],
            'name': 'a.b.c.d'
        }]
        responseObject = HTTPResponse(
            body=StringIO(msgpack.dumps(data)),
            status=200,
            preload_content=False,
            headers={'Content-Type': 'application/x-msgpack'})
        http_request.return_value = responseObject

        result = reader.fetch_multi(
            startTime,
            endTime,
            now=endTime,
            requestContext={'forwardHeaders': {
                'Authorization': 'Basic xxxx'
            }})
        expected_response = [{
            'pathExpression': 'a.b.c.d',
            'name': 'a.b.c.d',
            'time_info': (1496262000, 1496262060, 60),
            'values': [1.0, 0.0, 1.0, 0.0, 1.0],
        }]
        self.assertEqual(result, expected_response)
        self.assertEqual(http_request.call_args[0], (
            'GET',
            'http://8.8.8.8/graphite/render/',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('format', 'msgpack'),
                    ('local', '0'),
                    ('noCache', '1'),
                    ('from', startTime),
                    ('until', endTime),
                    ('target', 'a.b.c.d'),
                    ('now', endTime),
                ],
                'headers': {
                    'Authorization': 'Basic xxxx'
                },
                'preload_content':
                False,
                'timeout':
                10,
            })

        # non-pickle response
        responseObject = HTTPResponse(body=StringIO('error'),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        with self.assertRaisesRegexp(
                Exception,
                'Error decoding render response from http://[^ ]+: .+'):
            reader.fetch(startTime, endTime)

        # non-200 response
        responseObject = HTTPResponse(body=StringIO('error'),
                                      status=500,
                                      preload_content=False)
        http_request.return_value = responseObject

        with self.assertRaisesRegexp(Exception,
                                     'Error response 500 from http://[^ ]+'):
            reader.fetch(startTime, endTime)

        # exception raised by request()
        http_request.side_effect = Exception('error')

        with self.assertRaisesRegexp(Exception,
                                     'Error requesting http://[^ ]+: error'):
            reader.fetch(startTime, endTime)
    def test_auto_complete_values(self, http_request):
      finder = RemoteFinder('127.0.0.1')

      data = [
        'value1',
        'value2',
      ]

      responseObject = HTTPResponse(body=BytesIO(json.dumps(data).encode('utf-8')), status=200, preload_content=False)
      http_request.return_value = responseObject

      result = finder.auto_complete_values(['name=test'], 'tag1', 'value')

      self.assertIsInstance(result, list)

      self.assertEqual(http_request.call_args[0], (
        'POST',
        'http://127.0.0.1/tags/autoComplete/values',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('tag', 'tag1'),
          ('valuePrefix', 'value'),
          ('limit', '100'),
          ('local', '1'),
          ('expr', 'name=test'),
        ],
        'headers': None,
        'preload_content': False,
        'timeout': 10,
      })

      self.assertEqual(len(result), 2)

      self.assertEqual(result[0], 'value1')
      self.assertEqual(result[1], 'value2')

      # explicit limit & forward headers
      responseObject = HTTPResponse(body=BytesIO(json.dumps(data).encode('utf-8')), status=200, preload_content=False)
      http_request.return_value = responseObject

      result = finder.auto_complete_values(['name=test', 'tag3=value3'], 'tag1', 'value', limit=5, requestContext={'forwardHeaders': {'X-Test': 'test'}})

      self.assertIsInstance(result, list)

      self.assertEqual(http_request.call_args[0], (
        'POST',
        'http://127.0.0.1/tags/autoComplete/values',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('tag', 'tag1'),
          ('valuePrefix', 'value'),
          ('limit', '5'),
          ('local', '1'),
          ('expr', 'name=test'),
          ('expr', 'tag3=value3'),
        ],
        'headers': {'X-Test': 'test'},
        'preload_content': False,
        'timeout': 10,
      })

      self.assertEqual(len(result), 2)

      self.assertEqual(result[0], 'value1')
      self.assertEqual(result[1], 'value2')

      # non-json response
      responseObject = HTTPResponse(body=BytesIO(b'error'), status=200, preload_content=False)
      http_request.return_value = responseObject

      with self.assertRaisesRegexp(Exception, 'Error decoding autocomplete values response from http://[^ ]+: .+'):
        result = finder.auto_complete_values(['name=test'], 'tag1', 'value')
    def test_auto_complete_values(self, http_request):
        finder = RemoteFinder('127.0.0.1')

        data = [
            'value1',
            'value2',
        ]

        responseObject = HTTPResponse(body=BytesIO(
            json.dumps(data).encode('utf-8')),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        result = finder.auto_complete_values(['name=test'], 'tag1', 'value')

        self.assertIsInstance(result, list)

        self.assertEqual(http_request.call_args[0], (
            'POST',
            'http://127.0.0.1/tags/autoComplete/values',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('tag', 'tag1'),
                    ('valuePrefix', 'value'),
                    ('limit', '100'),
                    ('expr', 'name=test'),
                ],
                'headers':
                None,
                'preload_content':
                False,
                'timeout':
                10,
            })

        self.assertEqual(len(result), 2)

        self.assertEqual(result[0], 'value1')
        self.assertEqual(result[1], 'value2')

        # explicit limit & forward headers
        responseObject = HTTPResponse(body=BytesIO(
            json.dumps(data).encode('utf-8')),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        result = finder.auto_complete_values(
            ['name=test', 'tag3=value3'],
            'tag1',
            'value',
            limit=5,
            requestContext={'forwardHeaders': {
                'X-Test': 'test'
            }})

        self.assertIsInstance(result, list)

        self.assertEqual(http_request.call_args[0], (
            'POST',
            'http://127.0.0.1/tags/autoComplete/values',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('tag', 'tag1'),
                    ('valuePrefix', 'value'),
                    ('limit', '5'),
                    ('expr', 'name=test'),
                    ('expr', 'tag3=value3'),
                ],
                'headers': {
                    'X-Test': 'test'
                },
                'preload_content':
                False,
                'timeout':
                10,
            })

        self.assertEqual(len(result), 2)

        self.assertEqual(result[0], 'value1')
        self.assertEqual(result[1], 'value2')

        # non-json response
        responseObject = HTTPResponse(body=BytesIO(b'error'),
                                      status=200,
                                      preload_content=False)
        http_request.return_value = responseObject

        with self.assertRaisesRegexp(
                Exception,
                'Error decoding autocomplete values response from http://[^ ]+: .+'
        ):
            result = finder.auto_complete_values(['name=test'], 'tag1',
                                                 'value')
    def _test_find_nodes(self, http_request):
      finder = RemoteFinder('127.0.0.1')

      startTime = 1496262000
      endTime   = 1496262060

      data = [
        {
          'path': 'a.b.c',
          'is_leaf': False,
        },
        {
          'path': 'a.b.c.d',
          'is_leaf': True,
        },
      ]
      responseObject = HTTPResponse(body=BytesIO(pickle.dumps(data)), status=200, preload_content=False)
      http_request.return_value = responseObject

      query = FindQuery('a.b.c', startTime, endTime)
      nodes = finder.find_nodes(query)

      self.assertEqual(http_request.call_args[0], (
        'POST',
        'http://127.0.0.1/metrics/find/',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('local', '1'),
          ('format', 'pickle'),
          ('query', 'a.b.c'),
          ('from', startTime),
          ('until', endTime),
        ],
        'headers': None,
        'preload_content': False,
        'timeout': 10,
      })

      self.assertEqual(len(nodes), 2)

      self.assertIsInstance(nodes[0], BranchNode)
      self.assertEqual(nodes[0].path, 'a.b.c')

      self.assertIsInstance(nodes[1], LeafNode)
      self.assertEqual(nodes[1].path, 'a.b.c.d')

      finder = RemoteFinder('https://127.0.0.1?format=msgpack')

      data = [
        {
          'path': 'a.b.c',
          'is_leaf': False,
        },
        {
          'path': 'a.b.c.d',
          'is_leaf': True,
        },
      ]
      responseObject = HTTPResponse(
        body=BytesIO(msgpack.dumps(data, use_bin_type=True)),
        status=200,
        preload_content=False,
        headers={'Content-Type': 'application/x-msgpack'}
      )
      http_request.return_value = responseObject

      query = FindQuery('a.b.c', None, None)
      nodes = finder.find_nodes(query)

      self.assertEqual(http_request.call_args[0], (
        'POST',
        'https://127.0.0.1/metrics/find/',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('local', '1'),
          ('format', 'msgpack'),
          ('query', 'a.b.c'),
        ],
        'headers': None,
        'preload_content': False,
        'timeout': 10,
      })

      self.assertEqual(len(nodes), 2)

      self.assertIsInstance(nodes[0], BranchNode)
      self.assertEqual(nodes[0].path, 'a.b.c')

      self.assertIsInstance(nodes[1], LeafNode)
      self.assertEqual(nodes[1].path, 'a.b.c.d')

      # non-pickle response
      responseObject = HTTPResponse(body=BytesIO(b'error'), status=200, preload_content=False)
      http_request.return_value = responseObject

      with self.assertRaisesRegexp(Exception, 'Error decoding response from https://[^ ]+: .+'):
        finder.find_nodes(query)
Beispiel #29
0
    def test_find_nodes(self, http_request):
        finder = RemoteFinder('127.0.0.1')

        startTime = 1496262000
        endTime = 1496262060

        data = [
            {
                'path': 'a.b.c',
                'is_leaf': False,
            },
            {
                'path': 'a.b.c.d',
                'is_leaf': True,
            },
        ]
        responseObject = HTTPResponse(body=StringIO(pickle.dumps(data)),
                                      status=200)
        http_request.return_value = responseObject

        query = FindQuery('a.b.c', startTime, endTime)
        result = finder.find_nodes(query)

        self.assertIsInstance(result, types.GeneratorType)

        nodes = list(result)

        self.assertEqual(http_request.call_args[0], (
            'POST',
            'http://127.0.0.1/metrics/find/',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('local', '1'),
                    ('format', 'pickle'),
                    ('query', 'a.b.c'),
                    ('from', startTime),
                    ('until', endTime),
                ],
                'headers':
                None,
                'timeout':
                10,
            })

        self.assertEqual(len(nodes), 2)

        self.assertIsInstance(nodes[0], BranchNode)
        self.assertEqual(nodes[0].path, 'a.b.c')

        self.assertIsInstance(nodes[1], LeafNode)
        self.assertEqual(nodes[1].path, 'a.b.c.d')

        query = FindQuery('a.b.c', None, None)
        result = finder.find_nodes(query)

        self.assertIsInstance(result, types.GeneratorType)

        nodes = list(result)

        self.assertEqual(http_request.call_args[0], (
            'POST',
            'http://127.0.0.1/metrics/find/',
        ))
        self.assertEqual(
            http_request.call_args[1], {
                'fields': [
                    ('local', '1'),
                    ('format', 'pickle'),
                    ('query', 'a.b.c'),
                ],
                'headers':
                None,
                'timeout':
                10,
            })

        self.assertEqual(len(nodes), 2)

        self.assertIsInstance(nodes[0], BranchNode)
        self.assertEqual(nodes[0].path, 'a.b.c')

        self.assertIsInstance(nodes[1], LeafNode)
        self.assertEqual(nodes[1].path, 'a.b.c.d')

        # non-pickle response
        responseObject = HTTPResponse(body='error', status=200)
        http_request.return_value = responseObject

        result = finder.find_nodes(query)

        with self.assertRaisesRegexp(
                Exception,
                'Error decoding find response from http://[^ ]+: .+'):
            list(result)
    def test_find_nodes(self, http_request):
      finder = RemoteFinder('127.0.0.1')

      startTime = 1496262000
      endTime   = 1496262060

      data = [
        {
          'path': 'a.b.c',
          'is_leaf': False,
        },
        {
          'path': 'a.b.c.d',
          'is_leaf': True,
        },
      ]
      responseObject = HTTPResponse(body=BytesIO(pickle.dumps(data)), status=200, preload_content=False)
      http_request.return_value = responseObject

      query = FindQuery('a.b.c', startTime, endTime)
      nodes = finder.find_nodes(query)

      self.assertEqual(http_request.call_args[0], (
        'POST',
        'http://127.0.0.1/metrics/find/',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('local', '1'),
          ('format', 'pickle'),
          ('query', 'a.b.c'),
          ('from', startTime),
          ('until', endTime),
        ],
        'headers': None,
        'preload_content': False,
        'timeout': 10,
      })

      self.assertEqual(len(nodes), 2)

      self.assertIsInstance(nodes[0], BranchNode)
      self.assertEqual(nodes[0].path, 'a.b.c')

      self.assertIsInstance(nodes[1], LeafNode)
      self.assertEqual(nodes[1].path, 'a.b.c.d')

      finder = RemoteFinder('https://127.0.0.1?format=msgpack')

      data = [
        {
          'path': 'a.b.c',
          'is_leaf': False,
        },
        {
          'path': 'a.b.c.d',
          'is_leaf': True,
        },
      ]
      responseObject = HTTPResponse(
        body=BytesIO(msgpack.dumps(data, use_bin_type=True)),
        status=200,
        preload_content=False,
        headers={'Content-Type': 'application/x-msgpack'}
      )
      http_request.return_value = responseObject

      query = FindQuery('a.b.c', None, None)
      nodes = finder.find_nodes(query)

      self.assertEqual(http_request.call_args[0], (
        'POST',
        'https://127.0.0.1/metrics/find/',
      ))
      self.assertEqual(http_request.call_args[1], {
        'fields': [
          ('local', '1'),
          ('format', 'msgpack'),
          ('query', 'a.b.c'),
        ],
        'headers': None,
        'preload_content': False,
        'timeout': 10,
      })

      self.assertEqual(len(nodes), 2)

      self.assertIsInstance(nodes[0], BranchNode)
      self.assertEqual(nodes[0].path, 'a.b.c')

      self.assertIsInstance(nodes[1], LeafNode)
      self.assertEqual(nodes[1].path, 'a.b.c.d')

      # non-pickle response
      responseObject = HTTPResponse(body=BytesIO(b'error'), status=200, preload_content=False)
      http_request.return_value = responseObject

      with self.assertRaisesRegexp(Exception, 'Error decoding find response from https://[^ ]+: .+'):
        finder.find_nodes(query)