Skip to content

Commit

Permalink
Merge pull request #157 from powerapi-ng/refactor/issue156/refactor_s…
Browse files Browse the repository at this point in the history
…imlple_and_dummy_formulas

Refactor/issue156/refactor simlple and dummy formulas
  • Loading branch information
roda82 committed Apr 14, 2023
2 parents ea5a4bf + 6b040da commit 1d90829
Show file tree
Hide file tree
Showing 21 changed files with 141 additions and 323 deletions.
1 change: 0 additions & 1 deletion powerapi/formula/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,5 @@

from powerapi.formula.handlers import FormulaPoisonPillMessageHandler
from powerapi.formula.abstract_cpu_dram_formula import AbstractCpuDramFormula
from powerapi.formula.dummy.dummy_formula_actor import DummyFormulaActor
from powerapi.formula.formula_actor import FormulaActor, FormulaState
from powerapi.formula.simple.simple_formula_actor import SimpleFormulaActor
7 changes: 4 additions & 3 deletions powerapi/puller/simple/simple_puller_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import logging
from typing import Type

from powerapi.actor import Actor, State
Expand Down Expand Up @@ -65,15 +65,16 @@ class SimplePullerActor(Actor):
Simple Actor that generated a given number of messages of a given type
"""

def __init__(self, name: str, number_of_reports_to_send: int, report_type_to_send: Type[Report], report_filter):
def __init__(self, name: str, number_of_reports_to_send: int, report_type_to_send: Type[Report], report_filter,
level_logger: int = logging.WARNING):
"""
Create an actor with the given information
:param str name: The actor's name
:param int number_of_reports_to_send: Number of reports to send
:param Report report_type_to_send: Report type to be sent
:param Filter report_filter: Filters and the associated dispatchers and rules
"""
Actor.__init__(self, name)
Actor.__init__(self, name, level_logger=level_logger)
self.state = SimplePullerState(self, number_of_reports_to_send, report_type_to_send, report_filter)

def setup(self):
Expand Down
8 changes: 6 additions & 2 deletions powerapi/pusher/simple/simple_pusher_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import logging

from multiprocessing import Value

from powerapi.actor import Actor, State
from powerapi.handler import PoisonPillMessageHandler
Expand All @@ -52,6 +55,7 @@ def __init__(self, actor, number_of_reports_to_store: int):
State.__init__(self, actor)
self.number_of_reports_to_store = number_of_reports_to_store
self.reports = []
self.alive = Value('i', 1)


class SimplePusherActor(Actor):
Expand All @@ -61,8 +65,8 @@ class SimplePusherActor(Actor):
The Pusher allows to save Report sent by Formula.
"""

def __init__(self, name: str, number_of_reports_to_store: int):
Actor.__init__(self, name)
def __init__(self, name: str, number_of_reports_to_store: int, level_logger: int = logging.WARNING):
Actor.__init__(self, name=name, level_logger=level_logger)
self.state = SimplePusherState(self, number_of_reports_to_store)

def setup(self):
Expand Down
4 changes: 2 additions & 2 deletions powerapi/pusher/simple/simple_pusher_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def handle(self, report: Report):
self.state.actor.logger.debug('received message ' + str(report))
self.save_report(report)
self.state.actor.logger.debug(str(report) + ' saved to list')

self.state.actor.logger.debug("reports saved :" + str(len(self.state.reports)))
self.stop_actor_if_required()

