From f8a00897b067521ca1eb99e29ce649c070eef5cb Mon Sep 17 00:00:00 2001 From: jld3103 Date: Fri, 16 Dec 2022 13:10:44 +0100 Subject: [PATCH 1/2] tool: Update docker image version when updating nextcloud server --- tool/update.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tool/update.sh b/tool/update.sh index 99410c6c..10c93121 100755 --- a/tool/update.sh +++ b/tool/update.sh @@ -23,6 +23,12 @@ elif [ -d "external/nextcloud-$1" ]; then latest_tag="$(git tag --sort=v:refname | grep -vi "rc" | grep -vi "alpha" | grep -vi "beta" | tail -n 1)" git reset --hard "$latest_tag" git submodule update + + if [[ "$1" == "server" ]]; then + # shellcheck disable=SC2001 + image_version=$(echo "$latest_tag" | sed "s/^v//") + sed -i "s/FROM nextcloud:.*/FROM nextcloud:$image_version/" ../../tool/Dockerfile.dev + fi ) else echo "$1 not found" From 989caab7fb622331ddce4dc75de05eebde751406 Mon Sep 17 00:00:00 2001 From: jld3103 Date: Fri, 16 Dec 2022 14:24:13 +0100 Subject: [PATCH 2/2] tool,nextcloud: Only use a single Dockerfile for development and testing --- .../test/{core_test.dart => core.dart} | 40 ++++--- packages/nextcloud/test/helper.dart | 112 ++---------------- packages/nextcloud/test/main_test.dart | 19 +++ .../test/{news_test.dart => news.dart} | 4 +- .../test/{notes_test.dart => notes.dart} | 4 +- ...fications_test.dart => notifications.dart} | 4 +- ...ng_api_test.dart => provisioning_api.dart} | 4 +- ...user_status_test.dart => user_status.dart} | 4 +- .../test/{webdav_test.dart => webdav.dart} | 4 +- tool/Dockerfile.dev | 3 +- tool/build-dev-container-image.sh | 2 +- .../nextcloud/test => tool}/overlay/.gitkeep | 0 12 files changed, 72 insertions(+), 128 deletions(-) rename packages/nextcloud/test/{core_test.dart => core.dart} (73%) create mode 100644 packages/nextcloud/test/main_test.dart rename packages/nextcloud/test/{news_test.dart => news.dart} (99%) rename packages/nextcloud/test/{notes_test.dart => notes.dart} (97%) rename packages/nextcloud/test/{notifications_test.dart => notifications.dart} (98%) rename packages/nextcloud/test/{provisioning_api_test.dart => provisioning_api.dart} (92%) rename packages/nextcloud/test/{user_status_test.dart => user_status.dart} (99%) rename packages/nextcloud/test/{webdav_test.dart => webdav.dart} (99%) rename {packages/nextcloud/test => tool}/overlay/.gitkeep (100%) diff --git a/packages/nextcloud/test/core_test.dart b/packages/nextcloud/test/core.dart similarity index 73% rename from packages/nextcloud/test/core_test.dart rename to packages/nextcloud/test/core.dart index ff99eaaf..6a086d64 100644 --- a/packages/nextcloud/test/core_test.dart +++ b/packages/nextcloud/test/core.dart @@ -4,13 +4,10 @@ import 'package:test/test.dart'; import 'helper.dart'; Future main() async { - final image = await getDockerImage( - apps: [ - 'news', - 'notes', - ], - ); + await run(await getDockerImage()); +} +Future run(final DockerImage image) async { group('core', () { late DockerContainer container; late TestNextcloudClient client; @@ -27,11 +24,12 @@ Future main() async { test('Get status', () async { final status = await client.core.getStatus(); + print(status.toJson()); expect(status.installed, true); expect(status.maintenance, false); expect(status.needsDbUpgrade, false); - expect(status.version, startsWith(nextcloudVersion)); - expect(status.versionstring, startsWith('${nextcloudVersion.split('.')[0]}.')); + expect(status.version, startsWith('25.0.2')); + expect(status.versionstring, '25.0.2'); expect(status.edition, ''); expect(status.productname, 'Nextcloud'); expect(status.extendedSupport, false); @@ -39,8 +37,8 @@ Future main() async { test('Get capabilities', () async { final capabilities = await client.core.getCapabilities(); - expect(capabilities.ocs.data.version.major.toString(), nextcloudVersion.split('.')[0]); - expect(capabilities.ocs.data.version.string, nextcloudVersion); + expect(capabilities.ocs.data.version.major.toString(), '25'); + expect(capabilities.ocs.data.version.string, '25.0.2'); expect(capabilities.ocs.data.capabilities.theming!.name, 'Nextcloud'); expect(capabilities.ocs.data.capabilities.theming!.url, 'https://nextcloud.com'); expect(capabilities.ocs.data.capabilities.theming!.slogan, 'a safe home for all your data'); @@ -75,7 +73,7 @@ Future main() async { ShareType.group.code, ], ); - expect(response.ocs.data, hasLength(2)); + expect(response.ocs.data, hasLength(3)); expect(response.ocs.data[0].id, 'admin'); expect(response.ocs.data[0].label, 'admin'); @@ -85,13 +83,21 @@ Future main() async { expect(response.ocs.data[0].subline, ''); expect(response.ocs.data[0].shareWithDisplayNameUnique, 'admin@example.com'); - expect(response.ocs.data[1].id, 'admin'); - expect(response.ocs.data[1].label, 'admin'); - expect(response.ocs.data[1].icon, ''); - expect(response.ocs.data[1].source, 'groups'); - expect(response.ocs.data[1].status.string, isEmpty); + expect(response.ocs.data[1].id, 'user2'); + expect(response.ocs.data[1].label, 'User Two'); + expect(response.ocs.data[1].icon, 'icon-user'); + expect(response.ocs.data[1].source, 'users'); + expect(response.ocs.data[1].status.string, isNull); expect(response.ocs.data[1].subline, ''); - expect(response.ocs.data[1].shareWithDisplayNameUnique, ''); + expect(response.ocs.data[1].shareWithDisplayNameUnique, 'user2'); + + expect(response.ocs.data[2].id, 'admin'); + expect(response.ocs.data[2].label, 'admin'); + expect(response.ocs.data[2].icon, ''); + expect(response.ocs.data[2].source, 'groups'); + expect(response.ocs.data[2].status.string, isEmpty); + expect(response.ocs.data[2].subline, ''); + expect(response.ocs.data[2].shareWithDisplayNameUnique, ''); }); }); } diff --git a/packages/nextcloud/test/helper.dart b/packages/nextcloud/test/helper.dart index b1fcc05f..fe26cb19 100644 --- a/packages/nextcloud/test/helper.dart +++ b/packages/nextcloud/test/helper.dart @@ -3,23 +3,10 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; -import 'package:crypto/crypto.dart'; import 'package:nextcloud/nextcloud.dart'; import 'package:process_run/cmd_run.dart'; import 'package:test/test.dart'; -const String nextcloudVersion = '25.0.2'; -const String defaultUsername = 'user1'; -const String defaultPassword = 'user1'; - -class DockerImage { - DockerImage({ - required this.name, - }); - - final String name; -} - class DockerContainer { DockerContainer({ required this.id, @@ -98,8 +85,8 @@ class TestNextcloudClient extends NextcloudClient { Future getTestClient( final DockerContainer container, { - final String? username = defaultUsername, - final String? password = defaultPassword, + final String? username = 'user1', + final String? password = 'user1', final bool useAppPassword = false, final AppType appType = AppType.unknown, final String? userAgentOverride, @@ -172,7 +159,7 @@ Future getDockerContainer(final DockerImage image) async { '$port:80', '--add-host', 'host.docker.internal:host-gateway', - image.name, + image, ], ); // 125 means the docker run command itself has failed which indicated the port is already used @@ -191,23 +178,10 @@ Future getDockerContainer(final DockerImage image) async { ); } -Future getDockerImage({ - final List? users, - final List? apps, -}) async { - final hash = sha1 - .convert( - utf8.encode( - [ - if (users != null) - for (final user in users) user.toString(), - if (apps != null) ...apps, - ].join(), - ), - ) - .toString(); +typedef DockerImage = String; - final dockerImageName = 'nextcloud-neon-$hash'; +Future getDockerImage() async { + const dockerImageName = 'nextcloud-neon-dev'; final inputStream = StreamController>(); final process = runExecutableArguments( @@ -218,21 +192,13 @@ Future getDockerImage({ dockerImageName, '-f', '-', - './test', + '../../tool', ], stdout: stdout, stderr: stderr, stdin: inputStream.stream, ); - inputStream.add( - utf8.encode( - TestDockerHelper.generateInstructions( - nextcloudVersion, - users: users, - apps: apps, - ), - ), - ); + inputStream.add(utf8.encode(File('../../tool/Dockerfile.dev').readAsStringSync())); await inputStream.close(); final result = await process; @@ -240,9 +206,7 @@ Future getDockerImage({ throw Exception('Failed to build docker image'); } - return DockerImage( - name: dockerImageName, - ); + return dockerImageName; } class TestNextcloudUser { @@ -257,64 +221,6 @@ class TestNextcloudUser { final String? displayName; } -class TestDockerHelper { - static String generateInstructions( - final String nextcloudVersion, { - final List? users, - final List? apps, - }) { - users?.sort((final a, final b) => a.username.compareTo(b.username)); - apps?.sort(); - - final instructions = [ - generateFromNextcloudImageInstruction(nextcloudVersion), - 'WORKDIR /usr/src/nextcloud', - 'RUN chown -R www-data:www-data .', - 'USER www-data', - 'RUN ./occ maintenance:install --admin-pass admin --admin-email admin@example.com', - 'RUN ./occ app:disable password_policy', - 'RUN ./occ config:system:set allow_local_remote_servers --value=true', - generateCreateTestUserInstruction(), - if (apps != null) ...[ - for (final app in apps) ...[ - generateInstallAppInstruction(app), - ], - ], - if (users != null) ...[ - for (final user in users) ...[ - generateCreateUserInstruction(user), - ], - ], - 'RUN ./occ app:enable password_policy', - 'COPY --chown=www-data:www-data overlay /usr/src/nextcloud/', - '', - ]; - - return instructions.join('\n'); - } - - static String generateFromNextcloudImageInstruction( - final String nextcloudVersion, - ) => - 'FROM nextcloud:$nextcloudVersion'; - - static String generateCreateTestUserInstruction() => generateCreateUserInstruction( - TestNextcloudUser( - defaultUsername, - defaultPassword, - displayName: 'User One', - ), - ); - - static String generateCreateUserInstruction(final TestNextcloudUser user) => - 'RUN OC_PASS="${user.password}" ./occ user:add --password-from-env ${user.displayName != null ? '--display-name="${user.displayName}"' : ''} ${user.username}'; - - static String generateInstallAppInstruction( - final String appName, - ) => - 'RUN ./occ app:install $appName'; -} - int randomPort() => 1024 + Random().nextInt(65535 - 1024); void expectDateInReasonableTimeRange(final DateTime actual, final DateTime expected) { diff --git a/packages/nextcloud/test/main_test.dart b/packages/nextcloud/test/main_test.dart new file mode 100644 index 00000000..66907429 --- /dev/null +++ b/packages/nextcloud/test/main_test.dart @@ -0,0 +1,19 @@ +import 'core.dart' as core; +import 'helper.dart'; +import 'news.dart' as news; +import 'notes.dart' as notes; +import 'notifications.dart' as notifications; +import 'provisioning_api.dart' as provisioning_api; +import 'user_status.dart' as user_status; +import 'webdav.dart' as webdav; + +Future main() async { + final image = await getDockerImage(); + await core.run(image); + await news.run(image); + await notes.run(image); + await notifications.run(image); + await provisioning_api.run(image); + await user_status.run(image); + await webdav.run(image); +} diff --git a/packages/nextcloud/test/news_test.dart b/packages/nextcloud/test/news.dart similarity index 99% rename from packages/nextcloud/test/news_test.dart rename to packages/nextcloud/test/news.dart index d16c265c..d4000094 100644 --- a/packages/nextcloud/test/news_test.dart +++ b/packages/nextcloud/test/news.dart @@ -7,8 +7,10 @@ const wikipediaFeedURL = 'https://en.wikipedia.org/w/api.php?action=featuredfeed const nasaFeedURL = 'https://www.nasa.gov/rss/dyn/breaking_news.rss'; Future main() async { - final image = await getDockerImage(apps: ['news']); + await run(await getDockerImage()); +} +Future run(final DockerImage image) async { group('news', () { late DockerContainer container; late TestNextcloudClient client; diff --git a/packages/nextcloud/test/notes_test.dart b/packages/nextcloud/test/notes.dart similarity index 97% rename from packages/nextcloud/test/notes_test.dart rename to packages/nextcloud/test/notes.dart index 1af2e752..ff6583bf 100644 --- a/packages/nextcloud/test/notes_test.dart +++ b/packages/nextcloud/test/notes.dart @@ -4,8 +4,10 @@ import 'package:test/test.dart'; import 'helper.dart'; Future main() async { - final image = await getDockerImage(apps: ['notes']); + await run(await getDockerImage()); +} +Future run(final DockerImage image) async { group('notes', () { late DockerContainer container; late TestNextcloudClient client; diff --git a/packages/nextcloud/test/notifications_test.dart b/packages/nextcloud/test/notifications.dart similarity index 98% rename from packages/nextcloud/test/notifications_test.dart rename to packages/nextcloud/test/notifications.dart index 7be7e7ae..83d16979 100644 --- a/packages/nextcloud/test/notifications_test.dart +++ b/packages/nextcloud/test/notifications.dart @@ -8,8 +8,10 @@ import 'package:test/test.dart'; import 'helper.dart'; Future main() async { - final image = await getDockerImage(); + await run(await getDockerImage()); +} +Future run(final DockerImage image) async { group('notifications', () { late DockerContainer container; late TestNextcloudClient client; diff --git a/packages/nextcloud/test/provisioning_api_test.dart b/packages/nextcloud/test/provisioning_api.dart similarity index 92% rename from packages/nextcloud/test/provisioning_api_test.dart rename to packages/nextcloud/test/provisioning_api.dart index 27b64df2..45fdc60c 100644 --- a/packages/nextcloud/test/provisioning_api_test.dart +++ b/packages/nextcloud/test/provisioning_api.dart @@ -4,8 +4,10 @@ import 'package:test/test.dart'; import 'helper.dart'; Future main() async { - final image = await getDockerImage(); + await run(await getDockerImage()); +} +Future run(final DockerImage image) async { group('provisioning_api', () { late DockerContainer container; late TestNextcloudClient client; diff --git a/packages/nextcloud/test/user_status_test.dart b/packages/nextcloud/test/user_status.dart similarity index 99% rename from packages/nextcloud/test/user_status_test.dart rename to packages/nextcloud/test/user_status.dart index ca408931..a8104254 100644 --- a/packages/nextcloud/test/user_status_test.dart +++ b/packages/nextcloud/test/user_status.dart @@ -4,8 +4,10 @@ import 'package:test/test.dart'; import 'helper.dart'; Future main() async { - final image = await getDockerImage(); + await run(await getDockerImage()); +} +Future run(final DockerImage image) async { group('user_status', () { late DockerContainer container; late TestNextcloudClient client; diff --git a/packages/nextcloud/test/webdav_test.dart b/packages/nextcloud/test/webdav.dart similarity index 99% rename from packages/nextcloud/test/webdav_test.dart rename to packages/nextcloud/test/webdav.dart index 6d37ee16..f9753eb2 100644 --- a/packages/nextcloud/test/webdav_test.dart +++ b/packages/nextcloud/test/webdav.dart @@ -8,8 +8,10 @@ import 'package:test/test.dart'; import 'helper.dart'; Future main() async { - final image = await getDockerImage(); + await run(await getDockerImage()); +} +Future run(final DockerImage image) async { group('webdav', () { late DockerContainer container; late TestNextcloudClient client; diff --git a/tool/Dockerfile.dev b/tool/Dockerfile.dev index 19bccaed..a160112f 100644 --- a/tool/Dockerfile.dev +++ b/tool/Dockerfile.dev @@ -4,9 +4,9 @@ RUN chown -R www-data:www-data . USER www-data RUN ./occ maintenance:install --admin-pass admin --admin-email admin@example.com -RUN ./occ app:disable password_policy RUN ./occ config:system:set allow_local_remote_servers --value=true RUN ./occ config:system:set trusted_domains 1 --value=10.0.2.2 +RUN ./occ app:disable password_policy RUN OC_PASS="user1" ./occ user:add --password-from-env --display-name "User One" user1 RUN OC_PASS="user2" ./occ user:add --password-from-env --display-name "User Two" user2 @@ -14,4 +14,5 @@ RUN OC_PASS="user2" ./occ user:add --password-from-env --display-name "User Two" RUN ./occ app:install news RUN ./occ app:install notes +RUN ./occ app:enable password_policy COPY --chown=www-data:www-data overlay /usr/src/nextcloud/ diff --git a/tool/build-dev-container-image.sh b/tool/build-dev-container-image.sh index 77665c13..9df071bc 100755 --- a/tool/build-dev-container-image.sh +++ b/tool/build-dev-container-image.sh @@ -2,4 +2,4 @@ set -euxo pipefail cd "$(dirname "$0")/.." -docker build -t nextcloud-neon-dev -f - ./packages/nextcloud/test < tool/Dockerfile.dev +docker build -t nextcloud-neon-dev -f - ./tool < tool/Dockerfile.dev diff --git a/packages/nextcloud/test/overlay/.gitkeep b/tool/overlay/.gitkeep similarity index 100% rename from packages/nextcloud/test/overlay/.gitkeep rename to tool/overlay/.gitkeep