diff --git a/powerapi-cli/src/main/scala/org/powerapi/app/PowerAPI.scala b/powerapi-cli/src/main/scala/org/powerapi/app/PowerAPI.scala
index 5163a14..572a4e6 100644
--- a/powerapi-cli/src/main/scala/org/powerapi/app/PowerAPI.scala
+++ b/powerapi-cli/src/main/scala/org/powerapi/app/PowerAPI.scala
@@ -31,7 +31,8 @@ import org.powerapi.core.power._
import org.powerapi.module.cpu.dvfs.CpuDvfsModule
import org.powerapi.module.cpu.simple.{SigarCpuSimpleModule, ProcFSCpuSimpleModule}
import org.powerapi.module.libpfm.{LibpfmModule, LibpfmHelper, LibpfmCoreProcessModule, LibpfmCoreModule, LibpfmProcessModule}
-import org.powerapi.module.powerspy.PowerSpyModule
+import org.powerapi.module.extPMeter.powerspy.PowerSpyModule
+import org.powerapi.module.extPMeter.g5k.G5kOmegaWattModule
import scala.concurrent.duration.DurationInt
import scala.sys
import scala.sys.process.stringSeqToProcess
@@ -43,7 +44,7 @@ import scala.sys.process.stringSeqToProcess
* @author Loïc Huertas
*/
object PowerAPI extends App {
- val modulesR = """(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|rapl)(,(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|rapl))*""".r
+ val modulesR = """(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|g5k-omegawatt|rapl)(,(procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-process|powerspy|g5k-omegawatt|rapl))*""".r
val aggR = """max|min|geomean|logsum|mean|median|stdev|sum|variance""".r
val durationR = """\d+""".r
val pidR = """(\d+)""".r
@@ -113,7 +114,7 @@ object PowerAPI extends App {
|You can use different settings per software-defined power meter for some modules by using the optional prefix option.
|Please, refer to the documentation inside the GitHub wiki for further details.
|
- |usage: ./powerapi modules [procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-proces|powerspy|rapl,...] *--prefix [name]* \
+ |usage: ./powerapi modules [procfs-cpu-simple|sigar-cpu-simple|cpu-dvfs|libpfm|libpfm-process|libpfm-core|libpfm-core-proces|powerspy|g5k-omegawatt|rapl,...] *--prefix [name]* \
| monitor --frequency [ms] --targets [pid, ..., app, ...|all] --agg [max|min|geomean|logsum|mean|median|stdev|sum|variance] --[console,file [filepath],chart] \
| duration [s]
|
@@ -180,7 +181,8 @@ object PowerAPI extends App {
case "libpfm-process" => LibpfmProcessModule(powerMeterConf('prefix).asInstanceOf[Option[String]], libpfmHelper.get)
case "libpfm-core" => LibpfmCoreModule(powerMeterConf('prefix).asInstanceOf[Option[String]], libpfmHelper.get)
case "libpfm-core-process" => LibpfmCoreProcessModule(powerMeterConf('prefix).asInstanceOf[Option[String]], libpfmHelper.get)
- case "powerspy" => PowerSpyModule()
+ case "powerspy" => PowerSpyModule(powerMeterConf('prefix).asInstanceOf[Option[String]])
+ case "g5k-omegawatt" => G5kOmegaWattModule(powerMeterConf('prefix).asInstanceOf[Option[String]])
case "rapl" => RAPLModule()
}
}).toSeq
diff --git a/powerapi-core/src/main/scala/org/powerapi/core/ExternalPMeter.scala b/powerapi-core/src/main/scala/org/powerapi/core/ExternalPMeter.scala
index 29b51ad..47cf25f 100644
--- a/powerapi-core/src/main/scala/org/powerapi/core/ExternalPMeter.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/core/ExternalPMeter.scala
@@ -28,7 +28,7 @@ package org.powerapi.core
* @author Maxime Colmant
*/
trait ExternalPMeter {
- def init(): Unit
+ def init(bus: MessageBus): Unit
def start(): Unit
def stop(): Unit
}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyChannel.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterChannel.scala
similarity index 63%
rename from powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyChannel.scala
rename to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterChannel.scala
index a2d27e0..e1e81ad 100644
--- a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyChannel.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterChannel.scala
@@ -20,59 +20,60 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import akka.actor.ActorRef
import org.powerapi.core.{Channel, Message, MessageBus}
import org.powerapi.core.power.Power
/**
- * PowerSpyChannel channel and messages.
+ * ExtPMeterChannel channel and messages.
*
* @author Maxime Colmant
+ * @author Loïc Huertas
*/
-object PowerSpyChannel extends Channel {
+object ExtPMeterChannel extends Channel {
- type M = PowerSpyPower
+ type M = ExtPMeterPower
/**
- * PowerSpyPower is represented as a dedicated type of message.
+ * ExtPMeterPower is represented as a dedicated type of message.
*
* @param topic: subject used for routing the message.
* @param power: power consumption got by an external device.
*/
- case class PowerSpyPower(topic: String,
- power: Power) extends Message
+ case class ExtPMeterPower(topic: String,
+ power: Power) extends Message
/**
* Topic for communicating with the Sensor actor.
*/
- private val pMeterTopic = "powerspy:power"
+ private val pMeterTopic = "extpmeter:power"
/**
* Topic for communicating with the Formula actor.
*/
- private val topic = "sensor:powerspy"
+ private val topic = "sensor:extpmeter"
/**
- * Publish a PowerSpyPower in the event bus.
+ * Publish a ExtPMeterPower in the event bus.
*/
- def publishExternalPowerSpyPower(power: Power): MessageBus => Unit = {
- publish(PowerSpyPower(pMeterTopic, power))
+ def publishExternalPMeterPower(power: Power): MessageBus => Unit = {
+ publish(ExtPMeterPower(pMeterTopic, power))
}
- def publishPowerSpyPower(power: Power): MessageBus => Unit = {
- publish(PowerSpyPower(topic, power))
+ def publishPMeterPower(power: Power): MessageBus => Unit = {
+ publish(ExtPMeterPower(topic, power))
}
/**
* External methods used for interacting with the bus.
*/
- def subscribeExternalPowerSpyPower: MessageBus => ActorRef => Unit = {
+ def subscribeExternalPMeterPower: MessageBus => ActorRef => Unit = {
subscribe(pMeterTopic)
}
- def subscribePowerSpyPower: MessageBus => ActorRef => Unit = {
+ def subscribePMeterPower: MessageBus => ActorRef => Unit = {
subscribe(topic)
}
}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormula.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormula.scala
similarity index 81%
rename from powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormula.scala
rename to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormula.scala
index f3ebce0..b18fbef 100644
--- a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormula.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormula.scala
@@ -20,7 +20,7 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import akka.event.LoggingReceive
import org.powerapi.core.{OSHelper, APIComponent, MessageBus}
@@ -29,7 +29,7 @@ import org.powerapi.core.power._
import org.powerapi.core.target.{Application, All, Process, TargetUsageRatio}
import org.powerapi.module.{Cache, CacheKey}
import org.powerapi.module.PowerChannel.publishRawPowerReport
-import org.powerapi.module.powerspy.PowerSpyChannel.{PowerSpyPower, subscribePowerSpyPower}
+import org.powerapi.module.extPMeter.ExtPMeterChannel.{ExtPMeterPower, subscribePMeterPower}
import scala.reflect.ClassTag
/**
@@ -39,20 +39,21 @@ import scala.reflect.ClassTag
* The simple CpuSensor is used for getting the Target cpu usage ratio (UsageReport).
*
* @author Maxime Colmant
+ * @author Loïc Huertas
*/
-class PowerSpyFormula(eventBus: MessageBus, osHelper: OSHelper, idlePower: Power) extends APIComponent {
+class ExtPMeterFormula(eventBus: MessageBus, osHelper: OSHelper, idlePower: Power) extends APIComponent {
override def preStart(): Unit = {
- subscribePowerSpyPower(eventBus)(self)
+ subscribePMeterPower(eventBus)(self)
subscribeMonitorTick(eventBus)(self)
super.preStart()
}
def receive: PartialFunction[Any, Unit] = running(None)
- def running(pspyPower: Option[PowerSpyPower]): PartialFunction[Any, Unit] = LoggingReceive {
- case msg: PowerSpyPower => context.become(running(Some(msg)))
- case msg: MonitorTick => compute(pspyPower, msg)
+ def running(epmPower: Option[ExtPMeterPower]): PartialFunction[Any, Unit] = LoggingReceive {
+ case msg: ExtPMeterPower => context.become(running(Some(msg)))
+ case msg: MonitorTick => compute(epmPower, msg)
} orElse default
// In order to compute the target's ratio
@@ -98,17 +99,17 @@ class PowerSpyFormula(eventBus: MessageBus, osHelper: OSHelper, idlePower: Power
}
}
- def compute(pSpyPower: Option[PowerSpyPower], monitorTick: MonitorTick): Unit = {
- pSpyPower match {
+ def compute(epmPower: Option[ExtPMeterPower], monitorTick: MonitorTick): Unit = {
+ epmPower match {
case Some(pPower) => {
lazy val dynamicP = if(pPower.power.toMilliWatts - idlePower.toMilliWatts > 0) pPower.power - idlePower else 0.W
monitorTick.target match {
- case All => publishRawPowerReport(monitorTick.muid, monitorTick.target, pPower.power, "PowerSpy", monitorTick.tick)(eventBus)
- case _ => publishRawPowerReport(monitorTick.muid, monitorTick.target, dynamicP * targetCpuUsageRatio(monitorTick).ratio, "PowerSpy", monitorTick.tick)(eventBus)
+ case All => publishRawPowerReport(monitorTick.muid, monitorTick.target, pPower.power, "ExtPMeter", monitorTick.tick)(eventBus)
+ case _ => publishRawPowerReport(monitorTick.muid, monitorTick.target, dynamicP * targetCpuUsageRatio(monitorTick).ratio, "ExtPMeter", monitorTick.tick)(eventBus)
}
}
- case _ => log.debug("{}", "no PowerSpyPower message received")
+ case _ => log.debug("{}", "no ExtPMeterPower message received")
}
}
}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormulaConfiguration.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaConfiguration.scala
similarity index 87%
rename from powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormulaConfiguration.scala
rename to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaConfiguration.scala
index 397cd96..bf6bc84 100644
--- a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyFormulaConfiguration.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaConfiguration.scala
@@ -20,7 +20,7 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import org.powerapi.core.{Configuration, ConfigValue}
import org.powerapi.core.power._
@@ -29,8 +29,9 @@ import org.powerapi.core.power._
* Main configuration.
*
* @author Maxime Colmant
+ * @author Loïc Huertas
*/
-trait PowerSpyFormulaConfiguration extends Configuration {
+trait ExtPMeterFormulaConfiguration extends Configuration {
lazy val idlePower = load { _.getDouble(s"powerapi.hardware.idle-power") } match {
case ConfigValue(idle) => idle.W
case _ => 0.W
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyModule.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterModule.scala
similarity index 67%
rename from powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyModule.scala
rename to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterModule.scala
index 4133b69..27310b8 100644
--- a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyModule.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterModule.scala
@@ -20,17 +20,17 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import org.powerapi.PowerModule
-import org.powerapi.core.{OSHelper, LinuxHelper}
+import org.powerapi.core.{ExternalPMeter, OSHelper}
import org.powerapi.core.power.Power
import scala.concurrent.duration.FiniteDuration
-class PowerSpyModule(osHelper: OSHelper, mac: String, interval: FiniteDuration, idlePower: Power) extends PowerModule {
+class ExtPMeterModule(osHelper: OSHelper, extPMeter: ExternalPMeter, idlePower: Power) extends PowerModule {
lazy val underlyingClasses = eventBus match {
case Some(bus) => {
- (Seq((classOf[PowerSpySensor], Seq(new PowerSpyPMeter(bus, mac, interval)))), Seq((classOf[PowerSpyFormula], Seq(osHelper, idlePower))))
+ (Seq((classOf[ExtPMeterSensor], Seq(extPMeter))), Seq((classOf[ExtPMeterFormula], Seq(osHelper, idlePower))))
}
case _ => (Seq(), Seq())
}
@@ -39,10 +39,3 @@ class PowerSpyModule(osHelper: OSHelper, mac: String, interval: FiniteDuration,
lazy val underlyingFormulaeClasses = underlyingClasses._2
}
-object PowerSpyModule extends PowerSpyFormulaConfiguration with PowerSpyPMeterConfiguration {
- def apply(): PowerSpyModule = {
- val linuxHelper = new LinuxHelper
-
- new PowerSpyModule(linuxHelper, mac, interval, idlePower)
- }
-}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpySensor.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterSensor.scala
similarity index 68%
rename from powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpySensor.scala
rename to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterSensor.scala
index 2df2469..4d9e094 100644
--- a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpySensor.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/ExtPMeterSensor.scala
@@ -20,22 +20,23 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import akka.event.LoggingReceive
import org.powerapi.core.{ExternalPMeter, MessageBus, APIComponent}
-import org.powerapi.module.powerspy.PowerSpyChannel.{PowerSpyPower, publishPowerSpyPower, subscribeExternalPowerSpyPower}
+import org.powerapi.module.extPMeter.ExtPMeterChannel.{ExtPMeterPower, publishPMeterPower, subscribeExternalPMeterPower}
/**
- * PowerSpySensor's implementation by using an helper.
+ * ExtPMeterSensor's implementation by using an helper.
*
* @author Maxime Colmant
+ * @author Loïc Huertas
*/
-class PowerSpySensor(eventBus: MessageBus, pMeter: ExternalPMeter) extends APIComponent {
+class ExtPMeterSensor(eventBus: MessageBus, pMeter: ExternalPMeter) extends APIComponent {
override def preStart(): Unit = {
- subscribeExternalPowerSpyPower(eventBus)(self)
- pMeter.init()
+ subscribeExternalPMeterPower(eventBus)(self)
+ pMeter.init(eventBus)
pMeter.start()
super.preStart()
}
@@ -46,10 +47,10 @@ class PowerSpySensor(eventBus: MessageBus, pMeter: ExternalPMeter) extends APICo
}
def receive: PartialFunction[Any, Unit] = LoggingReceive {
- case msg: PowerSpyPower => sense(msg)
+ case msg: ExtPMeterPower => sense(msg)
} orElse default
- def sense(pSpyPower: PowerSpyPower): Unit = {
- publishPowerSpyPower(pSpyPower.power)(eventBus)
+ def sense(epmPower: ExtPMeterPower): Unit = {
+ publishPMeterPower(epmPower.power)(eventBus)
}
}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kOmegaWattModule.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kOmegaWattModule.scala
new file mode 100644
index 0000000..38bd6cc
--- /dev/null
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kOmegaWattModule.scala
@@ -0,0 +1,35 @@
+/*
+ * This software is licensed under the GNU Affero General Public License, quoted below.
+ *
+ * This file is a part of PowerAPI.
+ *
+ * Copyright (C) 2011-2015 Inria, University of Lille 1.
+ *
+ * PowerAPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * PowerAPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with PowerAPI.
+ *
+ * If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
+ */
+package org.powerapi.module.extPMeter.g5k
+
+import org.powerapi.core.LinuxHelper
+import org.powerapi.module.extPMeter.{ExtPMeterFormulaConfiguration, ExtPMeterModule}
+
+object G5kOmegaWattModule extends ExtPMeterFormulaConfiguration {
+ def apply(prefixConfig: Option[String] = None): ExtPMeterModule = {
+ val conf = new G5kPMeterConfiguration(prefixConfig)
+ val linuxHelper = new LinuxHelper
+
+ new ExtPMeterModule(linuxHelper, new G5kPMeter(conf.probe, conf.interval), idlePower)
+ }
+}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kPMeter.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kPMeter.scala
new file mode 100644
index 0000000..3017bac
--- /dev/null
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kPMeter.scala
@@ -0,0 +1,101 @@
+/*
+ * This software is licensed under the GNU Affero General Public License, quoted below.
+ *
+ * This file is a part of PowerAPI.
+ *
+ * Copyright (C) 2011-2015 Inria, University of Lille 1.
+ *
+ * PowerAPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * PowerAPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with PowerAPI.
+ *
+ * If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
+ */
+package org.powerapi.module.extPMeter.g5k
+
+import org.powerapi.core.{MessageBus, ExternalPMeter}
+import org.powerapi.core.power._
+import org.powerapi.module.extPMeter.ExtPMeterChannel.publishExternalPMeterPower
+import org.apache.logging.log4j.LogManager
+import scala.concurrent.duration.{FiniteDuration, DurationInt}
+import spray.json._
+import DefaultJsonProtocol._
+
+
+case class PowerR(integrated: Double, timestamp: Long, `type`: String, unit: String, value: Double)
+case class Probe(power: PowerR)
+
+object PowerJsonProtocol extends DefaultJsonProtocol {
+ implicit val powerrFormat = jsonFormat5(PowerR)
+ implicit def probeFormat = jsonFormat1(Probe)
+}
+
+/**
+ * Powermeter (Omegawatt) from Grid5000 Lyon site special helper.
+ * @see https://intranet.grid5000.fr/supervision/lyon/wattmetre/
+ *
+ * @author Loïc Huertas
+ */
+class G5kPMeter(probeUrl: String, interval: FiniteDuration) extends ExternalPMeter {
+
+ @volatile private var running = true
+ @volatile private var thread: Option[java.lang.Thread] = None
+
+ protected var eventBus: Option[MessageBus] = None
+
+ private val log = LogManager.getLogger
+
+ def init(bus: MessageBus): Unit = {
+ eventBus = Some(bus)
+ running = true
+ }
+
+ def start(): Unit = {
+ thread match {
+ case None => {
+ val threadInst = new java.lang.Thread {
+ override def run(): Unit = {
+ while(running) {
+ readRealTime() match {
+ case Some(rtValue) if eventBus.get != None => publishExternalPMeterPower(Power(rtValue.value, rtValue.unit))(eventBus.get)
+ case _ => {}
+ }
+ Thread.sleep(interval.toMillis)
+ }
+ }
+ }
+
+ threadInst.start()
+ thread = Some(threadInst)
+ }
+ case _ => log.debug("Connexion already established")
+ }
+ }
+
+ def stop(): Unit = {
+ running = false
+
+ thread match {
+ case Some(thr) => thr.join(1.seconds.toMillis)
+ case _ => log.debug("Call the method start() before stopping.")
+ }
+
+ thread = None
+ }
+
+ private def readRealTime(): Option[PowerR] = {
+ import PowerJsonProtocol._
+ val json = scala.io.Source.fromURL(probeUrl).mkString.parseJson
+ val result = json.asJsObject.fields.head._2.convertTo[Probe]
+ Some(result.power)
+ }
+}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kPMeterConfiguration.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kPMeterConfiguration.scala
new file mode 100644
index 0000000..1e231b0
--- /dev/null
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/g5k/G5kPMeterConfiguration.scala
@@ -0,0 +1,44 @@
+/*
+ * This software is licensed under the GNU Affero General Public License, quoted below.
+ *
+ * This file is a part of PowerAPI.
+ *
+ * Copyright (C) 2011-2015 Inria, University of Lille 1.
+ *
+ * PowerAPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * PowerAPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with PowerAPI.
+ *
+ * If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
+ */
+package org.powerapi.module.extPMeter.g5k
+
+import java.util.concurrent.TimeUnit
+import org.powerapi.core.{ConfigValue, Configuration}
+import scala.concurrent.duration.{FiniteDuration, DurationLong}
+
+/**
+ * Main configuration.
+ *
+ * @author Loïc Huertas
+ */
+class G5kPMeterConfiguration(prefix: Option[String]) extends Configuration(prefix) {
+ lazy val probe: String = load { _.getString(s"${configurationPath}g5k.probe") } match {
+ case ConfigValue(address) => address
+ case _ => ""
+ }
+
+ lazy val interval: FiniteDuration = load { _.getDuration(s"${configurationPath}g5k.interval", TimeUnit.NANOSECONDS) } match {
+ case ConfigValue(value) => value.nanoseconds
+ case _ => 1l.seconds
+ }
+}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyModule.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyModule.scala
new file mode 100644
index 0000000..2f72bc2
--- /dev/null
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyModule.scala
@@ -0,0 +1,35 @@
+/*
+ * This software is licensed under the GNU Affero General Public License, quoted below.
+ *
+ * This file is a part of PowerAPI.
+ *
+ * Copyright (C) 2011-2015 Inria, University of Lille 1.
+ *
+ * PowerAPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * PowerAPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with PowerAPI.
+ *
+ * If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
+ */
+package org.powerapi.module.extPMeter.powerspy
+
+import org.powerapi.core.LinuxHelper
+import org.powerapi.module.extPMeter.{ExtPMeterFormulaConfiguration, ExtPMeterModule}
+
+object PowerSpyModule extends ExtPMeterFormulaConfiguration {
+ def apply(prefixConfig: Option[String] = None): ExtPMeterModule = {
+ val conf = new PowerSpyPMeterConfiguration(prefixConfig)
+ val linuxHelper = new LinuxHelper
+
+ new ExtPMeterModule(linuxHelper, new PowerSpyPMeter(conf.mac, conf.interval), idlePower)
+ }
+}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyPMeter.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyPMeter.scala
similarity index 86%
rename from powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyPMeter.scala
rename to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyPMeter.scala
index 7274e49..6e1d19b 100644
--- a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyPMeter.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyPMeter.scala
@@ -20,12 +20,12 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter.powerspy
import fr.inria.powerspy.core.PowerSpy
import org.powerapi.core.{MessageBus, ExternalPMeter}
import org.powerapi.core.power._
-import org.powerapi.module.powerspy.PowerSpyChannel.publishExternalPowerSpyPower
+import org.powerapi.module.extPMeter.ExtPMeterChannel.publishExternalPMeterPower
import org.apache.logging.log4j.LogManager
import scala.concurrent.duration.{FiniteDuration, DurationInt}
@@ -35,16 +35,19 @@ import scala.concurrent.duration.{FiniteDuration, DurationInt}
*
* @author Maxime Colmant
*/
-class PowerSpyPMeter(eventBus: MessageBus, mac: String, interval: FiniteDuration) extends ExternalPMeter {
+class PowerSpyPMeter(mac: String, interval: FiniteDuration) extends ExternalPMeter {
@volatile private var running = true
@volatile private var thread: Option[java.lang.Thread] = None
@volatile private var powerspy: Option[PowerSpy] = None
+ protected var eventBus: Option[MessageBus] = None
+
private val log = LogManager.getLogger
- def init(): Unit = {
+ def init(bus: MessageBus): Unit = {
powerspy = PowerSpy.init(mac)
+ eventBus = Some(bus)
running = true
}
@@ -66,7 +69,7 @@ class PowerSpyPMeter(eventBus: MessageBus, mac: String, interval: FiniteDuration
override def run(): Unit = {
while(running) {
pSpy.readRealTime() match {
- case Some(rtValue) => publishExternalPowerSpyPower(rtValue.power.W)(eventBus)
+ case Some(rtValue) if eventBus.get != None => publishExternalPMeterPower(rtValue.power.W)(eventBus.get)
case _ => {}
}
}
diff --git a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyPMeterConfiguration.scala b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyPMeterConfiguration.scala
similarity index 78%
rename from powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyPMeterConfiguration.scala
rename to powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyPMeterConfiguration.scala
index 712084f..b502089 100644
--- a/powerapi-core/src/main/scala/org/powerapi/module/powerspy/PowerSpyPMeterConfiguration.scala
+++ b/powerapi-core/src/main/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyPMeterConfiguration.scala
@@ -20,7 +20,7 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter.powerspy
import java.util.concurrent.TimeUnit
import org.powerapi.core.{ConfigValue, Configuration}
@@ -31,13 +31,13 @@ import scala.concurrent.duration.{FiniteDuration, DurationLong}
*
* @author Maxime Colmant
*/
-trait PowerSpyPMeterConfiguration extends Configuration {
- lazy val mac = load { _.getString("powerspy.mac") } match {
+class PowerSpyPMeterConfiguration(prefix: Option[String]) extends Configuration(prefix) {
+ lazy val mac: String = load { _.getString(s"${configurationPath}powerspy.mac") } match {
case ConfigValue(address) => address
case _ => ""
}
- lazy val interval: FiniteDuration = load { _.getDuration("powerspy.interval", TimeUnit.NANOSECONDS) } match {
+ lazy val interval: FiniteDuration = load { _.getDuration(s"${configurationPath}powerspy.interval", TimeUnit.NANOSECONDS) } match {
case ConfigValue(value) => value.nanoseconds
case _ => 1l.seconds
}
diff --git a/powerapi-core/src/test/resources/configuration-suite.conf b/powerapi-core/src/test/resources/configuration-suite.conf
index bf345dc..467e0fd 100644
--- a/powerapi-core/src/test/resources/configuration-suite.conf
+++ b/powerapi-core/src/test/resources/configuration-suite.conf
@@ -86,9 +86,12 @@ powerapi.libpfm.NR-perf-event-open = 128
powerapi.hardware.idle-power = 87.50
-powerspy.mac = "00:0B:CE:07:1E:9B"
+powerspy.mac = "00:06:66:4D:F4:BB"
powerspy.interval = 250ms
+g5k.probe = "http://kwapi.lyon.grid5000.fr:5000/probes/lyon.taurus-1/power/"
+g5k.interval = 250ms
+
powerapi.procfs.cpu-info-path = "p1"
powerapi.cpu.msr-path = "p2"
diff --git a/powerapi-core/src/test/scala/org/powerapi/PowerMeterSuite.scala b/powerapi-core/src/test/scala/org/powerapi/PowerMeterSuite.scala
index 722c308..39fecae 100644
--- a/powerapi-core/src/test/scala/org/powerapi/PowerMeterSuite.scala
+++ b/powerapi-core/src/test/scala/org/powerapi/PowerMeterSuite.scala
@@ -25,14 +25,21 @@ package org.powerapi
import akka.actor.{Props, ActorSystem}
import akka.testkit.{TestActorRef, TestKit}
import akka.util.Timeout
-import org.powerapi.core.MessageBus
+import org.powerapi.core.{ExternalPMeter, MessageBus}
import org.powerapi.module.cpu.dvfs.CpuDvfsModule
import org.powerapi.module.cpu.simple.{SigarCpuSimpleModule, ProcFSCpuSimpleModule}
import org.powerapi.module.libpfm.{LibpfmCoreProcessModule, LibpfmCoreSensorModule, LibpfmHelper, LibpfmCoreModule, LibpfmModule, LibpfmProcessModule}
-import org.powerapi.module.powerspy.PowerSpyModule
+import org.powerapi.module.extPMeter.powerspy.PowerSpyModule
+import org.powerapi.module.extPMeter.g5k.G5kOmegaWattModule
import org.powerapi.module.rapl.RAPLModule
import scala.concurrent.duration.DurationInt
+class MockPMeter extends ExternalPMeter {
+ def init(bus: MessageBus): Unit = {}
+ def start(): Unit = {}
+ def stop(): Unit = {}
+}
+
class PowerMeterSuite(system: ActorSystem) extends UnitTest(system) {
implicit val timeout = Timeout(1.seconds)
@@ -102,7 +109,12 @@ class PowerMeterSuite(system: ActorSystem) extends UnitTest(system) {
}
it should "load the PowerSpyModule" ignore new EventBus {
- val actor = TestActorRef(Props(classOf[PowerMeterActor], eventBus, Seq(PowerSpyModule()), Timeout(1.seconds)))(system)
+ val actor = TestActorRef(Props(classOf[PowerMeterActor], eventBus, Seq(PowerSpyModule(None)), Timeout(1.seconds)))(system)
+ actor.children.size should equal(4)
+ }
+
+ it should "load the G5kOmegaWattModule" ignore new EventBus {
+ val actor = TestActorRef(Props(classOf[PowerMeterActor], eventBus, Seq(G5kOmegaWattModule(None)), Timeout(1.seconds)))(system)
actor.children.size should equal(4)
}
diff --git a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyFormulaConfigurationSuite.scala b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaConfigurationSuite.scala
similarity index 77%
rename from powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyFormulaConfigurationSuite.scala
rename to powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaConfigurationSuite.scala
index 4eb097f..efa642b 100644
--- a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyFormulaConfigurationSuite.scala
+++ b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaConfigurationSuite.scala
@@ -20,7 +20,7 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import akka.actor.ActorSystem
import akka.testkit.TestKit
@@ -29,18 +29,18 @@ import org.powerapi.UnitTest
import org.powerapi.core.power._
import scala.concurrent.duration.DurationInt
-class PowerSpyFormulaConfigurationSuite(system: ActorSystem) extends UnitTest(system) {
+class ExtPMeterFormulaConfigurationSuite(system: ActorSystem) extends UnitTest(system) {
implicit val timeout = Timeout(1.seconds)
- def this() = this(ActorSystem("PowerSpyFormulaConfigurationSuite"))
+ def this() = this(ActorSystem("ExtPMeterFormulaConfigurationSuite"))
override def afterAll() = {
TestKit.shutdownActorSystem(system)
}
- "The PowerSpyFormulaConfiguration" should "read correctly the values from a resource file" in {
- val configuration = new PowerSpyFormulaConfiguration {}
+ "The ExtPMeterFormulaConfiguration" should "read correctly the values from a resource file" in {
+ val configuration = new ExtPMeterFormulaConfiguration {}
configuration.idlePower should equal(87.50.W)
}
diff --git a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyFormulaSuite.scala b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaSuite.scala
similarity index 91%
rename from powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyFormulaSuite.scala
rename to powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaSuite.scala
index f91ba81..391e256 100644
--- a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyFormulaSuite.scala
+++ b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterFormulaSuite.scala
@@ -20,7 +20,7 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import akka.actor.{ActorSystem, Props}
import akka.testkit.{TestActorRef, TestKit}
@@ -32,18 +32,18 @@ import org.powerapi.core.{OSHelper, MessageBus, Thread, TimeInStates}
import org.powerapi.core.MonitorChannel.publishMonitorTick
import org.powerapi.core.target.{All, Application, intToProcess, Process, Target, TargetUsageRatio}
import org.powerapi.module.PowerChannel.{RawPowerReport, subscribeRawPowerReport}
-import org.powerapi.module.powerspy.PowerSpyChannel.publishPowerSpyPower
+import org.powerapi.module.extPMeter.ExtPMeterChannel.publishPMeterPower
import scala.concurrent.duration.DurationInt
-class PowerSpyFormulaSuite(system: ActorSystem) extends UnitTest(system) {
+class ExtPMeterFormulaSuite(system: ActorSystem) extends UnitTest(system) {
- def this() = this(ActorSystem("PowerSpyFormulaSuite"))
+ def this() = this(ActorSystem("ExtPMeterFormulaSuite"))
override def afterAll() = {
TestKit.shutdownActorSystem(system)
}
- "A PowerSpyFormula" should "listen PowerSpyPower/UsageReport messages and produce PowerReport messages" in {
+ "A ExtPMeterFormula" should "listen ExtPMeterPower/UsageReport messages and produce PowerReport messages" in {
val eventBus = new MessageBus
val globalElapsedTime1: Long = 43171 + 1 + 24917 + 25883594 + 1160 + 19 + 1477 + 0
@@ -66,7 +66,7 @@ class PowerSpyFormulaSuite(system: ActorSystem) extends UnitTest(system) {
val processRatio1 = TargetUsageRatio((p1ElapsedTime - oldP1ElapsedTime).toDouble / (activeElapsedTime1 - oldActiveElapsedTime1))
val processRatio2 = TargetUsageRatio((p2ElapsedTime - oldP2ElapsedTime).toDouble / (activeElapsedTime2 - oldActiveElapsedTime2))
- TestActorRef(Props(classOf[PowerSpyFormula], eventBus, new OSHelper {
+ TestActorRef(Props(classOf[ExtPMeterFormula], eventBus, new OSHelper {
import org.powerapi.core.GlobalCpuTime
private var targetTimes = Map[Target, List[Long]](
@@ -120,7 +120,7 @@ class PowerSpyFormulaSuite(system: ActorSystem) extends UnitTest(system) {
publishMonitorTick(muid1, 1, tickMock)(eventBus)
expectNoMsg(3.seconds)
- publishPowerSpyPower(120.W)(eventBus)
+ publishPMeterPower(120.W)(eventBus)
publishMonitorTick(muid1, 1, tickMock)(eventBus)
var ret = expectMsgClass(classOf[RawPowerReport])
@@ -143,7 +143,7 @@ class PowerSpyFormulaSuite(system: ActorSystem) extends UnitTest(system) {
ret.power should equal(120.W)
ret.tick should equal(tickMock)
- publishPowerSpyPower(150.W)(eventBus)
+ publishPMeterPower(150.W)(eventBus)
publishMonitorTick(muid1, 1, tickMock)(eventBus)
ret = expectMsgClass(classOf[RawPowerReport])
@@ -158,7 +158,7 @@ class PowerSpyFormulaSuite(system: ActorSystem) extends UnitTest(system) {
ret.power should equal((processRatio2.ratio * (150 - 90)).W)
ret.tick should equal(tickMock)
- publishPowerSpyPower(140.W)(eventBus)
+ publishPMeterPower(140.W)(eventBus)
publishMonitorTick(muid3, All, tickMock)(eventBus)
ret = expectMsgClass(classOf[RawPowerReport])
diff --git a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyModulesSuite.scala b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterModulesSuite.scala
similarity index 77%
rename from powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyModulesSuite.scala
rename to powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterModulesSuite.scala
index d8f1966..979a591 100644
--- a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyModulesSuite.scala
+++ b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterModulesSuite.scala
@@ -20,29 +20,29 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter
import java.util.UUID
import akka.actor.ActorSystem
import akka.testkit.TestKit
import akka.util.Timeout
import org.powerapi.UnitTest
-import org.powerapi.core.{MessageBus, GlobalCpuTime, TimeInStates, OSHelper, Thread}
+import org.powerapi.core.{ExternalPMeter, MessageBus, GlobalCpuTime, TimeInStates, OSHelper, Thread}
import org.powerapi.core.target.{Application, TargetUsageRatio, Process}
import org.powerapi.core.power._
import scala.concurrent.duration.DurationInt
-class PowerSpyModulesSuite(system: ActorSystem) extends UnitTest(system) {
+class ExtPMeterModulesSuite(system: ActorSystem) extends UnitTest(system) {
implicit val timeout = Timeout(1.seconds)
- def this() = this(ActorSystem("PowerSpyModulesSuite"))
+ def this() = this(ActorSystem("ExtPMeterModulesSuite"))
override def afterAll() = {
TestKit.shutdownActorSystem(system)
}
- "The PowerSpyModule class" should "create the underlying classes (sensors/formulae)" in {
+ "The ExtPMeterModule class" should "create the underlying classes (sensors/formulae)" in {
val osHelper = new OSHelper {
override def getCPUFrequencies: Set[Long] = Set()
override def getThreads(process: Process): Set[Thread] = Set()
@@ -53,17 +53,23 @@ class PowerSpyModulesSuite(system: ActorSystem) extends UnitTest(system) {
override def getGlobalCpuTime: GlobalCpuTime = GlobalCpuTime(0, 0)
override def getProcesses(application: Application): Set[Process] = Set()
}
+
+ val mockPMeter = new ExternalPMeter {
+ def init(bus: MessageBus): Unit = {}
+ def start(): Unit = {}
+ def stop(): Unit = {}
+ }
- val module = new PowerSpyModule(osHelper, "00:00:00:00:00:00", 10.seconds, 1.W) {
+ val module = new ExtPMeterModule(osHelper, mockPMeter, 1.W) {
eventBus = Some(new MessageBus)
}
module.underlyingSensorsClasses.size should equal(1)
- module.underlyingSensorsClasses(0)._1 should equal(classOf[PowerSpySensor])
+ module.underlyingSensorsClasses(0)._1 should equal(classOf[ExtPMeterSensor])
module.underlyingSensorsClasses(0)._2.size should equal(1)
- module.underlyingSensorsClasses(0)._2(0).getClass should equal(classOf[PowerSpyPMeter])
+ module.underlyingSensorsClasses(0)._2(0).getClass should equal(mockPMeter.getClass)
module.underlyingFormulaeClasses.size should equal(1)
- module.underlyingFormulaeClasses(0)._1 should equal(classOf[PowerSpyFormula])
+ module.underlyingFormulaeClasses(0)._1 should equal(classOf[ExtPMeterFormula])
module.underlyingFormulaeClasses(0)._2.size should equal(2)
module.underlyingFormulaeClasses(0)._2(0) should equal(osHelper)
module.underlyingFormulaeClasses(0)._2(1) should equal(1.W)
diff --git a/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterSensorSuite.scala b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterSensorSuite.scala
new file mode 100644
index 0000000..0329eba
--- /dev/null
+++ b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/ExtPMeterSensorSuite.scala
@@ -0,0 +1,107 @@
+/*
+ * This software is licensed under the GNU Affero General Public License, quoted below.
+ *
+ * This file is a part of PowerAPI.
+ *
+ * Copyright (C) 2011-2015 Inria, University of Lille 1.
+ *
+ * PowerAPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * PowerAPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with PowerAPI.
+ *
+ * If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
+ */
+package org.powerapi.module.extPMeter
+
+import akka.actor.{Actor, ActorSystem, Props}
+import akka.pattern.gracefulStop
+import akka.testkit.{TestActorRef, TestKit}
+import akka.util.Timeout
+import org.powerapi.UnitTest
+import org.powerapi.core.{MessageBus, ExternalPMeter}
+import org.powerapi.module.extPMeter.ExtPMeterChannel.publishExternalPMeterPower
+import org.powerapi.core.power._
+import org.powerapi.module.extPMeter.ExtPMeterChannel.{ExtPMeterPower, subscribePMeterPower}
+import org.powerapi.module.extPMeter.powerspy.PowerSpyPMeter
+import org.powerapi.module.extPMeter.g5k.G5kPMeter
+import scala.concurrent.duration.DurationInt
+
+class MockPMeter(eventBus: MessageBus) extends ExternalPMeter {
+ def init(bus: MessageBus): Unit = {}
+ def start(): Unit = {
+ publishExternalPMeterPower(10.W)(eventBus)
+ publishExternalPMeterPower(20.W)(eventBus)
+ publishExternalPMeterPower(14.W)(eventBus)
+ }
+ def stop(): Unit = {}
+}
+
+class ExtPMeterPowerListener(eventBus: MessageBus) extends Actor {
+ override def preStart(): Unit = {
+ subscribePMeterPower(eventBus)(self)
+ }
+
+ def receive = {
+ case msg: ExtPMeterPower => println(msg)
+ }
+}
+
+class ExtPMeterSensorSuite(system: ActorSystem) extends UnitTest(system) {
+ implicit val timeout = Timeout(1.seconds)
+
+ def this() = this(ActorSystem("ExtPMeterSensorSuite"))
+
+ override def afterAll() = {
+ TestKit.shutdownActorSystem(system)
+ }
+
+ trait EventBus {
+ val eventBus = new MessageBus
+ }
+
+ "A ExtPMeterSensor" should "listen ExtPMeterPower messages, build a new message and then publish it" in new EventBus {
+ subscribePMeterPower(eventBus)(testActor)
+ val extpmSensor = TestActorRef(Props(classOf[ExtPMeterSensor], eventBus, new MockPMeter(eventBus)), "extpmSensor")(system)
+
+ expectMsgClass(classOf[ExtPMeterPower]) match {
+ case ExtPMeterPower(_, power) => power should equal(10.W)
+ }
+ expectMsgClass(classOf[ExtPMeterPower]) match {
+ case ExtPMeterPower(_, power) => power should equal(20.W)
+ }
+ expectMsgClass(classOf[ExtPMeterPower]) match {
+ case ExtPMeterPower(_, power) => power should equal(14.W)
+ }
+
+ gracefulStop(extpmSensor, 15.seconds)
+ }
+
+ it should "open the connection with the PowerSpy, build new messages and then publish them" ignore new EventBus {
+ val listener = TestActorRef(Props(classOf[ExtPMeterPowerListener], eventBus), "listener")(system)
+ val extpmSensor = TestActorRef(Props(classOf[ExtPMeterSensor], eventBus, new PowerSpyPMeter("00:06:66:4D:F4:BB", 1.seconds)), "pSpySensor")(system)
+
+ Thread.sleep(15.seconds.toMillis)
+
+ gracefulStop(extpmSensor, 15.seconds)
+ gracefulStop(listener, 15.seconds)
+ }
+
+ it should "open the connection with the grid5000 OmegaWatt, build new messages and then publish them" ignore new EventBus {
+ val listener = TestActorRef(Props(classOf[ExtPMeterPowerListener], eventBus), "listener")(system)
+ val extpmSensor = TestActorRef(Props(classOf[ExtPMeterSensor], eventBus, new G5kPMeter("http://kwapi.lyon.grid5000.fr:5000/probes/lyon.taurus-1/power/", 1.seconds)), "g5kowSensor")(system)
+
+ Thread.sleep(15.seconds.toMillis)
+
+ gracefulStop(extpmSensor, 15.seconds)
+ gracefulStop(listener, 15.seconds)
+ }
+}
diff --git a/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/g5k/G5kConfigurationSuite.scala b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/g5k/G5kConfigurationSuite.scala
new file mode 100644
index 0000000..48a9745
--- /dev/null
+++ b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/g5k/G5kConfigurationSuite.scala
@@ -0,0 +1,47 @@
+/*
+ * This software is licensed under the GNU Affero General Public License, quoted below.
+ *
+ * This file is a part of PowerAPI.
+ *
+ * Copyright (C) 2011-2015 Inria, University of Lille 1.
+ *
+ * PowerAPI is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * PowerAPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with PowerAPI.
+ *
+ * If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
+ */
+package org.powerapi.module.extPMeter.g5k
+
+import akka.actor.ActorSystem
+import akka.testkit.TestKit
+import akka.util.Timeout
+import org.powerapi.UnitTest
+import scala.concurrent.duration.DurationInt
+
+class G5kPMeterConfigurationSuite(system: ActorSystem) extends UnitTest(system) {
+
+ implicit val timeout = Timeout(1.seconds)
+
+ def this() = this(ActorSystem("G5kPMeterConfigurationSuite"))
+
+ override def afterAll() = {
+ TestKit.shutdownActorSystem(system)
+ }
+
+ "The G5kPMeterConfiguration" should "read correctly the values from a resource file" in {
+ val configuration = new G5kPMeterConfiguration(None)
+
+ configuration.probe should equal("http://kwapi.lyon.grid5000.fr:5000/probes/lyon.taurus-1/power/")
+ configuration.interval should equal(250.milliseconds)
+ }
+}
diff --git a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyPMeterConfigurationSuite.scala b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyConfigurationSuite.scala
similarity index 89%
rename from powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyPMeterConfigurationSuite.scala
rename to powerapi-core/src/test/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyConfigurationSuite.scala
index 1c4f7f2..ea27a91 100644
--- a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpyPMeterConfigurationSuite.scala
+++ b/powerapi-core/src/test/scala/org/powerapi/module/extPMeter/powerspy/PowerSpyConfigurationSuite.scala
@@ -20,7 +20,7 @@
*
* If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
*/
-package org.powerapi.module.powerspy
+package org.powerapi.module.extPMeter.powerspy
import akka.actor.ActorSystem
import akka.testkit.TestKit
@@ -39,9 +39,9 @@ class PowerSpyPMeterConfigurationSuite(system: ActorSystem) extends UnitTest(sys
}
"The PowerSpyPMeterConfiguration" should "read correctly the values from a resource file" in {
- val configuration = new PowerSpyPMeterConfiguration {}
+ val configuration = new PowerSpyPMeterConfiguration(None)
- configuration.mac should equal("00:0B:CE:07:1E:9B")
+ configuration.mac should equal("00:06:66:4D:F4:BB")
configuration.interval should equal(250.milliseconds)
}
}
diff --git a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpySensorSuite.scala b/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpySensorSuite.scala
deleted file mode 100644
index 4693a8c..0000000
--- a/powerapi-core/src/test/scala/org/powerapi/module/powerspy/PowerSpySensorSuite.scala
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * This software is licensed under the GNU Affero General Public License, quoted below.
- *
- * This file is a part of PowerAPI.
- *
- * Copyright (C) 2011-2015 Inria, University of Lille 1.
- *
- * PowerAPI is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * PowerAPI is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with PowerAPI.
- *
- * If not, please consult http://www.gnu.org/licenses/agpl-3.0.html.
- */
-package org.powerapi.module.powerspy
-
-import akka.actor.{Actor, ActorSystem, Props}
-import akka.pattern.gracefulStop
-import akka.testkit.{TestActorRef, TestKit}
-import akka.util.Timeout
-import org.powerapi.UnitTest
-import org.powerapi.core.{MessageBus, ExternalPMeter}
-import org.powerapi.module.powerspy.PowerSpyChannel.publishExternalPowerSpyPower
-import org.powerapi.core.power._
-import org.powerapi.module.powerspy.PowerSpyChannel.{PowerSpyPower, subscribePowerSpyPower}
-import scala.concurrent.duration.DurationInt
-
-class MockPMeter(eventBus: MessageBus) extends ExternalPMeter {
- def init(): Unit = {}
- def start(): Unit = {
- publishExternalPowerSpyPower(10.W)(eventBus)
- publishExternalPowerSpyPower(20.W)(eventBus)
- publishExternalPowerSpyPower(14.W)(eventBus)
- }
- def stop(): Unit = {}
-}
-
-class PowerSpyPowerListener(eventBus: MessageBus) extends Actor {
- override def preStart(): Unit = {
- subscribePowerSpyPower(eventBus)(self)
- }
-
- def receive = {
- case msg: PowerSpyPower => println(msg)
- }
-}
-
-class PowerSpySensorSuite(system: ActorSystem) extends UnitTest(system) {
- implicit val timeout = Timeout(1.seconds)
-
- def this() = this(ActorSystem("PowerSpySensorSuite"))
-
- override def afterAll() = {
- TestKit.shutdownActorSystem(system)
- }
-
- trait EventBus {
- val eventBus = new MessageBus
- }
-
- "A PowerSpySensor" should "listen PowerSpyPower messages, build a new message and then publish it" in new EventBus {
- subscribePowerSpyPower(eventBus)(testActor)
- val pSpySensor = TestActorRef(Props(classOf[PowerSpySensor], eventBus, new MockPMeter(eventBus)), "pSpySensor")(system)
-
- expectMsgClass(classOf[PowerSpyPower]) match {
- case PowerSpyPower(_, power) => power should equal(10.W)
- }
- expectMsgClass(classOf[PowerSpyPower]) match {
- case PowerSpyPower(_, power) => power should equal(20.W)
- }
- expectMsgClass(classOf[PowerSpyPower]) match {
- case PowerSpyPower(_, power) => power should equal(14.W)
- }
-
- gracefulStop(pSpySensor, 15.seconds)
- }
-
- it should "open the connection with the power meter, build new messages and then publish them" ignore new EventBus {
- val listener = TestActorRef(Props(classOf[PowerSpyPowerListener], eventBus), "listener")(system)
- val pSpySensor = TestActorRef(Props(classOf[PowerSpySensor], eventBus, new PowerSpyPMeter(eventBus, "00:0b:ce:07:1e:9b", 1.seconds)), "pSpySensor")(system)
-
- Thread.sleep(15.seconds.toMillis)
-
- gracefulStop(pSpySensor, 15.seconds)
- gracefulStop(listener, 15.seconds)
- }
-}
diff --git a/powerapi-daemon/src/main/scala/org/powerapi/daemon/PowerAPId.scala b/powerapi-daemon/src/main/scala/org/powerapi/daemon/PowerAPId.scala
index 297ff6e..474a6c3 100644
--- a/powerapi-daemon/src/main/scala/org/powerapi/daemon/PowerAPId.scala
+++ b/powerapi-daemon/src/main/scala/org/powerapi/daemon/PowerAPId.scala
@@ -40,7 +40,8 @@ import org.powerapi.core.power._
import org.powerapi.module.cpu.dvfs.CpuDvfsModule
import org.powerapi.module.cpu.simple.{SigarCpuSimpleModule, ProcFSCpuSimpleModule}
import org.powerapi.module.libpfm.{LibpfmHelper, LibpfmCoreProcessModule, LibpfmCoreModule}
-import org.powerapi.module.powerspy.PowerSpyModule
+import org.powerapi.module.extPMeter.powerspy.PowerSpyModule
+import org.powerapi.module.extPMeter.g5k.G5kOmegaWattModule
/**
* PowerAPI daemon.
@@ -113,7 +114,8 @@ class PowerAPId extends Daemon {
libpfmHelper.get.init()
LibpfmCoreProcessModule(None, libpfmHelper.get)
}
- case "powerspy" => PowerSpyModule()
+ case "powerspy" => PowerSpyModule(None)
+ case "g5k-omegawatt" => G5kOmegaWattModule(None)
case "rapl" => RAPLModule()
}
}).toSeq
diff --git a/powerapi-sampling/src/main/scala/org/powerapi/sampling/Sampling.scala b/powerapi-sampling/src/main/scala/org/powerapi/sampling/Sampling.scala
index 2345807..357dbcc 100644
--- a/powerapi-sampling/src/main/scala/org/powerapi/sampling/Sampling.scala
+++ b/powerapi-sampling/src/main/scala/org/powerapi/sampling/Sampling.scala
@@ -32,7 +32,7 @@ import org.powerapi.module.libpfm.{LibpfmHelper, LibpfmCoreSensorModule}
import org.powerapi.module.libpfm.PerformanceCounterChannel.{subscribePCReport, PCReport}
import org.powerapi.core.power._
import org.powerapi.core.target.All
-import org.powerapi.module.powerspy.PowerSpyModule
+import org.powerapi.module.extPMeter.powerspy.PowerSpyModule
import scala.concurrent.duration.DurationInt
import scala.sys.process.{ProcessLogger, stringSeqToProcess}
import scala.concurrent.ExecutionContext.Implicits.global
@@ -356,7 +356,7 @@ object Sampling {
def apply(outputPath: String, configuration: SamplingConfiguration, libpfmHelper: LibpfmHelper): Sampling = {
libpfmHelper.init()
powerapi = Some(PowerMeter.loadModule(LibpfmCoreSensorModule(None, libpfmHelper, configuration.events)))
- externalPMeter = Some(PowerMeter.loadModule(PowerSpyModule()))
+ externalPMeter = Some(PowerMeter.loadModule(PowerSpyModule(None)))
new Sampling(outputPath, configuration, libpfmHelper, powerapi.get, externalPMeter.get)
}
}