def save_report(self, report: Report):
Expand All @@ -78,8 +78,8 @@ def stop_actor_if_required(self):
"""
if len(self.state.reports) >= self.state.number_of_reports_to_store:
self.state.actor.logger.debug("reports saved :" + str(len(self.state.reports)))
print("reports saved :" + str(len(self.state.reports)))
self.state.actor.send_control(PoisonPillMessage(sender_name='system'))
self.state.alive = 0
self.state.actor.logger.debug("exit request sent")


Expand Down
2 changes: 1 addition & 1 deletion tests/acceptation/crash/test_crash_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@
import os
import pytest

from powerapi.formula import DummyFormulaActor

from tests.utils.acceptation import MainProcess
from tests.utils.acceptation import get_actor_by_name, DISPATCHER_ACTOR_NAME
# noinspection PyUnresolvedReferences
from tests.utils.db.mongo import mongo_database
from tests.utils.formula.dummy import DummyFormulaActor
from tests.utils.report.hwpc import extract_rapl_reports_with_2_sockets


Expand Down
2 changes: 1 addition & 1 deletion tests/acceptation/test_simple_architecture.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
import pymongo

from powerapi.actor import Supervisor
from powerapi.formula.dummy import DummyFormulaActor
from tests.utils.formula.dummy import DummyFormulaActor

from tests.utils.acceptation import launch_simple_architecture, BASIC_CONFIG, SOCKET_DEPTH_LEVEL, \
INFLUX_OUTPUT_CONFIG, CSV_INPUT_OUTPUT_CONFIG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
import pymongo

from powerapi.actor import Supervisor
from powerapi.formula.dummy import DummyFormulaActor
from tests.utils.formula.dummy import DummyFormulaActor
from tests.utils.acceptation import launch_simple_architecture, SOCKET_DEPTH_LEVEL, LIBVIRT_CONFIG
# noinspection PyUnresolvedReferences
from tests.utils.db.mongo import MONGO_URI, MONGO_INPUT_COLLECTION_NAME, MONGO_OUTPUT_COLLECTION_NAME, \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
import pytest

from powerapi.actor import Supervisor
from powerapi.formula.dummy import DummyFormulaActor
from tests.utils.formula.dummy import DummyFormulaActor

from tests.utils.acceptation import launch_simple_architecture, SOCKET_DEPTH_LEVEL, \
get_basic_config_with_stream
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
from powerapi.message import StartMessage
from powerapi.report import HWPCReport, PowerReport
from powerapi.dispatch_rule import HWPCDispatchRule, HWPCDepthLevel
from tests.utils.dummy_actor import DummyActor
from tests.utils.actor.dummy_actor import DummyActor
from tests.utils.report.hwpc import gen_HWPCReports
from tests.unit.actor.abstract_test_actor import recv_from_pipe

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/actor/abstract_test_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from powerapi.pusher import PusherActor
from powerapi.report import PowerReport, HWPCReport
from tests.utils.db import FakeDB
from tests.utils.dummy_actor import DummyActor
from tests.utils.actor.dummy_actor import DummyActor

SENDER_NAME = 'test case'

Expand Down
3 changes: 2 additions & 1 deletion tests/unit/dispatcher/test_dispatcher_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@

from powerapi.dispatch_rule import DispatchRule
from powerapi.dispatcher import DispatcherActor, RouteTable, extract_formula_id
from powerapi.formula import DummyFormulaActor
from powerapi.message import PoisonPillMessage
from powerapi.report import Report, HWPCReport, PowerReport

from tests.unit.actor.abstract_test_actor import AbstractTestActor, recv_from_pipe, is_actor_alive, \
PUSHER_NAME_POWER_REPORT

from tests.utils.formula.dummy import DummyFormulaActor


def define_dispatch_rules(rules):
"""
Expand Down
6 changes: 4 additions & 2 deletions tests/unit/puller/simple/test_simple_puller_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from powerapi.filter import Filter
from powerapi.report import HWPCReport
from powerapi.puller.simple.simple_puller_actor import SimplePullerActor
from tests.utils.dummy_actor import DummyActor
from tests.utils.actor.dummy_actor import DummyActor

from tests.unit.actor.abstract_test_actor import AbstractTestActor, recv_from_pipe, is_actor_alive

