Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
avsej committed Oct 4, 2024
1 parent 007e4f6 commit 2af0d42
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 68 deletions.
14 changes: 9 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@ jobs:
- nts
- zts
server:
- 7.6.0
- 7.2.4
- 7.6.3
- 7.2.5
- 7.1.6
- 7.0.5
steps:
Expand All @@ -331,7 +331,7 @@ jobs:
- name: Install cbdinocluster
run: |
mkdir -p "$HOME/bin"
curl -L -o "$HOME/bin/cbdinocluster" https://github.com/couchbaselabs/cbdinocluster/releases/download/v0.0.35/cbdinocluster-linux
curl -L -o "$HOME/bin/cbdinocluster" https://github.com/couchbaselabs/cbdinocluster/releases/download/v0.0.52/cbdinocluster-linux-amd64
chmod a+x "$HOME/bin/cbdinocluster"
echo "$HOME/bin" >> $GITHUB_PATH
- name: Initialize cbdinocluster
Expand All @@ -341,7 +341,11 @@ jobs:
env:
CLUSTERCONFIG: |
nodes:
- count: 2
- count: 1
version: ${{ matrix.server }}
services:
- kv
- count: 1
version: ${{ matrix.server }}
services:
- kv
Expand All @@ -358,7 +362,7 @@ jobs:
run: |
CLUSTER_ID=$(cbdinocluster -v allocate --def="${CLUSTERCONFIG}")
CONNECTION_STRING=$(cbdinocluster -v connstr "${CLUSTER_ID}")
cbdinocluster -v buckets add ${CLUSTER_ID} default --ram-quota-mb=100 --flush-enabled=true
cbdinocluster -v buckets add ${CLUSTER_ID} default --ram-quota-mb=100 --flush-enabled=true --num-replicas=1
cbdinocluster -v buckets load-sample ${CLUSTER_ID} travel-sample
echo "CLUSTER_ID=${CLUSTER_ID}" >> "$GITHUB_ENV"
echo "TEST_CONNECTION_STRING=${CONNECTION_STRING}?dump_configuration=true" >> "$GITHUB_ENV"
Expand Down
5 changes: 5 additions & 0 deletions bin/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ def capture(*args)
output
end

if ENV["CB_VALGRIND"]
ENV["USE_ZEND_ALLOC"] = 0
ENV["ZEND_DONT_UNLOAD_MODULES"] = 1
end

project_root = File.expand_path(File.join(__dir__, ".."))
build_root = File.join(project_root, "build")

Expand Down
130 changes: 100 additions & 30 deletions tests/Helpers/ConsistencyUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

use Exception;

const MANAGEMENT_PORT = 8091;
const VIEWS_PORT = 8092;
const PORTS = [
'mgmt' => 8091,
'views' => 8092,
'n1ql' => 8093,
'fts' => 8094,
];

class ConsistencyUtils
{
private string $hostname;
Expand Down Expand Up @@ -39,7 +44,7 @@ public function waitUntilUserPresent(string $userName, string $domain = 'local')
[$this, 'resourceIsPresent'],
"User $userName is not present on all nodes",
true,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -54,7 +59,7 @@ public function waitUntilUserDropped(string $userName, string $domain = 'local')
[$this, 'resourceIsDropped'],
"User $userName is not dropped on all nodes",
true,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -69,7 +74,7 @@ public function waitUntilGroupPresent(string $groupName): void
[$this, 'resourceIsPresent'],
"Group $groupName is not present on all nodes",
true,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -81,7 +86,7 @@ public function waitUntilGroupDropped(string $groupName): void
[$this, 'resourceIsDropped'],
"Group $groupName is not dropped on all nodes",
true,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -93,7 +98,7 @@ public function waitUntilBucketPresent(string $bucketName): void
[$this, 'resourceIsPresent'],
"Bucket $bucketName is not present on all nodes",
true,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -105,7 +110,7 @@ public function waitUntilBucketDropped(string $bucketName): void
[$this, 'resourceIsDropped'],
"Bucket $bucketName is not dropped on all nodes",
true,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -117,7 +122,7 @@ public function waitUntilDesignDocumentPresent(string $bucketName, string $desig
[$this, 'resourceIsPresent'],
"Design document $designDocumentName on bucket $bucketName is not present on all nodes",
true,
VIEWS_PORT
'views'
);
}

