Beispiel #1
0
class CeresTreeTest(TestCase):
    def setUp(self):
        with patch('ceres.isdir', new=Mock(return_value=True)):
            self.ceres_tree = CeresTree('/graphite/storage/ceres')

    @patch('ceres.isdir', new=Mock(return_value=False))
    def test_init_invalid(self):
        self.assertRaises(ValueError, CeresTree, '/nonexistent_path')

    @patch('ceres.isdir', new=Mock(return_value=True))
    @patch('ceres.abspath')
    def test_init_valid(self, abspath_mock):
        abspath_mock.return_value = '/var/graphite/storage/ceres'
        tree = CeresTree('/graphite/storage/ceres')
        abspath_mock.assert_called_once_with('/graphite/storage/ceres')
        self.assertEqual('/var/graphite/storage/ceres', tree.root)

    @patch('ceres.isdir', new=Mock(return_value=True))
    def test_init_sets_default_cache_behavior(self):
        tree = CeresTree('/graphite/storage/ceres')
        self.assertEqual(DEFAULT_NODE_CACHING_BEHAVIOR,
                         tree.nodeCachingBehavior)

    @patch('ceres.isdir', new=Mock(return_value=False))
    @patch.object(CeresTree, '__init__')
    @patch('os.makedirs')
    def test_create_tree_new_dir(self, makedirs_mock, ceres_tree_init_mock):
        ceres_tree_init_mock.return_value = None
        with patch.object(builtins, 'open', mock_open()) as open_mock:
            CeresTree.createTree('/graphite/storage/ceres')
            makedirs_mock.assert_called_once_with(
                '/graphite/storage/ceres/.ceres-tree', DIR_PERMS)
            self.assertFalse(open_mock.called)
            ceres_tree_init_mock.assert_called_once_with(
                '/graphite/storage/ceres')

    @patch('ceres.isdir', new=Mock(return_value=True))
    @patch.object(CeresTree, '__init__')
    @patch('os.makedirs')
    def test_create_tree_existing_dir(self, makedirs_mock,
                                      ceres_tree_init_mock):
        ceres_tree_init_mock.return_value = None
        with patch.object(builtins, 'open', mock_open()) as open_mock:
            CeresTree.createTree('/graphite/storage/ceres')
            self.assertFalse(makedirs_mock.called)
            self.assertFalse(open_mock.called)
            ceres_tree_init_mock.assert_called_once_with(
                '/graphite/storage/ceres')

    @patch('ceres.isdir', new=Mock(return_value=True))
    @patch.object(CeresTree, '__init__', new=Mock(return_value=None))
    @patch('os.makedirs', new=Mock())
    def test_create_tree_write_props(self):
        props = {"foo_prop": "foo_value", "bar_prop": "bar_value"}
        with patch.object(builtins, 'open', mock_open()) as open_mock:
            CeresTree.createTree('/graphite/storage/ceres', **props)
            for (prop, value) in props.items():
                open_mock.assert_any_call(
                    path.join('/graphite/storage/ceres', '.ceres-tree', prop),
                    'w')
                open_mock.return_value.write.assert_any_call(value)

    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    def test_get_node_path_clean(self):
        result = self.ceres_tree.getNodePath(
            '/graphite/storage/ceres/metric/foo')
        self.assertEqual('metric.foo', result)

    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    def test_get_node_path_trailing_slash(self):
        result = self.ceres_tree.getNodePath(
            '/graphite/storage/ceres/metric/foo/')
        self.assertEqual('metric.foo', result)

    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    def test_get_node_path_outside_tree(self):
        self.assertRaises(ValueError, self.ceres_tree.getNodePath,
                          '/metric/foo')

    @patch('ceres.CeresNode', spec=CeresNode)
    def test_get_node_uncached(self, ceres_node_mock):
        ceres_node_mock.isNodeDir.return_value = True
        result = self.ceres_tree.getNode('metrics.foo')
        ceres_node_mock.assert_called_once_with(
            self.ceres_tree, 'metrics.foo',
            '/graphite/storage/ceres/metrics/foo')
        self.assertEqual(result, ceres_node_mock())

    @patch('ceres.CeresNode', spec=CeresNode)
    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    @patch('ceres.glob', new=Mock(side_effect=lambda x: [x]))
    def test_find_explicit_metric(self, ceres_node_mock):
        ceres_node_mock.isNodeDir.return_value = True
        result = list(self.ceres_tree.find('metrics.foo'))
        self.assertEqual(1, len(result))
        self.assertEqual(result[0], ceres_node_mock())

    @patch('ceres.CeresNode', spec=CeresNode)
    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    @patch('ceres.glob')
    def test_find_wildcard(self, glob_mock, ceres_node_mock):
        matches = ['foo', 'bar', 'baz']
        glob_mock.side_effect = lambda x: [x.replace('*', m) for m in matches]
        ceres_node_mock.isNodeDir.return_value = True
        result = list(self.ceres_tree.find('metrics.*'))
        self.assertEqual(3, len(result))
        ceres_node_mock.assert_any_call(self.ceres_tree, 'metrics.foo', ANY)
        ceres_node_mock.assert_any_call(self.ceres_tree, 'metrics.bar', ANY)
        ceres_node_mock.assert_any_call(self.ceres_tree, 'metrics.baz', ANY)

    @patch('ceres.CeresNode', spec=CeresNode)
    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    @patch('ceres.glob', new=Mock(return_value=[]))
    def test_find_wildcard_no_matches(self, ceres_node_mock):
        ceres_node_mock.isNodeDir.return_value = False
        result = list(self.ceres_tree.find('metrics.*'))
        self.assertEqual(0, len(result))
        self.assertFalse(ceres_node_mock.called)

    @patch('ceres.CeresNode', spec=CeresNode)
    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    @patch('ceres.glob', new=Mock(side_effect=lambda x: [x]))
    def test_find_metric_with_interval(self, ceres_node_mock):
        ceres_node_mock.isNodeDir.return_value = True
        ceres_node_mock.return_value.hasDataForInterval.return_value = False
        result = list(self.ceres_tree.find('metrics.foo', 0, 1000))
        self.assertEqual(0, len(result))
        ceres_node_mock.return_value.hasDataForInterval.assert_called_once_with(
            0, 1000)

    @patch('ceres.CeresNode', spec=CeresNode)
    @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
    @patch('ceres.glob', new=Mock(side_effect=lambda x: [x]))
    def test_find_metric_with_interval_not_found(self, ceres_node_mock):
        ceres_node_mock.isNodeDir.return_value = True
        ceres_node_mock.return_value.hasDataForInterval.return_value = True
        result = list(self.ceres_tree.find('metrics.foo', 0, 1000))
        self.assertEqual(result[0], ceres_node_mock())
        ceres_node_mock.return_value.hasDataForInterval.assert_called_once_with(
            0, 1000)

    def test_store_invalid_node(self):
        with patch.object(self.ceres_tree,
                          'getNode',
                          new=Mock(return_value=None)):
            datapoints = [(100, 1.0)]
            self.assertRaises(NodeNotFound, self.ceres_tree.store,
                              'metrics.foo', datapoints)

    @patch('ceres.CeresNode', spec=CeresNode)
    def test_store_valid_node(self, ceres_node_mock):
        datapoints = [(100, 1.0)]
        self.ceres_tree.store('metrics.foo', datapoints)
        ceres_node_mock.assert_called_once_with(self.ceres_tree, 'metrics.foo',
                                                ANY)
        ceres_node_mock.return_value.write.assert_called_once_with(datapoints)

    def fetch_invalid_node(self):
        with patch.object(self.ceres_tree,
                          'getNode',
                          new=Mock(return_value=None)):
            self.assertRaises(NodeNotFound, self.ceres_tree.fetch,
                              'metrics.foo')

    @patch('ceres.CeresNode', spec=CeresNode)
    def fetch_metric(self, ceres_node_mock):
        read_mock = ceres_node_mock.return_value.read
        read_mock.return_value = Mock(spec=TimeSeriesData)
        result = self.ceres_tree.fetch('metrics.foo', 0, 1000)
        ceres_node_mock.assert_called_once_with(self.ceres_tree, 'metrics.foo',
                                                ANY)
        read_mock.assert_called_once_with(0, 1000)
        self.assertEqual(Mock(spec=TimeSeriesData), result)

    def test_set_node_caching_behavior_validates_names(self):
        self.ceres_tree.setNodeCachingBehavior('none')
        self.assertEquals('none', self.ceres_tree.nodeCachingBehavior)
        self.ceres_tree.setNodeCachingBehavior('all')
        self.assertEquals('all', self.ceres_tree.nodeCachingBehavior)
        self.assertRaises(ValueError, self.ceres_tree.setNodeCachingBehavior,
                          'foo')
        # Assert unchanged
        self.assertEquals('all', self.ceres_tree.nodeCachingBehavior)
