You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iota.apache.org by to...@apache.org on 2016/07/21 23:37:55 UTC

[04/10] incubator-iota git commit: Adding tests for Monitor.scala

Adding tests for Monitor.scala


Project: http://git-wip-us.apache.org/repos/asf/incubator-iota/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-iota/commit/d3db1525
Tree: http://git-wip-us.apache.org/repos/asf/incubator-iota/tree/d3db1525
Diff: http://git-wip-us.apache.org/repos/asf/incubator-iota/diff/d3db1525

Branch: refs/heads/master
Commit: d3db1525228fa2b15e693760c650c909f0558b6b
Parents: db380c0
Author: Barbara Gomes <ba...@gmail.com>
Authored: Tue Jul 19 14:03:11 2016 -0700
Committer: Barbara Gomes <ba...@gmail.com>
Committed: Tue Jul 19 14:03:11 2016 -0700

----------------------------------------------------------------------
 .../scala/org/apache/iota/fey/Application.scala |   2 +-
 .../org/apache/iota/fey/IdentifyFeyActors.scala |   2 +-
 .../scala/org/apache/iota/fey/Monitor.scala     |  17 +--
 .../scala/org/apache/iota/fey/TrieNode.scala    |  51 ++++++-
 .../apache/iota/fey/IdentifyFeyActorsSpec.scala |   4 +-
 .../scala/org/apache/iota/fey/MonitorSpec.scala | 148 +++++++++++++++++++
 6 files changed, 210 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-iota/blob/d3db1525/fey-core/src/main/scala/org/apache/iota/fey/Application.scala
