Exemplo n.º 1
0
    def test_param_type_int_or_inf(self):
        self.assertTrue(
            validateParams(
                'TestParam',
                [Param('param', ParamTypes.intOrInf)],
                [1],
                {},
            ))

        self.assertTrue(
            validateParams(
                'TestParam',
                [Param('param', ParamTypes.intOrInf)],
                [float('inf')],
                {},
            ))

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            [Param('param', ParamTypes.intOrInf)],
            [1.2],
            {},
        )
Exemplo n.º 2
0
    def test_mixed_cases(self):
        self.assertEqual(
            validateParams('TestParam', self.params, ['one', 'two'],
                           {'three': '3'}), (['one', 'two'], {
                               'three': '3'
                           }))

        self.assertEqual(
            validateParams('TestParam', self.params, ['one'], {
                'three': '3',
                'two': '2'
            }),
            (['one'], {
                'three': '3',
                'two': '2'
            }),
        )

        # positional args don't check the name
        self.assertEqual(
            validateParams('TestParam', self.params, ['one', 'two', 'four'],
                           {}), (['one', 'two', 'four'], {}))

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            self.params,
            [],
            {
                'three': '3',
                'two': '2'
            },
        )

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            self.params,
            ['one', 'three'],
            {'two': '2'},
        )

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            self.params,
            ['three'],
            {
                'one': '1',
                'two': '2'
            },
        )
Exemplo n.º 3
0
    def test_multiple_property(self):
        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            [
                Param('one', ParamTypes.string, required=True),
                Param('two', ParamTypes.string, required=True),
                Param(
                    'three', ParamTypes.string, required=True, multiple=False),
            ],
            ['one', 'two', 'three', 'four'],
            {},
        )

        self.assertTrue(
            validateParams(
                'TestParam',
                [
                    Param('one', ParamTypes.string, required=True),
                    Param('two', ParamTypes.string, required=True),
                    Param('three',
                          ParamTypes.string,
                          required=True,
                          multiple=True),
                ],
                ['one', 'two', 'three', 'four'],
                {},
            ))
Exemplo n.º 4
0
    def test_options_property(self):
        self.assertTrue(
            validateParams(
                'TestParam',
                [
                    Param('one', ParamTypes.string, required=True),
                    Param('two', ParamTypes.string, required=True),
                    Param('three',
                          ParamTypes.string,
                          required=True,
                          options=['3', 'three']),
                ],
                ['one', 'two', '3'],
                {},
            ))

        self.assertTrue(
            validateParams(
                'TestParam',
                [
                    Param('one', ParamTypes.string, required=True),
                    Param('two', ParamTypes.string, required=True),
                    Param('three',
                          ParamTypes.string,
                          required=True,
                          options=['3', 'three']),
                ],
                ['one', 'two', 'three'],
                {},
            ))

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            [
                Param('one', ParamTypes.string, required=True),
                Param('two', ParamTypes.string, required=True),
                Param('three',
                      ParamTypes.string,
                      required=True,
                      options=['3', 'three']),
            ],
            ['one', 'two', 'four'],
            {},
        )
Exemplo n.º 5
0
 def test_default_value(self):
     # if no value is specified, but there is a default value, we don't
     # want the validator to raise an exception because 'None' is invalid
     self.assertEqual(
         validateParams('TestParam', [
             Param('one', ParamTypes.aggFunc, default='sum'),
         ], [], {}),
         ([], {}),
     )
Exemplo n.º 6
0
    def test_simple_args(self):
        self.assertEqual(
            validateParams('TestParam', self.params, ['arg1', 'arg2', 'arg3'],
                           {}),
            (['arg1', 'arg2', 'arg3'], {}),
        )

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            self.params,
            ['arg1', 'arg2'],
            {},
        )
Exemplo n.º 7
0
    def test_use_series_function_as_aggregator(self):
        # powSeries is a series function which is marked as a valid aggregator
        self.assertEqual(
            validateParams('TestParam', [
                Param('func', ParamTypes.aggOrSeriesFunc, required=True),
            ], ['powSeries'], {}),
            (['powSeries'], {}),
        )

        # squareRoot is a series function which is not marked as a valid aggregator
        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            [
                Param('func', ParamTypes.aggOrSeriesFunc, required=True),
            ],
            ['squareRoot'],
            {},
        )
Exemplo n.º 8
0
    def test_multiple_property(self):
        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            [
                Param('one', ParamTypes.string, required=True),
                Param('two', ParamTypes.string, required=True),
                Param(
                    'three', ParamTypes.string, required=True, multiple=False),
            ],
            ['one', 'two', 'three', 'four'],
            {},
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('one', ParamTypes.string, required=True),
                Param('two', ParamTypes.string, required=True),
                Param('three', ParamTypes.string, required=True,
                      multiple=True),
            ], ['one', 'two', 'three', 'four'], {}),
            (['one', 'two', 'three', 'four'], {}),
        )

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            [
                Param('one', ParamTypes.string, required=True),
                Param('two', ParamTypes.string, required=True),
                Param('three', ParamTypes.string, required=True,
                      multiple=True),
            ],
            ['one', 'two', 'three'],
            # should fail because parameters which are specified multiple times
            # cannot be in kwargs, only args
            {'three': '3'},
        )