Beispiel #2
0
class CeresTreeTest(TestCase):
  def setUp(self):
    with patch('ceres.isdir', new=Mock(return_value=True)):
      self.ceres_tree = CeresTree('/graphite/storage/ceres')

  @patch('ceres.isdir', new=Mock(return_value=False))
  def test_init_invalid(self):
    self.assertRaises(ValueError, CeresTree, '/nonexistent_path')

  @patch('ceres.isdir', new=Mock(return_value=True))
  @patch('ceres.abspath')
  def test_init_valid(self, abspath_mock):
    abspath_mock.return_value = '/var/graphite/storage/ceres'
    tree = CeresTree('/graphite/storage/ceres')
    abspath_mock.assert_called_once_with('/graphite/storage/ceres')
    self.assertEqual('/var/graphite/storage/ceres', tree.root)

  @patch('ceres.isdir', new=Mock(return_value=True))
  def test_init_sets_default_cache_behavior(self):
    tree = CeresTree('/graphite/storage/ceres')
    self.assertEqual(DEFAULT_NODE_CACHING_BEHAVIOR, tree.nodeCachingBehavior)

  @patch('ceres.isdir', new=Mock(return_value=False))
  @patch.object(CeresTree, '__init__')
  @patch('os.makedirs')
  def test_create_tree_new_dir(self, makedirs_mock, ceres_tree_init_mock):
    ceres_tree_init_mock.return_value = None
    with patch.object(builtins, 'open', mock_open()) as open_mock:
      CeresTree.createTree('/graphite/storage/ceres')
      makedirs_mock.assert_called_once_with('/graphite/storage/ceres/.ceres-tree', DIR_PERMS)
      self.assertFalse(open_mock.called)
      ceres_tree_init_mock.assert_called_once_with('/graphite/storage/ceres')

  @patch('ceres.isdir', new=Mock(return_value=True))
  @patch.object(CeresTree, '__init__')
  @patch('os.makedirs')
  def test_create_tree_existing_dir(self, makedirs_mock, ceres_tree_init_mock):
    ceres_tree_init_mock.return_value = None
    with patch.object(builtins, 'open', mock_open()) as open_mock:
      CeresTree.createTree('/graphite/storage/ceres')
      self.assertFalse(makedirs_mock.called)
      self.assertFalse(open_mock.called)
      ceres_tree_init_mock.assert_called_once_with('/graphite/storage/ceres')

  @patch('ceres.isdir', new=Mock(return_value=True))
  @patch.object(CeresTree, '__init__', new=Mock(return_value=None))
  @patch('os.makedirs', new=Mock())
  def test_create_tree_write_props(self):
    props = {
      "foo_prop": "foo_value",
      "bar_prop": "bar_value"}
    with patch.object(builtins, 'open', mock_open()) as open_mock:
      CeresTree.createTree('/graphite/storage/ceres', **props)
      for (prop, value) in props.items():
        open_mock.assert_any_call(path.join('/graphite/storage/ceres', '.ceres-tree', prop), 'w')
        open_mock.return_value.write.assert_any_call(value)

  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  def test_get_node_path_clean(self):
    result = self.ceres_tree.getNodePath('/graphite/storage/ceres/metric/foo')
    self.assertEqual('metric.foo', result)

  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  def test_get_node_path_trailing_slash(self):
    result = self.ceres_tree.getNodePath('/graphite/storage/ceres/metric/foo/')
    self.assertEqual('metric.foo', result)

  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  def test_get_node_path_outside_tree(self):
    self.assertRaises(ValueError, self.ceres_tree.getNodePath, '/metric/foo')

  @patch('ceres.CeresNode', spec=CeresNode)
  def test_get_node_uncached(self, ceres_node_mock):
    ceres_node_mock.isNodeDir.return_value = True
    result = self.ceres_tree.getNode('metrics.foo')
    ceres_node_mock.assert_called_once_with(
      self.ceres_tree,
      'metrics.foo',
      '/graphite/storage/ceres/metrics/foo')
    self.assertEqual(result, ceres_node_mock())

  @patch('ceres.CeresNode', spec=CeresNode)
  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  @patch('ceres.glob', new=Mock(side_effect=lambda x: [x]))
  def test_find_explicit_metric(self, ceres_node_mock):
    ceres_node_mock.isNodeDir.return_value = True
    result = list(self.ceres_tree.find('metrics.foo'))
    self.assertEqual(1, len(result))
    self.assertEqual(result[0], ceres_node_mock())

  @patch('ceres.CeresNode', spec=CeresNode)
  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  @patch('ceres.glob')
  def test_find_wildcard(self, glob_mock, ceres_node_mock):
    matches = ['foo', 'bar', 'baz']
    glob_mock.side_effect = lambda x: [x.replace('*', m) for m in matches]
    ceres_node_mock.isNodeDir.return_value = True
    result = list(self.ceres_tree.find('metrics.*'))
    self.assertEqual(3, len(result))
    ceres_node_mock.assert_any_call(self.ceres_tree, 'metrics.foo', ANY)
    ceres_node_mock.assert_any_call(self.ceres_tree, 'metrics.bar', ANY)
    ceres_node_mock.assert_any_call(self.ceres_tree, 'metrics.baz', ANY)

  @patch('ceres.CeresNode', spec=CeresNode)
  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  @patch('ceres.glob', new=Mock(return_value=[]))
  def test_find_wildcard_no_matches(self, ceres_node_mock):
    ceres_node_mock.isNodeDir.return_value = False
    result = list(self.ceres_tree.find('metrics.*'))
    self.assertEqual(0, len(result))
    self.assertFalse(ceres_node_mock.called)

  @patch('ceres.CeresNode', spec=CeresNode)
  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  @patch('ceres.glob', new=Mock(side_effect=lambda x: [x]))
  def test_find_metric_with_interval(self, ceres_node_mock):
    ceres_node_mock.isNodeDir.return_value = True
    ceres_node_mock.return_value.hasDataForInterval.return_value = False
    result = list(self.ceres_tree.find('metrics.foo', 0, 1000))
    self.assertEqual(0, len(result))
    ceres_node_mock.return_value.hasDataForInterval.assert_called_once_with(0, 1000)

  @patch('ceres.CeresNode', spec=CeresNode)
  @patch('ceres.abspath', new=Mock(side_effect=lambda x: x))
  @patch('ceres.glob', new=Mock(side_effect=lambda x: [x]))
  def test_find_metric_with_interval_not_found(self, ceres_node_mock):
    ceres_node_mock.isNodeDir.return_value = True
    ceres_node_mock.return_value.hasDataForInterval.return_value = True
    result = list(self.ceres_tree.find('metrics.foo', 0, 1000))
    self.assertEqual(result[0], ceres_node_mock())
    ceres_node_mock.return_value.hasDataForInterval.assert_called_once_with(0, 1000)

  def test_store_invalid_node(self):
    with patch.object(self.ceres_tree, 'getNode', new=Mock(return_value=None)):
      datapoints = [(100, 1.0)]
      self.assertRaises(NodeNotFound, self.ceres_tree.store, 'metrics.foo', datapoints)

  @patch('ceres.CeresNode', spec=CeresNode)
  def test_store_valid_node(self, ceres_node_mock):
    datapoints = [(100, 1.0)]
    self.ceres_tree.store('metrics.foo', datapoints)
    ceres_node_mock.assert_called_once_with(self.ceres_tree, 'metrics.foo', ANY)
    ceres_node_mock.return_value.write.assert_called_once_with(datapoints)

  def fetch_invalid_node(self):
    with patch.object(self.ceres_tree, 'getNode', new=Mock(return_value=None)):
      self.assertRaises(NodeNotFound, self.ceres_tree.fetch, 'metrics.foo')

  @patch('ceres.CeresNode', spec=CeresNode)
  def fetch_metric(self, ceres_node_mock):
    read_mock = ceres_node_mock.return_value.read
    read_mock.return_value = Mock(spec=TimeSeriesData)
    result = self.ceres_tree.fetch('metrics.foo', 0, 1000)
    ceres_node_mock.assert_called_once_with(self.ceres_tree, 'metrics.foo', ANY)
    read_mock.assert_called_once_with(0, 1000)
    self.assertEqual(Mock(spec=TimeSeriesData), result)

  def test_set_node_caching_behavior_validates_names(self):
    self.ceres_tree.setNodeCachingBehavior('none')
    self.assertEquals('none', self.ceres_tree.nodeCachingBehavior)
    self.ceres_tree.setNodeCachingBehavior('all')
    self.assertEquals('all', self.ceres_tree.nodeCachingBehavior)
    self.assertRaises(ValueError, self.ceres_tree.setNodeCachingBehavior, 'foo')
    # Assert unchanged
    self.assertEquals('all', self.ceres_tree.nodeCachingBehavior)