Coverage for watcher/decision_engine/scoring/dummy_scoring_container.py: 84%
33 statements
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-17 12:22 +0000
« prev ^ index » next coverage.py v7.8.2, created at 2025-06-17 12:22 +0000
1# -*- encoding: utf-8 -*-
2# Copyright (c) 2016 Intel
3#
4# Authors: Tomasz Kaczynski <tomasz.kaczynski@intel.com>
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15# implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
20from oslo_log import log
21from oslo_serialization import jsonutils
23from watcher._i18n import _
24from watcher.decision_engine.scoring import base
26LOG = log.getLogger(__name__)
29class DummyScoringContainer(base.ScoringEngineContainer):
30 """Sample Scoring Engine container returning a list of scoring engines.
32 Please note that it can be used in dynamic scenarios and the returned list
33 might return instances based on some external configuration (e.g. in
34 database). In order for these scoring engines to become discoverable in
35 Watcher API and Watcher CLI, a database re-sync is required. It can be
36 executed using watcher-sync tool for example.
37 """
39 @classmethod
40 def get_scoring_engine_list(cls):
41 return [
42 SimpleFunctionScorer(
43 'dummy_min_scorer',
44 'Dummy Scorer calculating the minimum value',
45 min),
46 SimpleFunctionScorer(
47 'dummy_max_scorer',
48 'Dummy Scorer calculating the maximum value',
49 max),
50 SimpleFunctionScorer(
51 'dummy_avg_scorer',
52 'Dummy Scorer calculating the average value',
53 lambda x: float(sum(x)) / len(x)),
54 ]
57class SimpleFunctionScorer(base.ScoringEngine):
58 """A simple generic scoring engine for demonstration purposes only.
60 A generic scoring engine implementation, which is expecting a JSON
61 formatted array of numbers to be passed as an input for score calculation.
62 It then executes the aggregate function on this array and returns an
63 array with a single aggregated number (also JSON formatted).
64 """
66 def __init__(self, name, description, aggregate_function):
67 super(SimpleFunctionScorer, self).__init__(config=None)
68 self._name = name
69 self._description = description
70 self._aggregate_function = aggregate_function
72 def get_name(self):
73 return self._name
75 def get_description(self):
76 return self._description
78 def get_metainfo(self):
79 return ''
81 def calculate_score(self, features):
82 LOG.debug('Calculating score, features: %s', features)
84 # Basic input validation
85 try:
86 flist = jsonutils.loads(features)
87 except Exception as e:
88 raise ValueError(_('Unable to parse features: %s') % e)
89 if type(flist) is not list: 89 ↛ 90line 89 didn't jump to line 90 because the condition on line 89 was never true
90 raise ValueError(_('JSON list expected in feature argument'))
91 if len(flist) < 1: 91 ↛ 92line 91 didn't jump to line 92 because the condition on line 91 was never true
92 raise ValueError(_('At least one feature is required'))
94 # Calculate the result
95 result = self._aggregate_function(flist)
97 # Return the aggregated result
98 return jsonutils.dumps([result])