Exemplo n.º 9
0
    def test_simple_kwargs(self):
        self.assertEqual(
            validateParams('TestParam', self.params, [], {
                'one': '1',
                'two': '2',
                'three': '3'
            }),
            ([], {
                'one': '1',
                'two': '2',
                'three': '3'
            }),
        )

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            self.params,
            [],
            {
                'one': '1',
                'two': '2'
            },
        )

        self.assertRaises(
            InputParameterError,
            validateParams,
            'TestParam',
            self.params,
            [],
            {
                'one': '1',
                'two': '2',
                'four': '4'
            },
        )
def evaluateTokens(requestContext, tokens, replacements=None, pipedArg=None):
  if tokens.template:
    arglist = dict()
    if tokens.template.kwargs:
      arglist.update(dict([(kwarg.argname, evaluateScalarTokens(kwarg.args[0])) for kwarg in tokens.template.kwargs]))
    if tokens.template.args:
      arglist.update(dict([(str(i+1), evaluateScalarTokens(arg)) for i, arg in enumerate(tokens.template.args)]))
    if 'template' in requestContext:
      arglist.update(requestContext['template'])
    return evaluateTokens(requestContext, tokens.template, arglist)

  if tokens.expression:
    if tokens.expression.pipedCalls:
      # when the expression has piped calls, we pop the right-most call and pass the remaining
      # expression into it via pipedArg, to get the same result as a nested call
      rightMost = tokens.expression.pipedCalls.pop()
      return evaluateTokens(requestContext, rightMost, replacements, tokens)

    return evaluateTokens(requestContext, tokens.expression, replacements)

  if tokens.pathExpression:
    expression = tokens.pathExpression
    if replacements:
      for name in replacements:
        if expression == '$'+name:
          val = replacements[name]
          if not isinstance(val, six.string_types):
            return val
          elif re.match(r'^-?[\d.]+$', val):
            return float(val)
          else:
            return val
        else:
          expression = expression.replace('$'+name, str(replacements[name]))
    return fetchData(requestContext, expression)

  if tokens.call:
    if tokens.call.funcname == 'template':
      # if template propagates down here, it means the grammar didn't match the invocation
      # as tokens.template. this generally happens if you try to pass non-numeric/string args
      raise InputParameterError("invalid template() syntax, only string/numeric arguments are allowed")

    if tokens.call.funcname == 'seriesByTag':
      return fetchData(requestContext, tokens.call.raw)

    try:
      func = SeriesFunction(tokens.call.funcname)
    except KeyError:
      raise InputParameterError('Received request for unknown function: {func}'.format(func=tokens.call.funcname))

    rawArgs = tokens.call.args or []
    if pipedArg is not None:
      rawArgs.insert(0, pipedArg)
    args = [evaluateTokens(requestContext, arg, replacements) for arg in rawArgs]
    requestContext['args'] = rawArgs
    kwargs = dict([(kwarg.argname, evaluateTokens(requestContext, kwarg.args[0], replacements))
                   for kwarg in tokens.call.kwargs])

    def handleInvalidParameters(e):
      e.setSourceIdHeaders(requestContext.get('sourceIdHeaders', {}))
      e.setTargets(requestContext.get('targets', []))
      e.setFunction(tokens.call.funcname, args, kwargs)

      if settings.ENFORCE_INPUT_VALIDATION:
        raise e

      if not getattr(handleInvalidParameters, 'alreadyLogged', False):
        log.warning('%s', str(e))

        # only log invalid parameters once
        setattr(handleInvalidParameters, 'alreadyLogged', True)

    if hasattr(func, 'params'):
      try:
        (args, kwargs) = validateParams(tokens.call.funcname, func.params, args, kwargs)
      except InputParameterError as e:
        handleInvalidParameters(e)

    try:
      return func(requestContext, *args, **kwargs)
    except NormalizeEmptyResultError:
      return []
    except InputParameterError as e:
      handleInvalidParameters(e)

  return evaluateScalarTokens(tokens)
Exemplo n.º 11
0
    def test_various_type_conversions(self):
        self.assertEqual(
            validateParams('TestParam', [
                Param('bool', ParamTypes.boolean),
            ], ['true'], {}),
            ([True], {}),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('bool', ParamTypes.boolean),
            ], [], {'bool': 'false'}),
            ([], {
                'bool': False
            }),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('bool1', ParamTypes.boolean),
                Param('bool2', ParamTypes.boolean),
            ], [0], {'bool2': 1}),
            ([False], {
                'bool2': True
            }),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('float', ParamTypes.float),
            ], ['1e3'], {}),
            ([float(1000)], {}),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('float', ParamTypes.float),
            ], ['0.123'], {}),
            ([float(0.123)], {}),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('float', ParamTypes.float),
            ], [], {'float': 'inf'}),
            ([], {
                'float': float('inf')
            }),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('int', ParamTypes.integer),
            ], ['123'], {}),
            ([123], {}),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('int', ParamTypes.integer),
            ], [], {'int': '-123'}),
            ([], {
                'int': -123
            }),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('intOrInf', ParamTypes.intOrInf),
            ], ['123'], {}),
            ([123], {}),
        )

        self.assertEqual(
            validateParams('TestParam', [
                Param('intOrInf', ParamTypes.intOrInf),
            ], [], {'intOrInf': float('inf')}),
            ([], {
                'intOrInf': float('inf')
            }),
        )