Expand All @@ -129,7 +134,7 @@ public function waitUntilDesignDocumentDropped(string $bucketName, string $desig
[$this, 'resourceIsDropped'],
"Design document $designDocumentName on bucket $bucketName is not dropped on all nodes",
true,
VIEWS_PORT
'views'
);
}

Expand All @@ -141,7 +146,7 @@ public function waitUntilViewPresent(string $bucketName, string $designDocumentN
[$this, 'resourceIsPresent'],
"View $viewName on design document $designDocumentName on bucket $bucketName is not present on all nodes",
true,
VIEWS_PORT
'views'
);
}

Expand All @@ -153,7 +158,7 @@ public function waitUntilViewDropped(string $bucketName, string $designDocumentN
[$this, 'resourceIsDropped'],
"View $viewName on design document $designDocumentName on bucket $bucketName is not dropped on all nodes",
true,
VIEWS_PORT
'views'
);
}

Expand All @@ -174,7 +179,7 @@ public function waitUntilScopePresent(string $bucketName, string $scopeName): vo
$scopePresent,
"Scope $scopeName on bucket $bucketName is not present on all nodes",
false,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -195,7 +200,7 @@ public function waitUntilScopeDropped(string $bucketName, string $scopeName): vo
$scopeDropped,
"Scope $scopeName on bucket $bucketName is not dropped on all nodes",
false,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -220,7 +225,7 @@ public function waitUntilCollectionPresent(string $bucketName, string $scopeName
$collectionPresent,
"Collection $collectionName on scope $scopeName on bucket $bucketName is not present on all nodes",
false,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -245,7 +250,7 @@ public function waitUntilCollectionDropped(string $bucketName, string $scopeName
$collectionDropped,
"Collection $collectionName on scope $scopeName on bucket $bucketName is not dropped on all nodes",
false,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -258,7 +263,7 @@ public function waitUntilBucketUpdated(string $bucketName, callable $predicate,
$predicate,
$errorMsg ?? "Bucket $bucketName has not been updated on all nodes",
false,
MANAGEMENT_PORT
'mgmt'
);
}

Expand All @@ -271,28 +276,29 @@ public function waitUntilCollectionUpdated(string $bucketName, string $scopeName
$predicate,
$errorMsg ?? "Collection $collectionName has not been updated on all nodes",
false,
MANAGEMENT_PORT
'mgmt'
);
}

