You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by ch...@apache.org on 2018/08/20 04:33:36 UTC

[incubator-openwhisk] branch master updated: Use ArtifactStore to manipulate data in NamespaceBlacklistTests (#3890)

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 2578703  Use ArtifactStore to manipulate data in NamespaceBlacklistTests (#3890)
2578703 is described below

commit 2578703d67ba693f27309c468b4ca5c62bbbe79e
Author: jiangpch <ji...@navercorp.com>
AuthorDate: Mon Aug 20 12:33:32 2018 +0800

    Use ArtifactStore to manipulate data in NamespaceBlacklistTests (#3890)
    
    Use ArtifactStore abstraction instead of CouchDB specific code to make NamespaceBlacklistTests generic. This enables it to be run against all supported databases
---
 .../scala/whisk/core/database/test/DbUtils.scala   |  22 +++++
 .../ArtifactStoreSubjectQueryBehaviors.scala       |  37 +-------
 .../invoker/test/NamespaceBlacklistTests.scala     | 103 +++++++--------------
 3 files changed, 59 insertions(+), 103 deletions(-)

diff --git a/tests/src/test/scala/whisk/core/database/test/DbUtils.scala b/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
index 6d39304..7f83d27 100644
--- a/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
+++ b/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
@@ -129,6 +129,28 @@ trait DbUtils extends Assertions {
   }
 
   /**
+   * Wait on a view to update with documents added(don't specify the namespace). This uses retry above,
+   * where the step performs a direct db query to retrieve the view and check the count
+   * matches the given value.
+   */
+  def waitOnView[Au](db: ArtifactStore[Au], count: Int, view: View)(implicit context: ExecutionContext,
+                                                                    transid: TransactionId,
+                                                                    timeout: Duration): Unit = {
+    val success = retry(
+      () => {
+        val startKey = List.empty
+        val endKey = List.empty
+        db.query(view.name, startKey, endKey, 0, 0, false, true, false, StaleParameter.No) map { l =>
+          if (l.length != count) {
+            throw RetryOp()
+          } else true
+        }
+      },
+      timeout)
+    assert(success.isSuccess, "wait aborted")
+  }
+
+  /**
    * Wait on a view specific to a collection to update with documents added to that collection in namespace.
    * This uses retry above, where the step performs a collection-specific view query using the collection
    * factory. The result count from the view is checked against the given value.
diff --git a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala
index a50b29c..06150d5 100644
--- a/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala
+++ b/tests/src/test/scala/whisk/core/database/test/behavior/ArtifactStoreSubjectQueryBehaviors.scala
@@ -17,16 +17,12 @@
 
 package whisk.core.database.test.behavior
 
-import spray.json.DefaultJsonProtocol._
 import spray.json.{JsBoolean, JsObject}
 import whisk.common.TransactionId
-import whisk.core.database.{NoDocumentException, StaleParameter}
+import whisk.core.database.NoDocumentException
 import whisk.core.entity._
-import whisk.core.entity.types.AuthStore
 import whisk.core.invoker.NamespaceBlacklist
 
-import scala.concurrent.duration.Duration
-
 trait ArtifactStoreSubjectQueryBehaviors extends ArtifactStoreBehaviorBase {
 
   behavior of s"${storeType}ArtifactStore query subjects"
@@ -138,7 +134,7 @@ trait ArtifactStoreSubjectQueryBehaviors extends ArtifactStoreBehaviorBase {
 
     //2 for limits
     //2 for 2 namespace in user blocked
-    waitOnBlacklistView(authStore, 2 + 2)
+    waitOnView(authStore, 2 + 2, NamespaceBlacklist.view)
 
     //Use contains assertion to ensure that even if same db is used by other setup
     //we at least get our expected entries
@@ -148,35 +144,6 @@ trait ArtifactStoreSubjectQueryBehaviors extends ArtifactStoreBehaviorBase {
       .futureValue should contain allElementsOf Seq(n1, n2, n4, n5).map(_.asString).toSet
   }
 
-  def waitOnBlacklistView(db: AuthStore, count: Int)(implicit transid: TransactionId, timeout: Duration) = {
-    val success = retry(() => {
-      blacklistCount().map { listCount =>
-        if (listCount != count) {
-          throw RetryOp()
-        } else true
-      }
-    }, timeout)
-    assert(success.isSuccess, "wait aborted after: " + timeout + ": " + success)
-  }
-
-  private def blacklistCount()(implicit transid: TransactionId) = {
-    //NamespaceBlacklist uses StaleParameter.UpdateAfter which would lead to race condition
-    //So use actual call here
-    authStore
-      .query(
-        table = NamespaceBlacklist.view.name,
-        startKey = List.empty,
-        endKey = List.empty,
-        skip = 0,
-        limit = Int.MaxValue,
-        includeDocs = false,
-        descending = true,
-        reduce = false,
-        stale = StaleParameter.No)
-      .map(_.map(_.fields("key").convertTo[String]).toSet)
-      .map(_.size)
-  }
-
   private class LimitEntity(name: EntityName, limits: UserLimits) extends WhiskAuth(Subject(), Set.empty) {
     override def docid = DocId(s"${name.name}/limits")
 
diff --git a/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala b/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala
index 033678c..c9f5a7f 100644
--- a/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala
+++ b/tests/src/test/scala/whisk/core/invoker/test/NamespaceBlacklistTests.scala
@@ -23,13 +23,9 @@ import org.junit.runner.RunWith
 import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures}
 import org.scalatest.junit.JUnitRunner
 import org.scalatest.{FlatSpec, Matchers}
-import pureconfig.loadConfigOrThrow
-import spray.json.DefaultJsonProtocol._
 import spray.json._
 import whisk.common.TransactionId
-import whisk.core.database.CouchDbConfig
-import whisk.core.ConfigKeys
-import whisk.core.database.test.{DbUtils, ExtendedCouchDbRestClient}
+import whisk.core.database.test.DbUtils
 import whisk.core.entity._
 import whisk.core.invoker.NamespaceBlacklist
 import whisk.utils.{retry => testRetry}
@@ -51,38 +47,13 @@ class NamespaceBlacklistTests
   implicit val materializer = ActorMaterializer()
   implicit val tid = TransactionId.testing
 
-  val dbConfig = loadConfigOrThrow[CouchDbConfig](ConfigKeys.couchdb)
   val authStore = WhiskAuthStore.datastore()
-  val subjectsDb = new ExtendedCouchDbRestClient(
-    dbConfig.protocol,
-    dbConfig.host,
-    dbConfig.port,
-    dbConfig.username,
-    dbConfig.password,
-    dbConfig.databaseFor[WhiskAuth])
-
-  /* Identities needed for the first test */
-  val uuid1 = UUID()
-  val uuid2 = UUID()
-  val uuid3 = UUID()
-  val identities = Seq(
-    Identity(
-      Subject(),
-      Namespace(EntityName("testnamespace1"), uuid1),
-      BasicAuthenticationAuthKey(uuid1, Secret()),
-      Set.empty,
-      UserLimits(invocationsPerMinute = Some(0))),
-    Identity(
-      Subject(),
-      Namespace(EntityName("testnamespace2"), uuid2),
-      BasicAuthenticationAuthKey(uuid2, Secret()),
-      Set.empty,
-      UserLimits(concurrentInvocations = Some(0))),
-    Identity(
-      Subject(),
-      Namespace(EntityName("testnamespace3"), uuid3),
-      BasicAuthenticationAuthKey(uuid3, Secret()),
-      Set.empty,
+
+  val limitsAndAuths = Seq(
+    new LimitEntity(EntityName("testnamespace1"), UserLimits(invocationsPerMinute = Some(0))),
+    new LimitEntity(EntityName("testnamespace2"), UserLimits(concurrentInvocations = Some(0))),
+    new LimitEntity(
+      EntityName("testnamespace3"),
       UserLimits(invocationsPerMinute = Some(1), concurrentInvocations = Some(1))))
 
   /* Subject document needed for the second test */
@@ -92,49 +63,34 @@ class NamespaceBlacklistTests
   val ak5 = BasicAuthenticationAuthKey(uuid5, Secret())
   val ns4 = Namespace(EntityName("different1"), uuid4)
   val ns5 = Namespace(EntityName("different2"), uuid5)
-  val subject = WhiskAuth(Subject(), Set(WhiskNamespace(ns4, ak4), WhiskNamespace(ns5, ak5)))
-  val blockedSubject = JsObject(subject.toJson.fields + ("blocked" -> true.toJson))
+  val blockedSubject = new ExtendedAuth(Subject(), Set(WhiskNamespace(ns4, ak4), WhiskNamespace(ns5, ak5)), true)
 
-  val blockedNamespacesCount = 2 + subject.namespaces.size
+  val blockedNamespacesCount = 2 + blockedSubject.namespaces.size
 
-  def authToIdentities(auth: WhiskAuth): Set[Identity] = {
+  private def authToIdentities(auth: WhiskAuth): Set[Identity] = {
     auth.namespaces.map { ns =>
       Identity(auth.subject, ns.namespace, ns.authkey, Set.empty, UserLimits())
     }
   }
 
-  override protected def withFixture(test: NoArgTest) = {
-    assume(isCouchStore(authStore))
-    super.withFixture(test)
+  private def limitToIdentity(limit: LimitEntity): Identity = {
+    val namespace = limit.docid.id.dropRight("/limits".length)
+    Identity(
+      limit.subject,
+      Namespace(EntityName(namespace), UUID()),
+      BasicAuthenticationAuthKey(UUID(), Secret()),
+      Set(),
+      UserLimits())
   }
 
   override def beforeAll() = {
-    val documents = identities.map { i =>
-      (i.namespace.name + "/limits", i.limits.toJson.asJsObject)
-    } :+ (subject.subject.asString, blockedSubject)
-
-    // Add all documents to the database
-    documents.foreach { case (id, doc) => subjectsDb.putDoc(id, doc).futureValue }
-
-    // Waits for the 2 blocked identities + the namespaces of the blocked subject
-    waitOnView(subjectsDb, NamespaceBlacklist.view.ddoc, NamespaceBlacklist.view.view, blockedNamespacesCount)(
-      executionContext,
-      1.minute)
+    limitsAndAuths foreach (put(authStore, _))
+    put(authStore, blockedSubject)
+    waitOnView(authStore, blockedNamespacesCount, NamespaceBlacklist.view)
   }
 
   override def afterAll() = {
-    val ids = identities.map(_.namespace.name + "/limits") :+ subject.subject.asString
-
-    // Force remove all documents with those ids by first getting and then deleting the documents
-    ids.foreach { id =>
-      val docE = subjectsDb.getDoc(id).futureValue
-      docE shouldBe 'right
-      val doc = docE.right.get
-      subjectsDb
-        .deleteDoc(doc.fields("_id").convertTo[String], doc.fields("_rev").convertTo[String])
-        .futureValue
-    }
-
+    cleanup()
     super.afterAll()
   }
 
@@ -145,7 +101,18 @@ class NamespaceBlacklistTests
       blacklist.refreshBlacklist().futureValue should have size blockedNamespacesCount
     }, 60, Some(1.second))
 
-    identities.map(blacklist.isBlacklisted) shouldBe Seq(true, true, false)
-    authToIdentities(subject).toSeq.map(blacklist.isBlacklisted) shouldBe Seq(true, true)
+    limitsAndAuths.map(limitToIdentity).map(blacklist.isBlacklisted) shouldBe Seq(true, true, false)
+    authToIdentities(blockedSubject).toSeq.map(blacklist.isBlacklisted) shouldBe Seq(true, true)
+  }
+
+  class LimitEntity(name: EntityName, limits: UserLimits) extends WhiskAuth(Subject(), namespaces = Set.empty) {
+    override def docid = DocId(s"${name.name}/limits")
+
+    override def toJson = UserLimits.serdes.write(limits).asJsObject
+  }
+
+  class ExtendedAuth(subject: Subject, namespaces: Set[WhiskNamespace], blocked: Boolean)
+      extends WhiskAuth(subject, namespaces) {
+    override def toJson = JsObject(super.toJson.fields + ("blocked" -> JsBoolean(blocked)))
   }
 }