Expand Down Expand Up @@ -146,8 +146,10 @@ def test_start_actor_send_reports_to_dispatcher(self,
count = 0
report = REPORT_TYPE_TO_BE_SENT.create_empty_report()

# while count < NUMBER_OF_REPORTS_TO_SEND:
started_actor.send_data(SimplePullerSendReportsMessage('system', ACTOR_NAME))

while count < NUMBER_OF_REPORTS_TO_SEND:
started_actor.send_data(SimplePullerSendReportsMessage('system', ACTOR_NAME))
sleep(1)
assert recv_from_pipe(dummy_pipe_out, 2) == (DISPATCHER_NAME, report)
count += 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# Copyright (c) 2022, INRIA
# Copyright (c) 2022, University of Lille
# Copyright (c) 2023, INRIA
# Copyright (c) 2023, University of Lille
# All rights reserved.

#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:

#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.

#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.

#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.

#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Copyright (c) 2021, INRIA
# Copyright (c) 2021, University of Lille
# Copyright (c) 2022, INRIA
# Copyright (c) 2022, University of Lille
# All rights reserved.

# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -27,34 +27,39 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# pylint: disable=arguments-differ,redefined-outer-name,unused-argument,no-self-use
import pytest
from powerapi.handler import PoisonPillMessageHandler, StartHandler
from powerapi.message import StartMessage, PoisonPillMessage
from powerapi.actor import Actor, State
from tests.utils.actor.dummy_handlers import DummyHandler

from powerapi.formula.dummy import DummyFormulaActor
from powerapi.report import Report
from tests.unit.actor.abstract_test_actor import PUSHER_NAME_POWER_REPORT, AbstractTestActor, recv_from_pipe
LOGGER_NAME = 'multiprocess_test_logger'


class TestDummyFormula(AbstractTestActor):
class DummyActorState(State):
"""
Class for testing the DummyFormulaActor
Message used to start a DummyActor
:param pipe: pipe used to send message to pytest process
"""
@pytest.fixture
def actor(self, started_fake_pusher_power_report):
actor = DummyFormulaActor(name='test_dummy_formula',
pushers={PUSHER_NAME_POWER_REPORT: started_fake_pusher_power_report},
socket=0,
core=0)

return actor
def __init__(self, actor: Actor, pipe):
State.__init__(self, actor)
self.pipe = pipe

def test_send_Report_to_dummy_formula_make_formula_send_power_report_with_42_as_power_value_after_1_second(
self, started_actor, dummy_pipe_out, shutdown_system):

class DummyActor(Actor):
"""
Actor that forward all start message (except StartMessage) into a pipe to the test process
"""

def __init__(self, name: str, pipe, message_type):
Actor.__init__(self, name)
self.state = DummyActorState(self, pipe)
self.message_type = message_type

def setup(self):
"""
Check that a sent report is processed by the actor formula
Define message handler
"""
report1 = Report(1, 2, 3)
started_actor.send_data(report1)

_, msg = recv_from_pipe(dummy_pipe_out, 2)
assert msg.power == 42
self.add_handler(self.message_type, DummyHandler(self.state))
self.add_handler(PoisonPillMessage, PoisonPillMessageHandler(self.state))
self.add_handler(StartMessage, StartHandler(self.state))
51 changes: 51 additions & 0 deletions tests/utils/actor/dummy_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright (c) 2022, INRIA
# Copyright (c) 2022, University of Lille
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import logging

from powerapi.handler import Handler
from powerapi.message import Message


class DummyHandler(Handler):

"""
Dummy actor handler for testing purposes
"""

def __init__(self, state):
Handler.__init__(self, state)

def handle(self, msg: Message):
"""
Handle a message and return a new state value of the actor
:param Object msg: the message received by the actor
"""
self.state.pipe.send((self.state.actor.name, msg))
logging.debug('receive : ' + str(msg), extra={'actor_name': self.state.actor.name})
Loading

0 comments on commit 1d90829

Please sign in to comment.