diff options
-rw-r--r-- | .drone.yml | 124 | ||||
-rw-r--r-- | tests/integration/config/behat.yml | 6 | ||||
-rw-r--r-- | tests/integration/features/bootstrap/FeatureContext.php | 73 | ||||
-rw-r--r-- | tests/integration/features/bootstrap/FederationContext.php | 121 | ||||
-rw-r--r-- | tests/integration/features/federation/invite.feature | 4 | ||||
-rwxr-xr-x | tests/integration/run.sh | 7 |
6 files changed, 282 insertions, 53 deletions
diff --git a/.drone.yml b/.drone.yml index 78fc3fea9..1d07dc769 100644 --- a/.drone.yml +++ b/.drone.yml @@ -215,6 +215,41 @@ trigger: --- kind: pipeline +name: int-sqlite-federation + +steps: + - name: integration-federation + image: ghcr.io/nextcloud/continuous-integration-php8.0:latest + environment: + APP_NAME: spreed + CORE_BRANCH: master + DATABASEHOST: sqlite + commands: + - bash tests/drone-run-integration-tests.sh || exit 0 + - wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh + - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST + - cd ../server + - ./occ app:enable $APP_NAME + - cd apps/$APP_NAME + + # Run integration tests + - cd tests/integration/ + - bash run.sh features/federation + +services: + - name: cache + image: ghcr.io/nextcloud/continuous-integration-redis:latest + +trigger: + branch: + - master + - stable* + event: + - pull_request + - push + +--- +kind: pipeline name: int-sqlite-sharing steps: @@ -561,6 +596,51 @@ trigger: --- kind: pipeline +name: int-mysql-federation + +steps: + - name: integration-federation + image: ghcr.io/nextcloud/continuous-integration-php8.0:latest + environment: + APP_NAME: spreed + CORE_BRANCH: master + DATABASEHOST: mysql + commands: + - bash tests/drone-run-integration-tests.sh || exit 0 + - wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh + - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST + - cd ../server + - ./occ app:enable $APP_NAME + - cd apps/$APP_NAME + + # Run integration tests + - cd tests/integration/ + - bash run.sh features/federation + +services: + - name: cache + image: ghcr.io/nextcloud/continuous-integration-redis:latest + - name: mysql + image: ghcr.io/nextcloud/continuous-integration-mariadb-10.4:10.4 + environment: + MYSQL_ROOT_PASSWORD: owncloud + MYSQL_USER: oc_autotest + MYSQL_PASSWORD: owncloud + MYSQL_DATABASE: oc_autotest + command: [ "--innodb_large_prefix=true", "--innodb_file_format=barracuda", "--innodb_file_per_table=true" ] + tmpfs: + - /var/lib/mysql + +trigger: + branch: + - master + - stable* + event: + # - pull_request + - push + +--- +kind: pipeline name: int-mysql-sharing steps: @@ -921,6 +1001,50 @@ trigger: --- kind: pipeline +name: int-pgsql-federation + +steps: + - name: integration-federation + image: ghcr.io/nextcloud/continuous-integration-php8.0:latest + environment: + APP_NAME: spreed + CORE_BRANCH: master + DATABASEHOST: pgsql + commands: + - bash tests/drone-run-integration-tests.sh || exit 0 + - wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh + - bash ./before_install.sh $APP_NAME $CORE_BRANCH $DATABASEHOST + - cd ../server + - ./occ app:enable $APP_NAME + - cd apps/$APP_NAME + + # Run integration tests + - cd tests/integration/ + - bash run.sh features/federation + +services: + - name: cache + image: ghcr.io/nextcloud/continuous-integration-redis:latest + - name: pgsql + image: ghcr.io/nextcloud/continuous-integration-postgres-13:postgres-13 + environment: + POSTGRES_USER: oc_autotest + POSTGRES_DB: oc_autotest_dummy + POSTGRES_HOST_AUTH_METHOD: trust + POSTGRES_PASSWORD: + tmpfs: + - /var/lib/postgresql/data + +trigger: + branch: + - master + - stable* + event: + # - pull_request + - push + +--- +kind: pipeline name: int-pgsql-sharing steps: diff --git a/tests/integration/config/behat.yml b/tests/integration/config/behat.yml index 0d8eb080b..25ae8de49 100644 --- a/tests/integration/config/behat.yml +++ b/tests/integration/config/behat.yml @@ -7,6 +7,12 @@ default: - '%paths.base%/../features' contexts: - FeatureContext + - FederationContext: + baseUrl: http://localhost:8080/ + admin: + - admin + - admin + regularUserPassword: 123456 - SharingContext: baseUrl: http://localhost:8080/ admin: diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index 9d6ab1e11..b24f467b8 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -75,6 +75,9 @@ class FeatureContext implements Context, SnippetAcceptingContext { protected $baseUrl; /** @var string */ + protected $baseRemoteUrl; + + /** @var string */ protected $lastEtag; /** @var array */ @@ -122,6 +125,7 @@ class FeatureContext implements Context, SnippetAcceptingContext { public function __construct() { $this->cookieJars = []; $this->baseUrl = getenv('TEST_SERVER_URL'); + $this->baseRemoteUrl = getenv('TEST_REMOTE_URL'); $this->guestsAppWasEnabled = null; } @@ -359,63 +363,30 @@ class FeatureContext implements Context, SnippetAcceptingContext { */ private function assertInvites($invites, TableNode $formData) { Assert::assertCount(count($formData->getHash()), $invites, 'Invite count does not match'); - Assert::assertEquals($formData->getHash(), array_map(function ($room, $expectedRoom) { - if (!isset(self::$identifierToToken[$room['name']])) { - self::$identifierToToken[$room['name']] = $room['token']; - } - if (!isset(self::$tokenToIdentifier[$room['token']])) { - self::$tokenToIdentifier[$room['token']] = $room['name']; - } + Assert::assertEquals($formData->getHash(), array_map(function ($invite, $expectedInvite) { $data = []; - if (isset($expectedRoom['id'])) { - $data['id'] = self::$tokenToIdentifier[$room['token']]; - } - if (isset($expectedRoom['name'])) { - $data['name'] = $room['name']; - } - if (isset($expectedRoom['description'])) { - $data['description'] = $room['description']; - } - if (isset($expectedRoom['type'])) { - $data['type'] = (string) $room['type']; - } - if (isset($expectedRoom['hasPassword'])) { - $data['hasPassword'] = (string) $room['hasPassword']; - } - if (isset($expectedRoom['readOnly'])) { - $data['readOnly'] = (string) $room['readOnly']; + if (isset($expectedInvite['id'])) { + $data['id'] = self::$tokenToIdentifier[$invite['token']]; } - if (isset($expectedRoom['listable'])) { - $data['listable'] = (string) $room['listable']; - } - if (isset($expectedRoom['participantType'])) { - $data['participantType'] = (string) $room['participantType']; - } - if (isset($expectedRoom['sipEnabled'])) { - $data['sipEnabled'] = (string) $room['sipEnabled']; - } - if (isset($expectedRoom['callFlag'])) { - $data['callFlag'] = (int) $room['callFlag']; - } - if (isset($expectedRoom['attendeePin'])) { - $data['attendeePin'] = $room['attendeePin'] ? '**PIN**' : ''; + if (isset($expectedInvite['access_token'])) { + $data['access_token'] = (string) $invite['access_token']; } - if (isset($expectedRoom['lastMessage'])) { - $data['lastMessage'] = $room['lastMessage'] ? $room['lastMessage']['message'] : ''; + if (isset($expectedInvite['remote_token'])) { + $data['remote_token'] = self::$tokenToIdentifier[$invite['remote_token']] ?? 'unknown-token'; } - if (isset($expectedRoom['unreadMention'])) { - $data['unreadMention'] = (int) $room['unreadMention']; - } - if (isset($expectedRoom['unreadMentionDirect'])) { - $data['unreadMentionDirect'] = (int) $room['unreadMentionDirect']; - } - if (isset($expectedRoom['participants'])) { - throw new \Exception('participants key needs to be checked via participants endpoint'); + if (isset($expectedInvite['remote_server'])) { + if ($invite['remote_server'] === 'localhost:8080') { + $data['remote_server'] = 'LOCAL'; + } elseif ($invite['remote_server'] === 'localhost:8180') { + $data['remote_server'] = 'REMOTE'; + } else { + $data['remote_server'] = 'unknown-server'; + } } return $data; - }, $rooms, $formData->getHash())); + }, $invites, $formData->getHash())); } /** @@ -518,7 +489,7 @@ class FeatureContext implements Context, SnippetAcceptingContext { } if (isset($attendee['actorId'], $attendee['actorType']) && $attendee['actorType'] === 'federated_users') { - $attendee['actorId'] .= '@' . rtrim($this->baseUrl, '/'); + $attendee['actorId'] .= '@' . rtrim($this->baseRemoteUrl, '/'); } if (isset($attendee['participantType'])) { @@ -1177,7 +1148,7 @@ class FeatureContext implements Context, SnippetAcceptingContext { $this->setCurrentUser($user); if ($newType === 'remote') { - $newId .= '@' . $this->baseUrl; + $newId .= '@' . $this->baseRemoteUrl; } $this->sendRequest( diff --git a/tests/integration/features/bootstrap/FederationContext.php b/tests/integration/features/bootstrap/FederationContext.php new file mode 100644 index 000000000..c4a7c3ce8 --- /dev/null +++ b/tests/integration/features/bootstrap/FederationContext.php @@ -0,0 +1,121 @@ +<?php +/** + * @copyright Copyright (c) 2016 Sergio Bertolin <sbertolin@solidgear.es> + * + * @author Bjoern Schiessle <bjoern@schiessle.org> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> + * @author Daniel Calviño Sánchez <danxuliu@gmail.com> + * @author Joas Schilling <coding@schilljs.com> + * @author Robin Appelman <robin@icewind.nl> + * @author Sergio Bertolin <sbertolin@solidgear.es> + * @author Sergio Bertolín <sbertolin@solidgear.es> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +use Behat\Behat\Context\Context; +use Behat\Behat\Context\SnippetAcceptingContext; + +require __DIR__ . '/../../vendor/autoload.php'; + +/** + * Federation context. + */ +class FederationContext implements Context, SnippetAcceptingContext { + + /** @var string */ + private $baseUrl = ''; + /** @var string */ + private $baseRemoteUrl = ''; + + /** @var ResponseInterface */ + private $response = null; + + /** @var string */ + private $currentUser = ''; + + /** @var string */ + private $regularUserPassword; + + /** @var \SimpleXMLElement */ + private $lastCreatedShareData = null; + + public function __construct(string $baseUrl, array $admin, string $regularUserPassword) { + $this->baseUrl = $baseUrl; + $this->adminUser = $admin; + $this->regularUserPassword = $regularUserPassword; + + // in case of ci deployment we take the server url from the environment + $testServerUrl = getenv('TEST_SERVER_URL'); + if ($testServerUrl !== false) { + $this->baseUrl = $testServerUrl; + } + $testServerUrl = getenv('TEST_REMOTE_URL'); + if ($testServerUrl !== false) { + $this->baseRemoteUrl = $testServerUrl; + } + } + + /** @var string */ + private static $phpFederatedServerPid = ''; + + /** @var string */ + private $lastAcceptedRemoteShareId; + + /** + * @BeforeScenario + * @AfterScenario + * + * The server is started also after the scenarios to ensure that it is + * properly cleaned up if stopped. + */ + public function startFederatedServer() { + if (self::$phpFederatedServerPid !== '') { + return; + } + + $port = getenv('PORT_FED'); + $rootDir = getenv('NEXTCLOUD_ROOT_DIR'); + + self::$phpFederatedServerPid = exec('php -S localhost:' . $port . ' -t ' . $rootDir . ' >/dev/null & echo $!'); + } + +// /** +// * @BeforeScenario +// */ +// public function cleanupRemoteStorages() { +// // Ensure that dangling remote storages from previous tests will not +// // interfere with the current scenario. +// // The storages must be cleaned before each scenario; they can not be +// // cleaned after each scenario, as this hook is executed before the hook +// // that removes the users, so the shares would be still valid and thus +// // the storages would not be dangling yet. +// $this->runOcc(['sharing:cleanup-remote-storages']); +// } + + /** + * @When /^remote server is stopped$/ + */ + public function remoteServerIsStopped() { + if (self::$phpFederatedServerPid === '') { + return; + } + + exec('kill ' . self::$phpFederatedServerPid); + + self::$phpFederatedServerPid = ''; + } +} diff --git a/tests/integration/features/federation/invite.feature b/tests/integration/features/federation/invite.feature index 72b0fa656..26f93e6bb 100644 --- a/tests/integration/features/federation/invite.feature +++ b/tests/integration/features/federation/invite.feature @@ -26,5 +26,5 @@ Feature: federation/invite | users | participant1 | 1 | | federated_users | participant2 | 3 | And user "participant2" has the following invitations (v1) - | id | type | participantType | - | room | 3 | 1 | + | remote_server | remote_token | + | LOCAL | room | diff --git a/tests/integration/run.sh b/tests/integration/run.sh index 96248c9c4..f29b8008e 100755 --- a/tests/integration/run.sh +++ b/tests/integration/run.sh @@ -10,6 +10,12 @@ php -S localhost:8080 -t ${ROOT_DIR} & PHPPID=$! echo $PHPPID +# The federated server is started and stopped by the tests themselves +PORT_FED=8180 +export PORT_FED +NEXTCLOUD_ROOT_DIR=${ROOT_DIR} +export NEXTCLOUD_ROOT_DIR + # also kill php process in case of ctrl+c trap 'kill -TERM $PHPPID; wait $PHPPID' TERM @@ -19,6 +25,7 @@ ${ROOT_DIR}/occ app:enable spreedcheats || exit 1 ${ROOT_DIR}/occ app:list | grep spreed export TEST_SERVER_URL="http://localhost:8080/" +export TEST_REMOTE_URL="http://localhost:8180/" ${APP_INTEGRATION_DIR}/vendor/bin/behat -f junit -f pretty $1 $2 RESULT=$? |