This is an automated email from the ASF dual-hosted git repository.

chetanm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 6cc6ab4  Add common test codes for ActivationStore (#4031)
6cc6ab4 is described below

commit 6cc6ab4d28fac2afa892f0adb721bc1b228b42a4
Author: jiangpch <[email protected]>
AuthorDate: Fri Feb 15 11:58:29 2019 +0800

    Add common test codes for ActivationStore (#4031)
    
    Adds a suite of testcases to validate the implementations of 
ActivationStore SPI
---
 .../ArtifactActivationStoreBehaviorBase.scala      |  33 ++
 .../database/ArtifactActivationStoreTests.scala    |  57 ++++
 .../test/behavior/ActivationStoreBehavior.scala    |  23 ++
 .../behavior/ActivationStoreBehaviorBase.scala     | 106 +++++++
 .../behavior/ActivationStoreCRUDBehaviors.scala    |  70 ++++
 .../behavior/ActivationStoreQueryBehaviors.scala   | 353 +++++++++++++++++++++
 6 files changed, 642 insertions(+)

diff --git 
a/tests/src/test/scala/org/apache/openwhisk/core/database/ArtifactActivationStoreBehaviorBase.scala
 
b/tests/src/test/scala/org/apache/openwhisk/core/database/ArtifactActivationStoreBehaviorBase.scala
new file mode 100644
index 0000000..070d35e
--- /dev/null
+++ 
b/tests/src/test/scala/org/apache/openwhisk/core/database/ArtifactActivationStoreBehaviorBase.scala
@@ -0,0 +1,33 @@
+/*
+ * 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.openwhisk.core.database
+
+import akka.stream.ActorMaterializer
+import org.apache.openwhisk.core.controller.test.WhiskAuthHelpers
+import 
org.apache.openwhisk.core.database.test.behavior.ActivationStoreBehaviorBase
+import org.scalatest.FlatSpec
+
+trait ArtifactActivationStoreBehaviorBase extends FlatSpec with 
ActivationStoreBehaviorBase {
+  override def storeType = "Artifact"
+
+  override val context = UserContext(WhiskAuthHelpers.newIdentity())
+
+  override lazy val activationStore = {
+    ArtifactActivationStoreProvider.instance(actorSystem, 
ActorMaterializer.create(actorSystem), logging)
+  }
+}
diff --git 
a/tests/src/test/scala/org/apache/openwhisk/core/database/ArtifactActivationStoreTests.scala
 
b/tests/src/test/scala/org/apache/openwhisk/core/database/ArtifactActivationStoreTests.scala
new file mode 100644
index 0000000..86cb5ad
--- /dev/null
+++ 
b/tests/src/test/scala/org/apache/openwhisk/core/database/ArtifactActivationStoreTests.scala
@@ -0,0 +1,57 @@
+/*
+ * 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.openwhisk.core.database
+
+import java.time.Instant
+
+import org.apache.openwhisk.common.TransactionId
+import org.apache.openwhisk.core.database.test.behavior.ActivationStoreBehavior
+import org.apache.openwhisk.core.entity.{EntityPath, WhiskActivation}
+import org.apache.openwhisk.utils.retry
+import org.junit.runner.RunWith
+import org.scalatest.FlatSpec
+import org.scalatest.junit.JUnitRunner
+
+@RunWith(classOf[JUnitRunner])
+class ArtifactActivationStoreTests
+    extends FlatSpec
+    with ArtifactActivationStoreBehaviorBase
+    with ActivationStoreBehavior {
+  override def checkQueryActivations(namespace: String,
+                                     name: Option[String] = None,
+                                     skip: Int = 0,
+                                     limit: Int = 1000,
+                                     includeDocs: Boolean = false,
+                                     since: Option[Instant] = None,
+                                     upto: Option[Instant] = None,
+                                     context: UserContext,
+                                     expected: 
IndexedSeq[WhiskActivation])(implicit transid: TransactionId): Unit = {
+    // This is for compatible with CouchDB as it use option 
`StaleParameter.UpdateAfter`
+    retry(super.checkQueryActivations(namespace, name, skip, limit, 
includeDocs, since, upto, context, expected), 100)
+  }
+
+  override def checkCountActivations(namespace: String,
+                                     name: Option[EntityPath] = None,
+                                     skip: Int = 0,
+                                     since: Option[Instant] = None,
+                                     upto: Option[Instant] = None,
+                                     context: UserContext,
+                                     expected: Long)(implicit transid: 
TransactionId): Unit = {
+    retry(super.checkCountActivations(namespace, name, skip, since, upto, 
context, expected), 100)
+  }
+}
diff --git 
a/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreBehavior.scala
 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreBehavior.scala
new file mode 100644
index 0000000..83939eb
--- /dev/null
+++ 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreBehavior.scala
@@ -0,0 +1,23 @@
+/*
+ * 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.openwhisk.core.database.test.behavior
+
+trait ActivationStoreBehavior
+    extends ActivationStoreBehaviorBase
+    with ActivationStoreCRUDBehaviors
+    with ActivationStoreQueryBehaviors
diff --git 
a/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreBehaviorBase.scala
 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreBehaviorBase.scala
new file mode 100644
index 0000000..f8caad6
--- /dev/null
+++ 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreBehaviorBase.scala
@@ -0,0 +1,106 @@
+/*
+ * 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.openwhisk.core.database.test.behavior
+
+import java.time.Instant
+
+import akka.stream.ActorMaterializer
+import common.{StreamLogging, WskActorSystem}
+import org.apache.openwhisk.common.TransactionId
+import org.apache.openwhisk.core.database.{ActivationStore, 
CacheChangeNotification, UserContext}
+import 
org.apache.openwhisk.core.database.test.behavior.ArtifactStoreTestUtil.storeAvailable
+import org.apache.openwhisk.core.entity._
+import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures}
+import org.scalatest.{BeforeAndAfterEach, FlatSpec, Matchers, Outcome}
+
+import scala.collection.mutable.ListBuffer
+import scala.concurrent.Await
+import scala.concurrent.duration.Duration
+import scala.concurrent.duration.DurationInt
+import scala.language.postfixOps
+import scala.util.{Random, Try}
+
+trait ActivationStoreBehaviorBase
+    extends FlatSpec
+    with ScalaFutures
+    with Matchers
+    with StreamLogging
+    with WskActorSystem
+    with IntegrationPatience
+    with BeforeAndAfterEach {
+
+  protected implicit val materializer: ActorMaterializer = ActorMaterializer()
+  protected implicit val notifier: Option[CacheChangeNotification] = None
+
+  def context: UserContext
+  def activationStore: ActivationStore
+  private val docsToDelete = ListBuffer[(UserContext, ActivationId)]()
+
+  def storeType: String
+
+  protected def transId() = 
TransactionId(Random.alphanumeric.take(32).mkString)
+
+  override def afterEach(): Unit = {
+    cleanup()
+    stream.reset()
+  }
+
+  override protected def withFixture(test: NoArgTest): Outcome = {
+    assume(storeAvailable(storeAvailableCheck), s"$storeType not configured or 
available")
+    val outcome = super.withFixture(test)
+    if (outcome.isFailed) {
+      println(logLines.mkString("\n"))
+    }
+    outcome
+  }
+
+  protected def storeAvailableCheck: Try[Any] = Try(true)
+  //~----------------------------------------< utility methods >
+
+  protected def store(activation: WhiskActivation, context: UserContext)(
+    implicit transid: TransactionId,
+    notifier: Option[CacheChangeNotification]): DocInfo = {
+    val doc = activationStore.store(activation, context).futureValue
+    docsToDelete.append((context, ActivationId(activation.docid.asString)))
+    doc
+  }
+
+  protected def newActivation(ns: String, actionName: String, start: Long): 
WhiskActivation = {
+    WhiskActivation(
+      EntityPath(ns),
+      EntityName(actionName),
+      Subject(),
+      ActivationId.generate(),
+      Instant.ofEpochMilli(start),
+      Instant.ofEpochMilli(start + 1000))
+  }
+
+  /**
+   * Deletes all documents added to gc queue.
+   */
+  def cleanup()(implicit timeout: Duration = 10 seconds): Unit = {
+    implicit val tid: TransactionId = transId()
+    docsToDelete.map { e =>
+      Try {
+        Await.result(activationStore.delete(e._2, e._1), timeout)
+      }
+    }
+    docsToDelete.clear()
+  }
+
+}
diff --git 
a/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreCRUDBehaviors.scala
 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreCRUDBehaviors.scala
new file mode 100644
index 0000000..506ccec
--- /dev/null
+++ 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreCRUDBehaviors.scala
@@ -0,0 +1,70 @@
+/*
+ * 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.openwhisk.core.database.test.behavior
+
+import org.apache.openwhisk.common.TransactionId
+import org.apache.openwhisk.core.database.NoDocumentException
+import org.apache.openwhisk.core.entity.ActivationId
+
+import scala.util.Random
+
+trait ActivationStoreCRUDBehaviors extends ActivationStoreBehaviorBase {
+
+  behavior of s"${storeType}ActivationStore store"
+
+  it should "put activation and get docinfo" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action = s"action1_${Random.alphanumeric.take(4).mkString}"
+    val activation = newActivation(namespace, action, 1L)
+    val doc = store(activation, context)
+    doc shouldBe activation.docinfo
+  }
+
+  behavior of s"${storeType}ActivationStore delete"
+
+  it should "deletes existing activation" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action = s"action1_${Random.alphanumeric.take(4).mkString}"
+    val activation = newActivation(namespace, action, 1L)
+    store(activation, context)
+    activationStore.delete(ActivationId(activation.docid.asString), 
context).futureValue shouldBe true
+  }
+
+  it should "throws NoDocumentException when activation does not exist" in {
+    implicit val tid: TransactionId = transId()
+    activationStore.delete(ActivationId("non-existing-doc"), 
context).failed.futureValue shouldBe a[NoDocumentException]
+  }
+
+  behavior of s"${storeType}ActivationStore get"
+
+  it should "get existing activation matching id" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action = s"action1_${Random.alphanumeric.take(4).mkString}"
+    val activation = newActivation(namespace, action, 1L)
+    store(activation, context)
+    activationStore.get(ActivationId(activation.docid.asString), 
context).futureValue shouldBe activation
+  }
+
+  it should "throws NoDocumentException when activation does not exist" in {
+    implicit val tid: TransactionId = transId()
+    activationStore.get(ActivationId("non-existing-doc"), 
context).failed.futureValue shouldBe a[NoDocumentException]
+  }
+}
diff --git 
a/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreQueryBehaviors.scala
 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreQueryBehaviors.scala
new file mode 100644
index 0000000..c8123d5
--- /dev/null
+++ 
b/tests/src/test/scala/org/apache/openwhisk/core/database/test/behavior/ActivationStoreQueryBehaviors.scala
@@ -0,0 +1,353 @@
+/*
+ * 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.openwhisk.core.database.test.behavior
+
+import java.time.Instant
+
+import org.apache.openwhisk.common.TransactionId
+import org.apache.openwhisk.core.database.UserContext
+import org.apache.openwhisk.core.entity.{EntityPath, WhiskActivation}
+import spray.json.{JsNumber, JsObject}
+
+import scala.util.Random
+
+trait ActivationStoreQueryBehaviors extends ActivationStoreBehaviorBase {
+
+  protected def checkQueryActivations(namespace: String,
+                                      name: Option[String] = None,
+                                      skip: Int = 0,
+                                      limit: Int = 1000,
+                                      includeDocs: Boolean = false,
+                                      since: Option[Instant] = None,
+                                      upto: Option[Instant] = None,
+                                      context: UserContext,
+                                      expected: 
IndexedSeq[WhiskActivation])(implicit transid: TransactionId): Unit = {
+    val result =
+      name
+        .map { n =>
+          activationStore
+            .listActivationsMatchingName(
+              EntityPath(namespace),
+              EntityPath(n),
+              skip = skip,
+              limit = limit,
+              includeDocs = includeDocs,
+              since = since,
+              upto = upto,
+              context = context)
+        }
+        .getOrElse {
+          activationStore
+            .listActivationsInNamespace(
+              EntityPath(namespace),
+              skip = skip,
+              limit = limit,
+              includeDocs = includeDocs,
+              since = since,
+              upto = upto,
+              context = context)
+        }
+        .map { r =>
+          r.fold(left => left, right => right.map(wa => if (includeDocs) 
wa.toExtendedJson() else wa.summaryAsJson))
+        }
+        .futureValue
+
+    result should contain theSameElementsAs expected.map(wa =>
+      if (includeDocs) wa.toExtendedJson() else wa.summaryAsJson)
+  }
+
+  protected def checkCountActivations(namespace: String,
+                                      name: Option[EntityPath] = None,
+                                      skip: Int = 0,
+                                      since: Option[Instant] = None,
+                                      upto: Option[Instant] = None,
+                                      context: UserContext,
+                                      expected: Long)(implicit transid: 
TransactionId): Unit = {
+    val result = activationStore
+      .countActivationsInNamespace(
+        EntityPath(namespace),
+        name = name,
+        skip = skip,
+        since = since,
+        upto = upto,
+        context = context)
+      .futureValue
+
+    result shouldBe JsObject(WhiskActivation.collectionName -> 
JsNumber(expected))
+  }
+
+  behavior of s"${storeType}ActivationStore listActivationsInNamespace"
+
+  it should "find all entities" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+    val action2 = s"action2_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    val activations2 = (1000 until 1100 by 10).map(newActivation(namespace, 
action2, _))
+    activations2 foreach (store(_, context))
+
+    checkQueryActivations(namespace, context = context, expected = activations 
++ activations2)
+  }
+
+  it should "support since and upto filters" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(
+      namespace,
+      since = Some(Instant.ofEpochMilli(1060)),
+      context = context,
+      expected = activations.takeRight(4))
+
+    checkQueryActivations(
+      namespace,
+      upto = Some(Instant.ofEpochMilli(1060)),
+      context = context,
+      expected = activations.take(7))
+
+    checkQueryActivations(
+      namespace,
+      since = Some(Instant.ofEpochMilli(1030)),
+      upto = Some(Instant.ofEpochMilli(1060)),
+      context = context,
+      expected = activations.take(7).takeRight(4))
+  }
+
+  it should "support skipping results" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(namespace, skip = 5, context = context, expected = 
activations.take(5))
+  }
+
+  it should "support limiting results" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(namespace, limit = 5, context = context, expected = 
activations.takeRight(5))
+  }
+
+  it should "support including complete docs" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(namespace, includeDocs = true, context = context, 
expected = activations)
+  }
+
+  it should "throw exception for negative limits and skip" in {
+    implicit val tid: TransactionId = transId()
+
+    a[IllegalArgumentException] should be thrownBy activationStore
+      .listActivationsInNamespace(EntityPath("test"), skip = -1, limit = 10, 
context = context)
+
+    a[IllegalArgumentException] should be thrownBy activationStore
+      .listActivationsInNamespace(EntityPath("test"), skip = 0, limit = -1, 
context = context)
+  }
+
+  behavior of s"${storeType}ActivationStore listActivationsMatchingName"
+
+  it should "find all entities matching name" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+    val action2 = s"action2_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    val activations2 = (1000 until 1100 by 10).map(newActivation(namespace, 
action2, _))
+    activations2 foreach (store(_, context))
+
+    checkQueryActivations(namespace, Some(action1), context = context, 
expected = activations)
+  }
+
+  it should "support since and upto filters" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(
+      namespace,
+      Some(action1),
+      since = Some(Instant.ofEpochMilli(1060)),
+      context = context,
+      expected = activations.takeRight(4))
+
+    checkQueryActivations(
+      namespace,
+      Some(action1),
+      upto = Some(Instant.ofEpochMilli(1060)),
+      context = context,
+      expected = activations.take(7))
+
+    checkQueryActivations(
+      namespace,
+      Some(action1),
+      since = Some(Instant.ofEpochMilli(1030)),
+      upto = Some(Instant.ofEpochMilli(1060)),
+      context = context,
+      expected = activations.take(7).takeRight(4))
+  }
+
+  it should "support skipping results" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(namespace, Some(action1), skip = 5, context = 
context, expected = activations.take(5))
+  }
+
+  it should "support limiting results" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(namespace, Some(action1), limit = 5, context = 
context, expected = activations.takeRight(5))
+  }
+
+  it should "support including complete docs" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkQueryActivations(namespace, Some(action1), includeDocs = true, 
context = context, expected = activations)
+  }
+
+  it should "throw exception for negative limits and skip" in {
+    implicit val tid: TransactionId = transId()
+
+    a[IllegalArgumentException] should be thrownBy 
activationStore.listActivationsMatchingName(
+      EntityPath("test"),
+      name = EntityPath("testact"),
+      skip = -1,
+      limit = 10,
+      context = context)
+
+    a[IllegalArgumentException] should be thrownBy 
activationStore.listActivationsMatchingName(
+      EntityPath("test"),
+      name = EntityPath("testact"),
+      skip = 0,
+      limit = -1,
+      context = context)
+  }
+
+  behavior of s"${storeType}ActivationStore countActivationsInNamespace"
+
+  it should "should count all created activations" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkCountActivations(namespace, None, context = context, expected = 10)
+  }
+
+  it should "count with option name" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+    val action2 = s"action2_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    val activations2 = (1000 until 1100 by 10).map(newActivation(namespace, 
action2, _))
+    activations2 foreach (store(_, context))
+
+    checkCountActivations(namespace, Some(EntityPath(action1)), context = 
context, expected = 10)
+
+    checkCountActivations(namespace, Some(EntityPath(action2)), context = 
context, expected = 10)
+  }
+
+  it should "count with since and upto" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkCountActivations(namespace, None, since = 
Some(Instant.ofEpochMilli(1060L)), context = context, expected = 4)
+
+    checkCountActivations(namespace, None, upto = 
Some(Instant.ofEpochMilli(1060L)), context = context, expected = 7)
+
+    checkCountActivations(
+      namespace,
+      None,
+      since = Some(Instant.ofEpochMilli(1030L)),
+      upto = Some(Instant.ofEpochMilli(1060L)),
+      context = context,
+      expected = 4)
+  }
+
+  it should "count with skip" in {
+    implicit val tid: TransactionId = transId()
+    val namespace = s"ns_${Random.alphanumeric.take(4).mkString}"
+    val action1 = s"action1_${Random.alphanumeric.take(4).mkString}"
+
+    val activations = (1000 until 1100 by 10).map(newActivation(namespace, 
action1, _))
+    activations foreach (store(_, context))
+
+    checkCountActivations(namespace, None, skip = 4, context = context, 
expected = 10 - 4)
+    checkCountActivations(namespace, None, skip = 1000, context = context, 
expected = 0)
+  }
+
+  it should "throw exception for negative skip" in {
+    implicit val tid: TransactionId = transId()
+
+    a[IllegalArgumentException] should be thrownBy 
activationStore.countActivationsInNamespace(
+      namespace = EntityPath("test"),
+      name = None,
+      skip = -1,
+      context = context)
+  }
+}

Reply via email to