mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-22 02:38:32 -05:00
Merge pull request #5236 from owncloud/tests/cors-tests
[tests-only][full-ci] Add CORS API tests (#5187)
This commit is contained in:
+103
-61
@@ -101,8 +101,28 @@ config = {
|
||||
"earlyFail": True,
|
||||
},
|
||||
"localApiTests": {
|
||||
"skip": False,
|
||||
"earlyFail": True,
|
||||
"basic": {
|
||||
"suites": [
|
||||
"apiAccountsHashDifficulty",
|
||||
"apiArchiver",
|
||||
"apiContract",
|
||||
"apiGraph",
|
||||
"apiSpaces",
|
||||
"apiSpacesShares",
|
||||
],
|
||||
"skip": False,
|
||||
"earlyFail": True,
|
||||
},
|
||||
"apiCors": {
|
||||
"suites": [
|
||||
"apiCors",
|
||||
],
|
||||
"skip": False,
|
||||
"earlyFail": True,
|
||||
"extraServerEnvironment": {
|
||||
"OCIS_CORS_ALLOW_ORIGINS": "https://aphno.badal",
|
||||
},
|
||||
},
|
||||
},
|
||||
"apiTests": {
|
||||
"numberOfParts": 10,
|
||||
@@ -349,15 +369,8 @@ def testPipelines(ctx):
|
||||
pipelines.append(cs3ApiTests(ctx, "ocis", "default"))
|
||||
if "skip" not in config["wopiValidatorTests"] or not config["wopiValidatorTests"]["skip"]:
|
||||
pipelines.append(wopiValidatorTests(ctx, "ocis", "default"))
|
||||
if "skip" not in config["localApiTests"] or not config["localApiTests"]["skip"]:
|
||||
pipelines += [
|
||||
localApiTests(ctx, "ocis", "apiAccountsHashDifficulty"),
|
||||
localApiTests(ctx, "ocis", "apiSpaces"),
|
||||
localApiTests(ctx, "ocis", "apiSpacesShares"),
|
||||
localApiTests(ctx, "ocis", "apiContract"),
|
||||
localApiTests(ctx, "ocis", "apiArchiver"),
|
||||
localApiTests(ctx, "ocis", "apiGraph"),
|
||||
]
|
||||
|
||||
pipelines += localApiTestPipeline(ctx)
|
||||
|
||||
if "skip" not in config["apiTests"] or not config["apiTests"]["skip"]:
|
||||
pipelines += apiTests(ctx)
|
||||
@@ -670,58 +683,84 @@ def codestyle(ctx):
|
||||
|
||||
return pipelines
|
||||
|
||||
def localApiTests(ctx, storage, suite, accounts_hash_difficulty = 4):
|
||||
early_fail = config["localApiTests"]["earlyFail"] if "earlyFail" in config["localApiTests"] else False
|
||||
def localApiTestPipeline(ctx):
|
||||
pipelines = []
|
||||
|
||||
return {
|
||||
"kind": "pipeline",
|
||||
"type": "docker",
|
||||
"name": "localApiTests-%s-%s" % (suite, storage),
|
||||
"platform": {
|
||||
"os": "linux",
|
||||
"arch": "amd64",
|
||||
},
|
||||
"steps": skipIfUnchanged(ctx, "acceptance-tests") +
|
||||
restoreBuildArtifactCache(ctx, "ocis-binary-amd64", "ocis/bin") +
|
||||
ocisServer(storage, accounts_hash_difficulty) +
|
||||
restoreBuildArtifactCache(ctx, "testrunner", dirs["core"]) +
|
||||
[
|
||||
{
|
||||
"name": "localApiTests-%s-%s" % (suite, storage),
|
||||
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
|
||||
"environment": {
|
||||
"TEST_WITH_GRAPH_API": "true",
|
||||
"PATH_TO_OCIS": dirs["base"],
|
||||
"PATH_TO_CORE": "%s/%s" % (dirs["base"], dirs["core"]),
|
||||
"TEST_SERVER_URL": "https://ocis-server:9200",
|
||||
"OCIS_REVA_DATA_ROOT": "%s" % (dirs["ocisRevaDataRoot"] if storage == "owncloud" else ""),
|
||||
"OCIS_SKELETON_STRATEGY": "%s" % ("copy" if storage == "owncloud" else "upload"),
|
||||
"TEST_OCIS": "true",
|
||||
"SEND_SCENARIO_LINE_REFERENCES": "true",
|
||||
"STORAGE_DRIVER": storage,
|
||||
"BEHAT_SUITE": suite,
|
||||
"BEHAT_FILTER_TAGS": "~@skip&&~@skipOnGraph&&~@skipOnOcis-%s-Storage" % ("OC" if storage == "owncloud" else "OCIS"),
|
||||
"EXPECTED_FAILURES_FILE": "%s/tests/acceptance/expected-failures-localAPI-on-%s-storage.md" % (dirs["base"], storage.upper()),
|
||||
"UPLOAD_DELETE_WAIT_TIME": "1" if storage == "owncloud" else 0,
|
||||
},
|
||||
"commands": [
|
||||
"pwd",
|
||||
"ls -la",
|
||||
"make test-acceptance-api",
|
||||
],
|
||||
},
|
||||
] + failEarly(ctx, early_fail),
|
||||
"services": redisForOCStorage(storage),
|
||||
"depends_on": getPipelineNames([buildOcisBinaryForTesting(ctx)]) +
|
||||
getPipelineNames(cacheCoreReposForTesting(ctx)),
|
||||
"trigger": {
|
||||
"ref": [
|
||||
"refs/heads/master",
|
||||
"refs/pull/**",
|
||||
],
|
||||
},
|
||||
defaults = {
|
||||
"suites": {},
|
||||
"skip": False,
|
||||
"earlyFail": False,
|
||||
"extraEnvironment": {},
|
||||
"extraServerEnvironment": {},
|
||||
"storages": ["ocis"],
|
||||
"accounts_hash_difficulty": 4,
|
||||
}
|
||||
|
||||
if "localApiTests" in config:
|
||||
for name, matrix in config["localApiTests"].items():
|
||||
if "skip" not in matrix or not matrix["skip"]:
|
||||
params = {}
|
||||
for item in defaults:
|
||||
params[item] = matrix[item] if item in matrix else defaults[item]
|
||||
for suite in params["suites"]:
|
||||
early_fail = params["earlyFail"] if "earlyFail" in params else False
|
||||
for storage in params["storages"]:
|
||||
pipeline = {
|
||||
"kind": "pipeline",
|
||||
"type": "docker",
|
||||
"name": "localApiTests-%s-%s" % (suite, storage),
|
||||
"platform": {
|
||||
"os": "linux",
|
||||
"arch": "amd64",
|
||||
},
|
||||
"steps": skipIfUnchanged(ctx, "acceptance-tests") +
|
||||
restoreBuildArtifactCache(ctx, "ocis-binary-amd64", "ocis/bin") +
|
||||
ocisServer(storage, params["accounts_hash_difficulty"], extra_server_environment = params["extraServerEnvironment"]) +
|
||||
restoreBuildArtifactCache(ctx, "testrunner", dirs["core"]) +
|
||||
localApiTests(suite, storage, params["extraEnvironment"]) +
|
||||
failEarly(ctx, early_fail),
|
||||
"services": redisForOCStorage(storage),
|
||||
"depends_on": getPipelineNames([buildOcisBinaryForTesting(ctx)]) +
|
||||
getPipelineNames(cacheCoreReposForTesting(ctx)),
|
||||
"trigger": {
|
||||
"ref": [
|
||||
"refs/heads/master",
|
||||
"refs/pull/**",
|
||||
],
|
||||
},
|
||||
}
|
||||
pipelines.append(pipeline)
|
||||
return pipelines
|
||||
|
||||
def localApiTests(suite, storage, extra_environment = {}):
|
||||
environment = {
|
||||
"TEST_WITH_GRAPH_API": "true",
|
||||
"PATH_TO_OCIS": dirs["base"],
|
||||
"PATH_TO_CORE": "%s/%s" % (dirs["base"], dirs["core"]),
|
||||
"TEST_SERVER_URL": "https://ocis-server:9200",
|
||||
"OCIS_REVA_DATA_ROOT": "%s" % (dirs["ocisRevaDataRoot"] if storage == "owncloud" else ""),
|
||||
"OCIS_SKELETON_STRATEGY": "%s" % ("copy" if storage == "owncloud" else "upload"),
|
||||
"TEST_OCIS": "true",
|
||||
"SEND_SCENARIO_LINE_REFERENCES": "true",
|
||||
"STORAGE_DRIVER": storage,
|
||||
"BEHAT_SUITE": suite,
|
||||
"BEHAT_FILTER_TAGS": "~@skip&&~@skipOnGraph&&~@skipOnOcis-%s-Storage" % ("OC" if storage == "owncloud" else "OCIS"),
|
||||
"EXPECTED_FAILURES_FILE": "%s/tests/acceptance/expected-failures-localAPI-on-%s-storage.md" % (dirs["base"], storage.upper()),
|
||||
"UPLOAD_DELETE_WAIT_TIME": "1" if storage == "owncloud" else 0,
|
||||
}
|
||||
|
||||
for item in extra_environment:
|
||||
environment[item] = extra_environment[item]
|
||||
|
||||
return [{
|
||||
"name": "localApiTests-%s-%s" % (suite, storage),
|
||||
"image": OC_CI_PHP % DEFAULT_PHP_VERSION,
|
||||
"environment": environment,
|
||||
"commands": [
|
||||
"make test-acceptance-api",
|
||||
],
|
||||
}]
|
||||
|
||||
def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4):
|
||||
early_fail = config["cs3ApiTests"]["earlyFail"] if "earlyFail" in config["cs3ApiTests"] else False
|
||||
|
||||
@@ -1981,7 +2020,7 @@ def notify():
|
||||
},
|
||||
}
|
||||
|
||||
def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on = [], deploy_type = ""):
|
||||
def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on = [], deploy_type = "", extra_server_environment = {}):
|
||||
if deploy_type == "":
|
||||
user = "0:0"
|
||||
environment = {
|
||||
@@ -2114,6 +2153,9 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on =
|
||||
if (accounts_hash_difficulty != "default"):
|
||||
environment["ACCOUNTS_HASH_DIFFICULTY"] = accounts_hash_difficulty
|
||||
|
||||
for item in extra_server_environment:
|
||||
environment[item] = extra_server_environment[item]
|
||||
|
||||
return [
|
||||
{
|
||||
"name": "ocis-server",
|
||||
|
||||
@@ -136,5 +136,20 @@ default:
|
||||
- TUSContext:
|
||||
- SpacesTUSContext:
|
||||
|
||||
apiCors:
|
||||
paths:
|
||||
- '%paths.base%/../features/apiCors'
|
||||
context: *common_ldap_suite_context
|
||||
contexts:
|
||||
- SpacesContext:
|
||||
- FeatureContext: *common_feature_context_params
|
||||
- OccContext:
|
||||
- WebDavPropertiesContext:
|
||||
- FavoritesContext:
|
||||
- ChecksumContext:
|
||||
- FilesVersionsContext:
|
||||
- OCSContext:
|
||||
- TrashbinContext:
|
||||
|
||||
extensions:
|
||||
Cjm\Behat\StepThroughExtension: ~
|
||||
|
||||
@@ -68,3 +68,13 @@ The expected failures in this file are from features in the owncloud/ocis repo.
|
||||
- [apiGraph/editGroup.feature:23](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editGroup.feature#L23)
|
||||
- [apiGraph/editGroup.feature:24](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editGroup.feature#L24)
|
||||
- [apiGraph/editGroup.feature:25](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editGroup.feature#L25)
|
||||
|
||||
#### [CORS headers are not identical with oC10 headers](https://github.com/owncloud/ocis/issues/5195)
|
||||
- [apiCors/cors.feature:25](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L25)
|
||||
- [apiCors/cors.feature:26](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L26)
|
||||
- [apiCors/cors.feature:27](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L27)
|
||||
- [apiCors/cors.feature:28](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L28)
|
||||
|
||||
#### [Requests with invalid credentials do not return CORS headers](https://github.com/owncloud/ocis/issues/5194)
|
||||
- [apiCors/cors.feature:67](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L67)
|
||||
- [apiCors/cors.feature:68](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L68)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# NOTE: for running this feature locally, you need to run oCIS with the following env var:
|
||||
# CORS_ALLOWED_ORIGINS=https://aphno.badal
|
||||
@api @skipOnOcV10
|
||||
Feature: CORS headers
|
||||
|
||||
Background:
|
||||
Given user "Alice" has been created with default attributes and without skeleton files
|
||||
|
||||
|
||||
Scenario Outline: CORS headers should be returned when setting CORS domain sending Origin header
|
||||
Given using OCS API version "<ocs_api_version>"
|
||||
When user "Alice" sends HTTP method "GET" to OCS API endpoint "<endpoint>" with headers
|
||||
| header | value |
|
||||
| Origin | https://aphno.badal |
|
||||
Then the OCS status code should be "<ocs-code>"
|
||||
And the HTTP status code should be "<http-code>"
|
||||
And the following headers should be set
|
||||
| header | value |
|
||||
| Access-Control-Allow-Headers | OC-Checksum,OC-Total-Length,OCS-APIREQUEST,X-OC-Mtime,OC-RequestAppPassword,Accept,Authorization,Brief,Content-Length,Content-Range,Content-Type,Date,Depth,Destination,Host,If,If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,Location,Lock-Token,Overwrite,Prefer,Range,Schedule-Reply,Timeout,User-Agent,X-Expected-Entity-Length,Accept-Language,Access-Control-Request-Method,Access-Control-Allow-Origin,Cache-Control,ETag,OC-Autorename,OC-CalDav-Import,OC-Chunked,OC-Etag,OC-FileId,OC-LazyOps,OC-Total-File-Length,Origin,X-Request-ID,X-Requested-With |
|
||||
| Access-Control-Expose-Headers | Content-Location,DAV,ETag,Link,Lock-Token,OC-ETag,OC-Checksum,OC-FileId,OC-JobStatus-Location,OC-RequestAppPassword,Vary,Webdav-Location,X-Sabre-Status |
|
||||
| Access-Control-Allow-Origin | https://aphno.badal |
|
||||
| Access-Control-Allow-Methods | GET,OPTIONS,POST,PUT,DELETE,MKCOL,PROPFIND,PATCH,PROPPATCH,REPORT |
|
||||
Examples:
|
||||
| ocs_api_version | endpoint | ocs-code | http-code |
|
||||
| 1 | /config | 100 | 200 |
|
||||
| 2 | /config | 200 | 200 |
|
||||
| 1 | /apps/files_sharing/api/v1/shares | 100 | 200 |
|
||||
| 2 | /apps/files_sharing/api/v1/shares | 200 | 200 |
|
||||
|
||||
|
||||
Scenario Outline: CORS headers should not be returned when CORS domain does not match Origin header
|
||||
Given using OCS API version "<ocs_api_version>"
|
||||
When user "Alice" sends HTTP method "GET" to OCS API endpoint "<endpoint>" with headers
|
||||
| header | value |
|
||||
| Origin | https://mero.badal |
|
||||
Then the OCS status code should be "<ocs-code>"
|
||||
And the HTTP status code should be "<http-code>"
|
||||
And the following headers should not be set
|
||||
| header |
|
||||
| Access-Control-Allow-Headers |
|
||||
| Access-Control-Expose-Headers |
|
||||
| Access-Control-Allow-Origin |
|
||||
| Access-Control-Allow-Methods |
|
||||
Examples:
|
||||
| ocs_api_version | endpoint | ocs-code | http-code |
|
||||
| 1 | /config | 100 | 200 |
|
||||
| 2 | /config | 200 | 200 |
|
||||
| 1 | /apps/files_sharing/api/v1/shares | 100 | 200 |
|
||||
| 2 | /apps/files_sharing/api/v1/shares | 200 | 200 |
|
||||
|
||||
|
||||
Scenario Outline: CORS headers should be returned when an invalid password is used
|
||||
Given using OCS API version "<ocs_api_version>"
|
||||
When user "Alice" sends HTTP method "GET" to OCS API endpoint "<endpoint>" with headers using password "invalid"
|
||||
| header | value |
|
||||
| Origin | https://aphno.badal |
|
||||
Then the OCS status code should be "997"
|
||||
And the HTTP status code should be "401"
|
||||
And the following headers should be set
|
||||
| header | value |
|
||||
| Access-Control-Allow-Headers | OC-Checksum,OC-Total-Length,OCS-APIREQUEST,X-OC-Mtime,OC-RequestAppPassword,Accept,Authorization,Brief,Content-Length,Content-Range,Content-Type,Date,Depth,Destination,Host,If,If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,Location,Lock-Token,Overwrite,Prefer,Range,Schedule-Reply,Timeout,User-Agent,X-Expected-Entity-Length,Accept-Language,Access-Control-Request-Method,Access-Control-Allow-Origin,Cache-Control,ETag,OC-Autorename,OC-CalDav-Import,OC-Chunked,OC-Etag,OC-FileId,OC-LazyOps,OC-Total-File-Length,Origin,X-Request-ID,X-Requested-With |
|
||||
| Access-Control-Expose-Headers | Content-Location,DAV,ETag,Link,Lock-Token,OC-ETag,OC-Checksum,OC-FileId,OC-JobStatus-Location,OC-RequestAppPassword,Vary,Webdav-Location,X-Sabre-Status |
|
||||
| Access-Control-Allow-Origin | https://aphno.badal |
|
||||
| Access-Control-Allow-Methods | GET,OPTIONS,POST,PUT,DELETE,MKCOL,PROPFIND,PATCH,PROPPATCH,REPORT |
|
||||
Examples:
|
||||
| ocs_api_version | endpoint |
|
||||
| 1 | /apps/files_sharing/api/v1/shares |
|
||||
| 2 | /apps/files_sharing/api/v1/shares |
|
||||
Reference in New Issue
Block a user