You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/08/28 11:21:02 UTC

[GitHub] markusthoemmes closed pull request #3982: Make tests with CouchDB-views more stable.

markusthoemmes closed pull request #3982: Make tests with CouchDB-views more stable.
URL: https://github.com/apache/incubator-openwhisk/pull/3982
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

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 7f83d279ed..f4a1aac1d5 100644
--- a/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
+++ b/tests/src/test/scala/whisk/core/database/test/DbUtils.scala
@@ -55,6 +55,10 @@ trait DbUtils extends Assertions {
   val cnt = new AtomicInteger(0)
   def transid() = TransactionId(cnt.incrementAndGet().toString)
 
+  // Call each few successfully 5 before the test continues to increase probability, that each node of the
+  // CouchDB/Cloudant cluster is updated.
+  val successfulViewCalls = 5
+
   /**
    * Retry an operation 'step()' awaiting its result up to 'timeout'.
    * Attempt the operation up to 'count' times. The future from the
@@ -93,7 +97,8 @@ trait DbUtils extends Assertions {
   def waitOnView[Au](db: ArtifactStore[Au], namespace: EntityName, count: Int, view: View)(
     implicit context: ExecutionContext,
     transid: TransactionId,
-    timeout: Duration): Unit = waitOnViewImpl(db, namespace.asString, count, view)
+    timeout: Duration): Unit =
+    waitOnViewImpl(db, List(namespace.asString), List(namespace.asString, WhiskEntityQueries.TOP), count, view)
 
   /**
    * Wait on a view to update with documents added to namespace. This uses retry above,
@@ -103,51 +108,41 @@ trait DbUtils extends Assertions {
   def waitOnView[Au](db: ArtifactStore[Au], path: EntityPath, count: Int, view: View)(
     implicit context: ExecutionContext,
     transid: TransactionId,
-    timeout: Duration): Unit = waitOnViewImpl(db, path.asString, count, view)
+    timeout: Duration): Unit =
+    waitOnViewImpl(db, List(path.asString), List(path.asString, WhiskEntityQueries.TOP), count, view)
 
   /**
-   * Wait on a view to update with documents added to namespace. This uses retry above,
+   * 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.
    */
-  private def waitOnViewImpl[Au](db: ArtifactStore[Au], key: String, count: Int, view: View)(
-    implicit context: ExecutionContext,
-    transid: TransactionId,
-    timeout: Duration): Unit = {
-    val success = retry(
-      () => {
-        val startKey = List(key)
-        val endKey = List(key, WhiskEntityQueries.TOP)
-        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")
-  }
+  def waitOnView[Au](db: ArtifactStore[Au], count: Int, view: View)(implicit context: ExecutionContext,
+                                                                    transid: TransactionId,
+                                                                    timeout: Duration): Unit =
+    waitOnViewImpl(db, List.empty, List.empty, count, view)
 
   /**
-   * Wait on a view to update with documents added(don't specify the namespace). This uses retry above,
+   * Wait on a view to update with documents added to 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
+  private def waitOnViewImpl[Au](
+    db: ArtifactStore[Au],
+    startKey: List[String],
+    endKey: List[String],
+    count: Int,
+    view: View)(implicit context: ExecutionContext, transid: TransactionId, timeout: Duration): Unit = {
+    // Query the view at least `successfulViewCalls` times successfully, to handle inconsistency between several CouchDB-nodes.
+    (0 until successfulViewCalls).map { _ =>
+      val success = retry(() => {
         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")
+      }, timeout)
+      assert(success.isSuccess, "wait aborted")
+    }
   }
 
   /**
@@ -161,14 +156,17 @@ trait DbUtils extends Assertions {
     namespace: EntityPath,
     count: Int,
     includeDocs: Boolean = false)(implicit context: ExecutionContext, transid: TransactionId, timeout: Duration) = {
-    val success = retry(() => {
-      factory.listCollectionInNamespace(db, namespace, 0, 0, includeDocs) map { l =>
-        if (l.fold(_.length, _.length) < count) {
-          throw RetryOp()
-        } else true
-      }
-    }, timeout)
-    assert(success.isSuccess, "wait aborted")
+    // Query the view at least `successfulViewCalls` times successfully, to handle inconsistency between several CouchDB-nodes.
+    (0 until successfulViewCalls).map { _ =>
+      val success = retry(() => {
+        factory.listCollectionInNamespace(db, namespace, 0, 0, includeDocs) map { l =>
+          if (l.fold(_.length, _.length) < count) {
+            throw RetryOp()
+          } else true
+        }
+      }, timeout)
+      assert(success.isSuccess, "wait aborted")
+    }
   }
 
   /**
@@ -178,14 +176,17 @@ trait DbUtils extends Assertions {
   def waitOnView(db: AuthStore, authkey: BasicAuthenticationAuthKey, count: Int)(implicit context: ExecutionContext,
                                                                                  transid: TransactionId,
                                                                                  timeout: Duration) = {
-    val success = retry(() => {
-      Identity.list(db, List(authkey.uuid.asString, authkey.key.asString)) map { l =>
-        if (l.length != count) {
-          throw RetryOp()
-        } else true
-      }
-    }, timeout)
-    assert(success.isSuccess, "wait aborted after: " + timeout + ": " + success)
+    // Query the view at least `successfulViewCalls` times successfully, to handle inconsistency between several CouchDB-nodes.
+    (0 until successfulViewCalls).map { _ =>
+      val success = retry(() => {
+        Identity.list(db, List(authkey.uuid.asString, authkey.key.asString)) map { l =>
+          if (l.length != count) {
+            throw RetryOp()
+          } else true
+        }
+      }, timeout)
+      assert(success.isSuccess, "wait aborted after: " + timeout + ": " + success)
+    }
   }
 
   /**
@@ -194,20 +195,23 @@ trait DbUtils extends Assertions {
   def waitOnView(db: CouchDbRestClient, designDocName: String, viewName: String, count: Int)(
     implicit context: ExecutionContext,
     timeout: Duration) = {
-    val success = retry(
-      () => {
-        db.executeView(designDocName, viewName)().map {
-          case Right(doc) =>
-            val length = doc.fields("rows").convertTo[List[JsObject]].length
-            if (length != count) {
+    // Query the view at least `successfulViewCalls` times successfully, to handle inconsistency between several CouchDB-nodes.
+    (0 until successfulViewCalls).map { _ =>
+      val success = retry(
+        () => {
+          db.executeView(designDocName, viewName)().map {
+            case Right(doc) =>
+              val length = doc.fields("rows").convertTo[List[JsObject]].length
+              if (length != count) {
+                throw RetryOp()
+              } else true
+            case Left(_) =>
               throw RetryOp()
-            } else true
-          case Left(_) =>
-            throw RetryOp()
-        }
-      },
-      timeout)
-    assert(success.isSuccess, "wait aborted after: " + timeout + ": " + success)
+          }
+        },
+        timeout)
+      assert(success.isSuccess, "wait aborted after: " + timeout + ": " + success)
+    }
   }
 
   /**


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services