/**
* @throws Exception
*/
public function waitUntilAllNodesMatchPredicate(string $path, callable $predicate, string $errorMsg, bool $onlyStatusCode, int $port): void
public function waitUntilAllNodesMatchPredicate(string $path, callable $predicate, string $errorMsg, bool $onlyStatusCode, string $service, array $request = []): void
{
try {
$deadline = $this->currentTimeMillis() + 2000;
$deadline = $this->currentTimeMillis() + 200_000;
while ($this->currentTimeMillis() < $deadline) {
$predicateMatched = $this->allNodesMatchPredicate(
$path,
$predicate,
$onlyStatusCode,
$port
$service,
$request
);
if ($predicateMatched) {
return;
}
usleep(10_000);
usleep(100_000);
}
throw new Exception("Timed out waiting for nodes to match predicate");
} catch (Exception $e) {
Expand Down Expand Up @@ -332,11 +338,70 @@ public function waitForConfig(bool $isMock): void
/**
* @throws Exception
*/
private function allNodesMatchPredicate(string $path, callable $predicate, bool $onlyStatusCode, int $port): bool
public function waitUntilQueryIndexReady(string $bucketName, string $indexName, bool $isPrimary): void
{
foreach ($this->nodes as $key => $value) {
$url = "http://" . $key . ":" . $port . $path;
$response = $this->runHttpRequest($url, $onlyStatusCode);
fprintf(
STDERR,
"waiting until query index \"%s\" (is_primary=%s) of bucket \"%s\" present on all nodes\n",
$indexName,
$isPrimary ? "true" : "false",
$bucketName
);
$indexPresent = function ($response) use ($bucketName, $indexName, $isPrimary) {
foreach ($response->results as $result) {
$index = $result->indexes;

if (
$index->state == "online" &&
$index->keyspace_id == $bucketName &&
$index->name == $indexName &&
(isset($index->is_primary) && $index->is_primary) == $isPrimary
) {
return true;
}
}
return false;
};


$this->waitUntilAllNodesMatchPredicate(
"/query/service",
$indexPresent,
sprintf("index %s (primary=%s) is not present on all nodes\n", $indexName, $isPrimary ? "true" : "false"),
false,
"n1ql",
[
'method' => 'POST',
'header' => ['Content-type: application/json'],
'content' => json_encode(
[
'statement' => 'SELECT * FROM system:indexes'
]
)
]
);
}

/**
* @throws Exception
*/
private function allNodesMatchPredicate(string $path, callable $predicate, bool $onlyStatusCode, string $service, array $request): bool
{
foreach ($this->nodes as $hostname => $services) {
if ($service != "mgmt" && $service != "views") {
$found = false;
foreach ($services as $name) {
if ($service == $name) {
$found = true;
break;
}
}
if (!$found) {
continue;
}
}
$url = "http://" . $hostname . ":" . PORTS[$service] . $path;
$response = $this->runHttpRequest($url, $request, $onlyStatusCode);
$predicateMatched = $predicate($response);
if (!$predicateMatched) {
return false;
Expand All @@ -348,13 +413,18 @@ private function allNodesMatchPredicate(string $path, callable $predicate, bool
/**
* @throws Exception
*/
private function runHttpRequest(string $url, bool $onlyStatusCode)
private function runHttpRequest(string $url, array $request, bool $onlyStatusCode)
{
$headers = $request['header'] ?? [];
unset($request['header']);
$opts = array('http' =>
array(
array_merge(
[
'method' => 'GET',
'header' => $this->basicAuthString,
'header' => array_merge([$this->basicAuthString], $headers),
'ignore_errors' => true,
],
$request
)
);
$context = stream_context_create($opts);
Expand All @@ -363,7 +433,7 @@ private function runHttpRequest(string $url, bool $onlyStatusCode)
if ($onlyStatusCode) {
return $statusCode;
} elseif ($statusCode != 200) {
throw new Exception("Non 200 status code from response");
throw new Exception(sprintf("Non 200 status code from response (%d).\n%s", $statusCode, $response));
}
return json_decode($response);
}
Expand Down
9 changes: 8 additions & 1 deletion tests/Helpers/CouchbaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ public function openBucket(string $name = null): BucketInterface

public function defaultCollection(string $bucketName = null): CollectionInterface
{
if ($bucketName == null) {
$bucketName = self::env()->bucketName();
}
return $this->openBucket($bucketName)->defaultCollection();
}

Expand Down Expand Up @@ -290,7 +293,11 @@ protected function assertError($type, $code, $ex)

protected function assertErrorType($type, $ex)
{
$this->assertInstanceOf($type, $ex);
$this->assertInstanceOf(
$type,
$ex,
sprintf("Exception: %s, Message: %s", get_class($ex), $ex->getMessage())
);
}

protected function assertErrorMessage($msg, $ex)
Expand Down
4 changes: 1 addition & 3 deletions tests/KeyValueGetReplicaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ public function testGetAllReplicasReturnCorrectValue()
$res = $collection->upsert($id, ["answer" => 42], $opts);
$cas = $res->cas();
$this->assertNotNull($cas);
if (self::env()->useCaves()) {
sleep(1);
}
sleep(1);
$results = $collection->getAllReplicas($id);
$this->assertGreaterThanOrEqual(1, count($results));
$seenActiveVersion = false;
Expand Down
Loading

0 comments on commit 2af0d42

Please sign in to comment.