----------------------------------------------------------------------
diff --git a/fey-core/src/main/scala/org/apache/iota/fey/Application.scala b/fey-core/src/main/scala/org/apache/iota/fey/Application.scala
index 635bb09..eb08d63 100644
--- a/fey-core/src/main/scala/org/apache/iota/fey/Application.scala
+++ b/fey-core/src/main/scala/org/apache/iota/fey/Application.scala
@@ -55,5 +55,5 @@ object SYSTEM_ACTORS{
 object FEY_MONITOR{
   import FEY_SYSTEM._
 
-  val actorRef = system.actorOf(Props[Monitor], "FEY-MONITOR")
+  val actorRef = system.actorOf(Props(new Monitor(Monitor.events)), "FEY-MONITOR")
 }

http://git-wip-us.apache.org/repos/asf/incubator-iota/blob/d3db1525/fey-core/src/main/scala/org/apache/iota/fey/IdentifyFeyActors.scala
----------------------------------------------------------------------
diff --git a/fey-core/src/main/scala/org/apache/iota/fey/IdentifyFeyActors.scala b/fey-core/src/main/scala/org/apache/iota/fey/IdentifyFeyActors.scala
index f3852fe..ad51bb2 100644
--- a/fey-core/src/main/scala/org/apache/iota/fey/IdentifyFeyActors.scala
+++ b/fey-core/src/main/scala/org/apache/iota/fey/IdentifyFeyActors.scala
@@ -81,7 +81,7 @@ protected object IdentifyFeyActors{
     * @return string JSON
     */
   def generateTreeJson(): String = {
-    val trie = new Trie()
+    val trie = new Trie("FEY-MANAGEMENT-SYSTEM")
     actorsPath.map(_.replace("user/","")).foreach(trie.append(_))
 
     Json.stringify(trie.print)

http://git-wip-us.apache.org/repos/asf/incubator-iota/blob/d3db1525/fey-core/src/main/scala/org/apache/iota/fey/Monitor.scala
----------------------------------------------------------------------
diff --git a/fey-core/src/main/scala/org/apache/iota/fey/Monitor.scala b/fey-core/src/main/scala/org/apache/iota/fey/Monitor.scala
index 3c02e73..2de05b9 100644
--- a/fey-core/src/main/scala/org/apache/iota/fey/Monitor.scala
+++ b/fey-core/src/main/scala/org/apache/iota/fey/Monitor.scala
@@ -25,35 +25,34 @@ import scala.collection.mutable.ArrayBuffer
 /**
   * Created by barbaragomes on 7/8/16.
   */
-protected class Monitor extends Actor {
+protected class Monitor(eventsStore: Trie) extends Actor {
 
   import Monitor._
 
   val log: DiagnosticLoggingAdapter = Logging(this)
   log.mdc(Map("fileName" -> "monitor_events"))
 
-  override def postStop() = {
+  override def postStop(): Unit = {
     log.clearMDC()
   }
 
-
   override def receive: Receive = {
 
     case START(timestamp, info) =>
       logInfo(sender().path.toString, EVENTS.START, timestamp, info)
-      events.append(sender().path.toString,MonitorEvent(EVENTS.START, timestamp, info))
+      eventsStore.append(sender().path.toString,MonitorEvent(EVENTS.START, timestamp, info))
 
     case STOP(timestamp, info) =>
       logInfo(sender().path.toString, EVENTS.STOP, timestamp, info)
-      events.append(sender().path.toString,MonitorEvent(EVENTS.STOP, timestamp, info))
+      eventsStore.append(sender().path.toString,MonitorEvent(EVENTS.STOP, timestamp, info))
 
     case RESTART(reason, timestamp) =>
       logInfo(sender().path.toString, EVENTS.RESTART, timestamp, "", reason)
-      events.append(sender().path.toString,MonitorEvent(EVENTS.RESTART, timestamp, reason.getMessage))
+      eventsStore.append(sender().path.toString,MonitorEvent(EVENTS.RESTART, timestamp, reason.getMessage))
 
     case TERMINATE(actorPath, timestamp, info) =>
-      logInfo(sender().path.toString, EVENTS.TERMINATE, timestamp, info)
-      events.append(actorPath,MonitorEvent(EVENTS.TERMINATE, timestamp, info))
+      logInfo(actorPath, EVENTS.TERMINATE, timestamp, info)
+      eventsStore.append(actorPath,MonitorEvent(EVENTS.TERMINATE, timestamp, info))
 
   }
 
@@ -80,7 +79,7 @@ protected object Monitor{
   /**
     * Contains the lifecycle events for actors in Fey
     */
-  val events: Trie = new Trie()
+  val events: Trie = new Trie("FEY-MANAGEMENT-SYSTEM")
 
   //Static HTML content from d3
   val html = scala.io.Source.fromInputStream(getClass.getResourceAsStream("/eventsTable.html"), "UTF-8")

http://git-wip-us.apache.org/repos/asf/incubator-iota/blob/d3db1525/fey-core/src/main/scala/org/apache/iota/fey/TrieNode.scala
----------------------------------------------------------------------
diff --git a/fey-core/src/main/scala/org/apache/iota/fey/TrieNode.scala b/fey-core/src/main/scala/org/apache/iota/fey/TrieNode.scala
index 517abd5..4de3da7 100644
--- a/fey-core/src/main/scala/org/apache/iota/fey/TrieNode.scala
+++ b/fey-core/src/main/scala/org/apache/iota/fey/TrieNode.scala
@@ -27,9 +27,9 @@ import scala.collection.mutable.ArrayBuffer
  */
 case class TrieNode(path: String, children: ArrayBuffer[TrieNode], events:ArrayBuffer[Monitor.MonitorEvent])
 
-class Trie{
+protected class Trie(systemName: String){
 
-  private val root: TrieNode = TrieNode("FEY-MANAGEMENT-SYSTEM", ArrayBuffer.empty, ArrayBuffer.empty)
+  private val root: TrieNode = TrieNode(systemName, ArrayBuffer.empty, ArrayBuffer.empty)
   var elements: Int = 0
 
   def append(path: String, event: Monitor.MonitorEvent = null): Unit = {
@@ -51,6 +51,53 @@ class Trie{
     }
   }
 
+  def hasPath(path: String): Boolean = {
+    recHasPath(root, path.replaceFirst("akka://","").split("/"),1)
+  }
+
+  @tailrec private def recHasPath(root: TrieNode, path: Array[String], index: Int): Boolean = {
+    if(root != null && index < path.length) {
+      var nextRoot = root.children.filter(child => child.path == path(index))
+      if(nextRoot.isEmpty){
+        false
+      }else{
+        recHasPath(nextRoot(0), path, index + 1)
+      }
+    }else{
+      true
+    }
+  }
+
+  def getNode(path: String): Option[TrieNode] = {
+    recGetNode(root, path.replaceFirst("akka://","").split("/"),1)
+  }
+
+  @tailrec private def recGetNode(root: TrieNode, path: Array[String], index: Int): Option[TrieNode]= {
+    if(root != null && index < path.length) {
+      var nextRoot = root.children.filter(child => child.path == path(index))
+      if(nextRoot.isEmpty){
+        None
+      }else{
+        if(path.length - 1 == index){
+            Some(nextRoot(0))
+        }else {
+          recGetNode(nextRoot(0), path, index + 1)
+        }
+      }
+    }else{
+      None
+    }
+  }
+
+  def removeAllNodes(): Unit = {
+    var index = 0
+    while(index < root.children.length){
+      root.children.remove(index)
+      index += 1
+    }
+    elements = 0
+  }
+
   def print:JsValue = {
     getObject(root, null)
   }

http://git-wip-us.apache.org/repos/asf/incubator-iota/blob/d3db1525/fey-core/src/test/scala/org/apache/iota/fey/IdentifyFeyActorsSpec.scala
----------------------------------------------------------------------
diff --git a/fey-core/src/test/scala/org/apache/iota/fey/IdentifyFeyActorsSpec.scala b/fey-core/src/test/scala/org/apache/iota/fey/IdentifyFeyActorsSpec.scala
index f159d19..bf1a2cf 100644
--- a/fey-core/src/test/scala/org/apache/iota/fey/IdentifyFeyActorsSpec.scala
+++ b/fey-core/src/test/scala/org/apache/iota/fey/IdentifyFeyActorsSpec.scala
@@ -22,6 +22,8 @@ import akka.actor.{ActorRef, Props}
 
 class IdentifyFeyActorsSpec extends BaseAkkaSpec {
 
+  val aux_events = new Trie(systemName)
+
   "Sending IdentifyFeyActors.IDENTIFY_TREE to IdentifyFeyActors" should {
     s"result in one path added to IdentifyFeyActors.actorsPath" in {
       globalIdentifierRef ! IdentifyFeyActors.IDENTIFY_TREE(s"akka://$systemName/user")
@@ -37,7 +39,7 @@ class IdentifyFeyActorsSpec extends BaseAkkaSpec {
 
   "Creating a new actor in the system and sending IdentifyFeyActors.IDENTIFY_TREE to IdentifyFeyActors" should {
     s"result in two paths added to IdentifyFeyActors.actorsPath" in {
-      actor2 = system.actorOf(Props[Monitor],"MONITOR")
+      actor2 = system.actorOf(Props(new Monitor(aux_events)),"MONITOR")
       globalIdentifierRef ! IdentifyFeyActors.IDENTIFY_TREE(s"akka://$systemName/user")
       Thread.sleep(1000)
       IdentifyFeyActors.actorsPath.size should equal(2)

http://git-wip-us.apache.org/repos/asf/incubator-iota/blob/d3db1525/fey-core/src/test/scala/org/apache/iota/fey/MonitorSpec.scala
----------------------------------------------------------------------
diff --git a/fey-core/src/test/scala/org/apache/iota/fey/MonitorSpec.scala b/fey-core/src/test/scala/org/apache/iota/fey/MonitorSpec.scala
new file mode 100644
index 0000000..3008518
--- /dev/null
+++ b/fey-core/src/test/scala/org/apache/iota/fey/MonitorSpec.scala
@@ -0,0 +1,148 @@
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.iota.fey
+
+import akka.actor.Props
+import akka.testkit.{EventFilter, TestActorRef, TestProbe}
+
+class MonitorSpec extends BaseAkkaSpec{
+
+  val parent = TestProbe("MONITOR-PARENT")
+  val events = new Trie(systemName)
+  val monitorRef: TestActorRef[Monitor] = TestActorRef[Monitor]( Props(new Monitor(events)),parent.ref, "MONITOR-TEST")
+  val test_sender = TestProbe("MONITOR-SENDER")
+  var monitor1Node:TrieNode = _
+
+  "Creating a Monitor actor" should {
+    "result in creation of one actor in the system" in{
+      TestProbe().expectActor(s"${parent.ref.path}/MONITOR-TEST")
+    }
+    "result in one active actors" in{
+      globalIdentifierRef ! IdentifyFeyActors.IDENTIFY_TREE(parent.ref.path.toString)
+      Thread.sleep(200)
+      IdentifyFeyActors.actorsPath should have size(1)
+      IdentifyFeyActors.actorsPath should contain(s"${parent.ref.path}/MONITOR-TEST")
+    }
+  }
+
+  "Sending Monitor.START to monitor actor" should {
+    "result in logging START message" in {
+      EventFilter.info(message = s"START | 123 | ${test_sender.ref.path} | STARTINFO", occurrences = 1) intercept {
+        test_sender.send(monitorRef,Monitor.START(123,"STARTINFO"))
+      }
+    }
+    "result in new entry to events Trie" in {
+      events.elements should be(2)
+      events.hasPath(test_sender.ref.path.toString) should be(true)
+      val tmp = events.getNode(test_sender.ref.path.toString)
+      tmp shouldBe defined
+      monitor1Node = tmp.get
+      monitor1Node.events should have size(1)
+      monitor1Node.events should contain(Monitor.MonitorEvent("START", 123, "STARTINFO"))
+    }
+  }
+
+  "Sending Monitor.STOP to monitor actor" should {
+    "result in logging STOP message" in {
+      EventFilter.info(message = s"STOP | 789 | ${test_sender.ref.path} | STOPINFO", occurrences = 1) intercept {
+        test_sender.send(monitorRef,Monitor.STOP(789,"STOPINFO"))
+      }
+    }
+    "not add new path to events Trie" in {
+      events.elements should be(2)
+      events.hasPath(test_sender.ref.path.toString) should be(true)
+    }
+    "add new event to TrieNode" in{
+      monitor1Node.events should have size(2)
+      monitor1Node.events should contain(Monitor.MonitorEvent("START", 123, "STARTINFO"))
+      monitor1Node.events should contain(Monitor.MonitorEvent("STOP", 789, "STOPINFO"))
+    }
+  }
+
+  "Sending Monitor.RESTART to monitor actor" should {
+    "result in logging RESTART message" in {
+      EventFilter[IllegalArgumentException](occurrences = 1) intercept {
+        test_sender.send(monitorRef,Monitor.RESTART(new IllegalArgumentException("MONITOR-TEST"), 123))
+      }
+    }
+    "not add new path to events Trie" in {
+      events.elements should be(2)
+      events.hasPath(test_sender.ref.path.toString) should be(true)
+    }
+    "add new event to TrieNode" in{
+      monitor1Node.events should have size(3)
+      monitor1Node.events should contain(Monitor.MonitorEvent("START", 123, "STARTINFO"))
+      monitor1Node.events should contain(Monitor.MonitorEvent("STOP", 789, "STOPINFO"))
+      val exc = new IllegalArgumentException("MONITOR-TEST")
+      monitor1Node.events should contain(Monitor.MonitorEvent("RESTART", 123, exc.getMessage))
+    }
+  }
+
+  "Sending Monitor.TERMINATE to monitor actor" should {
+    "result in logging TERMINATE message" in {
+      EventFilter.info(message = s"TERMINATE | 789 | ${test_sender.ref.path} | TERMINATEINFO", occurrences = 1) intercept {
+       monitorRef ! Monitor.TERMINATE(test_sender.ref.path.toString,789,"TERMINATEINFO")
+      }
+    }
+    "not add new path to events Trie" in {
+      events.elements should be(2)
+      events.hasPath(test_sender.ref.path.toString) should be(true)
+    }
+    "add new event to TrieNode" in{
+      monitor1Node.events should have size(4)
+      monitor1Node.events should contain(Monitor.MonitorEvent("START", 123, "STARTINFO"))
+      monitor1Node.events should contain(Monitor.MonitorEvent("STOP", 789, "STOPINFO"))
+      val exc = new IllegalArgumentException("MONITOR-TEST")
+      monitor1Node.events should contain(Monitor.MonitorEvent("RESTART", 123, exc.getMessage))
+      monitor1Node.events should contain(Monitor.MonitorEvent("TERMINATE", 789, "TERMINATEINFO"))
+    }
+  }
+
+  "Calling logInfo from a Monitor actor" should {
+    "result in logging info when no throwable is specified" in {
+      EventFilter.info(message = s"STOP | 1 | path | info", occurrences = 1) intercept {
+        monitorRef.underlyingActor.logInfo("path", "STOP", 1, "info")
+      }
+    }
+    "result in logging error when throwable is specified" in {
+      EventFilter[IllegalArgumentException](occurrences = 1) intercept {
+        monitorRef.underlyingActor.logInfo("path", "STOP", 1, "info", new IllegalArgumentException("Test"))
+      }
+    }
+  }
+
+  var test_sender2 = TestProbe("MONITOR-SENDER-2")
+
+  "Sending Monitor.START from a different sender to monitor actor" should {
+    "result in logging START message" in {
+      EventFilter.info(message = s"START | 123 | ${test_sender2.ref.path} | STARTINFO2", occurrences = 1) intercept {
+        test_sender2.send(monitorRef,Monitor.START(123,"STARTINFO2"))
+      }
+    }
+    "result in new entry to events Trie" in {
+      events.elements should be(3)
+      events.hasPath(test_sender2.ref.path.toString) should be(true)
+      val tmpNode = events.getNode(test_sender2.ref.path.toString)
+      tmpNode shouldBe defined
+      tmpNode.get.events should have size(1)
+      tmpNode.get.events should contain(Monitor.MonitorEvent("START", 123, "STARTINFO2"))
+    }
+  }
+
+}