Setup ci for graph tests

Signed-off-by: Parajuli Kiran <kiranparajuli589@gmail.com>
This commit is contained in:
Parajuli Kiran
2022-04-06 20:48:29 +05:45
committed by saw-jan
parent 5b04aa1ee7
commit ce0e47b365
3 changed files with 239 additions and 61 deletions

View File

@@ -1,6 +1,6 @@
# The test runner source for API tests
CORE_COMMITID=8d336099571f9218e09ba5ddf0eb30b19cab7d4f
CORE_BRANCH=master
CORE_COMMITID=522eed81a36a195c42f1e8423c1ba3433c0c11d0
CORE_BRANCH=use-graph-helper-from-ocis
# The test runner source for UI tests
WEB_COMMITID=41c62d459c4e7bc4a04367eb80f45a8c29aa3baa

View File

@@ -61,31 +61,31 @@ config = {
"ocis",
],
"cs3ApiTests": {
"skip": False,
"skip": True,
"earlyFail": True,
},
"localApiTests": {
"skip": False,
"skip": True,
"earlyFail": True,
},
"apiTests": {
"numberOfParts": 10,
"skip": False,
"skip": True,
"skipExceptParts": [],
"earlyFail": True,
},
"uiTests": {
"filterTags": "@ocisSmokeTest",
"skip": False,
"skip": True,
"skipExceptParts": [],
"earlyFail": True,
},
"accountsUITests": {
"skip": False,
"skip": True,
"earlyFail": True,
},
"settingsUITests": {
"skip": False,
"skip": True,
"earlyFail": True,
},
"parallelApiTests": {
@@ -93,7 +93,7 @@ config = {
"suites": [
"apiShareManagement",
],
"skip": False,
"skip": True,
"earlyFail": True,
"cron": "nightly",
},
@@ -101,11 +101,17 @@ config = {
"suites": [
"apiWebdavOperations",
],
"skip": False,
"skip": True,
"earlyFail": True,
"cron": "nightly",
},
},
"graphApiTests": {
"skip": False,
"earlyFali": False,
"numberOfParts": 10,
"skipExceptParts": [],
},
"rocketchat": {
"channel": "ocis-internal",
"from_secret": "private_rocketchat",
@@ -189,7 +195,6 @@ def main(ctx):
test_pipelines = \
cancelPreviousBuilds() + \
[buildOcisBinaryForTesting(ctx)] + \
testOcisModules(ctx) + \
testPipelines(ctx)
build_release_pipelines = \
@@ -291,6 +296,9 @@ def testPipelines(ctx):
if "skip" not in config["parallelApiTests"] or not config["parallelApiTests"]["skip"]:
pipelines += parallelDeployAcceptancePipeline(ctx)
if "skip" not in config["graphApiTests"] or not config["graphApiTests"]["skip"]:
pipelines += graphApiAcceptancePipeline(ctx)
return pipelines
def testOcisModule(ctx, module):
@@ -1005,7 +1013,7 @@ def dockerRelease(ctx, arch):
},
},
],
"depends_on": getPipelineNames(testOcisModules(ctx) + testPipelines(ctx)),
"depends_on": getPipelineNames(testPipelines(ctx)),
"trigger": {
"ref": [
"refs/heads/master",
@@ -1130,7 +1138,7 @@ def binaryRelease(ctx, name):
},
},
],
"depends_on": getPipelineNames(testOcisModules(ctx) + testPipelines(ctx)),
"depends_on": getPipelineNames(testPipelines(ctx)),
"trigger": {
"ref": [
"refs/heads/master",
@@ -1609,7 +1617,67 @@ def notify(ctx):
},
}
def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on = [], testing_parallel_deploy = False):
def ocisServerWithIdp():
environment = {
"GRAPH_IDENTITY_BACKEND": "ldap",
"GRAPH_LDAP_URI": "ldaps://0.0.0.0:9235",
"GRAPH_LDAP_BIND_DN": "uid=libregraph,ou=sysusers,o=libregraph-idm",
"GRAPH_LDAP_BIND_PASSWORD": "idm",
"GRAPH_LDAP_USER_EMAIL_ATTRIBUTE": "mail",
"GRAPH_LDAP_USER_NAME_ATTRIBUTE": "uid",
"GRAPH_LDAP_USER_BASE_DN": "ou=users,o=libregraph-idm",
"GRAPH_LDAP_GROUP_BASE_DN": "ou=groups,o=libregraph-idm",
"GRAPH_LDAP_SERVER_WRITE_ENABLED": "true",
"IDP_INSECURE": "true",
"IDP_LDAP_FILTER": "(&(objectclass=inetOrgPerson)(objectClass=owncloud))",
"IDP_LDAP_URI": "ldaps://0.0.0.0:9235",
"IDP_LDAP_BIND_DN": "uid=idp,ou=sysusers,o=libregraph-idm",
"IDP_LDAP_BIND_PASSWORD": "idp",
"IDP_LDAP_BASE_DN": "ou=users,o=libregraph-idm",
"IDP_LDAP_LOGIN_ATTRIBUTE": "uid",
"IDP_LDAP_UUID_ATTRIBUTE": "ownclouduuid",
"IDP_LDAP_UUID_ATTRIBUTE_TYPE": "binary",
"PROXY_ACCOUNT_BACKEND_TYPE": "cs3",
"OCS_ACCOUNT_BACKEND_TYPE": "cs3",
"STORAGE_LDAP_HOSTNAME": "0.0.0.0",
"STORAGE_LDAP_PORT": 9235,
"STORAGE_LDAP_INSECURE": "true",
"STORAGE_LDAP_BASE_DN": "o=libregraph-idm",
"STORAGE_LDAP_BIND_DN": "uid=reva,ou=sysusers,o=libregraph-idm",
"STORAGE_LDAP_BIND_PASSWORD": "reva",
"STORAGE_LDAP_LOGINFILTER": "(&(objectclass=inetOrgPerson)(objectclass=owncloud)(|(uid={{login}})(mail={{login}})))",
"STORAGE_LDAP_USERFILTER": "(&(objectclass=inetOrgPerson)(objectclass=owncloud)(|(ownclouduuid={{.OpaqueId}})(uid={{.OpaqueId}})))",
"STORAGE_LDAP_USERATTRIBUTEFILTER": "(&(objectclass=owncloud)({{attr}}={{value}}))",
"STORAGE_LDAP_USERFINDFILTER": "(&(objectclass=owncloud)(|(uid={{query}}*)(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)(description={{query}}*)))",
"STORAGE_LDAP_USERGROUPFILER": "(&(objectclass=groupOfNames)(member={{query}}*))",
"STORAGE_LDAP_GROUPFILTER": "(&(objectclass=groupOfNames)(objectclass=owncloud)(ownclouduuid={{.OpaqueId}}*))",
"OCIS_RUN_EXTENSIONS": "settings,storage-metadata,graph,graph-explorer,ocs,store,thumbnails,web,webdav,storage-frontend,storage-gateway,storage-userprovider,storage-groupprovider,storage-authbasic,storage-authbearer,storage-authmachine,storage-users,storage-shares,storage-public-link,storage-appprovider,storage-sharing,proxy,idp,nats,idm",
"OCIS_INSECURE": "true",
"PROXY_ENABLE_BASIC_AUTH": "true",
}
return [
{
"name": "ocis-server",
"image": OC_CI_ALPINE,
"detach": True,
"environment": environment,
"commands": [
"ocis/bin/ocis server",
],
"volumes": [stepVolumeOC10Tests],
"depends_on": [],
},
{
"name": "wait-for-ocis-server",
"image": OC_CI_WAIT_FOR,
"commands": [
"wait-for -it ocis-server:9200 -t 300",
],
"depends_on": [],
},
]
def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on = [], testing_parallel_deploy = False, testing_graph_api = False):
if not testing_parallel_deploy:
user = "0:0"
environment = {
@@ -2415,6 +2483,72 @@ def parallelDeploymentOC10Server():
},
]
def graphApiAcceptancePipeline(ctx):
pipelines = []
debugParts = config["graphApiTests"]["skipExceptParts"]
debugPartsEnabled = (len(debugParts) != 0)
for runPart in range(1, config["graphApiTests"]["numberOfParts"] + 1):
if (not debugPartsEnabled or (debugPartsEnabled and runPart in debugParts)):
pipelines.append(
graphApiTests(ctx, runPart, config["graphApiTests"]["numberOfParts"]),
)
return pipelines
def graphApiTests(ctx, part_number = 1, number_of_parts = 1):
storage = "ocis"
early_fail = config["graphApiTests"]["earlyFail"] if "earlyFail" in config["graphApiTests"] else False
filterTags = "~@skipOnGraph&&~@skipOnOcis&&~@notToImplementOnOCIS&&~@toImplementOnOCIS&&~comments-app-required&&~@federation-app-required&&~@notifications-app-required&&~systemtags-app-required&&~@local_storage&&~@skipOnOcis-OCIS-Storage&&~@issue-ocis-3023"
return {
"kind": "pipeline",
"type": "docker",
"name": "Graph-Core-API-Tests-%s-storage-%s" % (storage, part_number),
"platform": {
"os": "linux",
"arch": "amd64",
},
"steps": skipIfUnchanged(ctx, "acceptance-tests") +
restoreBuildArtifactCache(ctx, "ocis-binary-amd64", "ocis/bin/ocis") +
ocisServerWithIdp() +
cloneCoreRepos() + [
{
"name": "Graph-oC10ApiTests-%s-storage-%s" % (storage, part_number),
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
"environment": {
"TEST_WITH_GRAPH_API": "true",
"PATH_TO_OCIS": "/drone/src",
"PATH_TO_CORE": "/srv/app/testrunner",
"TEST_SERVER_URL": "https://ocis-server:9200",
"SKELETON_DIR": "/srv/app/tmp/testing/data/apiSkeleton",
"OCIS_SKELETON_STRATEGY": "upload",
"TEST_OCIS": "true",
"SEND_SCENARIO_LINE_REFERENCES": "true",
"STORAGE_DRIVER": storage,
"BEHAT_FILTER_TAGS": filterTags,
"DIVIDE_INTO_NUM_PARTS": number_of_parts,
"RUN_PART": part_number,
"UPLOAD_DELETE_WAIT_TIME": 0,
},
"commands": [
"cd /srv/app/testrunner",
"make test-acceptance-api",
],
"volumes": [stepVolumeOC10Tests],
},
] + failEarly(ctx, early_fail),
"depends_on": getPipelineNames([buildOcisBinaryForTesting(ctx)]),
"trigger": {
"ref": [
"refs/heads/master",
"refs/tags/v*",
"refs/pull/**",
],
},
"volumes": [pipelineVolumeOC10Tests],
}
def ldapService():
return [{
"name": "openldap",

View File

@@ -101,13 +101,17 @@ class GraphContext implements Context {
*/
public function adminHasRetrievedUserUsingTheGraphApi(string $user):void {
$user = $this->featureContext->getActualUsername($user);
$userId = $this->featureContext->getAttributeOfCreatedUser($user, "id");
try {
$userId = $this->featureContext->getAttributeOfCreatedUser($user, "id");
} catch (Exception $e) {
$userId = $user;
}
$result = GraphHelper::getUser(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword(),
($userId) ?: $user
$userId
);
$this->featureContext->setResponse($result);
$this->featureContext->thenTheHTTPStatusCodeShouldBe(200);
@@ -250,13 +254,14 @@ class GraphContext implements Context {
return $found;
}
/**
* @param string $user
* @param string $group
*
* @return void
* @throws JsonException
*/
/**
* @param string $user
* @param string $group
*
* @return void
* @throws JsonException
* @throws GuzzleException
*/
public function userShouldNotBeMemberInGroupUsingTheGraphApi(string $user, string $group):void {
$found = $this->getUserPresenceInGroupUsingTheGraphApi($user, $group);
Assert::assertFalse($found, __METHOD__ . " User $user is member of group $group");
@@ -268,6 +273,7 @@ class GraphContext implements Context {
*
* @return void
* @throws JsonException
* @throws GuzzleException
*/
public function userShouldBeMemberInGroupUsingTheGraphApi(string $user, string $group):void {
$found = $this->getUserPresenceInGroupUsingTheGraphApi($user, $group);
@@ -310,17 +316,26 @@ class GraphContext implements Context {
$this->featureContext->getAdminUsername(),
$this->featureContext->getAdminPassword()
);
$jsonBody = $this->featureContext->getJsonDecodedResponse($response);
if ($response->getStatusCode() === 200) {
return $jsonBody;
return $this->featureContext->getJsonDecodedResponse($response);
} else {
throw new Exception(
__METHOD__
. "\nCould not retrieve groups list."
. "\nHTTP status code: " . $response->getStatusCode()
. "\nError code: " . $jsonBody["error"]["code"]
. "\nMessage: " . $jsonBody["error"]["message"]
);
try {
$jsonBody = $this->featureContext->getJsonDecodedResponse($response);
throw new Exception(
__METHOD__
. "\nCould not retrieve groups list."
. "\nHTTP status code: " . $response->getStatusCode()
. "\nError code: " . $jsonBody["error"]["code"]
. "\nMessage: " . $jsonBody["error"]["message"]
);
} catch (TypeError $e) {
throw new Exception(
__METHOD__
. "\nCould not retrieve groups list."
. "\nHTTP status code: " . $response->getStatusCode()
. "\nResponse body: " . $response->getBody()
);
}
}
}
@@ -341,17 +356,26 @@ class GraphContext implements Context {
$this->featureContext->getAdminPassword(),
$this->featureContext->getAttributeOfCreatedGroup($group, 'id')
);
$jsonBody = $this->featureContext->getJsonDecodedResponse($response);
if ($response->getStatusCode() === 200) {
return $jsonBody;
return $this->featureContext->getJsonDecodedResponse($response);
} else {
throw new Exception(
__METHOD__
. "\nCould not retrieve members list for group $group."
. "\nHTTP status code: " . $response->getStatusCode()
. "\nError code: " . $jsonBody["error"]["code"]
. "\nMessage: " . $jsonBody["error"]["message"]
);
try {
$jsonBody = $this->featureContext->getJsonDecodedResponse($response);
throw new Exception(
__METHOD__
. "\nCould not retrieve members list for group $group."
. "\nHTTP status code: " . $response->getStatusCode()
. "\nError code: " . $jsonBody["error"]["code"]
. "\nMessage: " . $jsonBody["error"]["message"]
);
} catch (TypeError $e) {
throw new Exception(
__METHOD__
. "\nCould not retrieve members list for group $group."
. "\nHTTP status code: " . $response->getStatusCode()
. "\nResponse body: " . $response->getBody()
);
}
}
}
@@ -383,24 +407,33 @@ class GraphContext implements Context {
$email,
$displayName
);
$jsonBody = $this->featureContext->getJsonDecodedResponse($response);
if ($response->getStatusCode() !== 200) {
throw new Exception(
__METHOD__
. "\nCould not create user $user"
. "\nError code: {$jsonBody['error']['code']}"
. "\nError message: {$jsonBody['error']['message']}"
);
try {
$jsonResponseBody = $this->featureContext->getJsonDecodedResponse($response);
throw new Exception(
__METHOD__
. "\nCould not create user $user"
. "\nError code: {$jsonResponseBody['error']['code']}"
. "\nError message: {$jsonResponseBody['error']['message']}"
);
} catch (TypeError $e) {
throw new Exception(
__METHOD__
. "\nCould not create user $user"
. "\nHTTP status code: " . $response->getStatusCode()
. "\nResponse body: " . $response->getBody()
);
}
} else {
return $jsonBody;
return $this->featureContext->getJsonDecodedResponse($response);
}
}
/**
* adds a user to a group
*
* @param string $group
* @param string $user
* @param string $group
* @param bool $checkResult
*
* @return void
@@ -409,8 +442,8 @@ class GraphContext implements Context {
* @throws GuzzleException
*/
public function adminHasAddedUserToGroupUsingTheGraphApi(
string $group,
string $user,
string $group,
bool $checkResult = true
) {
$groupId = $this->featureContext->getAttributeOfCreatedGroup($group, "id");
@@ -425,8 +458,10 @@ class GraphContext implements Context {
);
if ($checkResult && ($result->getStatusCode() !== 204)) {
throw new Exception(
"could not add user to group. "
. $result->getStatusCode() . " " . $result->getBody()
__METHOD__
. "\nCould not add user to group. "
. "\n HTTP status: " . $result->getStatusCode()
. "\n Response body: " . $result->getBody()
);
}
}
@@ -448,16 +483,25 @@ class GraphContext implements Context {
$this->featureContext->getAdminPassword(),
$group,
);
$jsonBody = $this->featureContext->getJsonDecodedResponse($result);
if ($result->getStatusCode() === 200) {
return $jsonBody;
return $this->featureContext->getJsonDecodedResponse($result);
} else {
throw new Exception(
__METHOD__
. "\nError: failed creating group '$group'"
. "\nStatus code: " . $jsonBody['error']['code']
. "\nMessage: " . $jsonBody['error']['message']
);
try {
$jsonBody = $this->featureContext->getJsonDecodedResponse($result);
throw new Exception(
__METHOD__
. "\nError: failed creating group '$group'"
. "\nStatus code: " . $jsonBody['error']['code']
. "\nMessage: " . $jsonBody['error']['message']
);
} catch (TypeError $e) {
throw new Exception(
__METHOD__
. "\nError: failed creating group '$group'"
. "\nHTTP status code: " . $result->getStatusCode()
. "\nResponse body: " . $result->getBody()
);
}
}
}
}