summaryrefslogtreecommitdiffstats
path: root/docs/templates/release/userguide/feature.userguide.rst
blob: 1d54d0ec7dda10a436c1e1f8021cb7726c8c871c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.. This work is licensed under a Creative Commons Attribution 4.0 International License.
.. http://creativecommons.org/licenses/by/4.0
.. (c) <optionally add copywriters name>

.. contents::
   :depth: 3
   :local:

<Feature> description
=====================
.. Describe the specific features and how it is realised in the scenario in a brief manner
.. to ensure the user understand the context for the user guide instructions to follow.

<Feature> capabilities and usage
================================
.. Describe the specific capabilities and usage for <XYZ> feature.
.. Provide enough information that a user will be able to operate the feature on a deployed scenario.

<Feature and API usage guidelines and example>
==============================================
.. Describe with examples how to use specific features, provide API examples and details required to
.. operate the feature on the platform.
.nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
# Copyright (c) 2017 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

from __future__ import absolute_import

import unittest
import mock

from tests.unit import STL_MOCKS

STLClient = mock.MagicMock()
stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
stl_patch.start()

if stl_patch:
    from yardstick.benchmark.runners.search import SearchRunner
    from yardstick.benchmark.runners.search import SearchRunnerHelper


class TestSearchRunnerHelper(unittest.TestCase):

    def test___call__(self):
        cls = mock.MagicMock()
        aborted = mock.MagicMock()
        scenario_cfg = {
            'runner': {},
        }

        benchmark = cls()
        method = getattr(benchmark, 'my_method')
        helper = SearchRunnerHelper(cls, 'my_method', scenario_cfg, {}, aborted)

        with helper.get_benchmark_instance():
            helper()

        self.assertEqual(method.call_count, 1)

    def test___call___error(self):
        cls = mock.MagicMock()
        aborted = mock.MagicMock()
        scenario_cfg = {
            'runner': {},
        }

        helper = SearchRunnerHelper(cls, 'my_method', scenario_cfg, {}, aborted)

        with self.assertRaises(RuntimeError):
            helper()

    @mock.patch('yardstick.benchmark.runners.search.time')
    def test_is_not_done(self, mock_time):
        cls = mock.MagicMock()
        aborted = mock.MagicMock()
        scenario_cfg = {
            'runner': {},
        }

        mock_time.time.side_effect = range(1000)

        helper = SearchRunnerHelper(cls, 'my_method', scenario_cfg, {}, aborted)

        index = -1
        for index in helper.is_not_done():
            if index >= 10:
                break

        self.assertGreaterEqual(index, 10)

    @mock.patch('yardstick.benchmark.runners.search.time')
    def test_is_not_done_immediate_stop(self, mock_time):
        cls = mock.MagicMock()
        aborted = mock.MagicMock()
        scenario_cfg = {
            'runner': {
                'run_step': '',
            },
        }

        helper = SearchRunnerHelper(cls, 'my_method', scenario_cfg, {}, aborted)

        index = -1
        for index in helper.is_not_done():
            if index >= 10:
                break

        self.assertEqual(index, -1)

class TestSearchRunner(unittest.TestCase):

    def test__worker_run_once(self):
        def update(*args):
            args[-1].update(data)

        data = {
            'key1': {
                'inner1': 'value1',
                'done': 0,
            },
            'key2': {
                'done': None,
            },
        }

        runner = SearchRunner({})
        runner.worker_helper = mock.MagicMock(side_effect=update)

        self.assertFalse(runner._worker_run_once('sequence 1'))

    def test__worker_run_once_done(self):
        def update(*args):
            args[-1].update(data)

        data = {
            'key1': {
                'inner1': 'value1',
                'done': 0,
            },
            'key2': {
                'done': None,
            },
            'key3': {
                'done': True,
            },
            'key4': [],
            'key5': 'value5',
        }

        runner = SearchRunner({})
        runner.worker_helper = mock.MagicMock(side_effect=update)

        self.assertTrue(runner._worker_run_once('sequence 1'))

    def test__worker_run_once_assertion_error_assert(self):
        runner = SearchRunner({})
        runner.sla_action = 'assert'
        runner.worker_helper = mock.MagicMock(side_effect=AssertionError)

        with self.assertRaises(AssertionError):
            runner._worker_run_once('sequence 1')

    def test__worker_run_once_assertion_error_monitor(self):
        runner = SearchRunner({})
        runner.sla_action = 'monitor'
        runner.worker_helper = mock.MagicMock(side_effect=AssertionError)

        self.assertFalse(runner._worker_run_once('sequence 1'))

    def test__worker_run_once_non_assertion_error_none(self):
        runner = SearchRunner({})
        runner.worker_helper = mock.MagicMock(side_effect=RuntimeError)

        self.assertTrue(runner._worker_run_once('sequence 1'))

    def test__worker_run_once_non_assertion_error(self):
        runner = SearchRunner({})
        runner.sla_action = 'monitor'
        runner.worker_helper = mock.MagicMock(side_effect=RuntimeError)

        self.assertFalse(runner._worker_run_once('sequence 1'))

    def test__worker_run(self):
        cls = mock.MagicMock()
        scenario_cfg = {
            'runner': {'interval': 0, 'timeout': 1},
        }

        runner = SearchRunner({})
        runner._worker_run_once = mock.MagicMock(side_effect=[0, 0, 1])

        runner._worker_run(cls, 'my_method', scenario_cfg, {})

    def test__worker_run_immediate_stop(self):
        cls = mock.MagicMock()
        scenario_cfg = {
            'runner': {
                'run_step': '',
            },
        }

        runner = SearchRunner({})
        runner._worker_run(cls, 'my_method', scenario_cfg, {})

    @mock.patch('yardstick.benchmark.runners.search.multiprocessing')
    def test__run_benchmark(self, mock_multi_process):
        cls = mock.MagicMock()
        scenario_cfg = {
            'runner': {},
        }

        runner = SearchRunner({})
        runner._run_benchmark(cls, 'my_method', scenario_cfg, {})
        self.assertEqual(mock_multi_process.Process.call_count, 1)