From 46eff34e69d1b3e2a73d568d06e78365a0c3b07b Mon Sep 17 00:00:00 2001 From: Wenjun Ruan Date: Thu, 27 Jun 2024 16:04:03 +0800 Subject: [PATCH 01/18] [Fix-16224] Add Shell using file E2E case (#16220) * Add Shell E2E case * Add shell using resource file e2e case * Upgrade checkout from v2 to v4 * Change interval to 500ms * Upgrade actions/upload-artifact --------- Co-authored-by: xiangzihao <460888207@qq.com> --- .github/workflows/api-test.yml | 12 +- .github/workflows/backend.yml | 12 +- .github/workflows/docs.yml | 10 +- .github/workflows/e2e-k8s.yml | 4 +- .github/workflows/e2e.yml | 20 +- .github/workflows/frontend.yml | 6 +- .github/workflows/issue-robot.yml | 2 +- .github/workflows/owasp-dependency-check.yaml | 4 +- .github/workflows/publish-docker.yaml | 2 +- .github/workflows/publish-helm-chart.yaml | 2 +- .github/workflows/unit-test.yml | 4 +- .../api/controller/ResourcesController.java | 10 + .../cases/ClickhouseDataSourceE2ETest.java | 3 +- .../e2e/cases/FileManageE2ETest.java | 5 +- .../e2e/cases/HiveDataSourceE2ETest.java | 3 +- .../e2e/cases/MysqlDataSourceE2ETest.java | 3 +- .../e2e/cases/PostgresDataSourceE2ETest.java | 3 +- .../e2e/cases/SqlServerDataSourceE2ETest.java | 3 +- .../e2e/cases/UserE2ETest.java | 3 +- .../e2e/cases/WorkerGroupE2ETest.java | 3 +- .../e2e/cases/WorkflowE2ETest.java | 3 +- .../e2e/cases/WorkflowHttpTaskE2ETest.java | 3 +- .../e2e/cases/WorkflowJavaTaskE2ETest.java | 3 +- .../e2e/cases/WorkflowSwitchE2ETest.java | 4 +- .../e2e/cases/tasks/ShellTaskE2ETest.java | 260 ++++++++++++++++++ .../cases/workflow/BaseWorkflowE2ETest.java | 219 +++++++++++++++ .../e2e/models/tenant/BootstrapTenant.java | 31 +++ .../e2e/models/tenant/DefaultTenant.java | 30 ++ .../e2e/models/tenant/ITenant.java | 26 ++ .../e2e/models/users/AdminUser.java | 62 +++++ .../e2e/models/users/IUser.java | 35 +++ .../dolphinscheduler/e2e/pages/LoginPage.java | 13 +- .../e2e/pages/common/CodeEditor.java | 5 +- .../e2e/pages/common/HttpInput.java | 3 +- .../e2e/pages/common/NavBarPage.java | 13 +- .../e2e/pages/datasource/DataSourcePage.java | 5 +- .../e2e/pages/project/ProjectDetailPage.java | 10 + .../e2e/pages/project/ProjectPage.java | 30 +- .../project/workflow/TaskInstanceTab.java | 25 +- .../pages/project/workflow/WorkflowForm.java | 3 +- .../project/workflow/WorkflowInstanceTab.java | 8 + .../project/workflow/WorkflowRunDialog.java | 3 +- .../workflow/task/SubWorkflowTaskForm.java | 5 +- .../project/workflow/task/SwitchTaskForm.java | 5 +- .../project/workflow/task/TaskNodeForm.java | 49 +++- .../e2e/pages/resource/FileManagePage.java | 95 ++++--- .../e2e/pages/resource/ResourcePage.java | 10 +- .../e2e/pages/security/EnvironmentPage.java | 5 +- .../e2e/pages/security/SecurityPage.java | 34 +-- .../e2e/pages/security/TenantPage.java | 64 ++++- .../e2e/pages/security/TokenPage.java | 11 +- .../e2e/pages/security/UserPage.java | 20 +- .../e2e/core/DolphinSchedulerExtension.java | 3 +- .../e2e/core/WebDriverHolder.java | 34 +++ .../e2e/core/WebDriverWaitFactory.java | 45 +++ .../spi/enums/ResourceType.java | 2 +- .../components/node/fields/use-resources.ts | 1 + .../projects/task/instance/batch-task.tsx | 1 + 58 files changed, 1109 insertions(+), 183 deletions(-) create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/BootstrapTenant.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/ITenant.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverHolder.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java diff --git a/.github/workflows/api-test.yml b/.github/workflows/api-test.yml index fd39bd097791c..b7a1aa4303f63 100644 --- a/.github/workflows/api-test.yml +++ b/.github/workflows/api-test.yml @@ -35,7 +35,7 @@ jobs: outputs: not-ignore: ${{ steps.filter.outputs.not-ignore }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721 id: filter with: @@ -49,7 +49,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Sanity Check @@ -73,7 +73,7 @@ jobs: run: | docker save apache/dolphinscheduler-standalone-server:ci -o /tmp/standalone-image.tar \ && du -sh /tmp/standalone-image.tar - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 name: Upload Docker Images with: name: standalone-image @@ -104,7 +104,7 @@ jobs: env: RECORDING_PATH: /tmp/recording-${{ matrix.case.name }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Cache local Maven repository @@ -113,7 +113,7 @@ jobs: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-api-test restore-keys: ${{ runner.os }}-maven- - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 name: Download Docker Images with: name: standalone-image @@ -127,7 +127,7 @@ jobs: -DfailIfNoTests=false \ -Dspotless.skip=false \ -Dtest=${{ matrix.case.class }} test - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: always() name: Upload Recording with: diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 37fb1bcd7eb83..8e83cd9792742 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -44,7 +44,7 @@ jobs: not-ignore: ${{ steps.filter.outputs.not-ignore }} db-schema: ${{ steps.filter.outputs.db-schema }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721 id: filter with: @@ -63,7 +63,7 @@ jobs: java: [ '8', '11' ] timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Set up JDK ${{ matrix.java }} @@ -91,7 +91,7 @@ jobs: -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 - name: Check dependency license run: tools/dependencies/check-LICENSE.sh - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: ${{ matrix.java == '8' }} name: Upload Binary Package with: @@ -115,10 +115,10 @@ jobs: - name: cluster-test-postgresql-with-postgresql-registry script: .github/workflows/cluster-test/postgresql_with_postgresql_registry/start-job.sh steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 name: Download Binary Package with: # Only run cluster test on jdk8 @@ -165,7 +165,7 @@ jobs: mkdir -p dolphinscheduler/dev dolphinscheduler/${{ matrix.version }} curl -sSf https://atlasgo.sh | sh - name: Download Tarball - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: binary-package-8 path: dolphinscheduler/dev diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 591bb0a65bb18..81eb7f20738a4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -30,7 +30,7 @@ jobs: timeout-minutes: 10 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Style Check run: ./mvnw spotless:check img-check: @@ -40,7 +40,7 @@ jobs: run: working-directory: docs steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python 3.9 uses: actions/setup-python@v2 with: @@ -54,7 +54,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: sudo npm install -g markdown-link-check@3.11.2 - run: sudo apt install plocate -y # NOTE: Change command from `find . -name "*.md"` to `find . -not -path "*/node_modules/*" -not -path "*/.tox/*" -name "*.md"` @@ -70,7 +70,7 @@ jobs: outputs: helm-doc: ${{ steps.filter.outputs.helm-doc }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721 id: filter with: @@ -84,7 +84,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Generating helm-doc diff --git a/.github/workflows/e2e-k8s.yml b/.github/workflows/e2e-k8s.yml index fb402b3c79737..351aea8802cc4 100644 --- a/.github/workflows/e2e-k8s.yml +++ b/.github/workflows/e2e-k8s.yml @@ -35,7 +35,7 @@ jobs: outputs: not-ignore: ${{ steps.filter.outputs.not-ignore }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721 id: filter with: @@ -49,7 +49,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Build Image diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5601dbbb3fb9b..d9a3cd795e09f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -35,7 +35,7 @@ jobs: outputs: not-ignore: ${{ steps.filter.outputs.not-ignore }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721 id: filter with: @@ -49,7 +49,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Sanity Check @@ -74,7 +74,7 @@ jobs: run: | docker save apache/dolphinscheduler-standalone-server:ci -o /tmp/standalone-image.tar \ && du -sh /tmp/standalone-image.tar - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 name: Upload Docker Images with: name: standalone-image @@ -120,10 +120,12 @@ jobs: class: org.apache.dolphinscheduler.e2e.cases.ClickhouseDataSourceE2ETest - name: PostgresDataSource class: org.apache.dolphinscheduler.e2e.cases.PostgresDataSourceE2ETest + - name: ShellTaskE2ETest + class: org.apache.dolphinscheduler.e2e.cases.tasks.ShellTaskE2ETest env: RECORDING_PATH: /tmp/recording-${{ matrix.case.name }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Cache local Maven repository @@ -132,7 +134,7 @@ jobs: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-e2e restore-keys: ${{ runner.os }}-maven- - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 name: Download Docker Images with: name: standalone-image @@ -145,7 +147,7 @@ jobs: ./mvnw -B -f dolphinscheduler-e2e/pom.xml -am \ -DfailIfNoTests=false \ -Dtest=${{ matrix.case.class }} test - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: always() name: Upload Recording with: @@ -167,7 +169,7 @@ jobs: env: RECORDING_PATH: /tmp/recording-${{ matrix.case.name }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Cache local Maven repository @@ -176,7 +178,7 @@ jobs: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}-e2e restore-keys: ${{ runner.os }}-maven- - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 name: Download Docker Images with: name: standalone-image @@ -189,7 +191,7 @@ jobs: ./mvnw -B -f dolphinscheduler-e2e/pom.xml -am \ -DfailIfNoTests=false \ -Dtest=${{ matrix.case.class }} test - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 if: always() name: Upload Recording with: diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index 502d669b66f69..87d178185add2 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -41,7 +41,7 @@ jobs: outputs: not-ignore: ${{ steps.filter.outputs.not-ignore }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721 id: filter with: @@ -58,7 +58,7 @@ jobs: matrix: os: [ ubuntu-latest, macos-latest ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - if: matrix.os == 'ubuntu-latest' @@ -82,7 +82,7 @@ jobs: needs: [ build, paths-filter ] if: always() steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Status run: | if [[ ${{ needs.paths-filter.outputs.not-ignore }} == 'false' && ${{ github.event_name }} == 'pull_request' ]]; then diff --git a/.github/workflows/issue-robot.yml b/.github/workflows/issue-robot.yml index ab00b346815db..06a363d11f7b9 100644 --- a/.github/workflows/issue-robot.yml +++ b/.github/workflows/issue-robot.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Checkout ${{ github.ref }}" - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: persist-credentials: false submodules: true diff --git a/.github/workflows/owasp-dependency-check.yaml b/.github/workflows/owasp-dependency-check.yaml index 54e51aafed2d9..b99486f298407 100644 --- a/.github/workflows/owasp-dependency-check.yaml +++ b/.github/workflows/owasp-dependency-check.yaml @@ -31,7 +31,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Set up JDK 8 @@ -42,7 +42,7 @@ jobs: - name: Run OWASP Dependency Check run: ./mvnw -B clean install verify dependency-check:check -DskipDepCheck=false -Dmaven.test.skip=true -Dspotless.skip=true - name: Upload report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ cancelled() || failure() }} continue-on-error: true with: diff --git a/.github/workflows/publish-docker.yaml b/.github/workflows/publish-docker.yaml index 06aa8c6950404..859e22f25c37c 100644 --- a/.github/workflows/publish-docker.yaml +++ b/.github/workflows/publish-docker.yaml @@ -33,7 +33,7 @@ jobs: packages: write timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Cache local Maven repository uses: actions/cache@v3 with: diff --git a/.github/workflows/publish-helm-chart.yaml b/.github/workflows/publish-helm-chart.yaml index e383373692699..247a55f4cc270 100644 --- a/.github/workflows/publish-helm-chart.yaml +++ b/.github/workflows/publish-helm-chart.yaml @@ -33,7 +33,7 @@ jobs: packages: write timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set environment variables run: | if [[ ${{ github.event_name }} == "release" ]]; then diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index a7e78a11f76ad..d0c88b9ca602f 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -40,7 +40,7 @@ jobs: outputs: not-ignore: ${{ steps.filter.outputs.not-ignore }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: dorny/paths-filter@b2feaf19c27470162a626bd6fa8438ae5b263721 id: filter with: @@ -57,7 +57,7 @@ jobs: java: ['8', '11'] timeout-minutes: 45 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: true - name: Sanity Check diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java index 0c9a34ee5389e..03eb42c5d6916 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java @@ -92,6 +92,16 @@ public class ResourcesController extends BaseController { @Autowired private ResourcesService resourceService; + @Operation(summary = "queryResourceList", description = "QUERY_RESOURCE_LIST_NOTES") + @Parameter(name = "type", description = "RESOURCE_TYPE", required = true, schema = @Schema(implementation = ResourceType.class)) + @GetMapping(value = "/list") + @ResponseStatus(HttpStatus.OK) + @ApiException(QUERY_RESOURCES_LIST_ERROR) + public Result> queryResourceList(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @RequestParam(value = "type") ResourceType type) { + return Result.success(resourceService.queryResourceFiles(loginUser, type)); + } + @Operation(summary = "createDirectory", description = "CREATE_RESOURCE_NOTES") @Parameters({ @Parameter(name = "type", description = "RESOURCE_TYPE", required = true, schema = @Schema(implementation = ResourceType.class)), diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java index e150e73e98a44..412b5f6a8a2df 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; @@ -82,7 +83,7 @@ void testCreateClickhouseDataSource() { page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); - new WebDriverWait(page.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.invisibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( new By.ByClassName("dialog-create-data-source"))); Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java index 1bfa997f85d84..ad041b9ac4499 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java @@ -24,6 +24,7 @@ import org.apache.dolphinscheduler.e2e.core.Constants; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.resource.FileManagePage; import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; @@ -98,7 +99,7 @@ public static void setup() { UserPage userPage = tenantPage.goToNav(SecurityPage.class) .goToTab(UserPage.class); - new WebDriverWait(userPage.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.visibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(userPage.driver()).until(ExpectedConditions.visibilityOfElementLocated( new By.ByClassName("name"))); userPage.update(user, user, email, phone, tenant) @@ -285,7 +286,7 @@ void testUploadUnder1GBFile() throws IOException { page.uploadFile(testUnder1GBFilePath.toFile().getAbsolutePath()); - new WebDriverWait(browser, Duration.ofSeconds(20)).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog"))); + WebDriverWaitFactory.createWebDriverWait(browser).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog"))); Awaitility.await().untilAsserted(() -> { assertThat(page.fileList()) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java index 9b6e661f52d12..3726ec1acdebe 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; @@ -82,7 +83,7 @@ void testCreateHiveDataSource() { page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, hivePassword, database, jdbcParams); - new WebDriverWait(page.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.invisibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( new By.ByClassName("dialog-create-data-source"))); Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java index 5078f55e3527c..5c0746a5b5475 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; @@ -82,7 +83,7 @@ void testCreateMysqlDataSource() { page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, mysqlPassword, database, jdbcParams); - new WebDriverWait(page.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.invisibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( new By.ByClassName("dialog-create-data-source"))); Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java index 647c6677416d5..cbed2b3b8ba31 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; @@ -82,7 +83,7 @@ void testCreatePostgresDataSource() { page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); - new WebDriverWait(page.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.invisibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( new By.ByClassName("dialog-create-data-source"))); Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java index 7777b9a441588..7f6ee662dd3f3 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; @@ -82,7 +83,7 @@ void testCreateSqlServerDataSource() { page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); - new WebDriverWait(page.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.invisibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( new By.ByClassName("dialog-create-data-source"))); Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java index 3ed263ec0e7c3..150e84b618294 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; @@ -119,7 +120,7 @@ void testCreateDuplicateUser() { void testEditUser() { UserPage page = new UserPage(browser); - new WebDriverWait(browser, Duration.ofSeconds(20)).until(ExpectedConditions.visibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(browser).until(ExpectedConditions.visibilityOfElementLocated( new By.ByClassName("name"))); browser.navigate().refresh(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java index b7f2a9474cad3..be8caf09136bd 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java @@ -23,6 +23,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.WorkerGroupPage; @@ -59,7 +60,7 @@ public static void setup() { void testCreateWorkerGroup() { final WorkerGroupPage page = new WorkerGroupPage(browser); - new WebDriverWait(page.driver(), Duration.ofSeconds(20)) + WebDriverWaitFactory.createWebDriverWait(page.driver()) .until(ExpectedConditions.urlContains("/security/worker-group-manage")); page.create(workerGroupName); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java index 0b97ab02af77c..bbfcacbcebaa4 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java @@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.e2e.cases; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; @@ -76,7 +77,7 @@ public static void setup() { .goToNav(SecurityPage.class) .goToTab(UserPage.class); - new WebDriverWait(userPage.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.visibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(userPage.driver()).until(ExpectedConditions.visibilityOfElementLocated( new By.ByClassName("name"))); userPage.update(user, user, email, phone, tenant) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java index 0993e61b813a6..3f78fd25f79ec 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java @@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.e2e.cases; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; @@ -76,7 +77,7 @@ public static void setup() { .goToNav(SecurityPage.class) .goToTab(UserPage.class); - new WebDriverWait(userPage.driver(), Duration.ofSeconds(20)).until(ExpectedConditions.visibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(userPage.driver()).until(ExpectedConditions.visibilityOfElementLocated( new By.ByClassName("name"))); userPage.update(user, user, email, phone, tenant) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java index 77c4e554bc72b..700ec03f43ce4 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java @@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.e2e.cases; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; @@ -92,7 +93,7 @@ public static void setup() { .goToNav(SecurityPage.class) .goToTab(UserPage.class); - new WebDriverWait(userPage.driver(), Duration.ofSeconds(20)) + WebDriverWaitFactory.createWebDriverWait(userPage.driver()) .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName("name"))); userPage.update(user, user, email, phone, tenant) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java index edf4bc59e2b44..cee9b52b47dbf 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java @@ -178,8 +178,8 @@ void testRunWorkflow() { Awaitility.await().untilAsserted(() -> { assertThat(taskInstances.size()).isEqualTo(3); - assertThat(taskInstances.stream().filter(row -> row.name().contains(ifBranchName)).count()).isEqualTo(1); - assertThat(taskInstances.stream().noneMatch(row -> row.name().contains(elseBranchName))).isTrue(); + assertThat(taskInstances.stream().filter(row -> row.taskInstanceName().contains(ifBranchName)).count()).isEqualTo(1); + assertThat(taskInstances.stream().noneMatch(row -> row.taskInstanceName().contains(elseBranchName))).isTrue(); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java new file mode 100644 index 0000000000000..fb44bc843ad90 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java @@ -0,0 +1,260 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.cases.tasks; + +import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest; +import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; +import org.apache.dolphinscheduler.e2e.pages.resource.FileManagePage; +import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; +import org.junit.FixMethodOrder; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.runners.MethodSorters; +import org.openqa.selenium.WebElement; +import org.testcontainers.shaded.org.awaitility.Awaitility; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") +public class ShellTaskE2ETest extends BaseWorkflowE2ETest { + + @Test + void testRunShellTasks_SuccessCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + // todo: use yaml to define the workflow + String workflowName = "SuccessCase"; + String taskName = "ShellSuccess"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.SHELL) + .script("echo hello world\n") + .name(taskName) + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + void testRunShellTasks_WorkflowParamsCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + // todo: use yaml to define the workflow + String workflowName = "WorkflowParamsCase"; + String taskName = "ShellSuccess"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.SHELL) + .script("[ \"${name}\" = \"tom\" ] && echo \"success\" || { echo \"failed\"; exit 1; }") + .name(taskName) + .submit() + + .submit() + .name(workflowName) + .addGlobalParam("name", "tom") + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + void testRunShellTasks_LocalParamsCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "LocalParamsCase"; + String taskName = "ShellSuccess"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.SHELL) + .script("[ \"${name}\" = \"tom\" ] && echo \"success\" || { echo \"failed\"; exit 1; }") + .name(taskName) + .addParam("name", "tom") + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + void testRunShellTasks_GlobalParamsOverrideLocalParamsCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "LocalParamsOverrideWorkflowParamsCase"; + String taskName = "ShellSuccess"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.SHELL) + .script("[ \"${name}\" = \"jerry\" ] && echo \"success\" || { echo \"failed\"; exit 1; }") + .name(taskName) + .addParam("name", "tom") + .submit() + + .submit() + .name(workflowName) + .addGlobalParam("name", "jerry") + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + void testRunShellTasks_UsingResourceFile() { + String testFileName = "echo"; + new ResourcePage(browser) + .goToNav(ResourcePage.class) + .goToTab(FileManagePage.class) + .createFileUntilSuccess(testFileName, "echo 123"); + + final WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "UsingResourceFile"; + String taskName = "ShellSuccess"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.SHELL) + .script("cat " + testFileName + ".sh") + .name(taskName) + .selectResource(testFileName) + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + void testRunShellTasks_FailedCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "FailedCase"; + String taskName = "ShellFailed"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.SHELL) + .script("echo 'I am failed'\n exit1\n") + .name(taskName) + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceFailed(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceFailed(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java new file mode 100644 index 0000000000000..aab2c7c06f679 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java @@ -0,0 +1,219 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.cases.workflow; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.apache.dolphinscheduler.e2e.core.WebDriverHolder; +import org.apache.dolphinscheduler.e2e.models.tenant.DefaultTenant; +import org.apache.dolphinscheduler.e2e.models.users.AdminUser; +import org.apache.dolphinscheduler.e2e.models.users.IUser; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; +import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; +import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; +import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; +import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; +import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; +import org.apache.dolphinscheduler.e2e.pages.security.UserPage; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.openqa.selenium.remote.RemoteWebDriver; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + +@Slf4j +public abstract class BaseWorkflowE2ETest { + + protected static String projectName = UUID.randomUUID().toString(); + + protected static final AdminUser adminUser = new AdminUser(); + + protected static RemoteWebDriver browser; + + @BeforeAll + public static void setup() { + browser = WebDriverHolder.getWebDriver(); + + TenantPage tenantPage = new LoginPage(browser) + .login(adminUser) + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class); + + if (tenantPage.tenants().stream().noneMatch(tenant -> tenant.tenantCode().equals(adminUser.getTenant()))) { + tenantPage + .create(adminUser.getTenant()) + .goToNav(SecurityPage.class) + .goToTab(UserPage.class) + .update(adminUser); + } + tenantPage + .goToNav(ProjectPage.class) + .createProjectUntilSuccess(projectName); + } + + protected void untilWorkflowDefinitionExist(String workflowName) { + WorkflowDefinitionTab workflowDefinitionPage = new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) + .as("Workflow list should contain newly-created workflow: %s", workflowName) + .anyMatch( + it -> it.getText().contains(workflowName) + )); + } + + protected void runWorkflow(String workflowName) { + final ProjectDetailPage projectPage = new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName); + + projectPage + .goToTab(WorkflowDefinitionTab.class) + .run(workflowName) + .submit(); + + } + + protected WorkflowInstanceTab.Row untilWorkflowInstanceExist(String workflowName) { + final ProjectDetailPage projectPage = new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName); + + return await() + .until(() -> { + browser.navigate().refresh(); + return projectPage + .goToTab(WorkflowInstanceTab.class) + .instances() + .stream() + .filter(it -> it.workflowInstanceName().startsWith(workflowName)) + .findFirst() + .orElse(null); + }, Objects::nonNull); + } + + protected WorkflowInstanceTab.Row untilWorkflowInstanceSuccess(String workflowName) { + final ProjectDetailPage projectPage = new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName); + return await() + .until(() -> { + browser.navigate().refresh(); + return projectPage + .goToTab(WorkflowInstanceTab.class) + .instances() + .stream() + .filter(it -> it.workflowInstanceName().startsWith(workflowName)) + .filter(WorkflowInstanceTab.Row::isSuccess) + .findFirst() + .orElse(null); + }, Objects::nonNull); + } + + protected WorkflowInstanceTab.Row untilWorkflowInstanceFailed(String workflowName) { + final ProjectDetailPage projectPage = new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName); + return await() + .until(() -> { + browser.navigate().refresh(); + List workflowInstances = projectPage + .goToTab(WorkflowInstanceTab.class) + .instances() + .stream() + .filter(it -> it.workflowInstanceName().startsWith(workflowName)) + .filter(WorkflowInstanceTab.Row::isFailed) + .collect(Collectors.toList()); + if (workflowInstances.isEmpty()) { + return null; + } + if (workflowInstances.size() > 1) { + throw new RuntimeException("More than one failed workflow instance found: " + + workflowInstances.stream() + .map(WorkflowInstanceTab.Row::workflowInstanceName).collect(Collectors.joining(", "))); + } + return workflowInstances.get(0); + }, Objects::nonNull); + } + + protected TaskInstanceTab.Row untilTaskInstanceSuccess(String workflowName, String taskName) { + final ProjectDetailPage projectPage = new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName); + return await() + .until(() -> { + browser.navigate().refresh(); + List taskInstances = projectPage + .goToTab(TaskInstanceTab.class) + .instances() + .stream() + .filter(it -> it.taskInstanceName().startsWith(taskName)) + .filter(it -> it.workflowInstanceName().startsWith(workflowName)) + .filter(TaskInstanceTab.Row::isSuccess) + .collect(Collectors.toList()); + + if (taskInstances.isEmpty()) { + return null; + } + if (taskInstances.size() > 1) { + throw new RuntimeException("More than one failed task instance found: " + + taskInstances.stream() + .map(TaskInstanceTab.Row::taskInstanceName).collect(Collectors.joining(", "))); + } + return taskInstances.get(0); + }, Objects::nonNull); + } + + protected TaskInstanceTab.Row untilTaskInstanceFailed(String workflowName, String taskName) { + final ProjectDetailPage projectPage = new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName); + return await() + .until(() -> { + browser.navigate().refresh(); + List taskInstances = projectPage + .goToTab(TaskInstanceTab.class) + .instances() + .stream() + .filter(it -> it.taskInstanceName().startsWith(taskName)) + .filter(it -> it.workflowInstanceName().startsWith(workflowName)) + .filter(TaskInstanceTab.Row::isFailed) + .collect(Collectors.toList()); + + if (taskInstances.isEmpty()) { + return null; + } + if (taskInstances.size() > 1) { + throw new RuntimeException("More than one failed task instance found: " + + taskInstances.stream() + .map(TaskInstanceTab.Row::taskInstanceName).collect(Collectors.joining(", "))); + } + return taskInstances.get(0); + }, Objects::nonNull); + } + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/BootstrapTenant.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/BootstrapTenant.java new file mode 100644 index 0000000000000..15af3197e2000 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/BootstrapTenant.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.models.tenant; + +public class BootstrapTenant implements ITenant { + + @Override + public String getTenantCode() { + return System.getProperty("user.name"); + } + + @Override + public String getDescription() { + return "bootstrap tenant"; + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java new file mode 100644 index 0000000000000..598265fa96a45 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.models.tenant; + +public class DefaultTenant implements ITenant { + @Override + public String getTenantCode() { + return "default"; + } + + @Override + public String getDescription() { + return ""; + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/ITenant.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/ITenant.java new file mode 100644 index 0000000000000..641acbf9d7760 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/ITenant.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.models.tenant; + +public interface ITenant { + + String getTenantCode(); + + String getDescription(); + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java new file mode 100644 index 0000000000000..da23bc26bf33b --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.models.users; + +import lombok.Data; +import org.apache.dolphinscheduler.e2e.models.tenant.BootstrapTenant; +import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; + +@Data +public class AdminUser implements IUser { + + private String userName; + + private String password; + + private String email; + + private String phone; + + private ITenant tenant; + + @Override + public String getUserName() { + return "admin"; + } + + @Override + public String getPassword() { + return "dolphinscheduler123"; + } + + @Override + public String getEmail() { + return "admin@gmail.com"; + } + + @Override + public String getPhone() { + return "15800000000"; + } + + @Override + public String getTenant() { + return new BootstrapTenant().getTenantCode(); + } + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java new file mode 100644 index 0000000000000..740a4b431e956 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.models.users; + +import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; + +public interface IUser { + + String getUserName(); + + String getPassword(); + + String getEmail(); + + String getPhone(); + + String getTenant(); + + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java index cde8c9d7780e4..a77149fac353f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java @@ -19,6 +19,8 @@ package org.apache.dolphinscheduler.e2e.pages; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.models.users.IUser; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; @@ -59,17 +61,20 @@ public LoginPage(RemoteWebDriver driver) { } @SneakyThrows - public NavBarPage login(String username, String password) { - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage)); + public NavBarPage login(IUser user) { + return login(user.getUserName(), user.getPassword()); + } + @SneakyThrows + public NavBarPage login(String username, String password) { + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage)); buttonSwitchLanguage().click(); inputUsername().sendKeys(username); inputPassword().sendKeys(password); buttonLogin().click(); - new WebDriverWait(driver, Duration.ofSeconds(30)) - .until(ExpectedConditions.urlContains("/home")); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/home")); return new NavBarPage(driver); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java index e55751c367a44..53ed30b362f7e 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java @@ -19,11 +19,10 @@ */ package org.apache.dolphinscheduler.e2e.pages.common; -import org.openqa.selenium.By; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; @@ -51,7 +50,7 @@ public CodeEditor(WebDriver driver) { } public CodeEditor content(String content) { - new WebDriverWait(this.driver, Duration.ofSeconds(20)).until(ExpectedConditions.elementToBeClickable(editor)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editor)); editor.click(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java index ce3f07c81965e..770de59009c15 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java @@ -22,6 +22,7 @@ package org.apache.dolphinscheduler.e2e.pages.common; import lombok.Getter; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -50,7 +51,7 @@ public HttpInput(WebDriver driver) { } public HttpInput content(String content) { - new WebDriverWait(this.driver, Duration.ofSeconds(20)).until(ExpectedConditions.elementToBeClickable(urlInput)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(urlInput)); urlInput().sendKeys(content); return this; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java index 0a6373977a79a..a6a64ccf92fd4 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java @@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.e2e.pages.common; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; @@ -64,26 +65,30 @@ public NavBarPage(RemoteWebDriver driver) { public T goToNav(Class nav) { if (nav == ProjectPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(projectTab)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(projectTab)); projectTab.click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/projects/list")); return nav.cast(new ProjectPage(driver)); } if (nav == SecurityPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(securityTab)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(securityTab)); securityTab.click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage")); return nav.cast(new SecurityPage(driver)); } if (nav == ResourcePage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(resourceTab)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(resourceTab)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", resourceTab()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage")); return nav.cast(new ResourcePage(driver)); } if (nav == DataSourcePage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(dataSourceTab)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(dataSourceTab)); dataSourceTab.click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/datasource")); return nav.cast(new DataSourcePage(driver)); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java index bd2f7e795bd7b..7f84ac29de7fa 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java @@ -22,6 +22,7 @@ import lombok.Getter; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import java.security.Key; @@ -74,12 +75,12 @@ public DataSourcePage createDataSource(String dataSourceType, String dataSourceN String jdbcParams) { buttonCreateDataSource().click(); - new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.visibilityOfElementLocated( + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated( new By.ByClassName("dialog-source-modal"))); dataSourceModal().findElement(By.className(dataSourceType.toUpperCase()+"-box")).click(); - new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase())); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase())); createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName); createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java index 2ad24507ab1d2..6e06db5039470 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java @@ -19,16 +19,22 @@ */ package org.apache.dolphinscheduler.e2e.pages.project; +import java.time.Duration; +import lombok.SneakyThrows; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; +import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; import lombok.Getter; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; @Getter public final class ProjectDetailPage extends NavBarPage { @@ -45,17 +51,21 @@ public ProjectDetailPage(RemoteWebDriver driver) { super(driver); } + @SneakyThrows public T goToTab(Class tab) { if (tab == WorkflowDefinitionTab.class) { menuProcessDefinition().click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow-definition")); return tab.cast(new WorkflowDefinitionTab(driver)); } if (tab == WorkflowInstanceTab.class) { menuProcessInstances().click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow/instances")); return tab.cast(new WorkflowInstanceTab(driver)); } if (tab == TaskInstanceTab.class) { menuTaskInstances().click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/task/instances")); return tab.cast(new TaskInstanceTab(driver)); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java index 6219fab099bf5..8be97f5db9080 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java @@ -35,6 +35,8 @@ import org.openqa.selenium.support.ui.WebDriverWait; import lombok.Getter; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; @Getter public final class ProjectPage extends NavBarPage implements NavBarItem { @@ -64,17 +66,25 @@ public ProjectPage create(String project) { buttonCreateProject().click(); createProjectForm().inputProjectName().sendKeys(project); createProjectForm().buttonSubmit().click(); + return this; + } + public ProjectPage createProjectUntilSuccess(String project) { + create(project); + await().untilAsserted(() -> assertThat(projectList()) + .as("project list should contain newly-created project") + .anyMatch(it -> it.getText().contains(project))); return this; } + public ProjectPage delete(String project) { projectList() - .stream() - .filter(it -> it.getText().contains(project)) - .findFirst() - .orElseThrow(() -> new RuntimeException("Cannot find project: " + project)) - .findElement(By.className("delete")).click(); + .stream() + .filter(it -> it.getText().contains(project)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Cannot find project: " + project)) + .findElement(By.className("delete")).click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); @@ -83,11 +93,11 @@ public ProjectPage delete(String project) { public ProjectDetailPage goTo(String project) { projectList().stream() - .filter(it -> it.getText().contains(project)) - .map(it -> it.findElement(By.className("project-name")).findElement(new By.ByTagName("button"))) - .findFirst() - .orElseThrow(() -> new RuntimeException("Cannot click the project item")) - .click(); + .filter(it -> it.getText().contains(project)) + .map(it -> it.findElement(By.className("project-name")).findElement(new By.ByTagName("button"))) + .findFirst() + .orElseThrow(() -> new RuntimeException("Cannot click the project item")) + .click(); return new ProjectDetailPage(driver); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java index 06f76676b8199..d1d81b70e42f8 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java @@ -35,7 +35,8 @@ @Getter public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPage.Tab { - @FindBy(className = "items-task-instances") + + @FindBy(className = "batch-task-instance-items") private List instanceList; public TaskInstanceTab(RemoteWebDriver driver) { @@ -47,7 +48,6 @@ public List instances() { .stream() .filter(WebElement::isDisplayed) .map(Row::new) - .filter(row -> !row.name().isEmpty()) .collect(Collectors.toList()); } @@ -55,12 +55,25 @@ public List instances() { public static class Row { private final WebElement row; - public String state() { - return row.findElement(By.className("task-instance-state")).getText(); + public String taskInstanceName() { + return row.findElement(By.cssSelector("td[data-col-key=name]")).getText(); + } + + public String workflowInstanceName() { + return row.findElement(By.cssSelector("td[data-col-key=processInstanceName]")).getText(); + } + + public int retryTimes() { + return Integer.parseInt(row.findElement(By.cssSelector("td[data-col-key=retryTimes]")).getText()); + } + + public boolean isSuccess() { + return !row.findElements(By.className("success")).isEmpty(); } - public String name() { - return row.findElement(By.className("task-instance-name")).getText(); + public boolean isFailed() { + return !row.findElements(By.className("failed")).isEmpty(); } + } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java index 58c5c96051ced..69573ab7fff57 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java @@ -19,6 +19,7 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTaskForm; @@ -93,7 +94,7 @@ public T addTask(TaskType type) { } public WebElement getTask(String taskName) { - List tasks = new WebDriverWait(driver, Duration.ofSeconds(20)) + List tasks = WebDriverWaitFactory.createWebDriverWait(driver) .until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("svg > g > g[class^='x6-graph-svg-stage'] > g[data-shape^='dag-task']"))); WebElement task = tasks.stream() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java index f55c5d0263ccc..2b7fa28274f90 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java @@ -86,6 +86,10 @@ public WorkflowInstanceTab deleteAll() { public static class Row { private final WebElement row; + public String workflowInstanceName() { + return row.findElement(By.className("workflow-name")).getText(); + } + public WebElement rerunButton() { return row.findElement(By.className("btn-rerun")); } @@ -94,6 +98,10 @@ public boolean isSuccess() { return !row.findElements(By.className("success")).isEmpty(); } + public boolean isFailed() { + return !row.findElements(By.className("failed")).isEmpty(); + } + public int executionTime() { return Integer.parseInt(row.findElement(By.className("workflow-run-times")).getText()); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java index 9a3e24fb8a646..9e337be43ef5d 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java @@ -19,6 +19,7 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; @@ -44,7 +45,7 @@ public WorkflowRunDialog(WorkflowDefinitionTab parent) { } public WorkflowDefinitionTab submit() { - new WebDriverWait(parent().driver(), Duration.ofSeconds(20)).until(ExpectedConditions.elementToBeClickable(buttonSubmit())); + WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.elementToBeClickable(buttonSubmit())); buttonSubmit().click(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java index d89037feaa56e..6f328ddf232c8 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java @@ -19,6 +19,7 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import lombok.Getter; @@ -54,11 +55,11 @@ public SubWorkflowTaskForm(WorkflowForm parent) { } public SubWorkflowTaskForm childNode(String node) { - new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown)); btnSelectChildNodeDropdown().click(); - new WebDriverWait(driver, Duration.ofSeconds(5)).until(ExpectedConditions.visibilityOfElementLocated(By.className( + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.className( "n-base-select-option__content"))); selectChildNode() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java index 988a00c7bd955..480f5b410b14b 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java @@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; import lombok.Getter; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; @@ -54,7 +55,7 @@ public SwitchTaskForm elseBranch(String elseBranchName) { final By optionsLocator = By.className("option-else-branches"); - new WebDriverWait(parent().driver(), Duration.ofSeconds(10)) + WebDriverWaitFactory.createWebDriverWait(parent().driver()) .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); List webElements = parent().driver().findElements(optionsLocator); @@ -79,7 +80,7 @@ public SwitchTaskForm addIfBranch(String switchScript, String ifBranchName) { final By optionsLocator = By.className("option-if-branches"); - new WebDriverWait(parent().driver(), Duration.ofSeconds(10)) + WebDriverWaitFactory.createWebDriverWait(parent().driver()) .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); List webElements = parent().driver().findElements(optionsLocator); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java index fadfd6c38b049..5d0a944b02da2 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java @@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; import lombok.Getter; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; @@ -28,13 +29,11 @@ import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.ByChained; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import java.time.Duration; import java.util.List; -import java.util.stream.Stream; @Getter public abstract class TaskNodeForm { @@ -48,14 +47,14 @@ public abstract class TaskNodeForm { private WebElement buttonSubmit; @FindBys({ - @FindBy(className = "input-param-key"), - @FindBy(tagName = "input"), + @FindBy(className = "input-param-key"), + @FindBy(tagName = "input"), }) private List inputParamKey; @FindBys({ - @FindBy(className = "input-param-value"), - @FindBy(tagName = "input"), + @FindBy(className = "input-param-value"), + @FindBy(tagName = "input"), }) private List inputParamValue; @@ -80,6 +79,13 @@ public abstract class TaskNodeForm { @FindBy(className = "btn-create-custom-parameter") private WebElement buttonCreateCustomParameters; + @FindBys({ + @FindBy(className = "resource-select"), + @FindBy(className = "n-base-selection"), + }) + private WebElement selectResource; + + private final WorkflowForm parent; TaskNodeForm(WorkflowForm parent) { @@ -118,15 +124,15 @@ public TaskNodeForm addParam(String key, String value) { return this; } - public TaskNodeForm selectEnv(String envName){ - ((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", selectEnv); + public TaskNodeForm selectEnv(String envName) { + ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", selectEnv); final By optionsLocator = By.className("n-base-selection-input__content"); - new WebDriverWait(parent.driver(), Duration.ofSeconds(20)) + WebDriverWaitFactory.createWebDriverWait(parent().driver()) .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); - List webElements = parent.driver().findElements(optionsLocator); + List webElements = parent.driver().findElements(optionsLocator); webElements.stream() .filter(it -> it.getText().contains(envName)) @@ -138,14 +144,14 @@ public TaskNodeForm selectEnv(String envName){ } public TaskNodeForm preTask(String preTaskName) { - ((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", selectPreTasks); + ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", selectPreTasks); final By optionsLocator = By.className("option-pre-tasks"); - new WebDriverWait(parent.driver(), Duration.ofSeconds(20)) + WebDriverWaitFactory.createWebDriverWait(parent.driver()) .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); - List webElements = parent.driver().findElements(optionsLocator); + List webElements = parent.driver().findElements(optionsLocator); webElements.stream() .filter(it -> it.getText().contains(preTaskName)) .findFirst() @@ -157,6 +163,23 @@ public TaskNodeForm preTask(String preTaskName) { return this; } + public TaskNodeForm selectResource(String resourceName) { + ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", selectResource); + + final By optionsLocator = By.className("n-tree-node-content__text"); + + WebDriverWaitFactory.createWebDriverWait(parent().driver()).until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); + + parent().driver() + .findElements(optionsLocator) + .stream() + .filter(it -> it.getText().startsWith(resourceName)) + .findFirst() + .orElseThrow(() -> new RuntimeException("No such resource: " + resourceName)) + .click(); + return this; + } + public WorkflowForm submit() { buttonSubmit.click(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java index a2a780be9d78e..412acf0f2acf3 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java @@ -22,6 +22,7 @@ import lombok.Getter; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; @@ -42,6 +43,8 @@ import java.io.File; import java.time.Duration; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; @Getter @@ -92,6 +95,7 @@ public FileManagePage(RemoteWebDriver driver) { uploadFileBox = new UploadFileBox(); editFileBox = new EditFileBox(); + } public FileManagePage createDirectory(String name) { @@ -114,13 +118,13 @@ public FileManagePage cancelCreateDirectory(String name) { public FileManagePage rename(String currentName, String AfterName) { fileList() - .stream() - .filter(it -> it.getText().contains(currentName)) - .flatMap(it -> it.findElements(By.className("btn-rename")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No rename button in file manage list")) - .click(); + .stream() + .filter(it -> it.getText().contains(currentName)) + .flatMap(it -> it.findElements(By.className("btn-rename")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No rename button in file manage list")) + .click(); renameBox().inputName().sendKeys(Keys.CONTROL + "a"); renameBox().inputName().sendKeys(Keys.BACK_SPACE); @@ -132,12 +136,12 @@ public FileManagePage rename(String currentName, String AfterName) { public FileManagePage createSubDirectory(String directoryName, String subDirectoryName) { fileList() - .stream() - .filter(it -> it.getText().contains(directoryName)) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName))) - .click(); + .stream() + .filter(it -> it.getText().contains(directoryName)) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName))) + .click(); buttonCreateDirectory().click(); @@ -149,42 +153,61 @@ public FileManagePage createSubDirectory(String directoryName, String subDirecto public FileManagePage delete(String name) { fileList() - .stream() - .filter(it -> it.getText().contains(name)) - .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No delete button in file manage list")) - .click(); + .stream() + .filter(it -> it.getText().contains(name)) + .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No delete button in file manage list")) + .click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); return this; } + // todo: add file type public FileManagePage createFile(String fileName, String scripts) { + + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonCreateFile())); + buttonCreateFile().click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create")); + createFileBox().inputFileName().sendKeys(fileName); createFileBox().codeEditor().content(scripts); createFileBox().buttonSubmit().click(); + // todo: check if the operation is successful + return this; + } + + public FileManagePage createFileUntilSuccess(String fileName, String scripts) { + + createFile(fileName, scripts); + await() + .untilAsserted(() -> + assertThat(fileList()) + .as("File list should contain newly-created file: " + fileName) + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(fileName))); return this; } public FileManagePage editFile(String fileName, String scripts) { fileList() - .stream() - .filter(it -> it.getText().contains(fileName)) - .flatMap(it -> it.findElements(By.className("btn-edit")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No edit button in file manage list")) - .click(); + .stream() + .filter(it -> it.getText().contains(fileName)) + .flatMap(it -> it.findElements(By.className("btn-edit")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No edit button in file manage list")) + .click(); - new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.urlContains("/edit")); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/edit")); - new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName)); editFileBox().codeEditor().content(scripts); editFileBox().buttonSubmit().click(); @@ -205,13 +228,13 @@ public FileManagePage uploadFile(String filePath) { public FileManagePage downloadFile(String fileName) { fileList() - .stream() - .filter(it -> it.getText().contains(fileName)) - .flatMap(it -> it.findElements(By.className("btn-download")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No download button in file manage list")) - .click(); + .stream() + .filter(it -> it.getText().contains(fileName)) + .flatMap(it -> it.findElements(By.className("btn-download")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No download button in file manage list")) + .click(); return this; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java index 933a6df85e53f..23264147f8c97 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java @@ -19,6 +19,7 @@ */ package org.apache.dolphinscheduler.e2e.pages.resource; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import java.time.Duration; @@ -27,6 +28,7 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; @@ -40,14 +42,16 @@ public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem { public ResourcePage(RemoteWebDriver driver) { super(driver); + + PageFactory.initElements(driver, this); } public T goToTab(Class tab) { if (tab == FileManagePage.class) { - new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.urlContains("/resource")); - new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.elementToBeClickable(fileManageTab)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource")); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(fileManageTab)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", fileManageTab()); - new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.urlContains("/file-manage")); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/file-manage")); return tab.cast(new FileManagePage(driver)); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java index 5d9f9bea36d93..c318c257e3e01 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java @@ -19,6 +19,7 @@ package org.apache.dolphinscheduler.e2e.pages.security; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import java.time.Duration; @@ -67,7 +68,7 @@ public EnvironmentPage create(String name, String config, String desc, String wo createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc); editEnvironmentForm().btnSelectWorkerGroupDropdown().click(); - new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( "n-base-select-option__content"))); editEnvironmentForm().selectWorkerGroupList() .stream() @@ -106,7 +107,7 @@ public EnvironmentPage update(String oldName, String name, String config, String if (editEnvironmentForm().selectedWorkerGroup().getAttribute("innerHTML").equals(workerGroup)) { editEnvironmentForm().btnSelectWorkerGroupDropdown().click(); - new WebDriverWait(driver, Duration.ofSeconds(20)).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( "n-base-select-option__content"))); editEnvironmentForm().selectWorkerGroupList() .stream() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java index 5a5bb9c2776b8..11cb748f7bd2c 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java @@ -20,6 +20,7 @@ package org.apache.dolphinscheduler.e2e.pages.security; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem; @@ -67,59 +68,60 @@ public SecurityPage(RemoteWebDriver driver) { } public T goToTab(Class tab) { + if (tab == TenantPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menuTenantManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuTenantManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTenantManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage")); return tab.cast(new TenantPage(driver)); } if (tab == UserPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menUserManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menUserManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menUserManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/user-manage")); return tab.cast(new UserPage(driver)); } if (tab == WorkerGroupPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menWorkerGroupManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/worker-group-manage")); return tab.cast(new WorkerGroupPage(driver)); } if (tab == QueuePage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menuQueueManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuQueueManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuQueueManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/yarn-queue-manage")); return tab.cast(new QueuePage(driver)); } if (tab == EnvironmentPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menuEnvironmentManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuEnvironmentManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuEnvironmentManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/environment-manage")); return tab.cast(new EnvironmentPage(driver)); } if (tab == ClusterPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menuClusterManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuClusterManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuClusterManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/cluster-manage")); return tab.cast(new ClusterPage(driver)); } if (tab == TokenPage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menuTokenManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuTokenManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTokenManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/token-manage")); return tab.cast(new TokenPage(driver)); } if (tab == NamespacePage.class) { - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.urlContains("/security")); - new WebDriverWait(driver, Duration.ofSeconds(60)).until(ExpectedConditions.elementToBeClickable(menuNamespaceManage)); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuNamespaceManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuNamespaceManage()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/k8s-namespace-manage")); return tab.cast(new NamespacePage(driver)); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java index cb24af307f704..e6b9f877c15a7 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java @@ -19,10 +19,14 @@ package org.apache.dolphinscheduler.e2e.pages.security; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import java.util.List; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; @@ -33,6 +37,9 @@ import org.openqa.selenium.support.PageFactory; import lombok.Getter; +import org.openqa.selenium.support.pagefactory.ByChained; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; @Getter public final class TenantPage extends NavBarPage implements SecurityPage.Tab { @@ -43,8 +50,8 @@ public final class TenantPage extends NavBarPage implements SecurityPage.Tab { private List tenantList; @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), }) private WebElement buttonConfirm; @@ -61,11 +68,28 @@ public TenantPage(RemoteWebDriver driver) { editTenantForm = new TenantForm(); } + public List tenants() { + return tenantList.stream() + .filter(WebElement::isDisplayed) + .map(Row::new) + .collect(Collectors.toList()); + } + + public boolean containsTenant(String tenant) { + return tenantList.stream() + .anyMatch(it -> it.findElement(By.className("tenant-code")).getText().contains(tenant)); + } + + public TenantPage create(ITenant tenant) { + return create(tenant.getTenantCode(), tenant.getDescription()); + } + public TenantPage create(String tenant) { return create(tenant, ""); } public TenantPage create(String tenant, String description) { + buttonCreateTenant().click(); tenantForm().inputTenantCode().sendKeys(tenant); tenantForm().inputDescription().sendKeys(description); @@ -76,12 +100,12 @@ public TenantPage create(String tenant, String description) { public TenantPage update(String tenant, String description) { tenantList().stream() - .filter(it -> it.findElement(By.className("tenant-code")).getAttribute("innerHTML").contains(tenant)) - .flatMap(it -> it.findElements(By.className("edit")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No edit button in tenant list")) - .click(); + .filter(it -> it.findElement(By.className("tenant-code")).getAttribute("innerHTML").contains(tenant)) + .flatMap(it -> it.findElements(By.className("edit")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No edit button in tenant list")) + .click(); editTenantForm().inputDescription().sendKeys(Keys.CONTROL + "a"); editTenantForm().inputDescription().sendKeys(Keys.BACK_SPACE); @@ -93,13 +117,13 @@ public TenantPage update(String tenant, String description) { public TenantPage delete(String tenant) { tenantList() - .stream() - .filter(it -> it.getText().contains(tenant)) - .flatMap(it -> it.findElements(By.className("delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No delete button in user list")) - .click(); + .stream() + .filter(it -> it.getText().contains(tenant)) + .flatMap(it -> it.findElements(By.className("delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No delete button in user list")) + .click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); @@ -133,4 +157,14 @@ public class TenantForm { @FindBy(className = "btn-cancel") private WebElement buttonCancel; } + + @RequiredArgsConstructor + public static class Row { + private final WebElement row; + + public String tenantCode() { + return row.findElement(By.cssSelector("td[data-col-key=tenantCode]")).getText(); + } + + } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java index 5def2ad64ff34..7be82a840aca8 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java @@ -19,6 +19,7 @@ package org.apache.dolphinscheduler.e2e.pages.security; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage.Tab; @@ -69,9 +70,9 @@ public TokenPage(RemoteWebDriver driver) { public TokenPage create(String userName) { buttonCreateToken().click(); - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown())); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown())); createTokenForm().selectUserNameDropdown().click(); - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( "n-base-select-option__content"))); createTokenForm().selectUserNameList() .stream() @@ -81,7 +82,7 @@ public TokenPage create(String userName) { userName))) .click(); - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken())); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken())); createTokenForm().buttonGenerateToken().click(); createTokenForm().buttonSubmit().click(); @@ -98,9 +99,9 @@ public TokenPage update(String userName) { .orElseThrow(() -> new RuntimeException("No edit button in token list")) .click(); - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); editTokenForm().buttonGenerateToken().click(); - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); editTokenForm().buttonSubmit().click(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java index 26a236ad52c8a..1ee52e8a281ee 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java @@ -19,6 +19,8 @@ package org.apache.dolphinscheduler.e2e.pages.security; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.models.users.IUser; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import java.time.Duration; @@ -67,7 +69,7 @@ public UserPage create(String user, String password, String email, String phone, createUserForm().btnSelectTenantDropdown().click(); - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( "n-base-select-option__content"))); createUserForm().selectTenant() @@ -84,7 +86,19 @@ public UserPage create(String user, String password, String email, String phone, return this; } - public UserPage update(String user, String editUser, String editEmail, String editPhone, + public UserPage update(IUser user) { + return update( + user.getUserName(), + user.getUserName(), + user.getEmail(), + user.getPhone(), + user.getTenant()); + } + + public UserPage update(String user, + String editUser, + String editEmail, + String editPhone, String tenant) { userList().stream() .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) @@ -100,7 +114,7 @@ public UserPage update(String user, String editUser, String editEmail, String ed createUserForm().btnSelectTenantDropdown().click(); - new WebDriverWait(driver, Duration.ofSeconds(30)).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( "n-base-select-option__content"))); createUserForm().selectTenant() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java index dcf22a2d6d88b..d40afe1f3a61c 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java @@ -80,7 +80,7 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall @SuppressWarnings("UnstableApiUsage") public void beforeAll(ExtensionContext context) throws IOException { Awaitility.setDefaultTimeout(Duration.ofSeconds(60)); - Awaitility.setDefaultPollInterval(Duration.ofSeconds(2)); + Awaitility.setDefaultPollInterval(Duration.ofMillis(500)); setRecordPath(); @@ -115,6 +115,7 @@ public void beforeAll(ExtensionContext context) throws IOException { .filter(it -> Modifier.isStatic(it.getModifiers())) .filter(f -> WebDriver.class.isAssignableFrom(f.getType())) .forEach(it -> setDriver(clazz, it)); + WebDriverHolder.setWebDriver(driver); } private void runInLocal() { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverHolder.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverHolder.java new file mode 100644 index 0000000000000..48e8c53e928c7 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverHolder.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.core; + +import org.openqa.selenium.remote.RemoteWebDriver; + +public class WebDriverHolder { + + public static RemoteWebDriver browser; + + public static void setWebDriver(RemoteWebDriver driver) { + browser = driver; + } + + public static RemoteWebDriver getWebDriver() { + return browser; + } + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java new file mode 100644 index 0000000000000..946fe071abe75 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.core; + +import java.time.Duration; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.WebDriverWait; + +public class WebDriverWaitFactory { + + private static final Duration DEFAULT_INTERVAL = Duration.ofMillis(500); + + private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(60); + + /** + * Create a WebDriverWait instance with default timeout 60s and interval 100ms. + */ + public static WebDriverWait createWebDriverWait(WebDriver driver) { + return createWebDriverWait(driver, DEFAULT_TIMEOUT); + } + + public static WebDriverWait createWebDriverWait(WebDriver driver, Duration timeout) { + return new WebDriverWait(driver, timeout, DEFAULT_INTERVAL); + } + + public static WebDriverWait createWebDriverWait(WebDriver driver, Duration timeout, Duration interval) { + return new WebDriverWait(driver, timeout, interval); + } + +} diff --git a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResourceType.java b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResourceType.java index 09132ebac9b4e..8be58ebb15c60 100644 --- a/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResourceType.java +++ b/dolphinscheduler-spi/src/main/java/org/apache/dolphinscheduler/spi/enums/ResourceType.java @@ -28,7 +28,7 @@ public enum ResourceType { /** - * 0 file, 1 udf + * 0 file */ FILE(0, "file"), ALL(2, "all"); diff --git a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts index 90ba0a40a79e3..f9fa187314720 100644 --- a/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts +++ b/dolphinscheduler-ui/src/views/projects/task/components/node/fields/use-resources.ts @@ -123,6 +123,7 @@ export function useResources( return { type: 'tree-select', field: 'resourceList', + class: 'resource-select', name: t('project.node.resources'), span: span, options: resourcesOptions, diff --git a/dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx b/dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx index 03ca177df2bd9..9e2eed243b868 100644 --- a/dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx +++ b/dolphinscheduler-ui/src/views/projects/task/instance/batch-task.tsx @@ -283,6 +283,7 @@ const BatchTaskInstance = defineComponent({ Date: Thu, 27 Jun 2024 21:49:21 +0800 Subject: [PATCH 02/18] [Fix-16228] Fix E2E health check url is not correct (#16227) --- .../docker/basic/docker-compose.yaml | 3 +-- .../datasource-clickhouse/docker-compose.yaml | 3 +-- .../datasource-hive/docker-compose.yaml | 3 +-- .../datasource-mysql/docker-compose.yaml | 3 +-- .../datasource-postgresql/docker-compose.yaml | 3 +-- .../datasource-sqlserver/docker-compose.yaml | 3 +-- .../docker/file-manage/docker-compose.yaml | 3 +-- .../test/core/DolphinSchedulerExtension.java | 23 +++++++++++-------- .../repository/impl/CommandDaoImplTest.java | 10 -------- .../docker/basic/docker-compose.yaml | 2 +- .../datasource-clickhouse/docker-compose.yaml | 2 +- .../datasource-hive/docker-compose.yaml | 2 +- .../datasource-mysql/docker-compose.yaml | 2 +- .../datasource-postgresql/docker-compose.yaml | 4 ++-- .../datasource-sqlserver/docker-compose.yaml | 2 +- .../docker/file-manage/docker-compose.yaml | 2 +- .../docker/workflow-http/docker-compose.yaml | 2 +- 17 files changed, 30 insertions(+), 42 deletions(-) diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/basic/docker-compose.yaml b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/basic/docker-compose.yaml index f1a1cf1fbb88a..edeca6af11fc3 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/basic/docker-compose.yaml +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/basic/docker-compose.yaml @@ -21,7 +21,6 @@ services: dolphinscheduler: image: apache/dolphinscheduler-standalone-server:ci environment: - MASTER_MAX_CPU_LOAD_AVG: 100 WORKER_TENANT_AUTO_CREATE: 'true' ports: - "12345:12345" @@ -29,7 +28,7 @@ services: network: ipv4_address: 10.5.0.5 healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 60s retries: 120 diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml index fd14568ad926e..29e4ba140ba65 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml @@ -21,14 +21,13 @@ services: dolphinscheduler: image: apache/dolphinscheduler-standalone-server:ci environment: - MASTER_MAX_CPU_LOAD_AVG: 100 WORKER_TENANT_AUTO_CREATE: 'true' ports: - "12345:12345" networks: - api-test healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 60s retries: 120 diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-hive/docker-compose.yaml b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-hive/docker-compose.yaml index 7cfe64badd639..c8ec0c5792c29 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-hive/docker-compose.yaml +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-hive/docker-compose.yaml @@ -21,14 +21,13 @@ services: dolphinscheduler: image: apache/dolphinscheduler-standalone-server:ci environment: - MASTER_MAX_CPU_LOAD_AVG: 100 WORKER_TENANT_AUTO_CREATE: 'true' ports: - "12345:12345" networks: - api-test healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 60s retries: 120 diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml index d4134ef3f9880..054e1bd482449 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml @@ -21,7 +21,6 @@ services: dolphinscheduler: image: apache/dolphinscheduler-standalone-server:ci environment: - MASTER_MAX_CPU_LOAD_AVG: 100 WORKER_TENANT_AUTO_CREATE: 'true' ports: - "12345:12345" @@ -31,7 +30,7 @@ services: - ./download-mysql.sh:/tmp/download-mysql.sh entrypoint: [ 'bash', '-c', '/bin/bash /tmp/download-mysql.sh && /opt/dolphinscheduler/bin/start.sh && tail -f /dev/null' ] healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 60s retries: 120 diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml index 00f88b4c9ad5f..5281556e85c49 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml @@ -21,14 +21,13 @@ services: dolphinscheduler: image: apache/dolphinscheduler-standalone-server:ci environment: - MASTER_MAX_CPU_LOAD_AVG: 100 WORKER_TENANT_AUTO_CREATE: 'true' ports: - "12345:12345" networks: - api-test healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 60s retries: 120 diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml index e8dde399b9b0b..656f6a3eccda7 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml @@ -21,14 +21,13 @@ services: dolphinscheduler: image: apache/dolphinscheduler-standalone-server:ci environment: - MASTER_MAX_CPU_LOAD_AVG: 100 WORKER_TENANT_AUTO_CREATE: 'true' ports: - "12345:12345" networks: - api-test healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 60s retries: 120 diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/file-manage/docker-compose.yaml b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/file-manage/docker-compose.yaml index 0ac4886ad8341..8dca2fbf03aeb 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/file-manage/docker-compose.yaml +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/docker/file-manage/docker-compose.yaml @@ -21,14 +21,13 @@ services: dolphinscheduler: image: apache/dolphinscheduler-standalone-server:ci environment: - MASTER_MAX_CPU_LOAD_AVG: 100 WORKER_TENANT_AUTO_CREATE: 'true' ports: - "12345:12345" networks: - api-test healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 60s retries: 120 diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinSchedulerExtension.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinSchedulerExtension.java index 87771cc0100cc..c91ecf99bfd7c 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinSchedulerExtension.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/org/apache/dolphinscheduler/api/test/core/DolphinSchedulerExtension.java @@ -24,6 +24,7 @@ import java.time.Duration; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -31,6 +32,7 @@ import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExtensionContext; import org.slf4j.Logger; +import org.testcontainers.containers.ContainerState; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; @@ -49,6 +51,9 @@ public void beforeAll(ExtensionContext context) { if (!localMode) { compose = createDockerCompose(context); compose.start(); + compose.getContainerByServiceName(serviceName) + .map(ContainerState::isHealthy) + .orElseThrow(() -> new IllegalStateException("DolphinScheduler service is not healthy")); } } @@ -63,17 +68,17 @@ private DockerComposeContainer createDockerCompose(ExtensionContext context) final Class clazz = context.getRequiredTestClass(); final DolphinScheduler annotation = clazz.getAnnotation(DolphinScheduler.class); final List files = Stream.of(annotation.composeFiles()) - .map(it -> DolphinScheduler.class.getClassLoader().getResource(it)) - .filter(Objects::nonNull) - .map(URL::getPath) - .map(File::new) - .collect(Collectors.toList()); + .map(it -> DolphinScheduler.class.getClassLoader().getResource(it)) + .filter(Objects::nonNull) + .map(URL::getPath) + .map(File::new) + .collect(Collectors.toList()); compose = new DockerComposeContainer<>(files) - .withPull(true) - .withTailChildContainers(true) - .withLogConsumer(serviceName, outputFrame -> log.info(outputFrame.getUtf8String())) - .waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(Constants.DOCKER_COMPOSE_DEFAULT_TIMEOUT))); + .withPull(true) + .withTailChildContainers(true) + .withLogConsumer(serviceName, outputFrame -> log.info(outputFrame.getUtf8String())) + .waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(Constants.DOCKER_COMPOSE_DEFAULT_TIMEOUT))); return compose; } diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/repository/impl/CommandDaoImplTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/repository/impl/CommandDaoImplTest.java index df5a2562aa4ee..9185a965512ad 100644 --- a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/repository/impl/CommandDaoImplTest.java +++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/repository/impl/CommandDaoImplTest.java @@ -18,7 +18,6 @@ package org.apache.dolphinscheduler.dao.repository.impl; import static com.google.common.truth.Truth.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; import org.apache.dolphinscheduler.common.enums.CommandType; import org.apache.dolphinscheduler.common.enums.FailureStrategy; @@ -34,7 +33,6 @@ import org.apache.commons.lang3.RandomUtils; import java.util.List; -import java.util.stream.Collectors; import org.junit.jupiter.api.RepeatedTest; import org.springframework.beans.factory.annotation.Autowired; @@ -63,14 +61,6 @@ void fetchCommandByIdSlot() { } List commands = commandDao.queryCommandByIdSlot(currentSlotIndex, totalSlot, idStep, fetchSize); - assertFalse(commands.isEmpty(), - "Commands should not be empty, currentSlotIndex: " + currentSlotIndex + - ", totalSlot: " + totalSlot + - ", idStep: " + idStep + - ", fetchSize: " + fetchSize + - ", total command size: " + commandSize + - ", total commands: " - + commandDao.queryAll().stream().map(Command::getId).collect(Collectors.toList())); assertThat(commands.size()) .isEqualTo(commandDao.queryAll() .stream() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml index 89d645c2c15c8..37bebedc647b0 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/basic/docker-compose.yaml @@ -28,7 +28,7 @@ services: networks: - e2e healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 5s retries: 120 diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml index 3b9ccc0f938d9..ec108f067ebfa 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-clickhouse/docker-compose.yaml @@ -28,7 +28,7 @@ services: networks: - e2e healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 5s retries: 120 diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-hive/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-hive/docker-compose.yaml index b7609ff874b62..d28abc8c22794 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-hive/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-hive/docker-compose.yaml @@ -28,7 +28,7 @@ services: networks: - e2e healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 5s retries: 120 diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml index 099736805e2be..8287eb83de054 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-mysql/docker-compose.yaml @@ -31,7 +31,7 @@ services: - ./download-mysql.sh:/tmp/download-mysql.sh entrypoint: ['bash', '-c', '/bin/bash /tmp/download-mysql.sh && /opt/dolphinscheduler/bin/start.sh && tail -f /dev/null'] healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 5s retries: 120 diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml index 7d1e38832cf95..878bf2436497f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-postgresql/docker-compose.yaml @@ -28,9 +28,9 @@ services: networks: - e2e healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s - timeout: 300s + timeout: 5s retries: 120 depends_on: postgres: diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml index cf94105313c5e..0e85692395b4f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/datasource-sqlserver/docker-compose.yaml @@ -28,7 +28,7 @@ services: networks: - e2e healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 5s retries: 120 diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/file-manage/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/file-manage/docker-compose.yaml index ccfe940a6db56..49b9de813fa8e 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/file-manage/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/file-manage/docker-compose.yaml @@ -28,7 +28,7 @@ services: networks: - e2e healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 5s retries: 120 diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/workflow-http/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/workflow-http/docker-compose.yaml index 2591e3d74adfa..0f6a4a620526f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/workflow-http/docker-compose.yaml +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/workflow-http/docker-compose.yaml @@ -29,7 +29,7 @@ services: networks: - e2e healthcheck: - test: [ "CMD", "curl", "http://localhost:12345/actuator/health" ] + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] interval: 5s timeout: 5s retries: 120 From 225e969d2dd47f46d53d29cd4246752f2b175a33 Mon Sep 17 00:00:00 2001 From: xiangzihao <460888207@qq.com> Date: Fri, 28 Jun 2024 09:51:02 +0800 Subject: [PATCH 03/18] [DSIP-51][Task] Remove unused pigeon task plugin (#16219) --- docs/configs/docsdev.js | 8 - docs/docs/en/guide/task/pigeon.md | 22 - docs/docs/en/guide/upgrade/incompatible.md | 1 + docs/docs/zh/guide/task/pigeon.md | 19 - docs/docs/zh/guide/upgrade/incompatible.md | 1 + docs/img/pigeon.png | Bin 1192 -> 0 bytes .../resources/dynamic-task-type-config.yaml | 2 - .../src/main/resources/task-type-config.yaml | 1 - dolphinscheduler-bom/pom.xml | 6 - .../src/main/resources/common.properties | 2 +- dolphinscheduler-dist/release-docs/LICENSE | 1 - .../licenses/LICENSE-Java-WebSocket.txt | 22 - .../cases/workflow/BaseWorkflowE2ETest.java | 3 +- .../e2e/pages/common/NavBarPage.java | 16 +- .../e2e/pages/project/ProjectDetailPage.java | 3 - .../pages/project/workflow/WorkflowForm.java | 2 +- .../project/workflow/WorkflowRunDialog.java | 4 + .../project/workflow/WorkflowSaveDialog.java | 13 +- .../e2e/pages/resource/FileManagePage.java | 13 +- .../e2e/core/DolphinSchedulerExtension.java | 2 +- .../src/main/resources/application.yaml | 2 +- .../storage/api/AbstractStorageOperator.java | 6 +- .../dolphinscheduler-task-all/pom.xml | 6 - .../dolphinscheduler-task-pigeon/pom.xml | 85 ---- .../dolphinscheduler-task-pigeon/readme.md | 0 .../plugin/task/pigeon/PigeonConfig.java | 86 ---- .../plugin/task/pigeon/PigeonParameters.java | 62 --- .../task/pigeon/PigeonParamsConstants.java | 27 -- .../plugin/task/pigeon/PigeonTask.java | 430 ------------------ .../plugin/task/pigeon/PigeonTaskChannel.java | 41 -- .../task/pigeon/PigeonTaskChannelFactory.java | 38 -- .../plugin/task/pigeon/config.properties | 26 -- .../plugin/task/pigeon/PigeonTaskTest.java | 142 ------ .../plugin/task/pigeon/PigeonTaskTest.json | 60 --- dolphinscheduler-task-plugin/pom.xml | 1 - .../public/images/task-icons/pigeon.png | Bin 1192 -> 0 bytes .../public/images/task-icons/pigeon_hover.png | Bin 1167 -> 0 bytes .../src/locales/en_US/project.ts | 1 - .../src/locales/zh_CN/project.ts | 1 - .../src/store/project/task-type.ts | 3 - .../src/store/project/types.ts | 1 - .../task/components/node/format-data.ts | 4 - .../task/components/node/tasks/index.ts | 2 - .../task/components/node/tasks/use-pigeon.ts | 68 --- .../projects/task/constants/task-type.ts | 4 - .../workflow/components/dag/dag.module.scss | 6 - .../workflow/definition/tree/index.tsx | 5 - tools/dependencies/known-dependencies.txt | 1 - 48 files changed, 38 insertions(+), 1211 deletions(-) delete mode 100644 docs/docs/en/guide/task/pigeon.md delete mode 100644 docs/docs/zh/guide/task/pigeon.md delete mode 100644 docs/img/pigeon.png delete mode 100644 dolphinscheduler-dist/release-docs/licenses/LICENSE-Java-WebSocket.txt delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/pom.xml delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/readme.md delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonConfig.java delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParameters.java delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParamsConstants.java delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTask.java delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannel.java delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannelFactory.java delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/resources/org/apache/dolphinscheduler/plugin/task/pigeon/config.properties delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.java delete mode 100644 dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/resources/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.json delete mode 100644 dolphinscheduler-ui/public/images/task-icons/pigeon.png delete mode 100644 dolphinscheduler-ui/public/images/task-icons/pigeon_hover.png delete mode 100644 dolphinscheduler-ui/src/views/projects/task/components/node/tasks/use-pigeon.ts diff --git a/docs/configs/docsdev.js b/docs/configs/docsdev.js index 8039aa41f30fe..08155a006b23a 100644 --- a/docs/configs/docsdev.js +++ b/docs/configs/docsdev.js @@ -145,10 +145,6 @@ export default { title: 'Sqoop', link: '/en-us/docs/dev/user_doc/guide/task/sqoop.html', }, - { - title: 'Pigeon', - link: '/en-us/docs/dev/user_doc/guide/task/pigeon.html', - }, { title: 'Conditions', link: '/en-us/docs/dev/user_doc/guide/task/conditions.html', @@ -877,10 +873,6 @@ export default { title: 'Sqoop', link: '/zh-cn/docs/dev/user_doc/guide/task/sqoop.html', }, - { - title: 'Pigeon', - link: '/zh-cn/docs/dev/user_doc/guide/task/pigeon.html', - }, { title: 'Conditions', link: '/zh-cn/docs/dev/user_doc/guide/task/conditions.html', diff --git a/docs/docs/en/guide/task/pigeon.md b/docs/docs/en/guide/task/pigeon.md deleted file mode 100644 index 43d538bf8fade..0000000000000 --- a/docs/docs/en/guide/task/pigeon.md +++ /dev/null @@ -1,22 +0,0 @@ -# Pigeon - -## Overview - -Pigeon is a task used to trigger remote tasks, acquire logs or status by calling remote WebSocket service. It is DolphinScheduler uses a remote WebSocket service to call tasks. - -## Create Task - -- Click `Project Management -> Project Name -> Workflow Definition`, and click the `Create Workflow` button to enter the DAG editing page. -- Drag from the toolbar to the canvas to create a new Pigeon task. - -## Task Parameters - -[//]: # (TODO: use the commented anchor below once our website template supports this syntax) -[//]: # (- Please refer to [DolphinScheduler Task Parameters Appendix](appendix.md#default-task-parameters) `Default Task Parameters` section for default parameters.) - -- Please refer to [DolphinScheduler Task Parameters Appendix](appendix.md) `Default Task Parameters` section for default parameters. - -| **Parameter** | **Description** | -|------------------|---------------------------------------| -| Target task name | Target task name of this Pigeon node. | - diff --git a/docs/docs/en/guide/upgrade/incompatible.md b/docs/docs/en/guide/upgrade/incompatible.md index a134cd5fd363a..d20dba51ba97a 100644 --- a/docs/docs/en/guide/upgrade/incompatible.md +++ b/docs/docs/en/guide/upgrade/incompatible.md @@ -29,4 +29,5 @@ This document records the incompatible updates between each version. You need to ## 3.3.0 * Remove the `udf-manage` function from the `resource center` ([#16209]) +* Remove the `Pigeon` from the `Task Plugin` ([#16218]) diff --git a/docs/docs/zh/guide/task/pigeon.md b/docs/docs/zh/guide/task/pigeon.md deleted file mode 100644 index d8138d3c02165..0000000000000 --- a/docs/docs/zh/guide/task/pigeon.md +++ /dev/null @@ -1,19 +0,0 @@ -# Pigeon - -Pigeon任务类型是通过调用远程websocket服务,实现远程任务的触发,状态、日志的获取,是 DolphinScheduler 通用远程 websocket 服务调用任务 - -## 创建任务 - -拖动工具栏中的任务节点到画板中即能完成任务创建 - -## 任务参数 - -[//]: # (TODO: use the commented anchor below once our website template supports this syntax) -[//]: # (- 默认参数说明请参考[DolphinScheduler任务参数附录](appendix.md#默认任务参数)`默认任务参数`一栏。) - -- 默认参数说明请参考[DolphinScheduler任务参数附录](appendix.md)`默认任务参数`一栏。 - -| **任务参数** | **描述** | -|----------|-------------------| -| 目标任务名 | 输入Pigeon任务的目标任务名称 | - diff --git a/docs/docs/zh/guide/upgrade/incompatible.md b/docs/docs/zh/guide/upgrade/incompatible.md index b25d35b1e3d08..a5260a06957f6 100644 --- a/docs/docs/zh/guide/upgrade/incompatible.md +++ b/docs/docs/zh/guide/upgrade/incompatible.md @@ -27,4 +27,5 @@ ## 3.3.0 * 从 `资源中心` 中移除了 `udf-manage` 功能 ([#16209]) +* 从 `任务插件` 中移除了 `Pigeon` 类型 ([#16218]) diff --git a/docs/img/pigeon.png b/docs/img/pigeon.png deleted file mode 100644 index 6fe21d2b1ee5f9be7f2cbccf9919a718fc860ad0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1192 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P3?%12mYf5m7>k44ofy`glX(ebp9}B_aRmzg z2ZL3sR_))vf9A}Y^XJb8l8Y8Cnmc#yk|j%k+@(vGE?l?}$N-7}8M9~4o;PnEPz{g- z3eK7}3n&g`0~vGX%mIo66+lQh7pMRz2vh(R2MR(IK-2?CAb^XYaUr^pW#Mc%1862t z7lgzV1d0OzP#mrX$c5MfVSuDzCO{Yvm2g40Mz}7J2ACGOEL;#-1fm5_!qq?+a1x>g z$c3mxRtAwmR)8!E(E=y?B+6a`V{~RokY6wZBNHIL{ zOIv$KPv3-zlc!9ZK6Cb*x$_n*T)KS4%GK-EZ`!hL`;MKv_Uzk#;NYRdM~|O8b^gND zYu9hwx^ws5!$*&wK70P^&D(eHKYaZ3^~cX&zyJLGH*LkkIAHR7?CIhdA|ZM9;7{l7 zLI$=E&+p#*I_r+ow3w~8jNG}GKI^hvG)b^i@M%=qqzTs))0b@B`uJ!5+uw54_t$>Z zp3nbp@7A+>AByYCe<{s5FkiM~$%@mybG9sAW1FmFRLhY%=lq5%x$Isy*fY1zSt_vF zWuw5%9cAx$OYbfYaZQaVoiH=D;VoaN@hRS{yhBOZlX?{We;(P>;(g0!F8i|IPill) z!X{bDUzoD&*&EC z%Zd4umhEGA|8n<9D)&R3qm+XEGFEB)nb3IG|IzwmYRl8po~OCrPJJNqna}z0LIXY% zo1%j$t7Xp^zGpH~*SOQX*}duDv$y@cUjjKCi#rdMUOBC?$=2ziqKPBd-wA;W-f;Jw zNnOe1eAy>a!gb0m!K|tUD;IxYRZH)!&uHD{moZ0^>v!Uf9~Se{4#vGu5}CK?ftc@o zl^5rNL>nCWHYYH!Jul}v*=*pEdy#dOk#)cY&(LM7nU?7uU##-}(32kyXOAmynDBh( z4ojmpoPaR;IWbkzLb6Mw<&;$U= CNoqg< diff --git a/dolphinscheduler-api/src/main/resources/dynamic-task-type-config.yaml b/dolphinscheduler-api/src/main/resources/dynamic-task-type-config.yaml index a9a2d55ff8ad0..74a2504d668e4 100644 --- a/dolphinscheduler-api/src/main/resources/dynamic-task-type-config.yaml +++ b/dolphinscheduler-api/src/main/resources/dynamic-task-type-config.yaml @@ -28,5 +28,3 @@ dynamic-task: - {name: DATA_QUALITY,icon: shell-icon.png,hover: shell-hover.png} machineLearning: - {name: JUPYTER,icon: shell-icon.png,hover: shell-hover.png} - other: - - {name: PIGEON,icon: shell-icon.png,hover: shell-hover.png} \ No newline at end of file diff --git a/dolphinscheduler-api/src/main/resources/task-type-config.yaml b/dolphinscheduler-api/src/main/resources/task-type-config.yaml index 9105d5069758e..05d1e6290aa4b 100644 --- a/dolphinscheduler-api/src/main/resources/task-type-config.yaml +++ b/dolphinscheduler-api/src/main/resources/task-type-config.yaml @@ -56,7 +56,6 @@ task: - 'PYTORCH' - 'KUBEFLOW' other: - - 'PIGEON' - 'ZEPPELIN' - 'CHUNJUN' - 'DATASYNC' diff --git a/dolphinscheduler-bom/pom.xml b/dolphinscheduler-bom/pom.xml index 8c59d1c4cabf2..0635239f8ce2d 100644 --- a/dolphinscheduler-bom/pom.xml +++ b/dolphinscheduler-bom/pom.xml @@ -31,7 +31,6 @@ 4.1.53.Final 2.7.3 2.4.1 - 1.5.1 3.5.2 2.3.2 1.2.20 @@ -169,11 +168,6 @@ test - - org.java-websocket - Java-WebSocket - ${java-websocket.version} - com.baomidou diff --git a/dolphinscheduler-common/src/main/resources/common.properties b/dolphinscheduler-common/src/main/resources/common.properties index cf1723700eb55..e0704bebe58f3 100644 --- a/dolphinscheduler-common/src/main/resources/common.properties +++ b/dolphinscheduler-common/src/main/resources/common.properties @@ -26,7 +26,7 @@ data.basedir.path=/tmp/dolphinscheduler # use shared file mount point resource.storage.type=LOCAL # resource store on HDFS/S3 path, resource file will store to this base path, self configuration, please make sure the directory exists on hdfs and have read write permissions. "/dolphinscheduler" is recommended -resource.storage.upload.base.path=/dolphinscheduler +resource.storage.upload.base.path=/tmp/dolphinscheduler # The Azure client ID (Azure Application (client) ID) resource.azure.client.id=minioadmin diff --git a/dolphinscheduler-dist/release-docs/LICENSE b/dolphinscheduler-dist/release-docs/LICENSE index 41400d26f5af5..290d0ab3f37e4 100644 --- a/dolphinscheduler-dist/release-docs/LICENSE +++ b/dolphinscheduler-dist/release-docs/LICENSE @@ -666,7 +666,6 @@ The text of each license is also included at licenses/LICENSE-[project].txt. animal-sniffer-annotations 1.19 https://mvnrepository.com/artifact/org.codehaus.mojo/animal-sniffer-annotations/1.19, MIT checker-qual 3.12.0 https://mvnrepository.com/artifact/org.checkerframework/checker-qual/3.12.0, MIT + GPLv2 checker-qual 3.19.0 https://mvnrepository.com/artifact/org.checkerframework/checker-qual/3.19.0, MIT + GPLv2 - Java-WebSocket 1.5.1: https://github.com/TooTallNate/Java-WebSocket, MIT oshi-core 6.1.1: https://mvnrepository.com/artifact/com.github.oshi/oshi-core/6.1.1, MIT unirest-java 3.7.04-standalone: https://mvnrepository.com/artifact/com.konghq/unirest-java/3.7.04, MIT classgraph 4.8.83: https://mvnrepository.com/artifact/io.github.classgraph/classgraph, MIT diff --git a/dolphinscheduler-dist/release-docs/licenses/LICENSE-Java-WebSocket.txt b/dolphinscheduler-dist/release-docs/licenses/LICENSE-Java-WebSocket.txt deleted file mode 100644 index dbf7415b4152c..0000000000000 --- a/dolphinscheduler-dist/release-docs/licenses/LICENSE-Java-WebSocket.txt +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2010-2020 Nathan Rajlich - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java index aab2c7c06f679..c2ee2ee447166 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java @@ -17,6 +17,7 @@ package org.apache.dolphinscheduler.e2e.cases.workflow; +import java.time.Duration; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -46,7 +47,7 @@ @Slf4j public abstract class BaseWorkflowE2ETest { - protected static String projectName = UUID.randomUUID().toString(); + protected static final String projectName = UUID.randomUUID().toString(); protected static final AdminUser adminUser = new AdminUser(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java index a6a64ccf92fd4..7b00a9bd29730 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java @@ -42,19 +42,19 @@ public class NavBarPage { protected final RemoteWebDriver driver; - @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(2) > .n-menu-item-content") + @FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Project')]") private WebElement projectTab; - @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(3) > .n-menu-item-content") + @FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Resources')]") private WebElement resourceTab; - @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(4) > .n-menu-item-content") + @FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Data Quality')]") private WebElement dataQualityTab; - @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(5) > .n-menu-item-content") + @FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Datasource')]") private WebElement dataSourceTab; - @FindBy(css = ".tab-horizontal .n-menu-item:nth-child(7) > .n-menu-item-content") + @FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Security')]") private WebElement securityTab; public NavBarPage(RemoteWebDriver driver) { @@ -66,14 +66,14 @@ public NavBarPage(RemoteWebDriver driver) { public T goToNav(Class nav) { if (nav == ProjectPage.class) { WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(projectTab)); - projectTab.click(); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", projectTab()); WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/projects/list")); return nav.cast(new ProjectPage(driver)); } if (nav == SecurityPage.class) { WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(securityTab)); - securityTab.click(); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", securityTab()); WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage")); return nav.cast(new SecurityPage(driver)); } @@ -87,7 +87,7 @@ public T goToNav(Class nav) { if (nav == DataSourcePage.class) { WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(dataSourceTab)); - dataSourceTab.click(); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", dataSourceTab()); WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/datasource")); return nav.cast(new DataSourcePage(driver)); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java index 6e06db5039470..c2fedeccfbb4b 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java @@ -19,7 +19,6 @@ */ package org.apache.dolphinscheduler.e2e.pages.project; -import java.time.Duration; import lombok.SneakyThrows; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; @@ -27,14 +26,12 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; -import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; import lombok.Getter; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; @Getter public final class ProjectDetailPage extends NavBarPage { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java index 69573ab7fff57..ce622b03978be 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java @@ -110,7 +110,7 @@ public WebElement getTask(String taskName) { public WorkflowSaveDialog submit() { buttonSave().click(); - + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(.,'Basic Information')]"))); return new WorkflowSaveDialog(this); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java index 9e337be43ef5d..ac8c22e5da012 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java @@ -20,6 +20,8 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; + +import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; @@ -45,6 +47,8 @@ public WorkflowRunDialog(WorkflowDefinitionTab parent) { } public WorkflowDefinitionTab submit() { + By runDialogTitleXpath = By.xpath(String.format("//*[contains(text(), '%s')]", "Please set the parameters before starting")); + WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.visibilityOfElementLocated(runDialogTitleXpath)); WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.elementToBeClickable(buttonSubmit())); buttonSubmit().click(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java index 6f7b8470ae6af..d61b6a8fb7672 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java @@ -20,7 +20,11 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow; import lombok.Getter; + +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; + import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -44,7 +48,7 @@ public final class WorkflowSaveDialog { }) private WebElement inputName; - @FindBy(className = "btn-submit") + @FindBy(xpath = "//div[contains(text(), 'Basic Information')]/../following-sibling::div[contains(@class, 'n-card__footer')]//button[contains(@class, 'btn-submit')]") private WebElement buttonSubmit; @FindBys({ @@ -72,8 +76,6 @@ public WorkflowSaveDialog name(String name) { public WorkflowSaveDialog addGlobalParam(String key, String value) { final int len = globalParamsItems().findElements(By.tagName("input")).size(); - final WebDriver driver = parent().driver(); - if (len == 0) { buttonGlobalCustomParameters().click(); @@ -90,8 +92,9 @@ public WorkflowSaveDialog addGlobalParam(String key, String value) { } public WorkflowForm submit() { - buttonSubmit().click(); - + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonSubmit)); + buttonSubmit.click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("workflow-definition")); return parent; } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java index 412acf0f2acf3..f2d594f155e61 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java @@ -62,8 +62,6 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab { private final RenameBox renameBox; - private final CreateFileBox createFileBox; - private final UploadFileBox uploadFileBox; private final EditFileBox editFileBox; @@ -90,8 +88,6 @@ public FileManagePage(RemoteWebDriver driver) { renameBox = new RenameBox(); - createFileBox = new CreateFileBox(); - uploadFileBox = new UploadFileBox(); editFileBox = new EditFileBox(); @@ -175,10 +171,11 @@ public FileManagePage createFile(String fileName, String scripts) { WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create")); - createFileBox().inputFileName().sendKeys(fileName); - createFileBox().codeEditor().content(scripts); - createFileBox().buttonSubmit().click(); - // todo: check if the operation is successful + CreateFileBox createFileBox = new CreateFileBox(); + createFileBox.inputFileName().sendKeys(fileName); + createFileBox.codeEditor().content(scripts); + createFileBox.buttonSubmit().click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage")); return this; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java index d40afe1f3a61c..eeadc41e25fde 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java @@ -79,7 +79,7 @@ final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCall @Override @SuppressWarnings("UnstableApiUsage") public void beforeAll(ExtensionContext context) throws IOException { - Awaitility.setDefaultTimeout(Duration.ofSeconds(60)); + Awaitility.setDefaultTimeout(Duration.ofSeconds(120)); Awaitility.setDefaultPollInterval(Duration.ofMillis(500)); setRecordPath(); diff --git a/dolphinscheduler-standalone-server/src/main/resources/application.yaml b/dolphinscheduler-standalone-server/src/main/resources/application.yaml index 906fc42085a94..e88cafa8ccec8 100644 --- a/dolphinscheduler-standalone-server/src/main/resources/application.yaml +++ b/dolphinscheduler-standalone-server/src/main/resources/application.yaml @@ -211,7 +211,7 @@ worker: server-load-protection: enabled: true # Worker max system cpu usage, when the worker's system cpu usage is smaller then this value, worker server can be dispatched tasks. - max-system-cpu-usage-percentage-thresholds: 0.9 + max-system-cpu-usage-percentage-thresholds: 1 # Worker max jvm cpu usage, when the worker's jvm cpu usage is smaller then this value, worker server can be dispatched tasks. max-jvm-cpu-usage-percentage-thresholds: 0.9 # Worker max System memory usage , when the worker's system memory usage is smaller then this value, worker server can be dispatched tasks. diff --git a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java index 34a4e464b5c67..924c581248fce 100644 --- a/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java +++ b/dolphinscheduler-storage-plugin/dolphinscheduler-storage-api/src/main/java/org/apache/dolphinscheduler/plugin/storage/api/AbstractStorageOperator.java @@ -26,11 +26,15 @@ import java.io.File; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.common.base.Preconditions; import com.google.common.io.Files; public abstract class AbstractStorageOperator implements StorageOperator { + private static final Logger log = LoggerFactory.getLogger(AbstractStorageOperator.class); protected final String resourceBaseAbsolutePath; public AbstractStorageOperator(String resourceBaseAbsolutePath) { @@ -60,7 +64,7 @@ public ResourceMetadata getResourceMetaData(String resourceAbsolutePath) { @Override public String getStorageBaseDirectory() { // All directory should end with File.separator - return PropertyUtils.getString(Constants.RESOURCE_UPLOAD_PATH, "/dolphinscheduler"); + return PropertyUtils.getString(Constants.RESOURCE_UPLOAD_PATH, "/tmp/dolphinscheduler"); } @Override diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml b/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml index 5e4c74b27ad92..fbaea0dddc9f9 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-all/pom.xml @@ -64,12 +64,6 @@ ${project.version} - - org.apache.dolphinscheduler - dolphinscheduler-task-pigeon - ${project.version} - - org.apache.dolphinscheduler dolphinscheduler-task-procedure diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/pom.xml b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/pom.xml deleted file mode 100644 index e4f036ae7df98..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/pom.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - 4.0.0 - - org.apache.dolphinscheduler - dolphinscheduler-task-plugin - dev-SNAPSHOT - - - dolphinscheduler-task-pigeon - jar - - - - org.apache.dolphinscheduler - dolphinscheduler-task-api - ${project.version} - - - org.apache.dolphinscheduler - dolphinscheduler-spi - provided - - - org.apache.commons - commons-collections4 - - - org.slf4j - slf4j-api - - - - - com.github.dreamhead - moco-core - 1.2.0 - test - - - com.github.dreamhead - moco-runner - 1.2.0 - test - - - commons-cli - commons-cli - - - - - - org.java-websocket - Java-WebSocket - - - - org.apache.httpcomponents - httpclient - - - org.apache.httpcomponents - httpcore - - - diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/readme.md b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/readme.md deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonConfig.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonConfig.java deleted file mode 100644 index fb5c1c76776bf..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonConfig.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.plugin.task.pigeon; - -import org.apache.commons.lang3.StringUtils; - -import java.util.ResourceBundle; - -public class PigeonConfig { - - private static PigeonConfig cfg; - - private final String jobTriggerUrl; - private final String jobTriggerPostBody; - private final String jobStatusUrl; - private final String jobStatusPostBody; - - private final String jobLogsFetchUrl; - private final String jobCancelPostBody; - - public static synchronized PigeonConfig getInstance() { - if (cfg == null) { - cfg = new PigeonConfig(); - } - return cfg; - } - - private PigeonConfig() { - ResourceBundle bundle = - ResourceBundle.getBundle(PigeonConfig.class.getPackage().getName().replace(".", "/") + "/config"); - this.jobTriggerUrl = bundle.getString("job.trigger.url"); - this.jobStatusUrl = bundle.getString("job.status.url"); - this.jobTriggerPostBody = bundle.getString("job.trigger.post.body"); - this.jobStatusPostBody = bundle.getString("job.status.post.body"); - this.jobLogsFetchUrl = bundle.getString("job.logs.fetch.url"); - this.jobCancelPostBody = bundle.getString("job.cancel.post.body"); - } - - public String getJobCancelPostBody(int taskId) { - return String.format(jobCancelPostBody, taskId); - } - - public String getJobTriggerUrl(String tisHost) { - checkHost(tisHost); - return String.format(this.jobTriggerUrl, tisHost); - } - - public String getJobTriggerPostBody() { - return jobTriggerPostBody; - } - - public String getJobStatusPostBody(int taskId) { - return String.format(jobStatusPostBody, taskId); - } - - public String getJobLogsFetchUrl(String host, String jobName, int taskId) { - checkHost(host); - return String.format(jobLogsFetchUrl, host, jobName, taskId); - } - - public String getJobStatusUrl(String tisHost) { - checkHost(tisHost); - return String.format(this.jobStatusUrl, tisHost); - } - - private static void checkHost(String tisHost) { - if (StringUtils.isBlank(tisHost)) { - throw new IllegalArgumentException("param tisHost can not be null"); - } - } -} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParameters.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParameters.java deleted file mode 100644 index f2b9aaf3eb02b..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParameters.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.plugin.task.pigeon; - -import org.apache.dolphinscheduler.plugin.task.api.model.ResourceInfo; -import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters; - -import org.apache.commons.lang3.StringUtils; - -import java.util.Collections; -import java.util.List; - -import lombok.extern.slf4j.Slf4j; - -/** - * TIS parameter - */ -@Slf4j -public class PigeonParameters extends AbstractParameters { - - /** - * Pigeon target job name - */ - private String targetJobName; - - public String getTargetJobName() { - return targetJobName; - } - - public void setTargetJobName(String targetJobName) { - this.targetJobName = targetJobName; - } - - @Override - public boolean checkParameters() { - if (StringUtils.isBlank(this.targetJobName)) { - log.error("checkParameters faild targetJobName can not be null"); - return false; - } - return true; - } - - @Override - public List getResourceFilesList() { - return Collections.emptyList(); - } -} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParamsConstants.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParamsConstants.java deleted file mode 100644 index e50755a728127..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonParamsConstants.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.plugin.task.pigeon; - -public class PigeonParamsConstants { - - public static String NAME_TARGET_JOB_NAME = "targetJobName"; - public static String TARGET_JOB_NAME = NAME_TARGET_JOB_NAME; - - private PigeonParamsConstants() { - } -} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTask.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTask.java deleted file mode 100644 index 55af378e832de..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTask.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.plugin.task.pigeon; - -import org.apache.dolphinscheduler.common.utils.JSONUtils; -import org.apache.dolphinscheduler.plugin.task.api.AbstractRemoteTask; -import org.apache.dolphinscheduler.plugin.task.api.TaskCallBack; -import org.apache.dolphinscheduler.plugin.task.api.TaskConstants; -import org.apache.dolphinscheduler.plugin.task.api.TaskException; -import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext; -import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpEntity; -import org.apache.http.StatusLine; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; - -import java.net.HttpURLConnection; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import lombok.extern.slf4j.Slf4j; - -import org.java_websocket.client.WebSocketClient; -import org.java_websocket.handshake.ServerHandshake; - -/** - * TIS DataX Task - **/ -@Slf4j -public class PigeonTask extends AbstractRemoteTask { - - public static final String KEY_POOL_VAR_PIGEON_HOST = "p_host"; - private final TaskExecutionContext taskExecutionContext; - - private PigeonParameters parameters; - private BizResult triggerResult; - private final PigeonConfig config; - - public PigeonTask(TaskExecutionContext taskExecutionContext) { - super(taskExecutionContext); - this.taskExecutionContext = taskExecutionContext; - this.config = PigeonConfig.getInstance(); - } - - @Override - public List getApplicationIds() throws TaskException { - return Collections.emptyList(); - } - - @Override - public void init() throws TaskException { - super.init(); - parameters = JSONUtils.parseObject(taskExecutionContext.getTaskParams(), PigeonParameters.class); - log.info("Initialize PIGEON task params {}", JSONUtils.toPrettyJsonString(parameters)); - if (parameters == null || !parameters.checkParameters()) { - throw new TaskException("datax task params is not valid"); - } - } - - // todo split handle to submit and track - @Override - public void handle(TaskCallBack taskCallBack) throws TaskException { - // Trigger PIGEON DataX pipeline - log.info("start execute PIGEON task"); - long startTime = System.currentTimeMillis(); - String targetJobName = this.parameters.getTargetJobName(); - String host = getHost(); - try { - final String triggerUrl = getTriggerUrl(); - final String getStatusUrl = config.getJobStatusUrl(host); - HttpPost post = new HttpPost(triggerUrl); - post.addHeader("appname", targetJobName); - addFormUrlencoded(post); - StringEntity entity = new StringEntity(config.getJobTriggerPostBody(), StandardCharsets.UTF_8); - post.setEntity(entity); - ExecResult execState = null; - int taskId; - WebSocketClient webSocket = null; - try ( - CloseableHttpClient client = HttpClients.createDefault(); - // trigger to start PIGEON dataX task - CloseableHttpResponse response = client.execute(post)) { - triggerResult = processResponse(triggerUrl, response, BizResult.class); - if (!triggerResult.isSuccess()) { - List errormsg = triggerResult.getErrormsg(); - StringBuffer errs = new StringBuffer(); - if (CollectionUtils.isNotEmpty(errormsg)) { - errs.append(",errs:").append(errormsg.stream().collect(Collectors.joining(","))); - } - throw new Exception("trigger PIGEON job faild taskName:" + targetJobName + errs.toString()); - } - taskId = triggerResult.getBizresult().getTaskid(); - - webSocket = receiveRealtimeLog(host, targetJobName, taskId); - - setAppIds(String.valueOf(taskId)); - - CloseableHttpResponse status = null; - - while (true) { - try { - post = new HttpPost(getStatusUrl); - entity = new StringEntity("{\n taskid: " + taskId + "\n, log: false }", StandardCharsets.UTF_8); - post.setEntity(entity); - status = client.execute(post); - StatusResult execStatus = processResponse(getStatusUrl, status, StatusResult.class); - Map bizresult = execStatus.getBizresult(); - Map s = (Map) bizresult.get("status"); - execState = ExecResult.parse((Integer) s.get("state")); - if (execState == ExecResult.SUCCESS || execState == ExecResult.FAILD) { - break; - } - Thread.sleep(3000); - } finally { - status.close(); - } - } - } finally { - if (webSocket != null) { - Thread.sleep(4000); - try { - webSocket.close(); - } catch (Throwable e) { - log.warn(e.getMessage(), e); - } - } - } - - long costTime = System.currentTimeMillis() - startTime; - log.info("PIGEON task: {},taskId:{} costTime : {} milliseconds, statusCode : {}", - targetJobName, taskId, costTime, (execState == ExecResult.SUCCESS) ? "'success'" : "'failure'"); - setExitStatusCode((execState == ExecResult.SUCCESS) ? TaskConstants.EXIT_CODE_SUCCESS - : TaskConstants.EXIT_CODE_FAILURE); - } catch (Exception e) { - log.error("execute PIGEON dataX faild,PIGEON task name:" + targetJobName, e); - setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE); - if (e instanceof InterruptedException) { - Thread.currentThread().interrupt(); - } - throw new TaskException("Execute pigeon task failed", e); - } - } - - @Override - public void submitApplication() throws TaskException { - - } - - @Override - public void trackApplicationStatus() throws TaskException { - - } - - private void addFormUrlencoded(HttpPost post) { - post.addHeader("content-type", "application/x-www-form-urlencoded"); - } - - @Override - public void cancelApplication() throws TaskException { - log.info("start to cancelApplication"); - Objects.requireNonNull(triggerResult, "triggerResult can not be null"); - log.info("start to cancelApplication taskId:{}", triggerResult.getTaskId()); - final String triggerUrl = getTriggerUrl(); - - StringEntity entity = - new StringEntity(config.getJobCancelPostBody(triggerResult.getTaskId()), StandardCharsets.UTF_8); - - CancelResult cancelResult = null; - HttpPost post = new HttpPost(triggerUrl); - addFormUrlencoded(post); - post.setEntity(entity); - try ( - CloseableHttpClient client = HttpClients.createDefault(); - // trigger to start TIS dataX task - CloseableHttpResponse response = client.execute(post)) { - cancelResult = processResponse(triggerUrl, response, CancelResult.class); - if (!cancelResult.isSuccess()) { - List errormsg = triggerResult.getErrormsg(); - StringBuffer errs = new StringBuffer(); - if (CollectionUtils.isNotEmpty(errormsg)) { - errs.append(",errs:").append(errormsg.stream().collect(Collectors.joining(","))); - } - throw new TaskException("cancel PIGEON job faild taskId:" + triggerResult.getTaskId() + errs); - } - } catch (ClientProtocolException e) { - throw new TaskException("client protocol error", e); - } catch (Exception e) { - throw new TaskException("pigeon execute error", e); - } - } - - private String getTriggerUrl() { - final String tisHost = getHost(); - return config.getJobTriggerUrl(tisHost); - } - - private String getHost() { - final String host = taskExecutionContext.getDefinedParams().get(KEY_POOL_VAR_PIGEON_HOST); - if (StringUtils.isEmpty(host)) { - throw new IllegalStateException("global var '" + KEY_POOL_VAR_PIGEON_HOST + "' can not be empty"); - } - return host; - } - - private WebSocketClient receiveRealtimeLog(final String tisHost, String dataXName, int taskId) throws Exception { - final String applyURI = config.getJobLogsFetchUrl(tisHost, dataXName, taskId); - log.info("apply ws connection,uri:{}", applyURI); - WebSocketClient webSocketClient = new WebSocketClient(new URI(applyURI)) { - - @Override - public void onOpen(ServerHandshake handshakedata) { - log.info("start to receive remote execute log"); - } - - @Override - public void onMessage(String message) { - ExecLog execLog = JSONUtils.parseObject(message, ExecLog.class); - log.info(execLog.getMsg()); - } - - @Override - public void onClose(int code, String reason, boolean remote) { - log.info("stop to receive remote log,reason:{},taskId:{}", reason, taskId); - } - - @Override - public void onError(Exception t) { - log.error(t.getMessage(), t); - } - }; - webSocketClient.connect(); - return webSocketClient; - } - - private T processResponse(String applyUrl, CloseableHttpResponse response, - Class clazz) throws Exception { - StatusLine resStatus = response.getStatusLine(); - if (HttpURLConnection.HTTP_OK != resStatus.getStatusCode()) { - throw new IllegalStateException("request server " + applyUrl + " faild:" + resStatus.getReasonPhrase()); - } - HttpEntity entity = response.getEntity(); - String resp = EntityUtils.toString(entity, StandardCharsets.UTF_8); - T result = JSONUtils.parseObject(resp, clazz); - return result; - } - - @Override - public AbstractParameters getParameters() { - Objects.requireNonNull(this.parameters, "tisParameters can not be null"); - return this.parameters; - } - - private static class CancelResult extends AjaxResult { - - private Object bizresult; - - @Override - public Object getBizresult() { - return this.bizresult; - } - - public void setBizresult(Object bizresult) { - this.bizresult = bizresult; - } - } - - private static class BizResult extends AjaxResult { - - private TriggerBuildResult bizresult; - - @Override - public TriggerBuildResult getBizresult() { - return this.bizresult; - } - - public int getTaskId() { - return bizresult.taskid; - } - - public void setBizresult(TriggerBuildResult bizresult) { - this.bizresult = bizresult; - } - } - - private static class StatusResult extends AjaxResult { - - private Map bizresult; - - @Override - public Map getBizresult() { - return this.bizresult; - } - - public void setBizresult(Map bizresult) { - this.bizresult = bizresult; - } - } - - private abstract static class AjaxResult { - - private boolean success; - - private List errormsg; - - private List msg; - - public abstract T getBizresult(); - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public List getErrormsg() { - return this.errormsg; - } - - public void setErrormsg(List errormsg) { - this.errormsg = errormsg; - } - - public List getMsg() { - return this.msg; - } - - public void setMsg(List msg) { - this.msg = msg; - } - - } - - private static class TriggerBuildResult { - - private int taskid; - - public int getTaskid() { - return taskid; - } - - public void setTaskid(int taskid) { - this.taskid = taskid; - } - } - - private enum ExecResult { - - SUCCESS(1), FAILD(-1), DOING(2), ASYN_DOING(22), CANCEL(3); - - private final int value; - - public static ExecResult parse(int value) { - for (ExecResult r : values()) { - if (r.value == value) { - return r; - } - } - throw new IllegalStateException("vale:" + value + " is illegal"); - } - - private ExecResult(int value) { - this.value = value; - } - - public int getValue() { - return this.value; - } - } - - private static class ExecLog { - - private String logType; - private String msg; - private int taskId; - - public String getLogType() { - return logType; - } - - public void setLogType(String logType) { - this.logType = logType; - } - - public String getMsg() { - return msg; - } - - public void setMsg(String msg) { - this.msg = msg; - } - - public int getTaskId() { - return taskId; - } - - public void setTaskId(int taskId) { - this.taskId = taskId; - } - } -} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannel.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannel.java deleted file mode 100644 index 112f087a574f9..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannel.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.plugin.task.pigeon; - -import org.apache.dolphinscheduler.common.utils.JSONUtils; -import org.apache.dolphinscheduler.plugin.task.api.AbstractTask; -import org.apache.dolphinscheduler.plugin.task.api.TaskChannel; -import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext; -import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class PigeonTaskChannel implements TaskChannel { - - @Override - public AbstractTask createTask(TaskExecutionContext taskRequest) { - return new PigeonTask(taskRequest); - } - - @Override - public AbstractParameters parseParameters(String taskParams) { - return JSONUtils.parseObject(taskParams, PigeonParameters.class); - } - -} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannelFactory.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannelFactory.java deleted file mode 100644 index 584f131a42359..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskChannelFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.plugin.task.pigeon; - -import org.apache.dolphinscheduler.plugin.task.api.TaskChannel; -import org.apache.dolphinscheduler.plugin.task.api.TaskChannelFactory; - -import com.google.auto.service.AutoService; - -@AutoService(TaskChannelFactory.class) -public class PigeonTaskChannelFactory implements TaskChannelFactory { - - @Override - public TaskChannel create() { - return new PigeonTaskChannel(); - } - - @Override - public String getName() { - return "PIGEON"; - } - -} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/resources/org/apache/dolphinscheduler/plugin/task/pigeon/config.properties b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/resources/org/apache/dolphinscheduler/plugin/task/pigeon/config.properties deleted file mode 100644 index c54e53ad41d12..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/main/resources/org/apache/dolphinscheduler/plugin/task/pigeon/config.properties +++ /dev/null @@ -1,26 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -job.trigger.url=http://%s/tjs/coredefine/coredefine.ajax -job.trigger.post.body=action=datax_action&emethod=trigger_fullbuild_task - -job.cancel.post.body=action=core_action&event_submit_do_cancel_task=y&taskid=%s - -job.status.url=http://%s/tjs/config/config.ajax?action=collection_action&emethod=get_task_status -job.status.post.body={\n taskid: %s\n, log: false } - -job.logs.fetch.url=ws://%s/tjs/download/logfeedback?logtype=full&collection=%s&taskid=%s \ No newline at end of file diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.java deleted file mode 100644 index 3eed4c20c40aa..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/java/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dolphinscheduler.plugin.task.pigeon; - -import static com.github.dreamhead.moco.Moco.file; -import static com.github.dreamhead.moco.MocoJsonRunner.jsonHttpServer; -import static com.github.dreamhead.moco.Runner.running; - -import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext; -import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus; - -import org.apache.commons.io.IOUtils; - -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.github.dreamhead.moco.HttpServer; - -public class PigeonTaskTest { - - private static final Logger logger = LoggerFactory.getLogger(PigeonTaskTest.class); - private PigeonTask pigeonTask; - - private TaskExecutionContext taskExecutionContext; - - @BeforeEach - public void before() throws Exception { - - String taskParams = "{\"targetJobName\":\"mysql_elastic\"}"; - - taskExecutionContext = Mockito.mock(TaskExecutionContext.class); - Mockito.when(taskExecutionContext.getTaskParams()).thenReturn(taskParams); - Mockito.when(taskExecutionContext.getExecutePath()).thenReturn("/tmp"); - Mockito.when(taskExecutionContext.getTaskAppId()).thenReturn(UUID.randomUUID().toString()); - Mockito.when(taskExecutionContext.getTenantCode()).thenReturn("root"); - Mockito.when(taskExecutionContext.getStartTime()).thenReturn(System.currentTimeMillis()); - Mockito.when(taskExecutionContext.getTaskTimeout()).thenReturn(10000); - Mockito.when(taskExecutionContext.getLogPath()).thenReturn("/tmp/dx"); - // Mockito.when(taskExecutionContext.getVarPool()) - // .thenReturn("[{\"direct\":\"IN\",\"prop\":\"" + TISTask.KEY_POOL_VAR_TIS_HOST + - // "\",\"type\":\"VARCHAR\",\"value\":\"127.0.0.1:8080\"}]"); - Map gloabParams = - Collections.singletonMap(PigeonTask.KEY_POOL_VAR_PIGEON_HOST, "127.0.0.1:8080"); - Mockito.when(taskExecutionContext.getDefinedParams()).thenReturn(gloabParams); - - pigeonTask = new PigeonTask(taskExecutionContext); - pigeonTask.init(); - - } - - @Test - public void testGetTISConfigParams() { - PigeonConfig cfg = PigeonConfig.getInstance(); - String tisHost = "127.0.0.1:8080"; - Assertions.assertEquals("http://127.0.0.1:8080/tjs/coredefine/coredefine.ajax", cfg.getJobTriggerUrl(tisHost)); - String jobName = "mysql_elastic"; - int taskId = 123; - Assertions.assertEquals( - "ws://" + tisHost + "/tjs/download/logfeedback?logtype=full&collection=mysql_elastic&taskid=" + taskId, - cfg.getJobLogsFetchUrl(tisHost, jobName, taskId)); - - Assertions.assertEquals("action=datax_action&emethod=trigger_fullbuild_task", cfg.getJobTriggerPostBody()); - - Assertions.assertEquals( - "http://127.0.0.1:8080/tjs/config/config.ajax?action=collection_action&emethod=get_task_status", - cfg.getJobStatusUrl(tisHost)); - - Assertions.assertEquals("{\n taskid: " + taskId + "\n, log: false }", cfg.getJobStatusPostBody(taskId)); - - Assertions.assertEquals("action=core_action&event_submit_do_cancel_task=y&taskid=" + taskId, - cfg.getJobCancelPostBody(taskId)); - } - - @Test - public void testInit() throws Exception { - try { - pigeonTask.init(); - } catch (Exception e) { - Assertions.fail(e.getMessage()); - } - } - - @Test - public void testHandle() throws Exception { - HttpServer server = jsonHttpServer(8080, - file("src/test/resources/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.json")); - - running(server, () -> { - pigeonTask.handle(null); - - Assertions.assertEquals(TaskExecutionStatus.SUCCESS, pigeonTask.getExitStatus()); - }); - } - - private String loadResContent(String resName) { - try (InputStream i = this.getClass().getResourceAsStream(resName)) { - Objects.requireNonNull(i, "resource " + resName + " relevant stream content can not be null"); - String content = IOUtils.toString(i, StandardCharsets.UTF_8); - - return content; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - // @Test - // public void testCancelApplication() - // throws Exception { - // try { - // tisTask.cancelApplication(true); - // } catch (Exception e) { - // Assertions.fail(e.getMessage()); - // } - // } - -} diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/resources/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.json b/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/resources/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.json deleted file mode 100644 index 5aef31fd21cdc..0000000000000 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-pigeon/src/test/resources/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.json +++ /dev/null @@ -1,60 +0,0 @@ -[ - { - "description": "trigger task execute", - "request": { - "uri": "/tjs/coredefine/coredefine.ajax", - "method": "post", - "headers": { - "Content-Type": "application/x-www-form-urlencoded", - "appname": "mysql_elastic" - }, - "text": "action=datax_action&emethod=trigger_fullbuild_task" - }, - "response": { - "text": "{\n \"success\":true,\n \"errormsg\":[],\n \"msg\":[],\n \"bizresult\":{\"taskid\": \"1087\"}\n}" - } - }, - { - "description": "Get task execute status", - "request": { - "uri": "/tjs/config/config.ajax", - "method": "post", - "headers": { - "Content-Type": "text/plain; charset=UTF-8" - }, - "queries": { - "action": "collection_action", - "emethod": "get_task_status" - }, - "text": "{\n taskid: 1087\n, log: false }" - }, - "response": { - "seq": [ - { - "text": "{\n \"success\": true,\n \"errormsg\": [\n \"err1\"\n ],\n \"bizresult\": {\n \"status\": {\n \"state\": 2\n }\n }\n}" - }, - { - "text": "{\n \"success\": true,\n \"errormsg\": [\n \"err1\"\n ],\n \"bizresult\": {\n \"status\": {\n \"state\": 1\n }\n }\n}" - } - ] - } - }, - { - "websocket": { - "uri": "/tjs/download/logfeedback", - "connected": "connected", - "sessions": [ - { - "request": { - "text": "logtype=full&collection=mysql_elastic&taskid=1087" - }, - "response": { - "broadcast": { - "content": "{\n \"logType\": \"FULL\",\n \"msg\": \"message 1\",\n \"taskId\": \"1087\"\n}" - } - } - } - ] - } - } -] \ No newline at end of file diff --git a/dolphinscheduler-task-plugin/pom.xml b/dolphinscheduler-task-plugin/pom.xml index f4c15732268e2..9036e88b676de 100644 --- a/dolphinscheduler-task-plugin/pom.xml +++ b/dolphinscheduler-task-plugin/pom.xml @@ -40,7 +40,6 @@ dolphinscheduler-task-sql dolphinscheduler-task-sqoop dolphinscheduler-task-procedure - dolphinscheduler-task-pigeon dolphinscheduler-task-dataquality dolphinscheduler-task-seatunnel dolphinscheduler-task-emr diff --git a/dolphinscheduler-ui/public/images/task-icons/pigeon.png b/dolphinscheduler-ui/public/images/task-icons/pigeon.png deleted file mode 100644 index 6fe21d2b1ee5f9be7f2cbccf9919a718fc860ad0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1192 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P3?%12mYf5m7>k44ofy`glX(ebp9}B_aRmzg z2ZL3sR_))vf9A}Y^XJb8l8Y8Cnmc#yk|j%k+@(vGE?l?}$N-7}8M9~4o;PnEPz{g- z3eK7}3n&g`0~vGX%mIo66+lQh7pMRz2vh(R2MR(IK-2?CAb^XYaUr^pW#Mc%1862t z7lgzV1d0OzP#mrX$c5MfVSuDzCO{Yvm2g40Mz}7J2ACGOEL;#-1fm5_!qq?+a1x>g z$c3mxRtAwmR)8!E(E=y?B+6a`V{~RokY6wZBNHIL{ zOIv$KPv3-zlc!9ZK6Cb*x$_n*T)KS4%GK-EZ`!hL`;MKv_Uzk#;NYRdM~|O8b^gND zYu9hwx^ws5!$*&wK70P^&D(eHKYaZ3^~cX&zyJLGH*LkkIAHR7?CIhdA|ZM9;7{l7 zLI$=E&+p#*I_r+ow3w~8jNG}GKI^hvG)b^i@M%=qqzTs))0b@B`uJ!5+uw54_t$>Z zp3nbp@7A+>AByYCe<{s5FkiM~$%@mybG9sAW1FmFRLhY%=lq5%x$Isy*fY1zSt_vF zWuw5%9cAx$OYbfYaZQaVoiH=D;VoaN@hRS{yhBOZlX?{We;(P>;(g0!F8i|IPill) z!X{bDUzoD&*&EC z%Zd4umhEGA|8n<9D)&R3qm+XEGFEB)nb3IG|IzwmYRl8po~OCrPJJNqna}z0LIXY% zo1%j$t7Xp^zGpH~*SOQX*}duDv$y@cUjjKCi#rdMUOBC?$=2ziqKPBd-wA;W-f;Jw zNnOe1eAy>a!gb0m!K|tUD;IxYRZH)!&uHD{moZ0^>v!Uf9~Se{4#vGu5}CK?ftc@o zl^5rNL>nCWHYYH!Jul}v*=*pEdy#dOk#)cY&(LM7nU?7uU##-}(32kyXOAmynDBh( z4ojmpoPaR;IWbkzLb6Mw<&;$U= CNoqg< diff --git a/dolphinscheduler-ui/public/images/task-icons/pigeon_hover.png b/dolphinscheduler-ui/public/images/task-icons/pigeon_hover.png deleted file mode 100644 index d9d651bf5dc7ba97346e432175afa85531357fae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1167 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P3?%12mYf5m7>k44ofy`glX(eb?+Ne;aRmzg z|NpVNCGAhtpOf8A;SwdefTm;&M&PWrDm{lCrx zkOIw_|MjQ;*PHZTYr=ocDIk@4lR=7gCjHk2%1->R)Bj%^C_Cl9?qo2d|Gy590n`i8 zGU>ktP-NnN?a3e$K!QLv(5Q+3HGxt<5g?-<#06;qvL}Mn1C@ak07Zaouq;#=SR+Ik zP#4Ha5Tho5jRJGwW&#-?Ss>~Mn+aq<>;f}TWZ}wy<^Zh&b3qE=Y@i8XE1(8K6o3UG z<^xHHdZ2cQN{~5d+96yp2~rF;AFdv%7@{3UPP#7W28_SSB|(0{42(?7EUau?+&sMe z0)j%qBBEmA5|Yv~a`Fm_O3Es#np)br`UWPZX66=_R@OGQ&hB2`KK=oL!C?`R(Xnv} zNhukbS=qVy1;wRhef<+AO`bM;&fIwm7q48ie#6F1o40M>xogkfeftj{ zK6c{tnafwMUcY(w-u)-fp1*kc>h+tq?>>J1^6mSNpTByTbeRS*-#9Y=v6`iQ z7K_KZ{pW(k{R2fEME&R4u4wYIF8uzrC>%#uX~mugyOO%gOFDzRh2r&rtUIKKZ((QbHX{a<)Ou zk_U|&{_nh7`J!l2%CY`7rJszu^tdvOFUa_$t(+*ojq&)(7fr|9A4*=ZGcQZHeXiDa zZ|%A`?F$dQgC91lxjfW6!ylDk!0#@%H+n$<>nx2{1HT-1*5m7R1-Sw<-UaMP+_Z4X z&Ejv5*0Qe3b1v?6VhQ~=XVzjhp0gaS;u@QGpSu&iB#&iQ9oJ1YiL&|qcK_BY5T$lT*9Q zSDbR46|nHJy7{g^MVGtR8${W>dw3Rl&1rk{ Date: Sat, 29 Jun 2024 14:34:30 +0800 Subject: [PATCH 04/18] [Fix-16211] Remove ExecutePath in buildJarCommand to fix Java Task in Jar Mode (#16238) --- .../plugin/task/java/JavaTask.java | 2 -- .../plugin/task/java/JavaTaskTest.java | 18 ++++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/main/java/org/apache/dolphinscheduler/plugin/task/java/JavaTask.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/main/java/org/apache/dolphinscheduler/plugin/task/java/JavaTask.java index fc23260345480..6423452a58750 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/main/java/org/apache/dolphinscheduler/plugin/task/java/JavaTask.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/main/java/org/apache/dolphinscheduler/plugin/task/java/JavaTask.java @@ -17,7 +17,6 @@ package org.apache.dolphinscheduler.plugin.task.java; -import static org.apache.dolphinscheduler.common.constants.Constants.FOLDER_SEPARATOR; import static org.apache.dolphinscheduler.plugin.task.java.JavaConstants.JAVA_HOME_VAR; import static org.apache.dolphinscheduler.plugin.task.java.JavaConstants.PUBLIC_CLASS_NAME_REGEX; @@ -187,7 +186,6 @@ protected String buildJarCommand() { .append("java").append(" ") .append(buildResourcePath()).append(" ") .append("-jar").append(" ") - .append(taskRequest.getExecutePath()).append(FOLDER_SEPARATOR) .append(mainJarAbsolutePathInLocal).append(" ") .append(javaParameters.getMainArgs().trim()).append(" ") .append(javaParameters.getJvmArgs().trim()); diff --git a/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/test/java/org/apache/dolphinscheduler/plugin/task/java/JavaTaskTest.java b/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/test/java/org/apache/dolphinscheduler/plugin/task/java/JavaTaskTest.java index c829415326143..b8af840c69f1d 100644 --- a/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/test/java/org/apache/dolphinscheduler/plugin/task/java/JavaTaskTest.java +++ b/dolphinscheduler-task-plugin/dolphinscheduler-task-java/src/test/java/org/apache/dolphinscheduler/plugin/task/java/JavaTaskTest.java @@ -85,7 +85,7 @@ public void buildJarCommand() { JavaTask javaTask = runJarType(); assertThat(javaTask.buildJarCommand()) .isEqualTo( - "${JAVA_HOME}/bin/java -classpath .:/tmp/dolphinscheduler/test/executepath:opt/share/jar/resource2.jar -jar /tmp/dolphinscheduler/test/executepath/opt/share/jar/main.jar -host 127.0.0.1 -port 8080 -xms:50m"); + "${JAVA_HOME}/bin/java -classpath .:/tmp/dolphinscheduler/test/executepath:/tmp/dolphinscheduler/test/executepath/opt/share/jar/resource2.jar -jar /tmp/dolphinscheduler/test/executepath/opt/share/jar/main.jar -host 127.0.0.1 -port 8080 -xms:50m"); } /** @@ -107,7 +107,7 @@ public void buildJavaCompileCommand() throws IOException { } assertThat(javaTask.buildJavaCompileCommand(sourceCode)) .isEqualTo( - "${JAVA_HOME}/bin/javac -classpath .:/tmp/dolphinscheduler/test/executepath:opt/share/jar/resource2.jar /tmp/dolphinscheduler/test/executepath/JavaTaskTest.java"); + "${JAVA_HOME}/bin/javac -classpath .:/tmp/dolphinscheduler/test/executepath:/tmp/dolphinscheduler/test/executepath/opt/share/jar/resource2.jar /tmp/dolphinscheduler/test/executepath/JavaTaskTest.java"); } finally { Path path = Paths.get(fileName); if (Files.exists(path)) { @@ -137,7 +137,7 @@ public void buildJavaCommand() throws Exception { } assertThat(javaTask.buildJavaCommand()) .isEqualTo( - "${JAVA_HOME}/bin/javac -classpath .:/tmp/dolphinscheduler/test/executepath:opt/share/jar/resource2.jar /tmp/dolphinscheduler/test/executepath/JavaTaskTest.java;${JAVA_HOME}/bin/java -classpath .:/tmp/dolphinscheduler/test/executepath:opt/share/jar/resource2.jar JavaTaskTest -host 127.0.0.1 -port 8080 -xms:50m"); + "${JAVA_HOME}/bin/javac -classpath .:/tmp/dolphinscheduler/test/executepath:/tmp/dolphinscheduler/test/executepath/opt/share/jar/resource2.jar /tmp/dolphinscheduler/test/executepath/JavaTaskTest.java;${JAVA_HOME}/bin/java -classpath .:/tmp/dolphinscheduler/test/executepath:/tmp/dolphinscheduler/test/executepath/opt/share/jar/resource2.jar JavaTaskTest -host 127.0.0.1 -port 8080 -xms:50m"); } /** @@ -254,15 +254,16 @@ public JavaTask runJavaType() { taskExecutionContext.setTaskAppId("runJavaType"); ResourceContext.ResourceItem resourceItem1 = new ResourceContext.ResourceItem(); resourceItem1.setResourceAbsolutePathInStorage("/opt/share/jar/resource2.jar"); - resourceItem1.setResourceAbsolutePathInLocal("opt/share/jar/resource2.jar"); + resourceItem1 + .setResourceAbsolutePathInLocal("/tmp/dolphinscheduler/test/executepath/opt/share/jar/resource2.jar"); ResourceContext.ResourceItem resourceItem2 = new ResourceContext.ResourceItem(); resourceItem2.setResourceAbsolutePathInStorage("/opt/share/jar/main.jar"); - resourceItem2.setResourceAbsolutePathInLocal("opt/share/jar/main.jar"); + resourceItem2.setResourceAbsolutePathInLocal("/tmp/dolphinscheduler/test/executepath/opt/share/jar/main.jar"); ResourceContext.ResourceItem resourceItem3 = new ResourceContext.ResourceItem(); resourceItem3.setResourceAbsolutePathInStorage("/JavaTaskTest.java"); - resourceItem3.setResourceAbsolutePathInLocal("JavaTaskTest.java"); + resourceItem3.setResourceAbsolutePathInLocal("/tmp/dolphinscheduler/test/executepath/JavaTaskTest.java"); ResourceContext resourceContext = new ResourceContext(); resourceContext.addResourceItem(resourceItem1); @@ -286,11 +287,12 @@ private JavaTask runJarType() { taskExecutionContext.setTaskAppId("runJavaType"); ResourceContext.ResourceItem resourceItem1 = new ResourceContext.ResourceItem(); resourceItem1.setResourceAbsolutePathInStorage("/opt/share/jar/resource2.jar"); - resourceItem1.setResourceAbsolutePathInLocal("opt/share/jar/resource2.jar"); + resourceItem1 + .setResourceAbsolutePathInLocal("/tmp/dolphinscheduler/test/executepath/opt/share/jar/resource2.jar"); ResourceContext.ResourceItem resourceItem2 = new ResourceContext.ResourceItem(); resourceItem2.setResourceAbsolutePathInStorage("/opt/share/jar/main.jar"); - resourceItem2.setResourceAbsolutePathInLocal("opt/share/jar/main.jar"); + resourceItem2.setResourceAbsolutePathInLocal("/tmp/dolphinscheduler/test/executepath/opt/share/jar/main.jar"); ResourceContext resourceContext = new ResourceContext(); resourceContext.addResourceItem(resourceItem1); From 177a001392467dd6eb6f1a2aa1175b0a5a3ef221 Mon Sep 17 00:00:00 2001 From: Wenjun Ruan Date: Sun, 30 Jun 2024 18:56:53 +0800 Subject: [PATCH 05/18] Remove unused dependentResult in TaskInstance (#16236) --- .../api/service/ProcessInstanceService.java | 3 - .../impl/ProcessInstanceServiceImpl.java | 63 +------------------ .../service/ProcessInstanceServiceTest.java | 18 ------ .../dao/entity/TaskInstance.java | 6 -- .../dao/utils/TaskInstanceUtils.java | 1 - 5 files changed, 1 insertion(+), 90 deletions(-) diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessInstanceService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessInstanceService.java index 7bf49e001664b..4df7a69da57d8 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessInstanceService.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessInstanceService.java @@ -25,7 +25,6 @@ import org.apache.dolphinscheduler.common.enums.WorkflowExecutionStatus; import org.apache.dolphinscheduler.dao.entity.ProcessInstance; import org.apache.dolphinscheduler.dao.entity.User; -import org.apache.dolphinscheduler.plugin.task.api.enums.DependResult; import java.io.IOException; import java.util.List; @@ -122,8 +121,6 @@ Map queryTaskListByProcessId(User loginUser, long projectCode, Integer processId) throws IOException; - Map parseLogForDependentResult(String log) throws IOException; - /** * query sub process instance detail info by task id * diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java index 5e5d703017c1e..11ff034bb64ef 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java @@ -21,7 +21,6 @@ import static org.apache.dolphinscheduler.api.enums.Status.PROCESS_INSTANCE_NOT_EXIST; import static org.apache.dolphinscheduler.api.enums.Status.PROCESS_INSTANCE_STATE_OPERATION_ERROR; import static org.apache.dolphinscheduler.common.constants.Constants.DATA_LIST; -import static org.apache.dolphinscheduler.common.constants.Constants.DEPENDENT_SPLIT; import static org.apache.dolphinscheduler.common.constants.Constants.GLOBAL_PARAMS; import static org.apache.dolphinscheduler.common.constants.Constants.LOCAL_PARAMS; import static org.apache.dolphinscheduler.common.constants.Constants.PROCESS_INSTANCE_STATE; @@ -59,7 +58,6 @@ import org.apache.dolphinscheduler.dao.entity.ProcessTaskRelationLog; import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.RelationSubWorkflow; -import org.apache.dolphinscheduler.dao.entity.ResponseTaskLog; import org.apache.dolphinscheduler.dao.entity.TaskDefinition; import org.apache.dolphinscheduler.dao.entity.TaskDefinitionLog; import org.apache.dolphinscheduler.dao.entity.TaskInstance; @@ -76,7 +74,6 @@ import org.apache.dolphinscheduler.dao.repository.ProcessInstanceMapDao; import org.apache.dolphinscheduler.dao.repository.TaskInstanceDao; import org.apache.dolphinscheduler.dao.utils.WorkflowUtils; -import org.apache.dolphinscheduler.plugin.task.api.enums.DependResult; import org.apache.dolphinscheduler.plugin.task.api.model.Property; import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils; import org.apache.dolphinscheduler.plugin.task.api.utils.TaskTypeUtils; @@ -86,11 +83,6 @@ import org.apache.commons.lang3.StringUtils; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -446,11 +438,10 @@ public Result queryProcessInstanceList(User loginUser, WorkflowInstanceQueryRequ * @param projectCode project code * @param processId process instance id * @return task list for the process instance - * @throws IOException io exception */ @Override public Map queryTaskListByProcessId(User loginUser, long projectCode, - Integer processId) throws IOException { + Integer processId) { Project project = projectMapper.queryByCode(projectCode); // check user access for project Map result = @@ -471,7 +462,6 @@ public Map queryTaskListByProcessId(User loginUser, long project } List taskInstanceList = taskInstanceDao.queryValidTaskListByWorkflowInstanceId(processId, processInstance.getTestFlag()); - addDependResultForTaskList(loginUser, taskInstanceList); Map resultMap = new HashMap<>(); resultMap.put(PROCESS_INSTANCE_STATE, processInstance.getState().toString()); resultMap.put(TASK_LIST, taskInstanceList); @@ -541,57 +531,6 @@ public List queryDynamicSubWorkflowInstances(User loginUs return allDynamicSubWorkflowDtos; } - /** - * add dependent result for dependent task - */ - private void addDependResultForTaskList(User loginUser, List taskInstanceList) throws IOException { - for (TaskInstance taskInstance : taskInstanceList) { - if (TaskTypeUtils.isDependentTask(taskInstance.getTaskType())) { - log.info("DEPENDENT type task instance need to set dependent result, taskCode:{}, taskInstanceId:{}", - taskInstance.getTaskCode(), taskInstance.getId()); - // TODO The result of dependent item should not be obtained from the log, waiting for optimization. - Result logResult = loggerService.queryLog(loginUser, - taskInstance.getId(), Constants.LOG_QUERY_SKIP_LINE_NUMBER, Constants.LOG_QUERY_LIMIT); - if (logResult.getCode() == Status.SUCCESS.ordinal()) { - String log = logResult.getData().getMessage(); - Map resultMap = parseLogForDependentResult(log); - taskInstance.setDependentResult(JSONUtils.toJsonString(resultMap)); - } - } - } - } - - @Override - public Map parseLogForDependentResult(String content) throws IOException { - Map resultMap = new HashMap<>(); - if (StringUtils.isEmpty(content)) { - log.warn("Log content is empty."); - return resultMap; - } - - BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(content.getBytes( - StandardCharsets.UTF_8)), StandardCharsets.UTF_8)); - String line; - while ((line = br.readLine()) != null) { - if (line.contains(DEPENDENT_SPLIT)) { - String[] tmpStringArray = line.split(":\\|\\|"); - if (tmpStringArray.length != 2) { - continue; - } - String dependResultString = tmpStringArray[1]; - String[] dependStringArray = dependResultString.split(","); - if (dependStringArray.length != 3) { - continue; - } - String key = dependStringArray[0].trim().split(":")[1].trim(); - String result = dependStringArray[1].trim().split(":")[1].trim(); - DependResult dependResult = DependResult.valueOf(result); - resultMap.put(key, dependResult); - } - } - return resultMap; - } - /** * query sub process instance detail info by task id * diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java index 208d880fc143e..26bbc9541202b 100644 --- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessInstanceServiceTest.java @@ -64,7 +64,6 @@ import org.apache.dolphinscheduler.dao.repository.ProcessInstanceMapDao; import org.apache.dolphinscheduler.dao.repository.TaskInstanceDao; import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager; -import org.apache.dolphinscheduler.plugin.task.api.enums.DependResult; import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus; import org.apache.dolphinscheduler.service.expand.CuringParamsService; import org.apache.dolphinscheduler.service.model.TaskNode; @@ -481,23 +480,6 @@ public void testQueryTaskListByProcessId() throws IOException { Assertions.assertEquals(Status.SUCCESS, successRes.get(Constants.STATUS)); } - @Test - public void testParseLogForDependentResult() throws IOException { - String logString = - "[INFO] 2019-03-19 17:11:08.475 org.apache.dolphinscheduler.server.worker.log.TaskLogger:[172]" - + " - [taskAppId=TASK_223_10739_452334] dependent item complete, :|| dependentKey: 223-ALL-day-last1Day, result: SUCCESS, dependentDate: Wed Mar 19 17:10:36 CST 2019\n" - + "[INFO] 2019-03-19 17:11:08.476 org.apache.dolphinscheduler.server.worker.runner.TaskScheduleThread:[172]" - + " - task : 223_10739_452334 exit status code : 0\n" - + "[root@node2 current]# "; - Map resultMap = - processInstanceService.parseLogForDependentResult(logString); - Assertions.assertEquals(1, resultMap.size()); - - resultMap.clear(); - resultMap = processInstanceService.parseLogForDependentResult(""); - Assertions.assertEquals(0, resultMap.size()); - } - @Test public void testQuerySubProcessInstanceByTaskId() { long projectCode = 1L; diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TaskInstance.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TaskInstance.java index 629cfe9aea169..81b99c15889b3 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TaskInstance.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/TaskInstance.java @@ -201,12 +201,6 @@ public class TaskInstance implements Serializable { @TableField(exist = false) private Priority processInstancePriority; - /** - * dependent state - */ - @TableField(exist = false) - private String dependentResult; - /** * workerGroup */ diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/utils/TaskInstanceUtils.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/utils/TaskInstanceUtils.java index e23fcb97b5862..6c1c7f03a3c5d 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/utils/TaskInstanceUtils.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/utils/TaskInstanceUtils.java @@ -62,7 +62,6 @@ public static void copyTaskInstance(TaskInstance source, TaskInstance target) { target.setMaxRetryTimes(source.getMaxRetryTimes()); target.setRetryInterval(source.getRetryInterval()); target.setTaskInstancePriority(source.getTaskInstancePriority()); - target.setDependentResult(source.getDependentResult()); target.setWorkerGroup(source.getWorkerGroup()); target.setEnvironmentCode(source.getEnvironmentCode()); target.setEnvironmentConfig(source.getEnvironmentConfig()); From 565a91790a47eba2c783d5a8374c75c289c5aaa2 Mon Sep 17 00:00:00 2001 From: xiangzihao <460888207@qq.com> Date: Sun, 30 Jun 2024 22:39:12 +0800 Subject: [PATCH 06/18] [Chore] [CI] Add api-test and e2e-test to spotless check (#16242) --- .github/workflows/api-test.yml | 2 +- .github/workflows/owasp-dependency-check.yaml | 3 +- .../api/test/cases/ExecutorAPITest.java | 46 +- .../test/cases/ProcessDefinitionAPITest.java | 87 ++- .../test/cases/ProcessInstanceAPITest.java | 70 +- .../api/test/cases/ProjectAPITest.java | 57 +- .../api/test/cases/SchedulerAPITest.java | 46 +- .../api/test/cases/TenantAPITest.java | 12 +- .../api/test/cases/WorkerGroupAPITest.java | 16 +- .../entity/TenantListPagingResponseData.java | 1 + .../TenantListPagingResponseTotalList.java | 1 + .../api/test/pages/LoginPage.java | 1 + .../api/test/pages/project/ProjectPage.java | 8 +- .../api/test/pages/security/TenantPage.java | 1 + .../test/pages/security/WorkerGroupPage.java | 7 +- .../api/test/pages/workflow/ExecutorPage.java | 10 +- .../pages/workflow/ProcessDefinitionPage.java | 8 +- .../pages/workflow/ProcessInstancePage.java | 5 - .../test/pages/workflow/SchedulerPage.java | 2 - .../api/test/utils/JSONUtils.java | 10 +- .../api/test/utils/RequestClient.java | 65 +- .../api/test/core/DolphinScheduler.java | 1 + .../test/core/DolphinSchedulerExtension.java | 10 +- .../cases/ClickhouseDataSourceE2ETest.java | 219 +++--- .../e2e/cases/ClusterE2ETest.java | 22 +- .../e2e/cases/EnvironmentE2ETest.java | 26 +- .../e2e/cases/FileManageE2ETest.java | 169 +++-- .../e2e/cases/HiveDataSourceE2ETest.java | 24 +- .../e2e/cases/MysqlDataSourceE2ETest.java | 221 +++--- .../e2e/cases/PostgresDataSourceE2ETest.java | 219 +++--- .../e2e/cases/ProjectE2ETest.java | 9 +- .../e2e/cases/QueueE2ETest.java | 12 +- .../e2e/cases/SqlServerDataSourceE2ETest.java | 219 +++--- .../e2e/cases/TenantE2ETest.java | 34 +- .../e2e/cases/TokenE2ETest.java | 23 +- .../e2e/cases/UserE2ETest.java | 39 +- .../e2e/cases/WorkerGroupE2ETest.java | 40 +- .../e2e/cases/WorkflowE2ETest.java | 91 ++- .../e2e/cases/WorkflowHttpTaskE2ETest.java | 21 +- .../e2e/cases/WorkflowJavaTaskE2ETest.java | 24 +- .../e2e/cases/WorkflowSwitchE2ETest.java | 95 ++- .../e2e/cases/tasks/ShellTaskE2ETest.java | 14 +- .../cases/workflow/BaseWorkflowE2ETest.java | 30 +- .../e2e/models/tenant/DefaultTenant.java | 1 + .../e2e/models/users/AdminUser.java | 3 +- .../e2e/models/users/IUser.java | 3 - .../dolphinscheduler/e2e/pages/LoginPage.java | 24 +- .../e2e/pages/common/CodeEditor.java | 14 +- .../e2e/pages/common/HttpInput.java | 11 +- .../e2e/pages/common/NavBarPage.java | 23 +- .../e2e/pages/datasource/DataSourcePage.java | 405 ++++++----- .../e2e/pages/project/ProjectDetailPage.java | 13 +- .../e2e/pages/project/ProjectPage.java | 14 +- .../project/workflow/TaskInstanceTab.java | 22 +- .../workflow/WorkflowDefinitionTab.java | 58 +- .../pages/project/workflow/WorkflowForm.java | 20 +- .../workflow/WorkflowFormatDialog.java | 11 +- .../project/workflow/WorkflowInstanceTab.java | 30 +- .../project/workflow/WorkflowRunDialog.java | 18 +- .../project/workflow/WorkflowSaveDialog.java | 15 +- .../project/workflow/task/HttpTaskForm.java | 5 +- .../project/workflow/task/JavaTaskForm.java | 4 +- .../project/workflow/task/ShellTaskForm.java | 3 +- .../workflow/task/SubWorkflowTaskForm.java | 19 +- .../project/workflow/task/SwitchTaskForm.java | 21 +- .../workflow/task/SwitchTaskIfBranch.java | 5 +- .../project/workflow/task/TaskNodeForm.java | 15 +- .../e2e/pages/resource/FileManagePage.java | 664 +++++++++--------- .../e2e/pages/resource/ResourcePage.java | 124 ++-- .../e2e/pages/security/ClusterPage.java | 29 +- .../e2e/pages/security/EnvironmentPage.java | 42 +- .../e2e/pages/security/NamespacePage.java | 9 +- .../e2e/pages/security/QueuePage.java | 11 +- .../e2e/pages/security/SecurityPage.java | 56 +- .../e2e/pages/security/TenantPage.java | 15 +- .../e2e/pages/security/TokenPage.java | 73 +- .../e2e/pages/security/UserPage.java | 79 ++- .../e2e/pages/security/WorkerGroupPage.java | 40 +- .../dolphinscheduler/e2e/core/Constants.java | 5 +- .../e2e/core/DolphinScheduler.java | 1 + .../e2e/core/DolphinSchedulerExtension.java | 37 +- .../e2e/core/TestDescription.java | 5 +- .../e2e/core/WebDriverWaitFactory.java | 1 + dolphinscheduler-e2e/pom.xml | 4 +- pom.xml | 8 + 85 files changed, 2000 insertions(+), 1980 deletions(-) diff --git a/.github/workflows/api-test.yml b/.github/workflows/api-test.yml index b7a1aa4303f63..8fdfe8872ad28 100644 --- a/.github/workflows/api-test.yml +++ b/.github/workflows/api-test.yml @@ -125,7 +125,7 @@ jobs: run: | ./mvnw -B -f dolphinscheduler-api-test/pom.xml -am \ -DfailIfNoTests=false \ - -Dspotless.skip=false \ + -Dspotless.skip=true \ -Dtest=${{ matrix.case.class }} test - uses: actions/upload-artifact@v4 if: always() diff --git a/.github/workflows/owasp-dependency-check.yaml b/.github/workflows/owasp-dependency-check.yaml index b99486f298407..0e56049d93d28 100644 --- a/.github/workflows/owasp-dependency-check.yaml +++ b/.github/workflows/owasp-dependency-check.yaml @@ -30,6 +30,7 @@ env: jobs: build: runs-on: ubuntu-latest + timeout-minutes: 120 steps: - uses: actions/checkout@v4 with: @@ -47,4 +48,4 @@ jobs: continue-on-error: true with: name: dependency report - path: target/dependency-check-report.html + path: target/dependency-check-report.html diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java index 3b90131af9b6c..6a563efb481b5 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ExecutorAPITest.java @@ -31,17 +31,8 @@ import org.apache.dolphinscheduler.common.enums.ReleaseState; import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.WarningType; -import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.User; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; - -import lombok.extern.slf4j.Slf4j; - import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.util.EntityUtils; @@ -51,6 +42,14 @@ import java.util.LinkedHashMap; import java.util.List; +import lombok.extern.slf4j.Slf4j; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; + //TODO: Some test cases rely on ProcessInstance APIs. Should complete remaining cases after ProcessInstance related API tests done. @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @Slf4j @@ -80,7 +79,8 @@ public class ExecutorAPITest { public static void setup() { LoginPage loginPage = new LoginPage(); HttpResponse loginHttpResponse = loginPage.login(username, password); - sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); + sessionId = + JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); executorPage = new ExecutorPage(sessionId); processDefinitionPage = new ProcessDefinitionPage(sessionId); projectPage = new ProjectPage(sessionId); @@ -103,24 +103,30 @@ public void testStartProcessInstance() { HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test"); HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess()); - projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); + projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse + .getBody().getData()).get(0)).get("code"); // upload test workflow definition json ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage - .importProcessDefinition(loginUser, projectCode, file); + .importProcessDefinition(loginUser, projectCode, file); String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity()); Assertions.assertTrue(data.contains("\"success\":true")); // get workflow definition code - HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); + HttpResponse queryAllProcessDefinitionByProjectCodeResponse = + processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); - Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world")); - processDefinitionCode = (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); + Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString() + .contains("hello world")); + processDefinitionCode = + (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse + .getBody().getData()).get(0)).get("processDefinition")).get("code"); // release test workflow - HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); + HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, + projectCode, processDefinitionCode, ReleaseState.ONLINE); Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); // trigger workflow instance @@ -128,11 +134,12 @@ public void testStartProcessInstance() { Date date = new Date(); String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date)); log.info("use current time {} as scheduleTime", scheduleTime); - HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode, processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE); + HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode, + processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE); Assertions.assertTrue(startProcessInstanceResponse.getBody().getSuccess()); triggerCode = (long) startProcessInstanceResponse.getBody().getData(); - } catch (Exception e) { + } catch (Exception e) { log.error("failed", e); Assertions.fail(); } @@ -141,7 +148,8 @@ public void testStartProcessInstance() { @Test @Order(2) public void testStartCheckProcessDefinition() { - HttpResponse testStartCheckProcessDefinitionResponse = executorPage.startCheckProcessDefinition(loginUser, projectCode, processDefinitionCode); + HttpResponse testStartCheckProcessDefinitionResponse = + executorPage.startCheckProcessDefinition(loginUser, projectCode, processDefinitionCode); Assertions.assertTrue(testStartCheckProcessDefinitionResponse.getBody().getSuccess()); } diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessDefinitionAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessDefinitionAPITest.java index 4c4507e785919..a5870ceca29d5 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessDefinitionAPITest.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessDefinitionAPITest.java @@ -30,21 +30,21 @@ import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.dao.entity.User; -import java.io.File;; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.util.EntityUtils; + +import java.io.File; import java.util.LinkedHashMap; import java.util.List; +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import lombok.extern.slf4j.Slf4j; - -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.util.EntityUtils; - @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @Slf4j public class ProcessDefinitionAPITest { @@ -67,12 +67,12 @@ public class ProcessDefinitionAPITest { private static String processDefinitionName; - @BeforeAll public static void setup() { LoginPage loginPage = new LoginPage(); HttpResponse loginHttpResponse = loginPage.login(username, password); - sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); + sessionId = + JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); processDefinitionPage = new ProcessDefinitionPage(sessionId); projectPage = new ProjectPage(sessionId); loginUser = new User(); @@ -93,14 +93,15 @@ public void testImportProcessDefinition() { HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess()); - projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); + projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse + .getBody().getData()).get(0)).get("code"); ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage - .importProcessDefinition(loginUser, projectCode, file); + .importProcessDefinition(loginUser, projectCode, file); String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity()); Assertions.assertTrue(data.contains("\"success\":true")); - } catch (Exception e) { + } catch (Exception e) { log.error("failed", e); Assertions.fail(); } @@ -109,72 +110,92 @@ public void testImportProcessDefinition() { @Test @Order(2) public void testQueryAllProcessDefinitionByProjectCode() { - HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); + HttpResponse queryAllProcessDefinitionByProjectCodeResponse = + processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); - Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world")); - processDefinitionCode = (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); - processDefinitionName = (String) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("name"); + Assertions.assertTrue( + queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world")); + processDefinitionCode = + (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse + .getBody().getData()).get(0)).get("processDefinition")).get("code"); + processDefinitionName = + (String) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse + .getBody().getData()).get(0)).get("processDefinition")).get("name"); } @Test @Order(3) public void testQueryProcessDefinitionByCode() { - HttpResponse queryProcessDefinitionByCodeResponse = processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); + HttpResponse queryProcessDefinitionByCodeResponse = + processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getSuccess()); - Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("hello world")); + Assertions.assertTrue( + queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("hello world")); } @Test @Order(4) public void testgetProcessListByProjectCode() { - HttpResponse getProcessListByProjectCodeResponse = processDefinitionPage.getProcessListByProjectCode(loginUser, projectCode); + HttpResponse getProcessListByProjectCodeResponse = + processDefinitionPage.getProcessListByProjectCode(loginUser, projectCode); Assertions.assertTrue(getProcessListByProjectCodeResponse.getBody().getSuccess()); - Assertions.assertTrue(getProcessListByProjectCodeResponse.getBody().getData().toString().contains("test_import")); + Assertions + .assertTrue(getProcessListByProjectCodeResponse.getBody().getData().toString().contains("test_import")); } @Test @Order(5) public void testQueryProcessDefinitionByName() { - HttpResponse queryProcessDefinitionByNameResponse = processDefinitionPage.queryProcessDefinitionByName(loginUser, projectCode, processDefinitionName); + HttpResponse queryProcessDefinitionByNameResponse = + processDefinitionPage.queryProcessDefinitionByName(loginUser, projectCode, processDefinitionName); Assertions.assertTrue(queryProcessDefinitionByNameResponse.getBody().getSuccess()); - Assertions.assertTrue(queryProcessDefinitionByNameResponse.getBody().getData().toString().contains("hello world")); + Assertions.assertTrue( + queryProcessDefinitionByNameResponse.getBody().getData().toString().contains("hello world")); } @Test @Order(6) public void testQueryProcessDefinitionList() { - HttpResponse queryProcessDefinitionListResponse = processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode); + HttpResponse queryProcessDefinitionListResponse = + processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode); Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getSuccess()); - Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world")); + Assertions + .assertTrue(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world")); } @Test @Order(7) public void testReleaseProcessDefinition() { - HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); + HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, + projectCode, processDefinitionCode, ReleaseState.ONLINE); Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); - HttpResponse queryProcessDefinitionByCodeResponse = processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); + HttpResponse queryProcessDefinitionByCodeResponse = + processDefinitionPage.queryProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getSuccess()); - Assertions.assertTrue(queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("releaseState=ONLINE")); + Assertions.assertTrue( + queryProcessDefinitionByCodeResponse.getBody().getData().toString().contains("releaseState=ONLINE")); } @Test @Order(8) public void testDeleteProcessDefinitionByCode() { - HttpResponse deleteProcessDefinitionByCodeResponse = processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); + HttpResponse deleteProcessDefinitionByCodeResponse = + processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); Assertions.assertFalse(deleteProcessDefinitionByCodeResponse.getBody().getSuccess()); - HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.OFFLINE); + HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, + projectCode, processDefinitionCode, ReleaseState.OFFLINE); Assertions.assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); - deleteProcessDefinitionByCodeResponse = processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); + deleteProcessDefinitionByCodeResponse = + processDefinitionPage.deleteProcessDefinitionByCode(loginUser, projectCode, processDefinitionCode); Assertions.assertTrue(deleteProcessDefinitionByCodeResponse.getBody().getSuccess()); - HttpResponse queryProcessDefinitionListResponse = processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode); + HttpResponse queryProcessDefinitionListResponse = + processDefinitionPage.queryProcessDefinitionList(loginUser, projectCode); Assertions.assertTrue(queryProcessDefinitionListResponse.getBody().getSuccess()); - Assertions.assertFalse(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world")); + Assertions + .assertFalse(queryProcessDefinitionListResponse.getBody().getData().toString().contains("hello world")); } } - - diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessInstanceAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessInstanceAPITest.java index 0c939bb0fb28f..1ddc2f8275b97 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessInstanceAPITest.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProcessInstanceAPITest.java @@ -48,6 +48,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -55,8 +57,6 @@ import org.junit.jupiter.api.Test; import org.testcontainers.shaded.org.awaitility.Awaitility; -import lombok.extern.slf4j.Slf4j; - @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @Slf4j public class ProcessInstanceAPITest { @@ -89,7 +89,8 @@ public class ProcessInstanceAPITest { public static void setup() { LoginPage loginPage = new LoginPage(); HttpResponse loginHttpResponse = loginPage.login(username, password); - sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); + sessionId = + JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); processInstancePage = new ProcessInstancePage(sessionId); executorPage = new ExecutorPage(sessionId); processDefinitionPage = new ProcessDefinitionPage(sessionId); @@ -113,24 +114,30 @@ public void testQueryProcessInstancesByTriggerCode() { HttpResponse createProjectResponse = projectPage.createProject(loginUser, "project-test"); HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); assertTrue(queryAllProjectListResponse.getBody().getSuccess()); - projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); + projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse + .getBody().getData()).get(0)).get("code"); // upload test workflow definition json ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); CloseableHttpResponse importProcessDefinitionResponse = processDefinitionPage - .importProcessDefinition(loginUser, projectCode, file); + .importProcessDefinition(loginUser, projectCode, file); String data = EntityUtils.toString(importProcessDefinitionResponse.getEntity()); assertTrue(data.contains("\"success\":true")); // get workflow definition code - HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); + HttpResponse queryAllProcessDefinitionByProjectCodeResponse = + processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); - assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString().contains("hello world")); - processDefinitionCode = (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); + assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getData().toString() + .contains("hello world")); + processDefinitionCode = + (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse + .getBody().getData()).get(0)).get("processDefinition")).get("code"); // release test workflow - HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); + HttpResponse releaseProcessDefinitionResponse = processDefinitionPage.releaseProcessDefinition(loginUser, + projectCode, processDefinitionCode, ReleaseState.ONLINE); assertTrue(releaseProcessDefinitionResponse.getBody().getSuccess()); // trigger workflow instance @@ -138,23 +145,27 @@ public void testQueryProcessInstancesByTriggerCode() { Date date = new Date(); String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date)); log.info("use current time {} as scheduleTime", scheduleTime); - HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode, processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE); + HttpResponse startProcessInstanceResponse = executorPage.startProcessInstance(loginUser, projectCode, + processDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE); assertTrue(startProcessInstanceResponse.getBody().getSuccess()); // make sure process instance has completed and successfully persisted into db Awaitility.await() - .atMost(30, TimeUnit.SECONDS) - .untilAsserted(() -> { - // query workflow instance by trigger code - triggerCode = (long) startProcessInstanceResponse.getBody().getData(); - HttpResponse queryProcessInstancesByTriggerCodeResponse = processInstancePage.queryProcessInstancesByTriggerCode(loginUser, projectCode, triggerCode); - assertTrue(queryProcessInstancesByTriggerCodeResponse.getBody().getSuccess()); - List> body = (List>) queryProcessInstancesByTriggerCodeResponse.getBody().getData(); - assertTrue(CollectionUtils.isNotEmpty(body)); - assertEquals("SUCCESS", body.get(0).get("state")); - processInstanceId = (int) body.get(0).get("id"); - }); - } catch (Exception e) { + .atMost(30, TimeUnit.SECONDS) + .untilAsserted(() -> { + // query workflow instance by trigger code + triggerCode = (long) startProcessInstanceResponse.getBody().getData(); + HttpResponse queryProcessInstancesByTriggerCodeResponse = processInstancePage + .queryProcessInstancesByTriggerCode(loginUser, projectCode, triggerCode); + assertTrue(queryProcessInstancesByTriggerCodeResponse.getBody().getSuccess()); + List> body = + (List>) queryProcessInstancesByTriggerCodeResponse + .getBody().getData(); + assertTrue(CollectionUtils.isNotEmpty(body)); + assertEquals("SUCCESS", body.get(0).get("state")); + processInstanceId = (int) body.get(0).get("id"); + }); + } catch (Exception e) { log.error("failed", e); Assertions.fail(); } @@ -163,7 +174,8 @@ public void testQueryProcessInstancesByTriggerCode() { @Test @Order(2) public void testQueryProcessInstanceList() { - HttpResponse queryProcessInstanceListResponse = processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10); + HttpResponse queryProcessInstanceListResponse = + processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10); assertTrue(queryProcessInstanceListResponse.getBody().getSuccess()); assertTrue(queryProcessInstanceListResponse.getBody().getData().toString().contains("test_import")); } @@ -171,7 +183,8 @@ public void testQueryProcessInstanceList() { @Test @Order(3) public void testQueryTaskListByProcessId() { - HttpResponse queryTaskListByProcessIdResponse = processInstancePage.queryTaskListByProcessId(loginUser, projectCode, processInstanceId); + HttpResponse queryTaskListByProcessIdResponse = + processInstancePage.queryTaskListByProcessId(loginUser, projectCode, processInstanceId); assertTrue(queryTaskListByProcessIdResponse.getBody().getSuccess()); assertTrue(queryTaskListByProcessIdResponse.getBody().getData().toString().contains("test_import")); } @@ -179,7 +192,8 @@ public void testQueryTaskListByProcessId() { @Test @Order(4) public void testQueryProcessInstanceById() { - HttpResponse queryProcessInstanceByIdResponse = processInstancePage.queryProcessInstanceById(loginUser, projectCode, processInstanceId); + HttpResponse queryProcessInstanceByIdResponse = + processInstancePage.queryProcessInstanceById(loginUser, projectCode, processInstanceId); assertTrue(queryProcessInstanceByIdResponse.getBody().getSuccess()); assertTrue(queryProcessInstanceByIdResponse.getBody().getData().toString().contains("test_import")); } @@ -187,10 +201,12 @@ public void testQueryProcessInstanceById() { @Test @Order(5) public void testDeleteProcessInstanceById() { - HttpResponse deleteProcessInstanceByIdResponse = processInstancePage.deleteProcessInstanceById(loginUser, projectCode, processInstanceId); + HttpResponse deleteProcessInstanceByIdResponse = + processInstancePage.deleteProcessInstanceById(loginUser, projectCode, processInstanceId); assertTrue(deleteProcessInstanceByIdResponse.getBody().getSuccess()); - HttpResponse queryProcessInstanceListResponse = processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10); + HttpResponse queryProcessInstanceListResponse = + processInstancePage.queryProcessInstanceList(loginUser, projectCode, 1, 10); assertTrue(queryProcessInstanceListResponse.getBody().getSuccess()); Assertions.assertFalse(queryProcessInstanceListResponse.getBody().getData().toString().contains("test_import")); } diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProjectAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProjectAPITest.java index 40caa45a31828..cf5621f06c37f 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProjectAPITest.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/ProjectAPITest.java @@ -29,17 +29,17 @@ import org.apache.dolphinscheduler.dao.entity.Project; import org.apache.dolphinscheduler.dao.entity.User; +import java.util.LinkedHashMap; +import java.util.List; + +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import lombok.extern.slf4j.Slf4j; - -import java.util.LinkedHashMap; -import java.util.List; - @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @Slf4j // TODO: Add more detailed permission control related cases after userPage test cases completed @@ -59,7 +59,8 @@ public class ProjectAPITest { public static void setup() { LoginPage loginPage = new LoginPage(); HttpResponse loginHttpResponse = loginPage.login(username, password); - sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); + sessionId = + JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); projectPage = new ProjectPage(sessionId); loginUser = new User(); loginUser.setUserName("admin"); @@ -98,7 +99,8 @@ public void testUpdateProject() { List projects = (List) queryAllProjectListResponse.getBody().getData(); Long code = (Long) projects.get(0).get("code"); - HttpResponse updateProjectResponse = projectPage.updateProject(loginUser, code,"project-new", loginUser.getUserName()); + HttpResponse updateProjectResponse = + projectPage.updateProject(loginUser, code, "project-new", loginUser.getUserName()); Assertions.assertTrue(updateProjectResponse.getBody().getSuccess()); queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); @@ -133,17 +135,21 @@ public void testQueryProjectListPaging() { @Test @Order(6) public void testQueryProjectWithAuthorizedLevelListPaging() { - HttpResponse queryProjectWithAuthorizedLevelListPagingResponse = projectPage.queryProjectWithAuthorizedLevelListPaging(loginUser, loginUser.getId(),1, 1); + HttpResponse queryProjectWithAuthorizedLevelListPagingResponse = + projectPage.queryProjectWithAuthorizedLevelListPaging(loginUser, loginUser.getId(), 1, 1); Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getSuccess()); - Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getData().toString().contains("project-new")); + Assertions.assertTrue(queryProjectWithAuthorizedLevelListPagingResponse.getBody().getData().toString() + .contains("project-new")); } @Test @Order(7) public void testQueryUnauthorizedProject() { - HttpResponse queryUnauthorizedProjectResponse = projectPage.queryUnauthorizedProject(loginUser, loginUser.getId()); + HttpResponse queryUnauthorizedProjectResponse = + projectPage.queryUnauthorizedProject(loginUser, loginUser.getId()); Assertions.assertTrue(queryUnauthorizedProjectResponse.getBody().getSuccess()); - // project-new was created by instead of authorized to this user, therefore, it should be in the unauthorized list + // project-new was created by instead of authorized to this user, therefore, it should be in the unauthorized + // list Assertions.assertTrue(queryUnauthorizedProjectResponse.getBody().getData().toString().contains("project-new")); } @@ -152,17 +158,21 @@ public void testQueryUnauthorizedProject() { public void testQueryAuthorizedProject() { HttpResponse queryAuthorizedProjectResponse = projectPage.queryAuthorizedProject(loginUser, loginUser.getId()); Assertions.assertTrue(queryAuthorizedProjectResponse.getBody().getSuccess()); - // project-new was created by instead of authorized to this user, therefore, it should not be in the authorized list + // project-new was created by instead of authorized to this user, therefore, it should not be in the authorized + // list Assertions.assertFalse(queryAuthorizedProjectResponse.getBody().getData().toString().contains("project-new")); } @Test @Order(9) public void testQueryProjectWithAuthorizedLevel() { - HttpResponse queryProjectWithAuthorizedLevelResponse = projectPage.queryProjectWithAuthorizedLevel(loginUser, loginUser.getId()); + HttpResponse queryProjectWithAuthorizedLevelResponse = + projectPage.queryProjectWithAuthorizedLevel(loginUser, loginUser.getId()); Assertions.assertTrue(queryProjectWithAuthorizedLevelResponse.getBody().getSuccess()); - // queryProjectWithAuthorizedLevel api returns a joint-set of projects both created by and authorized to the user - Assertions.assertTrue(queryProjectWithAuthorizedLevelResponse.getBody().getData().toString().contains("project-new")); + // queryProjectWithAuthorizedLevel api returns a joint-set of projects both created by and authorized to the + // user + Assertions.assertTrue( + queryProjectWithAuthorizedLevelResponse.getBody().getData().toString().contains("project-new")); } @Test @@ -181,10 +191,13 @@ public void testQueryAuthorizedUser() { @Test @Order(11) public void testQueryProjectCreatedAndAuthorizedByUser() { - HttpResponse queryProjectCreatedAndAuthorizedByUserResponse = projectPage.queryProjectCreatedAndAuthorizedByUser(loginUser); + HttpResponse queryProjectCreatedAndAuthorizedByUserResponse = + projectPage.queryProjectCreatedAndAuthorizedByUser(loginUser); Assertions.assertTrue(queryProjectCreatedAndAuthorizedByUserResponse.getBody().getSuccess()); - // queryProjectCreatedAndAuthorizedByUser api returns a joint-set of projects both created by and authorized to the user - Assertions.assertTrue(queryProjectCreatedAndAuthorizedByUserResponse.getBody().getData().toString().contains("project-new")); + // queryProjectCreatedAndAuthorizedByUser api returns a joint-set of projects both created by and authorized to + // the user + Assertions.assertTrue( + queryProjectCreatedAndAuthorizedByUserResponse.getBody().getData().toString().contains("project-new")); } @Test @@ -192,7 +205,8 @@ public void testQueryProjectCreatedAndAuthorizedByUser() { public void testQueryAllProjectListForDependent() { HttpResponse queryAllProjectListForDependentResponse = projectPage.queryAllProjectListForDependent(loginUser); Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getSuccess()); - Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new")); + Assertions.assertTrue( + queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new")); } @Test @@ -203,8 +217,7 @@ public void testDeleteProject() { Long code = (Long) projects.get(0).get("code"); HttpResponse queryAllProjectListForDependentResponse = projectPage.deleteProject(loginUser, code); Assertions.assertTrue(queryAllProjectListForDependentResponse.getBody().getSuccess()); - Assertions.assertFalse(queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new")); + Assertions.assertFalse( + queryAllProjectListForDependentResponse.getBody().getData().toString().contains("project-new")); } } - - diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/SchedulerAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/SchedulerAPITest.java index ac06afefc6f47..9d02acfd28bde 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/SchedulerAPITest.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/SchedulerAPITest.java @@ -35,14 +35,14 @@ import java.util.LinkedHashMap; import java.util.List; +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import lombok.extern.slf4j.Slf4j; - @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @Slf4j public class SchedulerAPITest { @@ -67,12 +67,12 @@ public class SchedulerAPITest { private static int scheduleId; - @BeforeAll public static void setup() { LoginPage loginPage = new LoginPage(); HttpResponse loginHttpResponse = loginPage.login(username, password); - sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); + sessionId = + JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); projectPage = new ProjectPage(sessionId); schedulerPage = new SchedulerPage(sessionId); processDefinitionPage = new ProcessDefinitionPage(sessionId); @@ -94,17 +94,24 @@ public void testCreateSchedule() { HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser); Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess()); - projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse.getBody().getData()).get(0)).get("code"); + projectCode = (long) ((LinkedHashMap) ((List) queryAllProjectListResponse + .getBody().getData()).get(0)).get("code"); ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("workflow-json/test.json").getFile()); processDefinitionPage.importProcessDefinition(loginUser, projectCode, file); - HttpResponse queryAllProcessDefinitionByProjectCodeResponse = processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); + HttpResponse queryAllProcessDefinitionByProjectCodeResponse = + processDefinitionPage.queryAllProcessDefinitionByProjectCode(loginUser, projectCode); Assertions.assertTrue(queryAllProcessDefinitionByProjectCodeResponse.getBody().getSuccess()); - processDefinitionCode = (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse.getBody().getData()).get(0)).get("processDefinition")).get("code"); - - processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, ReleaseState.ONLINE); - final String schedule = "{\"startTime\":\"2019-08-08 00:00:00\",\"endTime\":\"2100-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}" ; - HttpResponse createScheduleResponse = schedulerPage.createSchedule(loginUser, projectCode, processDefinitionCode, schedule); + processDefinitionCode = + (long) ((LinkedHashMap) ((LinkedHashMap) ((List) queryAllProcessDefinitionByProjectCodeResponse + .getBody().getData()).get(0)).get("processDefinition")).get("code"); + + processDefinitionPage.releaseProcessDefinition(loginUser, projectCode, processDefinitionCode, + ReleaseState.ONLINE); + final String schedule = + "{\"startTime\":\"2019-08-08 00:00:00\",\"endTime\":\"2100-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}"; + HttpResponse createScheduleResponse = + schedulerPage.createSchedule(loginUser, projectCode, processDefinitionCode, schedule); Assertions.assertTrue(createScheduleResponse.getBody().getSuccess()); Assertions.assertTrue(createScheduleResponse.getBody().getData().toString().contains("2019-08-08")); } @@ -115,13 +122,15 @@ public void testQueryScheduleList() { HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess()); Assertions.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("2019-08-08")); - scheduleId = (int) ((LinkedHashMap) ((List) queryScheduleListResponse.getBody().getData()).get(0)).get("id"); + scheduleId = (int) ((LinkedHashMap) ((List) queryScheduleListResponse.getBody() + .getData()).get(0)).get("id"); } @Test @Order(3) public void testPublishScheduleOnline() { - HttpResponse publishScheduleOnlineResponse = schedulerPage.publishScheduleOnline(loginUser, projectCode, scheduleId); + HttpResponse publishScheduleOnlineResponse = + schedulerPage.publishScheduleOnline(loginUser, projectCode, scheduleId); Assertions.assertTrue(publishScheduleOnlineResponse.getBody().getSuccess()); HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); @@ -137,14 +146,17 @@ public void testOfflineSchedule() { HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); Assertions.assertTrue(queryScheduleListResponse.getBody().getSuccess()); - Assertions.assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("releaseState=OFFLINE")); + Assertions + .assertTrue(queryScheduleListResponse.getBody().getData().toString().contains("releaseState=OFFLINE")); } @Test @Order(5) public void testUpdateSchedule() { - final String schedule = "{\"startTime\":\"1996-08-08 00:00:00\",\"endTime\":\"2200-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}"; - HttpResponse updateScheduleResponse = schedulerPage.updateSchedule(loginUser, projectCode, scheduleId, schedule); + final String schedule = + "{\"startTime\":\"1996-08-08 00:00:00\",\"endTime\":\"2200-08-08 00:00:00\",\"timezoneId\":\"America/Phoenix\",\"crontab\":\"0 0 3/6 * * ? *\"}"; + HttpResponse updateScheduleResponse = + schedulerPage.updateSchedule(loginUser, projectCode, scheduleId, schedule); Assertions.assertTrue(updateScheduleResponse.getBody().getSuccess()); HttpResponse queryScheduleListResponse = schedulerPage.queryScheduleList(loginUser, projectCode); @@ -163,5 +175,3 @@ public void testDeleteScheduleById() { Assertions.assertFalse(queryScheduleListResponse.getBody().getData().toString().contains("1996-08-08")); } } - - diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/TenantAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/TenantAPITest.java index 76dbd21cdc9f3..2f8e6aa056a5d 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/TenantAPITest.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/TenantAPITest.java @@ -28,17 +28,18 @@ import org.apache.dolphinscheduler.api.test.pages.security.TenantPage; import org.apache.dolphinscheduler.api.test.utils.JSONUtils; +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import lombok.extern.slf4j.Slf4j; - @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @Slf4j public class TenantAPITest { + private static final String tenant = System.getProperty("user.name"); private static final String user = "admin"; @@ -54,7 +55,8 @@ public static void setup() { LoginPage loginPage = new LoginPage(); HttpResponse loginHttpResponse = loginPage.login(user, password); - sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); + sessionId = + JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); } @AfterAll @@ -90,7 +92,9 @@ public void testGetTenantListPaging() { HttpResponse createTenantHttpResponse = tenantPage.getTenantListPaging(sessionId, 1, 10, ""); boolean result = false; - for (TenantListPagingResponseTotalList tenantListPagingResponseTotalList : JSONUtils.convertValue(createTenantHttpResponse.getBody().getData(), TenantListPagingResponseData.class).getTotalList()) { + for (TenantListPagingResponseTotalList tenantListPagingResponseTotalList : JSONUtils + .convertValue(createTenantHttpResponse.getBody().getData(), TenantListPagingResponseData.class) + .getTotalList()) { if (tenantListPagingResponseTotalList.getTenantCode().equals(tenant)) { result = true; existTenantId = tenantListPagingResponseTotalList.getId(); diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/WorkerGroupAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/WorkerGroupAPITest.java index a83dea06e1a32..d34f6bad2d3a7 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/WorkerGroupAPITest.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/WorkerGroupAPITest.java @@ -33,14 +33,14 @@ import java.util.List; import java.util.Set; +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import lombok.extern.slf4j.Slf4j; - @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @Slf4j public class WorkerGroupAPITest { @@ -59,7 +59,8 @@ public class WorkerGroupAPITest { public static void setup() { LoginPage loginPage = new LoginPage(); HttpResponse loginHttpResponse = loginPage.login(username, password); - sessionId = JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); + sessionId = + JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId(); workerGroupPage = new WorkerGroupPage(sessionId); loginUser = new User(); loginUser.setId(123); @@ -75,7 +76,7 @@ public static void cleanup() { @Order(1) public void testSaveWorkerGroup() { HttpResponse saveWorkerGroupHttpResponse = workerGroupPage - .saveWorkerGroup(loginUser, 1, "test_worker_group", "10.5.0.5:1234", "test", null); + .saveWorkerGroup(loginUser, 1, "test_worker_group", "10.5.0.5:1234", "test", null); Assertions.assertTrue(saveWorkerGroupHttpResponse.getBody().getSuccess()); HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser); @@ -88,9 +89,10 @@ public void testSaveWorkerGroup() { @Test @Order(2) public void testQueryAllWorkerGroupsPaging() { - HttpResponse queryAllWorkerGroupsPagingResponse = workerGroupPage.queryAllWorkerGroupsPaging(loginUser, 1, 2, null); + HttpResponse queryAllWorkerGroupsPagingResponse = + workerGroupPage.queryAllWorkerGroupsPaging(loginUser, 1, 2, null); Assertions.assertTrue(queryAllWorkerGroupsPagingResponse.getBody().getSuccess()); - String workerGroupPageInfoData = queryAllWorkerGroupsPagingResponse.getBody().getData().toString(); + String workerGroupPageInfoData = queryAllWorkerGroupsPagingResponse.getBody().getData().toString(); Assertions.assertTrue(workerGroupPageInfoData.contains("test_worker_group")); } @@ -100,7 +102,7 @@ public void testQueryAllWorkerGroups() { HttpResponse queryAllWorkerGroupsResponse = workerGroupPage.queryAllWorkerGroups(loginUser); Assertions.assertTrue(queryAllWorkerGroupsResponse.getBody().getSuccess()); - String workerGroupPageInfoData = queryAllWorkerGroupsResponse.getBody().getData().toString(); + String workerGroupPageInfoData = queryAllWorkerGroupsResponse.getBody().getData().toString(); Assertions.assertTrue(workerGroupPageInfoData.contains("test_worker_group")); } diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseData.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseData.java index 415d711ebc3cb..5577f58b3f56a 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseData.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseData.java @@ -29,6 +29,7 @@ @NoArgsConstructor @Data public class TenantListPagingResponseData { + private Integer currentPage; private Integer pageSize; diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseTotalList.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseTotalList.java index e75196af8eed1..25abbeb056100 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseTotalList.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/entity/TenantListPagingResponseTotalList.java @@ -29,6 +29,7 @@ @NoArgsConstructor @Data public class TenantListPagingResponseTotalList { + private Date createTime; private Date updateTime; diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/LoginPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/LoginPage.java index a94231329831f..8b40b080c6e53 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/LoginPage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/LoginPage.java @@ -26,6 +26,7 @@ import java.util.Map; public final class LoginPage { + public HttpResponse login(String username, String password) { Map params = new HashMap<>(); diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/project/ProjectPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/project/ProjectPage.java index b5f0a31bfc4f9..efd84c2ada946 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/project/ProjectPage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/project/ProjectPage.java @@ -19,8 +19,6 @@ package org.apache.dolphinscheduler.api.test.pages.project; -import lombok.AllArgsConstructor; - import org.apache.dolphinscheduler.api.test.core.Constants; import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.utils.RequestClient; @@ -29,8 +27,11 @@ import java.util.HashMap; import java.util.Map; +import lombok.AllArgsConstructor; + @AllArgsConstructor public final class ProjectPage { + private String sessionId; public HttpResponse createProject(User loginUser, String projectName) { @@ -90,7 +91,8 @@ public HttpResponse queryProjectListPaging(User loginUser, Integer pageSize, Int return requestClient.get("/projects", headers, params); } - public HttpResponse queryProjectWithAuthorizedLevelListPaging(User loginUser, Integer userId, Integer pageSize, Integer pageNo) { + public HttpResponse queryProjectWithAuthorizedLevelListPaging(User loginUser, Integer userId, Integer pageSize, + Integer pageNo) { Map params = new HashMap<>(); params.put("loginUser", loginUser); params.put("userId", userId); diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/TenantPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/TenantPage.java index 1d1d74de4990e..6c4b4733629c6 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/TenantPage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/TenantPage.java @@ -27,6 +27,7 @@ import java.util.Map; public final class TenantPage { + public HttpResponse createTenant(String sessionId, String tenant, Integer queueId, String description) { Map params = new HashMap<>(); params.put("tenantCode", tenant); diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/WorkerGroupPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/WorkerGroupPage.java index 9d6185fd9a02f..1d34d7e763328 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/WorkerGroupPage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/security/WorkerGroupPage.java @@ -19,8 +19,6 @@ package org.apache.dolphinscheduler.api.test.pages.security; -import lombok.AllArgsConstructor; - import org.apache.dolphinscheduler.api.test.core.Constants; import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.utils.RequestClient; @@ -29,13 +27,15 @@ import java.util.HashMap; import java.util.Map; +import lombok.AllArgsConstructor; @AllArgsConstructor public class WorkerGroupPage { private String sessionId; - public HttpResponse saveWorkerGroup(User loginUser, int id, String name, String addrList, String description, String otherParamsJson) { + public HttpResponse saveWorkerGroup(User loginUser, int id, String name, String addrList, String description, + String otherParamsJson) { Map params = new HashMap<>(); params.put("loginUser", loginUser); params.put("id", id); @@ -96,5 +96,4 @@ public HttpResponse queryWorkerAddressList(User loginUser) { return requestClient.get("/worker-groups/worker-address-list", headers, params); } - } diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ExecutorPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ExecutorPage.java index 7ae09cafeaa4b..1318aa6f3e213 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ExecutorPage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ExecutorPage.java @@ -34,14 +34,15 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; - @Slf4j @AllArgsConstructor public class ExecutorPage { private String sessionId; - public HttpResponse startProcessInstance(User loginUser, long projectCode, long processDefinitionCode, String scheduleTime, FailureStrategy failureStrategy, WarningType warningType) { + public HttpResponse startProcessInstance(User loginUser, long projectCode, long processDefinitionCode, + String scheduleTime, FailureStrategy failureStrategy, + WarningType warningType) { Map params = new HashMap<>(); params.put("loginUser", loginUser); params.put("processDefinitionCode", processDefinitionCode); @@ -93,7 +94,8 @@ public HttpResponse startCheckProcessDefinition(User loginUser, long projectCode return requestClient.post(url, headers, params); } - public HttpResponse executeTask(User loginUser, long projectCode, int processInstanceId, String startNodeList, TaskDependType taskDependType) { + public HttpResponse executeTask(User loginUser, long projectCode, int processInstanceId, String startNodeList, + TaskDependType taskDependType) { Map params = new HashMap<>(); params.put("loginUser", loginUser); params.put("processInstanceId", processInstanceId); @@ -107,4 +109,4 @@ public HttpResponse executeTask(User loginUser, long projectCode, int processIns return requestClient.post(url, headers, params); } -} \ No newline at end of file +} diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessDefinitionPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessDefinitionPage.java index ef72e997ae59a..3f3b715c39b2a 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessDefinitionPage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessDefinitionPage.java @@ -25,6 +25,8 @@ import org.apache.dolphinscheduler.common.enums.ReleaseState; import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.http.client.methods.CloseableHttpResponse; + import java.io.File; import java.util.HashMap; import java.util.Map; @@ -32,9 +34,6 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.http.client.methods.CloseableHttpResponse; - - @Slf4j @AllArgsConstructor public class ProcessDefinitionPage { @@ -107,7 +106,8 @@ public HttpResponse queryProcessDefinitionList(User loginUser, long projectCode) return requestClient.get(url, headers, params); } - public HttpResponse releaseProcessDefinition(User loginUser, long projectCode, long code, ReleaseState releaseState) { + public HttpResponse releaseProcessDefinition(User loginUser, long projectCode, long code, + ReleaseState releaseState) { Map params = new HashMap<>(); params.put("loginUser", loginUser); params.put("code", code); diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessInstancePage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessInstancePage.java index e07e1166b1c0a..eba4e6303650a 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessInstancePage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/ProcessInstancePage.java @@ -19,13 +19,9 @@ package org.apache.dolphinscheduler.api.test.pages.workflow; -import org.apache.dolphinscheduler.api.enums.ExecuteType; import org.apache.dolphinscheduler.api.test.core.Constants; import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.utils.RequestClient; -import org.apache.dolphinscheduler.common.enums.FailureStrategy; -import org.apache.dolphinscheduler.common.enums.TaskDependType; -import org.apache.dolphinscheduler.common.enums.WarningType; import org.apache.dolphinscheduler.dao.entity.User; import java.util.HashMap; @@ -34,7 +30,6 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; - @Slf4j @AllArgsConstructor public class ProcessInstancePage { diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/SchedulerPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/SchedulerPage.java index cfe23fd1bbc9d..d6b3b9a74382c 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/SchedulerPage.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/SchedulerPage.java @@ -30,7 +30,6 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; - @Slf4j @AllArgsConstructor public class SchedulerPage { @@ -63,7 +62,6 @@ public HttpResponse queryScheduleList(User loginUser, long projectCode) { return requestClient.post(url, headers, params); } - public HttpResponse publishScheduleOnline(User loginUser, long projectCode, int scheduleId) { Map params = new HashMap<>(); params.put("loginUser", loginUser); diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/JSONUtils.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/JSONUtils.java index 0d9a9b97429db..3a25c927ffb56 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/JSONUtils.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/JSONUtils.java @@ -17,12 +17,11 @@ package org.apache.dolphinscheduler.api.test.utils; -import static java.nio.charset.StandardCharsets.UTF_8; - import static com.fasterxml.jackson.databind.DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT; import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; import static com.fasterxml.jackson.databind.DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL; import static com.fasterxml.jackson.databind.MapperFeature.REQUIRE_SETTERS_FOR_GETTERS; +import static java.nio.charset.StandardCharsets.UTF_8; import org.apache.dolphinscheduler.api.test.core.Constants; @@ -72,8 +71,11 @@ public class JSONUtils { * can use static singleton, inject: just make sure to reuse! */ private static final ObjectMapper objectMapper = - new ObjectMapper().configure(FAIL_ON_UNKNOWN_PROPERTIES, false).configure(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true).configure(READ_UNKNOWN_ENUM_VALUES_AS_NULL, true) - .configure(REQUIRE_SETTERS_FOR_GETTERS, true).setTimeZone(TimeZone.getDefault()).setDateFormat(new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS)); + new ObjectMapper().configure(FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true) + .configure(READ_UNKNOWN_ENUM_VALUES_AS_NULL, true) + .configure(REQUIRE_SETTERS_FOR_GETTERS, true).setTimeZone(TimeZone.getDefault()) + .setDateFormat(new SimpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS)); private JSONUtils() { throw new UnsupportedOperationException("Construct JSONUtils"); diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/RequestClient.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/RequestClient.java index 2993ea8de3f4b..b04511f250d83 100644 --- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/RequestClient.java +++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/utils/RequestClient.java @@ -23,6 +23,15 @@ import org.apache.dolphinscheduler.api.test.entity.HttpResponse; import org.apache.dolphinscheduler.api.test.entity.HttpResponseBody; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicHeader; + import java.io.File; import java.io.FileInputStream; import java.util.HashMap; @@ -39,17 +48,6 @@ import okhttp3.RequestBody; import okhttp3.Response; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicHeader; -import org.apache.http.util.EntityUtils; - - @Slf4j public class RequestClient { @@ -70,10 +68,10 @@ public HttpResponse get(String url, Map headers, Map headers, Map headers, Map headers, Map headers, Map params, File file) { + public CloseableHttpResponse postWithFile(String url, Map headers, Map params, + File file) { try { Headers headersBuilder = Headers.of(headers); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.addTextBody("json", getParams(params), ContentType.MULTIPART_FORM_DATA); builder.addBinaryBody( - "file", - new FileInputStream(file), - ContentType.APPLICATION_OCTET_STREAM, - file.getName() - ); + "file", + new FileInputStream(file), + ContentType.APPLICATION_OCTET_STREAM, + file.getName()); HttpEntity multipart = builder.build(); String requestUrl = String.format("%s%s", Constants.DOLPHINSCHEDULER_API_URL, url); log.info("POST request to {}, Headers: {}, Params: {}", requestUrl, headersBuilder, params); @@ -199,7 +197,6 @@ public CloseableHttpResponse postWithFile(String url, Map header return null; } - @SneakyThrows public HttpResponse delete(String url, Map headers, Map params) { if (headers == null) { @@ -214,10 +211,10 @@ public HttpResponse delete(String url, Map headers, Map createDockerCompose(ExtensionContext context) .withPull(true) .withTailChildContainers(true) .withLogConsumer(serviceName, outputFrame -> log.info(outputFrame.getUtf8String())) - .waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(Constants.DOCKER_COMPOSE_DEFAULT_TIMEOUT))); + .waitingFor(serviceName, Wait.forHealthcheck() + .withStartupTimeout(Duration.ofSeconds(Constants.DOCKER_COMPOSE_DEFAULT_TIMEOUT))); return compose; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java index 412b5f6a8a2df..09d8fa4ea824e 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClickhouseDataSourceE2ETest.java @@ -1,112 +1,107 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.dolphinscheduler.e2e.cases; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; -import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; -import org.apache.dolphinscheduler.e2e.pages.LoginPage; -import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; - -import java.time.Duration; - -import org.testcontainers.shaded.org.awaitility.Awaitility; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - - -@DolphinScheduler(composeFiles = "docker/datasource-clickhouse/docker-compose.yaml") -public class ClickhouseDataSourceE2ETest { - private static RemoteWebDriver browser; - - private static final String tenant = System.getProperty("user.name"); - - private static final String user = "admin"; - - private static final String password = "dolphinscheduler123"; - - private static final String dataSourceType = "CLICKHOUSE"; - - private static final String dataSourceName = "clickhouse_test"; - - private static final String dataSourceDescription = "clickhouse_test"; - - private static final String ip = "clickhouse"; - - private static final String port = "8123"; - - private static final String userName = "ch_test"; - - private static final String pgPassword = "ch_test"; - - private static final String database = "ch_test"; - - private static final String jdbcParams = ""; - - - @BeforeAll - public static void setup() { - new LoginPage(browser) - .login(user, password) - .goToNav(DataSourcePage.class); - } - - @Test - @Order(10) - void testCreateClickhouseDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); - - WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( - new By.ByClassName("dialog-create-data-source"))); - - Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) - .as("DataSource list should contain newly-created database") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(dataSourceName))); - } - - @Test - @Order(20) - void testDeleteClickhouseDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.delete(dataSourceName); - - Awaitility.await().untilAsserted(() -> { - browser.navigate().refresh(); - - assertThat( - page.dataSourceItemsList() - ).noneMatch( - it -> it.getText().contains(dataSourceName) - ); - }); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.dolphinscheduler.e2e.cases; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; +import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.testcontainers.shaded.org.awaitility.Awaitility; + +@DolphinScheduler(composeFiles = "docker/datasource-clickhouse/docker-compose.yaml") +public class ClickhouseDataSourceE2ETest { + + private static RemoteWebDriver browser; + + private static final String tenant = System.getProperty("user.name"); + + private static final String user = "admin"; + + private static final String password = "dolphinscheduler123"; + + private static final String dataSourceType = "CLICKHOUSE"; + + private static final String dataSourceName = "clickhouse_test"; + + private static final String dataSourceDescription = "clickhouse_test"; + + private static final String ip = "clickhouse"; + + private static final String port = "8123"; + + private static final String userName = "ch_test"; + + private static final String pgPassword = "ch_test"; + + private static final String database = "ch_test"; + + private static final String jdbcParams = ""; + + @BeforeAll + public static void setup() { + new LoginPage(browser) + .login(user, password) + .goToNav(DataSourcePage.class); + } + + @Test + @Order(10) + void testCreateClickhouseDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, + database, jdbcParams); + + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( + new By.ByClassName("dialog-create-data-source"))); + + Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) + .as("DataSource list should contain newly-created database") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(dataSourceName))); + } + + @Test + @Order(20) + void testDeleteClickhouseDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.delete(dataSourceName); + + Awaitility.await().untilAsserted(() -> { + browser.navigate().refresh(); + + assertThat( + page.dataSourceItemsList()).noneMatch( + it -> it.getText().contains(dataSourceName)); + }); + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClusterE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClusterE2ETest.java index a7e526540bec5..b75b496b5e175 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClusterE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ClusterE2ETest.java @@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.e2e.cases; - import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; @@ -27,13 +26,13 @@ import org.apache.dolphinscheduler.e2e.pages.security.ClusterPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class ClusterE2ETest { @@ -53,8 +52,7 @@ public static void setup() { new LoginPage(browser) .login("admin", "dolphinscheduler123") .goToNav(SecurityPage.class) - .goToTab(ClusterPage.class) - ; + .goToTab(ClusterPage.class); } @Test @@ -78,10 +76,8 @@ void testCreateDuplicateCluster() { final ClusterPage page = new ClusterPage(browser); page.create(clusterName, clusterConfig, clusterDesc); - Awaitility.await().untilAsserted(() -> - assertThat(browser.findElement(By.tagName("body")).getText()) - .contains("already exists") - ); + Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) + .contains("already exists")); page.createClusterForm().buttonCancel().click(); } @@ -112,12 +108,10 @@ void testDeleteCluster() { browser.navigate().refresh(); assertThat( - page.clusterList() - ) - .as("Cluster list should not contain deleted cluster") - .noneMatch( - it -> it.getText().contains(clusterName) || it.getText().contains(editClusterName) - ); + page.clusterList()) + .as("Cluster list should not contain deleted cluster") + .noneMatch( + it -> it.getText().contains(clusterName) || it.getText().contains(editClusterName)); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java index 1e3d848645341..626f2cc44b4a5 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/EnvironmentE2ETest.java @@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.e2e.cases; - import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; @@ -27,13 +26,13 @@ import org.apache.dolphinscheduler.e2e.pages.security.EnvironmentPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class EnvironmentE2ETest { @@ -55,8 +54,7 @@ public static void setup() { new LoginPage(browser) .login("admin", "dolphinscheduler123") .goToNav(SecurityPage.class) - .goToTab(EnvironmentPage.class) - ; + .goToTab(EnvironmentPage.class); } @Test @@ -80,10 +78,8 @@ void testCreateDuplicateEnvironment() { final EnvironmentPage page = new EnvironmentPage(browser); page.create(environmentName, environmentConfig, environmentDesc, environmentWorkerGroup); - Awaitility.await().untilAsserted(() -> - assertThat(browser.findElement(By.tagName("body")).getText()) - .contains("already exists") - ); + Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) + .contains("already exists")); page.createEnvironmentForm().buttonCancel().click(); } @@ -92,7 +88,8 @@ void testCreateDuplicateEnvironment() { @Order(30) void testEditEnvironment() { final EnvironmentPage page = new EnvironmentPage(browser); - page.update(environmentName, editEnvironmentName, editEnvironmentConfig, editEnvironmentDesc, editEnvironmentWorkerGroup); + page.update(environmentName, editEnvironmentName, editEnvironmentConfig, editEnvironmentDesc, + editEnvironmentWorkerGroup); Awaitility.await().untilAsserted(() -> { browser.navigate().refresh(); @@ -114,12 +111,11 @@ void testDeleteEnvironment() { browser.navigate().refresh(); assertThat( - page.environmentList() - ) - .as("Environment list should not contain deleted environment") - .noneMatch( - it -> it.getText().contains(environmentName) || it.getText().contains(editEnvironmentName) - ); + page.environmentList()) + .as("Environment list should not contain deleted environment") + .noneMatch( + it -> it.getText().contains(environmentName) + || it.getText().contains(editEnvironmentName)); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java index ad041b9ac4499..83d45f4531a14 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java @@ -19,7 +19,6 @@ */ package org.apache.dolphinscheduler.e2e.cases; - import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.Constants; @@ -37,10 +36,10 @@ import java.io.RandomAccessFile; import java.nio.file.Files; import java.nio.file.Path; -import java.time.Duration; import java.util.Comparator; -import org.testcontainers.shaded.org.awaitility.Awaitility; +import lombok.SneakyThrows; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; @@ -49,12 +48,11 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.SneakyThrows; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/file-manage/docker-compose.yaml") public class FileManageE2ETest { + private static RemoteWebDriver browser; private static final String tenant = System.getProperty("user.name"); @@ -92,19 +90,19 @@ public static void setup() { .create(tenant); Awaitility.await().untilAsserted(() -> assertThat(tenantPage.tenantList()) - .as("Tenant list should contain newly-created tenant") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(tenant))); + .as("Tenant list should contain newly-created tenant") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(tenant))); UserPage userPage = tenantPage.goToNav(SecurityPage.class) - .goToTab(UserPage.class); + .goToTab(UserPage.class); WebDriverWaitFactory.createWebDriverWait(userPage.driver()).until(ExpectedConditions.visibilityOfElementLocated( new By.ByClassName("name"))); userPage.update(user, user, email, phone, tenant) - .goToNav(ResourcePage.class) - .goToTab(FileManagePage.class); + .goToNav(ResourcePage.class) + .goToTab(FileManagePage.class); } @AfterAll @@ -113,9 +111,9 @@ public static void cleanup() { Files.deleteIfExists(testUnder1GBFilePath); Files.deleteIfExists(testOver1GBFilePath); Files.walk(Constants.HOST_CHROME_DOWNLOAD_PATH) - .sorted(Comparator.reverseOrder()) - .map(Path::toFile) - .forEach(File::delete); + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); } @Test @@ -139,57 +137,57 @@ void testCancelCreateDirectory() { page.cancelCreateDirectory(testDirectoryName); Awaitility.await().untilAsserted(() -> assertThat(page.fileList()) - .as("File list should contain newly-created file") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(testDirectoryName))); + .as("File list should contain newly-created file") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(testDirectoryName))); } -// @Test -// @Order(20) -// void testCreateDuplicateDirectory() { -// final FileManagePage page = new FileManagePage(browser); -// -// page.createDirectory(testDirectoryName, "test_desc"); -// -// await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) -// .contains("resource already exists") -// ); -// -// page.createDirectoryBox().buttonCancel().click(); -// } - -// @Test -// @Order(21) -// void testCreateSubDirectory() { -// final FileManagePage page = new FileManagePage(browser); -// -// page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc"); -// -// await().untilAsserted(() -> assertThat(page.fileList()) -// .as("File list should contain newly-created file") -// .extracting(WebElement::getText) -// .anyMatch(it -> it.contains(testSubDirectoryName))); -// } - -/* -* when the storage is s3,the directory cannot be renamed -* */ -// @Test -// @Order(22) -// void testRenameDirectory() { -// final FileManagePage page = new FileManagePage(browser); -// -// page.rename(testDirectoryName, testRenameDirectoryName); -// -// await().untilAsserted(() -> { -// browser.navigate().refresh(); -// -// assertThat(page.fileList()) -// .as("File list should contain newly-created file") -// .extracting(WebElement::getText) -// .anyMatch(it -> it.contains(testRenameDirectoryName)); -// }); -// } + // @Test + // @Order(20) + // void testCreateDuplicateDirectory() { + // final FileManagePage page = new FileManagePage(browser); + // + // page.createDirectory(testDirectoryName, "test_desc"); + // + // await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) + // .contains("resource already exists") + // ); + // + // page.createDirectoryBox().buttonCancel().click(); + // } + + // @Test + // @Order(21) + // void testCreateSubDirectory() { + // final FileManagePage page = new FileManagePage(browser); + // + // page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc"); + // + // await().untilAsserted(() -> assertThat(page.fileList()) + // .as("File list should contain newly-created file") + // .extracting(WebElement::getText) + // .anyMatch(it -> it.contains(testSubDirectoryName))); + // } + + /* + * when the storage is s3,the directory cannot be renamed + */ + // @Test + // @Order(22) + // void testRenameDirectory() { + // final FileManagePage page = new FileManagePage(browser); + // + // page.rename(testDirectoryName, testRenameDirectoryName); + // + // await().untilAsserted(() -> { + // browser.navigate().refresh(); + // + // assertThat(page.fileList()) + // .as("File list should contain newly-created file") + // .extracting(WebElement::getText) + // .anyMatch(it -> it.contains(testRenameDirectoryName)); + // }); + // } @Test @Order(30) @@ -197,17 +195,15 @@ void testDeleteDirectory() { final FileManagePage page = new FileManagePage(browser); page.goToNav(ResourcePage.class) - .goToTab(FileManagePage.class) - .delete(testDirectoryName); + .goToTab(FileManagePage.class) + .delete(testDirectoryName); Awaitility.await().untilAsserted(() -> { browser.navigate().refresh(); assertThat( - page.fileList() - ).noneMatch( - it -> it.getText().contains(testDirectoryName) - ); + page.fileList()).noneMatch( + it -> it.getText().contains(testDirectoryName)); }); } @@ -220,9 +216,9 @@ void testCreateFile() { page.createFile(testFileName, scripts); Awaitility.await().untilAsserted(() -> assertThat(page.fileList()) - .as("File list should contain newly-created file") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(testFileName))); + .as("File list should contain newly-created file") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(testFileName))); } @Test @@ -236,9 +232,9 @@ void testRenameFile() { browser.navigate().refresh(); assertThat(page.fileList()) - .as("File list should contain newly-created file") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(testRenameFileName)); + .as("File list should contain newly-created file") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(testRenameFileName)); }); } @@ -251,9 +247,9 @@ void testEditFile() { page.editFile(testRenameFileName, scripts); Awaitility.await().untilAsserted(() -> assertThat(page.fileList()) - .as("File list should contain newly-created file") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(testRenameFileName))); + .as("File list should contain newly-created file") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(testRenameFileName))); } @Test @@ -267,10 +263,8 @@ void testDeleteFile() { browser.navigate().refresh(); assertThat( - page.fileList() - ).noneMatch( - it -> it.getText().contains(testRenameFileName) - ); + page.fileList()).noneMatch( + it -> it.getText().contains(testRenameFileName)); }); } @@ -286,13 +280,14 @@ void testUploadUnder1GBFile() throws IOException { page.uploadFile(testUnder1GBFilePath.toFile().getAbsolutePath()); - WebDriverWaitFactory.createWebDriverWait(browser).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog"))); + WebDriverWaitFactory.createWebDriverWait(browser) + .until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog"))); Awaitility.await().untilAsserted(() -> { assertThat(page.fileList()) - .as("File list should contain newly-created file") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(testUnder1GBFileName)); + .as("File list should contain newly-created file") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(testUnder1GBFileName)); }); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java index 3726ec1acdebe..fa9fb809139fd 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/HiveDataSourceE2ETest.java @@ -27,8 +27,6 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; -import java.time.Duration; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -36,11 +34,11 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/datasource-hive/docker-compose.yaml") public class HiveDataSourceE2ETest { + private static RemoteWebDriver browser; private static final String tenant = System.getProperty("user.name"); @@ -70,9 +68,8 @@ public class HiveDataSourceE2ETest { @BeforeAll public static void setup() { new LoginPage(browser) - .login(user, password) - .goToNav(DataSourcePage.class); - + .login(user, password) + .goToNav(DataSourcePage.class); } @@ -81,15 +78,16 @@ public static void setup() { void testCreateHiveDataSource() { final DataSourcePage page = new DataSourcePage(browser); - page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, hivePassword, database, jdbcParams); + page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, hivePassword, + database, jdbcParams); WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( new By.ByClassName("dialog-create-data-source"))); Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) - .as("DataSource list should contain newly-created database") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(dataSourceName))); + .as("DataSource list should contain newly-created database") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(dataSourceName))); } @Test @@ -103,10 +101,8 @@ void testDeleteHiveDataSource() { browser.navigate().refresh(); assertThat( - page.dataSourceItemsList() - ).noneMatch( - it -> it.getText().contains(dataSourceName) - ); + page.dataSourceItemsList()).noneMatch( + it -> it.getText().contains(dataSourceName)); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java index 5c0746a5b5475..faf033f0d0d81 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/MysqlDataSourceE2ETest.java @@ -1,113 +1,108 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.dolphinscheduler.e2e.cases; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; -import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; -import org.apache.dolphinscheduler.e2e.pages.LoginPage; -import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; - -import java.time.Duration; - -import org.testcontainers.shaded.org.awaitility.Awaitility; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - - -@DolphinScheduler(composeFiles = "docker/datasource-mysql/docker-compose.yaml") -public class MysqlDataSourceE2ETest { - private static RemoteWebDriver browser; - - private static final String tenant = System.getProperty("user.name"); - - private static final String user = "admin"; - - private static final String password = "dolphinscheduler123"; - - private static final String dataSourceType = "MYSQL"; - - private static final String dataSourceName = "mysql_test"; - - private static final String dataSourceDescription = "mysql_test"; - - private static final String ip = "mysql"; - - private static final String port = "3306"; - - private static final String userName = "root"; - - private static final String mysqlPassword = "123456"; - - private static final String database = "mysql"; - - private static final String jdbcParams = "{\"useSSL\": false}"; - - - @BeforeAll - public static void setup() { - new LoginPage(browser) - .login(user, password) - .goToNav(DataSourcePage.class); - } - - @Test - @Order(10) - void testCreateMysqlDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, mysqlPassword, database, jdbcParams); - - WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( - new By.ByClassName("dialog-create-data-source"))); - - Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) - .as("DataSource list should contain newly-created database") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(dataSourceName))); - } - - @Test - @Order(20) - void testDeleteMysqlDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.delete(dataSourceName); - - Awaitility.await().untilAsserted(() -> { - browser.navigate().refresh(); - - assertThat( - page.dataSourceItemsList() - ).noneMatch( - it -> it.getText().contains(dataSourceName) - ); - }); - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.dolphinscheduler.e2e.cases; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; +import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.testcontainers.shaded.org.awaitility.Awaitility; + +@DolphinScheduler(composeFiles = "docker/datasource-mysql/docker-compose.yaml") +public class MysqlDataSourceE2ETest { + + private static RemoteWebDriver browser; + + private static final String tenant = System.getProperty("user.name"); + + private static final String user = "admin"; + + private static final String password = "dolphinscheduler123"; + + private static final String dataSourceType = "MYSQL"; + + private static final String dataSourceName = "mysql_test"; + + private static final String dataSourceDescription = "mysql_test"; + + private static final String ip = "mysql"; + + private static final String port = "3306"; + + private static final String userName = "root"; + + private static final String mysqlPassword = "123456"; + + private static final String database = "mysql"; + + private static final String jdbcParams = "{\"useSSL\": false}"; + + @BeforeAll + public static void setup() { + new LoginPage(browser) + .login(user, password) + .goToNav(DataSourcePage.class); + } + + @Test + @Order(10) + void testCreateMysqlDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, mysqlPassword, + database, jdbcParams); + + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( + new By.ByClassName("dialog-create-data-source"))); + + Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) + .as("DataSource list should contain newly-created database") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(dataSourceName))); + } + + @Test + @Order(20) + void testDeleteMysqlDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.delete(dataSourceName); + + Awaitility.await().untilAsserted(() -> { + browser.navigate().refresh(); + + assertThat( + page.dataSourceItemsList()).noneMatch( + it -> it.getText().contains(dataSourceName)); + }); + } + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java index cbed2b3b8ba31..a8a1db9e3d111 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/PostgresDataSourceE2ETest.java @@ -1,112 +1,107 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.dolphinscheduler.e2e.cases; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; -import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; -import org.apache.dolphinscheduler.e2e.pages.LoginPage; -import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; - -import java.time.Duration; - -import org.testcontainers.shaded.org.awaitility.Awaitility; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - - -@DolphinScheduler(composeFiles = "docker/datasource-postgresql/docker-compose.yaml") -public class PostgresDataSourceE2ETest { - private static RemoteWebDriver browser; - - private static final String tenant = System.getProperty("user.name"); - - private static final String user = "admin"; - - private static final String password = "dolphinscheduler123"; - - private static final String dataSourceType = "POSTGRESQL"; - - private static final String dataSourceName = "postgres_test"; - - private static final String dataSourceDescription = "postgres_test"; - - private static final String ip = "postgres"; - - private static final String port = "5432"; - - private static final String userName = "postgres"; - - private static final String pgPassword = "postgres"; - - private static final String database = "postgres"; - - private static final String jdbcParams = ""; - - - @BeforeAll - public static void setup() { - new LoginPage(browser) - .login(user, password) - .goToNav(DataSourcePage.class); - } - - @Test - @Order(10) - void testCreatePostgresDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); - - WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( - new By.ByClassName("dialog-create-data-source"))); - - Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) - .as("DataSource list should contain newly-created database") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(dataSourceName))); - } - - @Test - @Order(20) - void testDeletePostgresDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.delete(dataSourceName); - - Awaitility.await().untilAsserted(() -> { - browser.navigate().refresh(); - - assertThat( - page.dataSourceItemsList() - ).noneMatch( - it -> it.getText().contains(dataSourceName) - ); - }); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.dolphinscheduler.e2e.cases; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; +import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.testcontainers.shaded.org.awaitility.Awaitility; + +@DolphinScheduler(composeFiles = "docker/datasource-postgresql/docker-compose.yaml") +public class PostgresDataSourceE2ETest { + + private static RemoteWebDriver browser; + + private static final String tenant = System.getProperty("user.name"); + + private static final String user = "admin"; + + private static final String password = "dolphinscheduler123"; + + private static final String dataSourceType = "POSTGRESQL"; + + private static final String dataSourceName = "postgres_test"; + + private static final String dataSourceDescription = "postgres_test"; + + private static final String ip = "postgres"; + + private static final String port = "5432"; + + private static final String userName = "postgres"; + + private static final String pgPassword = "postgres"; + + private static final String database = "postgres"; + + private static final String jdbcParams = ""; + + @BeforeAll + public static void setup() { + new LoginPage(browser) + .login(user, password) + .goToNav(DataSourcePage.class); + } + + @Test + @Order(10) + void testCreatePostgresDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, + database, jdbcParams); + + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( + new By.ByClassName("dialog-create-data-source"))); + + Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) + .as("DataSource list should contain newly-created database") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(dataSourceName))); + } + + @Test + @Order(20) + void testDeletePostgresDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.delete(dataSourceName); + + Awaitility.await().untilAsserted(() -> { + browser.navigate().refresh(); + + assertThat( + page.dataSourceItemsList()).noneMatch( + it -> it.getText().contains(dataSourceName)); + }); + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java index f9f54299e8d43..e23a1000b1c2d 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/ProjectE2ETest.java @@ -25,14 +25,15 @@ import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.remote.RemoteWebDriver; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class ProjectE2ETest { + private static final String project = "test-project-1"; private static RemoteWebDriver browser; @@ -59,10 +60,8 @@ void testDeleteProject() { Awaitility.await().untilAsserted(() -> { browser.navigate().refresh(); assertThat( - page.projectList() - ).noneMatch( - it -> it.getText().contains(project) - ); + page.projectList()).noneMatch( + it -> it.getText().contains(project)); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java index 0ad3ee3a357f2..c9c73d87149cd 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/QueueE2ETest.java @@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.e2e.cases; - import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; @@ -27,13 +26,13 @@ import org.apache.dolphinscheduler.e2e.pages.security.QueuePage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class QueueE2ETest { @@ -50,8 +49,7 @@ public static void setup() { new LoginPage(browser) .login("admin", "dolphinscheduler123") .goToNav(SecurityPage.class) - .goToTab(QueuePage.class) - ; + .goToTab(QueuePage.class); } @Test @@ -75,10 +73,8 @@ void testCreateDuplicateQueue() { final QueuePage page = new QueuePage(browser); page.create(queueName, queueValue); - Awaitility.await().untilAsserted(() -> - assertThat(browser.findElement(By.tagName("body")).getText()) - .contains("already exists") - ); + Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) + .contains("already exists")); page.createQueueForm().buttonCancel().click(); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java index 7f6ee662dd3f3..c01452eaecd6f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/SqlServerDataSourceE2ETest.java @@ -1,112 +1,107 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.dolphinscheduler.e2e.cases; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; -import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; -import org.apache.dolphinscheduler.e2e.pages.LoginPage; -import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; - -import java.time.Duration; - -import org.testcontainers.shaded.org.awaitility.Awaitility; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - - -@DolphinScheduler(composeFiles = "docker/datasource-sqlserver/docker-compose.yaml") -public class SqlServerDataSourceE2ETest { - private static RemoteWebDriver browser; - - private static final String tenant = System.getProperty("user.name"); - - private static final String user = "admin"; - - private static final String password = "dolphinscheduler123"; - - private static final String dataSourceType = "SQLSERVER"; - - private static final String dataSourceName = "sqlserver_test"; - - private static final String dataSourceDescription = "sqlserver_test"; - - private static final String ip = "sqlserver"; - - private static final String port = "1433"; - - private static final String userName = "sa"; - - private static final String pgPassword = "OcP2020123"; - - private static final String database = "master"; - - private static final String jdbcParams = ""; - - - @BeforeAll - public static void setup() { - new LoginPage(browser) - .login(user, password) - .goToNav(DataSourcePage.class); - } - - @Test - @Order(10) - void testCreateSqlServerDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, database, jdbcParams); - - WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( - new By.ByClassName("dialog-create-data-source"))); - - Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) - .as("DataSource list should contain newly-created database") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(dataSourceName))); - } - - @Test - @Order(20) - void testDeleteSqlServerDataSource() { - final DataSourcePage page = new DataSourcePage(browser); - - page.delete(dataSourceName); - - Awaitility.await().untilAsserted(() -> { - browser.navigate().refresh(); - - assertThat( - page.dataSourceItemsList() - ).noneMatch( - it -> it.getText().contains(dataSourceName) - ); - }); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.dolphinscheduler.e2e.cases; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; +import org.apache.dolphinscheduler.e2e.pages.datasource.DataSourcePage; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.testcontainers.shaded.org.awaitility.Awaitility; + +@DolphinScheduler(composeFiles = "docker/datasource-sqlserver/docker-compose.yaml") +public class SqlServerDataSourceE2ETest { + + private static RemoteWebDriver browser; + + private static final String tenant = System.getProperty("user.name"); + + private static final String user = "admin"; + + private static final String password = "dolphinscheduler123"; + + private static final String dataSourceType = "SQLSERVER"; + + private static final String dataSourceName = "sqlserver_test"; + + private static final String dataSourceDescription = "sqlserver_test"; + + private static final String ip = "sqlserver"; + + private static final String port = "1433"; + + private static final String userName = "sa"; + + private static final String pgPassword = "OcP2020123"; + + private static final String database = "master"; + + private static final String jdbcParams = ""; + + @BeforeAll + public static void setup() { + new LoginPage(browser) + .login(user, password) + .goToNav(DataSourcePage.class); + } + + @Test + @Order(10) + void testCreateSqlServerDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.createDataSource(dataSourceType, dataSourceName, dataSourceDescription, ip, port, userName, pgPassword, + database, jdbcParams); + + WebDriverWaitFactory.createWebDriverWait(page.driver()).until(ExpectedConditions.invisibilityOfElementLocated( + new By.ByClassName("dialog-create-data-source"))); + + Awaitility.await().untilAsserted(() -> assertThat(page.dataSourceItemsList()) + .as("DataSource list should contain newly-created database") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(dataSourceName))); + } + + @Test + @Order(20) + void testDeleteSqlServerDataSource() { + final DataSourcePage page = new DataSourcePage(browser); + + page.delete(dataSourceName); + + Awaitility.await().untilAsserted(() -> { + browser.navigate().refresh(); + + assertThat( + page.dataSourceItemsList()).noneMatch( + it -> it.getText().contains(dataSourceName)); + }); + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java index d80eae7b89d94..696c8f172f6f4 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TenantE2ETest.java @@ -26,16 +26,17 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class TenantE2ETest { + private static final String tenant = System.getProperty("user.name"); private static final String editDescription = "This is a test"; @@ -44,10 +45,9 @@ class TenantE2ETest { @BeforeAll public static void setup() { new LoginPage(browser) - .login("admin", "dolphinscheduler123") - .goToNav(SecurityPage.class) - .goToTab(TenantPage.class) - ; + .login("admin", "dolphinscheduler123") + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class); } @Test @@ -57,9 +57,9 @@ void testCreateTenant() { page.create(tenant); Awaitility.await().untilAsserted(() -> assertThat(page.tenantList()) - .as("Tenant list should contain newly-created tenant") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(tenant))); + .as("Tenant list should contain newly-created tenant") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(tenant))); } @Test @@ -69,10 +69,8 @@ void testCreateDuplicateTenant() { page.create(tenant); - Awaitility.await().untilAsserted(() -> - assertThat(browser.findElement(By.tagName("body")).getText()) - .contains("already exists") - ); + Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) + .contains("already exists")); page.tenantForm().buttonCancel().click(); } @@ -87,9 +85,9 @@ void testUpdateTenant() { Awaitility.await().untilAsserted(() -> { browser.navigate().refresh(); assertThat(page.tenantList()) - .as("Tenant list should contain newly-modified tenant") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(tenant)); + .as("Tenant list should contain newly-modified tenant") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(tenant)); }); } @@ -103,10 +101,8 @@ void testDeleteTenant() { browser.navigate().refresh(); assertThat( - page.tenantList() - ).noneMatch( - it -> it.getText().contains(tenant) - ); + page.tenantList()).noneMatch( + it -> it.getText().contains(tenant)); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java index 8d287637b0dea..7a23f7625c2ee 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/TokenE2ETest.java @@ -26,12 +26,12 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.TokenPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") public class TokenE2ETest { @@ -43,10 +43,9 @@ public class TokenE2ETest { @BeforeAll public static void setup() { new LoginPage(browser) - .login("admin", "dolphinscheduler123") - .goToNav(SecurityPage.class) - .goToTab(TokenPage.class) - ; + .login("admin", "dolphinscheduler123") + .goToNav(SecurityPage.class) + .goToTab(TokenPage.class); } @Test @@ -59,9 +58,9 @@ void testCreateToken() { browser.navigate().refresh(); assertThat(page.tokenList()) - .as("Token list should contain newly-created token") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(userName)); + .as("Token list should contain newly-created token") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(userName)); }); } @@ -76,9 +75,9 @@ void testEditToken() { browser.navigate().refresh(); assertThat(page.tokenList()) - .as("Token list should contain newly-modified token") - .extracting(WebElement::getText) - .isNotEqualTo(oldToken); + .as("Token list should contain newly-modified token") + .extracting(WebElement::getText) + .isNotEqualTo(oldToken); }); } @@ -92,7 +91,7 @@ void testDeleteToken() { browser.navigate().refresh(); assertThat(page.tokenList()) - .noneMatch(it -> it.getText().contains(userName)); + .noneMatch(it -> it.getText().contains(userName)); }); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java index 150e84b618294..59afb550ae73c 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java @@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.e2e.cases; - import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; @@ -30,9 +29,6 @@ import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; import org.apache.dolphinscheduler.e2e.pages.security.UserPage; -import java.time.Duration; - -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; @@ -41,10 +37,11 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class UserE2ETest { + private static final String tenant = System.getProperty("user.name"); private static final String user = "test_user"; private static final String password = "testUser123"; @@ -78,9 +75,9 @@ public static void setup() { @AfterAll public static void cleanup() { new NavBarPage(browser) - .goToNav(SecurityPage.class) - .goToTab(TenantPage.class) - .delete(tenant); + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .delete(tenant); } @Test @@ -94,9 +91,9 @@ void testCreateUser() { browser.navigate().refresh(); assertThat(page.userList()) - .as("User list should contain newly-created user") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(user)); + .as("User list should contain newly-created user") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(user)); }); } @@ -107,10 +104,8 @@ void testCreateDuplicateUser() { page.create(user, password, email, phone, tenant); - Awaitility.await().untilAsserted(() -> - assertThat(browser.findElement(By.tagName("body")).getText()) - .contains("already exists") - ); + Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) + .contains("already exists")); page.createUserForm().buttonCancel().click(); } @@ -130,12 +125,12 @@ void testEditUser() { Awaitility.await().untilAsserted(() -> { browser.navigate().refresh(); assertThat(page.userList()) - .as("User list should contain newly-modified User") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(editUser)); + .as("User list should contain newly-modified User") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(editUser)); }); } - + @Test @Order(40) void testDeleteUser() { @@ -147,10 +142,8 @@ void testDeleteUser() { browser.navigate().refresh(); assertThat( - page.userList() - ).noneMatch( - it -> it.getText().contains(user) || it.getText().contains(editUser) - ); + page.userList()).noneMatch( + it -> it.getText().contains(user) || it.getText().contains(editUser)); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java index be8caf09136bd..5b6aae81050d4 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkerGroupE2ETest.java @@ -19,7 +19,6 @@ package org.apache.dolphinscheduler.e2e.cases; - import static org.assertj.core.api.Assertions.assertThat; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; @@ -28,9 +27,6 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.WorkerGroupPage; -import java.time.Duration; - -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -38,10 +34,11 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class WorkerGroupE2ETest { + private static final String workerGroupName = "test_worker_group"; private static final String editWorkerGroupName = "edit_worker_group"; @@ -50,9 +47,9 @@ class WorkerGroupE2ETest { @BeforeAll public static void setup() { new LoginPage(browser) - .login("admin", "dolphinscheduler123") - .goToNav(SecurityPage.class) - .goToTab(WorkerGroupPage.class); + .login("admin", "dolphinscheduler123") + .goToNav(SecurityPage.class) + .goToTab(WorkerGroupPage.class); } @Test @@ -61,7 +58,7 @@ void testCreateWorkerGroup() { final WorkerGroupPage page = new WorkerGroupPage(browser); WebDriverWaitFactory.createWebDriverWait(page.driver()) - .until(ExpectedConditions.urlContains("/security/worker-group-manage")); + .until(ExpectedConditions.urlContains("/security/worker-group-manage")); page.create(workerGroupName); @@ -69,9 +66,9 @@ void testCreateWorkerGroup() { browser.navigate().refresh(); assertThat(page.workerGroupList()) - .as("workerGroup list should contain newly-created workerGroup") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(workerGroupName)); + .as("workerGroup list should contain newly-created workerGroup") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(workerGroupName)); }); } @@ -82,10 +79,8 @@ void testCreateDuplicateWorkerGroup() { page.create(workerGroupName); - Awaitility.await().untilAsserted(() -> - assertThat(browser.findElement(By.tagName("body")).getText()) - .contains("already exists") - ); + Awaitility.await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) + .contains("already exists")); page.createWorkerForm().buttonCancel().click(); } @@ -99,13 +94,12 @@ void testEditWorkerGroup() { Awaitility.await().untilAsserted(() -> { browser.navigate().refresh(); assertThat(page.workerGroupList()) - .as("workerGroup list should contain newly-modified workerGroup") - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(editWorkerGroupName)); + .as("workerGroup list should contain newly-modified workerGroup") + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(editWorkerGroupName)); }); } - @Test @Order(40) void testDeleteWorkerGroup() { @@ -117,10 +111,8 @@ void testDeleteWorkerGroup() { browser.navigate().refresh(); assertThat( - page.workerGroupList() - ).noneMatch( - it -> it.getText().contains(workerGroupName) || it.getText().contains(editWorkerGroupName) - ); + page.workerGroupList()).noneMatch( + it -> it.getText().contains(workerGroupName) || it.getText().contains(editWorkerGroupName)); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java index bbfcacbcebaa4..11543d709ce68 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java @@ -19,6 +19,8 @@ package org.apache.dolphinscheduler.e2e.cases; +import static org.assertj.core.api.Assertions.assertThat; + import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; @@ -35,7 +37,6 @@ import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; import org.apache.dolphinscheduler.e2e.pages.security.UserPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; @@ -43,14 +44,11 @@ import org.openqa.selenium.By; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.time.Duration; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class WorkflowE2ETest { + private static final String project = "test-workflow-1"; private static final String workflow = "test-workflow-1"; @@ -82,58 +80,55 @@ public static void setup() { userPage.update(user, user, email, phone, tenant) .goToNav(ProjectPage.class) - .create(project) - ; + .create(project); } @AfterAll public static void cleanup() { new NavBarPage(browser) - .goToNav(ProjectPage.class) - .goTo(project) - .goToTab(WorkflowDefinitionTab.class) - .delete(workflow); + .goToNav(ProjectPage.class) + .goTo(project) + .goToTab(WorkflowDefinitionTab.class) + .delete(workflow); new NavBarPage(browser) - .goToNav(ProjectPage.class) - .delete(project); + .goToNav(ProjectPage.class) + .delete(project); browser.navigate().refresh(); new NavBarPage(browser) - .goToNav(SecurityPage.class) - .goToTab(TenantPage.class) - .delete(tenant); + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .delete(tenant); } @Test @Order(1) void testCreateWorkflow() { WorkflowDefinitionTab workflowDefinitionPage = - new ProjectPage(browser) - .goTo(project) - .goToTab(WorkflowDefinitionTab.class); + new ProjectPage(browser) + .goTo(project) + .goToTab(WorkflowDefinitionTab.class); workflowDefinitionPage - .createWorkflow() + .createWorkflow() - . addTask(TaskType.SHELL) - .script("echo ${today}\necho ${global_param}\n") - .name("test-1") - .addParam("today", "${system.datetime}") - .submit() + .addTask(TaskType.SHELL) + .script("echo ${today}\necho ${global_param}\n") + .name("test-1") + .addParam("today", "${system.datetime}") + .submit() - .submit() - .name(workflow) - .addGlobalParam("global_param", "hello world") - .submit() - ; + .submit() + .name(workflow) + .addGlobalParam("global_param", "hello world") + .submit(); Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) .as("Workflow list should contain newly-created workflow") .anyMatch( - it -> it.getText().contains(workflow) - )); + it -> it.getText().contains(workflow))); workflowDefinitionPage.publish(workflow); } @@ -142,28 +137,26 @@ void testCreateWorkflow() { void testCreateSubWorkflow() { final String workflow = "test-sub-workflow-1"; WorkflowDefinitionTab workflowDefinitionPage = - new ProjectPage(browser) - .goToNav(ProjectPage.class) - .goTo(project) - .goToTab(WorkflowDefinitionTab.class); + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(project) + .goToTab(WorkflowDefinitionTab.class); workflowDefinitionPage - .createSubProcessWorkflow() + .createSubProcessWorkflow() - . addTask(TaskType.SUB_PROCESS) - .childNode("test-workflow-1") - .name("test-sub-1") - .submit() + .addTask(TaskType.SUB_PROCESS) + .childNode("test-workflow-1") + .name("test-sub-1") + .submit() - .submit() - .name(workflow) - .addGlobalParam("global_param", "hello world") - .submit() - ; + .submit() + .name(workflow) + .addGlobalParam("global_param", "hello world") + .submit(); Awaitility.await().untilAsserted(() -> assertThat( - workflowDefinitionPage.workflowList() - ).anyMatch(it -> it.getText().contains(workflow))); + workflowDefinitionPage.workflowList()).anyMatch(it -> it.getText().contains(workflow))); workflowDefinitionPage.publish(workflow); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java index 3f78fd25f79ec..e29c0f1f87b7f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowHttpTaskE2ETest.java @@ -19,6 +19,8 @@ package org.apache.dolphinscheduler.e2e.cases; +import static org.assertj.core.api.Assertions.assertThat; + import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; @@ -32,6 +34,7 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; import org.apache.dolphinscheduler.e2e.pages.security.UserPage; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; @@ -39,16 +42,10 @@ import org.openqa.selenium.By; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; import org.testcontainers.shaded.org.awaitility.Awaitility; - -import java.time.Duration; - -import static org.assertj.core.api.Assertions.assertThat; @DolphinScheduler(composeFiles = "docker/workflow-http/docker-compose.yaml") public class WorkflowHttpTaskE2ETest { - private static final String project = "test-workflow-1"; private static final String workflow = "test-workflow-1"; @@ -82,8 +79,7 @@ public static void setup() { userPage.update(user, user, email, phone, tenant) .goToNav(ProjectPage.class) - .create(project) - ; + .create(project); } @AfterAll @@ -116,7 +112,7 @@ void testCreateWorkflow() { workflowDefinitionPage .createWorkflow() - . addTask(WorkflowForm.TaskType.HTTP) + .addTask(WorkflowForm.TaskType.HTTP) .url(mockServerUrl) .name("test-1") .addParam("today", "${system.datetime}") @@ -125,18 +121,15 @@ void testCreateWorkflow() { .submit() .name(workflow) .addGlobalParam("global_param", "hello world") - .submit() - ; + .submit(); Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) .as("Workflow list should contain newly-created workflow") .anyMatch( - it -> it.getText().contains(workflow) - )); + it -> it.getText().contains(workflow))); workflowDefinitionPage.publish(workflow); } - @Test @Order(30) void testRunWorkflow() { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java index 700ec03f43ce4..332bb4ff6fb6f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowJavaTaskE2ETest.java @@ -19,6 +19,8 @@ package org.apache.dolphinscheduler.e2e.cases; +import static org.assertj.core.api.Assertions.assertThat; + import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.LoginPage; @@ -33,23 +35,19 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; import org.apache.dolphinscheduler.e2e.pages.security.UserPage; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; import org.testcontainers.shaded.org.awaitility.Awaitility; -import java.time.Duration; - -import static org.assertj.core.api.Assertions.assertThat; - @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") public class WorkflowJavaTaskE2ETest { + private static final String project = "test-workflow-1"; private static final String workflow = "test-workflow-1"; @@ -98,8 +96,7 @@ public static void setup() { userPage.update(user, user, email, phone, tenant) .goToNav(ProjectPage.class) - .create(project) - ; + .create(project); } @AfterAll @@ -122,8 +119,6 @@ public static void cleanup() { .delete(tenant); } - - @Test @Order(1) void testCreateWorkflow() { @@ -134,7 +129,7 @@ void testCreateWorkflow() { workflowDefinitionPage .createWorkflow() - . addTask(WorkflowForm.TaskType.JAVA) + .addTask(WorkflowForm.TaskType.JAVA) .script(javaContent) .name("test-1") .addParam("today", "${system.datetime}") @@ -143,18 +138,15 @@ void testCreateWorkflow() { .submit() .name(workflow) .addGlobalParam("global_param", "hello world") - .submit() - ; + .submit(); Awaitility.await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) .as("Workflow list should contain newly-created workflow") .anyMatch( - it -> it.getText().contains(workflow) - )); + it -> it.getText().contains(workflow))); workflowDefinitionPage.publish(workflow); } - @Test @Order(30) void testRunWorkflow() { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java index cee9b52b47dbf..685d5fdc523bc 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowSwitchE2ETest.java @@ -19,6 +19,8 @@ package org.apache.dolphinscheduler.e2e.cases; +import static org.assertj.core.api.Assertions.assertThat; + import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; @@ -35,19 +37,18 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; -import org.testcontainers.shaded.org.awaitility.Awaitility; +import java.util.List; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.openqa.selenium.remote.RemoteWebDriver; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; +import org.testcontainers.shaded.org.awaitility.Awaitility; @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") class WorkflowSwitchE2ETest { + private static final String project = "test-workflow-1"; private static final String workflow = "test-workflow-1"; private static final String ifBranchName = "key==1"; @@ -60,31 +61,28 @@ class WorkflowSwitchE2ETest { @BeforeAll public static void setup() { new LoginPage(browser) - .login("admin", "dolphinscheduler123") - .goToNav(SecurityPage.class) - .goToTab(TenantPage.class) - .create(tenant) - .goToNav(ProjectPage.class) - .create(project) - ; + .login("admin", "dolphinscheduler123") + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .create(tenant) + .goToNav(ProjectPage.class) + .create(project); } @AfterAll public static void cleanup() { new NavBarPage(browser) - .goToNav(ProjectPage.class) - .goTo(project) - .goToTab(WorkflowDefinitionTab.class) - .cancelPublishAll() - .deleteAll() - ; + .goToNav(ProjectPage.class) + .goTo(project) + .goToTab(WorkflowDefinitionTab.class) + .cancelPublishAll() + .deleteAll(); new NavBarPage(browser) - .goToNav(ProjectPage.class) - .delete(project) - .goToNav(SecurityPage.class) - .goToTab(TenantPage.class) - .delete(tenant) - ; + .goToNav(ProjectPage.class) + .delete(project) + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class) + .delete(tenant); } @Test @@ -92,33 +90,33 @@ public static void cleanup() { void testCreateSwitchWorkflow() { final WorkflowDefinitionTab workflowDefinitionPage = - new ProjectPage(browser) - .goTo(project) - .goToTab(WorkflowDefinitionTab.class); + new ProjectPage(browser) + .goTo(project) + .goToTab(WorkflowDefinitionTab.class); WorkflowForm workflowForm = workflowDefinitionPage.createWorkflow(); - workflowForm. addTask(TaskType.SHELL) - .script("echo ${today}\necho ${global_param}\n") - .name("pre-task") - .submit(); + workflowForm.addTask(TaskType.SHELL) + .script("echo ${today}\necho ${global_param}\n") + .name("pre-task") + .submit(); SwitchTaskForm switchTaskForm = workflowForm.addTask(TaskType.SWITCH); switchTaskForm.preTask("pre-task") - .name("switch") - .submit(); + .name("switch") + .submit(); workflowForm.addTask(TaskType.SHELL) - .script("echo ${key}") - .preTask("switch") - .name(ifBranchName) - .submit(); + .script("echo ${key}") + .preTask("switch") + .name(ifBranchName) + .submit(); workflowForm.addTask(TaskType.SHELL) - .script("echo ${key}") - .preTask("switch") - .name(elseBranchName) - .submit(); + .script("echo ${key}") + .preTask("switch") + .name(elseBranchName) + .submit(); // format dag workflowForm.formatDAG().confirm(); @@ -130,13 +128,12 @@ workflowForm. addTask(TaskType.SHELL) switchTaskForm.submit(); workflowForm.submit() - .name(workflow) - .addGlobalParam("key", "1") - .submit(); + .name(workflow) + .addGlobalParam("key", "1") + .submit(); Awaitility.await().untilAsserted(() -> assertThat( - workflowDefinitionPage.workflowList() - ).anyMatch(it -> it.getText().contains(workflow))); + workflowDefinitionPage.workflowList()).anyMatch(it -> it.getText().contains(workflow))); workflowDefinitionPage.publish(workflow); } @@ -178,8 +175,10 @@ void testRunWorkflow() { Awaitility.await().untilAsserted(() -> { assertThat(taskInstances.size()).isEqualTo(3); - assertThat(taskInstances.stream().filter(row -> row.taskInstanceName().contains(ifBranchName)).count()).isEqualTo(1); - assertThat(taskInstances.stream().noneMatch(row -> row.taskInstanceName().contains(elseBranchName))).isTrue(); + assertThat(taskInstances.stream().filter(row -> row.taskInstanceName().contains(ifBranchName)).count()) + .isEqualTo(1); + assertThat(taskInstances.stream().noneMatch(row -> row.taskInstanceName().contains(elseBranchName))) + .isTrue(); }); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java index fb44bc843ad90..975c4faa78b20 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java @@ -17,6 +17,8 @@ package org.apache.dolphinscheduler.e2e.cases.tasks; +import static org.assertj.core.api.Assertions.assertThat; + import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; @@ -27,16 +29,12 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; import org.apache.dolphinscheduler.e2e.pages.resource.FileManagePage; import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; -import org.junit.FixMethodOrder; -import org.junit.jupiter.api.Order; + +import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; -import org.junit.runners.MethodSorters; -import org.openqa.selenium.WebElement; -import org.testcontainers.shaded.org.awaitility.Awaitility; -import static org.assertj.core.api.Assertions.assertThat; -import static org.testcontainers.shaded.org.awaitility.Awaitility.await; +import org.junit.jupiter.api.TestMethodOrder; -@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@TestMethodOrder(MethodOrderer.MethodName.class) @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") public class ShellTaskE2ETest extends BaseWorkflowE2ETest { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java index c2ee2ee447166..e73f39ceb86b1 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java @@ -17,19 +17,12 @@ package org.apache.dolphinscheduler.e2e.cases.workflow; -import java.time.Duration; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.stream.Collectors; -import lombok.extern.slf4j.Slf4j; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + import org.apache.dolphinscheduler.e2e.core.WebDriverHolder; -import org.apache.dolphinscheduler.e2e.models.tenant.DefaultTenant; import org.apache.dolphinscheduler.e2e.models.users.AdminUser; -import org.apache.dolphinscheduler.e2e.models.users.IUser; import org.apache.dolphinscheduler.e2e.pages.LoginPage; -import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; @@ -38,11 +31,16 @@ import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; import org.apache.dolphinscheduler.e2e.pages.security.UserPage; -import org.junit.jupiter.api.AfterAll; + +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.BeforeAll; import org.openqa.selenium.remote.RemoteWebDriver; -import static org.assertj.core.api.Assertions.assertThat; -import static org.testcontainers.shaded.org.awaitility.Awaitility.await; @Slf4j public abstract class BaseWorkflowE2ETest { @@ -83,8 +81,7 @@ protected void untilWorkflowDefinitionExist(String workflowName) { await().untilAsserted(() -> assertThat(workflowDefinitionPage.workflowList()) .as("Workflow list should contain newly-created workflow: %s", workflowName) .anyMatch( - it -> it.getText().contains(workflowName) - )); + it -> it.getText().contains(workflowName))); } protected void runWorkflow(String workflowName) { @@ -155,7 +152,8 @@ protected WorkflowInstanceTab.Row untilWorkflowInstanceFailed(String workflowNam if (workflowInstances.size() > 1) { throw new RuntimeException("More than one failed workflow instance found: " + workflowInstances.stream() - .map(WorkflowInstanceTab.Row::workflowInstanceName).collect(Collectors.joining(", "))); + .map(WorkflowInstanceTab.Row::workflowInstanceName) + .collect(Collectors.joining(", "))); } return workflowInstances.get(0); }, Objects::nonNull); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java index 598265fa96a45..afd046e4b4e67 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/tenant/DefaultTenant.java @@ -18,6 +18,7 @@ package org.apache.dolphinscheduler.e2e.models.tenant; public class DefaultTenant implements ITenant { + @Override public String getTenantCode() { return "default"; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java index da23bc26bf33b..50189759e15ee 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/AdminUser.java @@ -17,10 +17,11 @@ package org.apache.dolphinscheduler.e2e.models.users; -import lombok.Data; import org.apache.dolphinscheduler.e2e.models.tenant.BootstrapTenant; import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; +import lombok.Data; + @Data public class AdminUser implements IUser { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java index 740a4b431e956..1782478a62e4d 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/users/IUser.java @@ -17,8 +17,6 @@ package org.apache.dolphinscheduler.e2e.models.users; -import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; - public interface IUser { String getUserName(); @@ -31,5 +29,4 @@ public interface IUser { String getTenant(); - } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java index a77149fac353f..65f0706e1945f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java @@ -22,31 +22,28 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.models.users.IUser; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; -import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; + +import lombok.Getter; +import lombok.SneakyThrows; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.Getter; -import lombok.SneakyThrows; - -import java.time.Duration; @Getter public final class LoginPage extends NavBarPage { + @FindBys({ - @FindBy(className = "input-user-name"), - @FindBy(tagName = "input"), + @FindBy(className = "input-user-name"), + @FindBy(tagName = "input"), }) private WebElement inputUsername; - @FindBys( { - @FindBy(className = "input-password"), - @FindBy(tagName = "input"), + @FindBys({ + @FindBy(className = "input-password"), + @FindBy(tagName = "input"), }) private WebElement inputPassword; @@ -67,7 +64,8 @@ public NavBarPage login(IUser user) { @SneakyThrows public NavBarPage login(String username, String password) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage)); buttonSwitchLanguage().click(); inputUsername().sendKeys(username); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java index 53ed30b362f7e..d1f4cc58ee7d5 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java @@ -20,25 +20,23 @@ package org.apache.dolphinscheduler.e2e.pages.common; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; + +import lombok.Getter; + import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; - -import lombok.Getter; - -import java.time.Duration; - import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; @Getter public final class CodeEditor { + @FindBys({ - @FindBy(className = "monaco-editor"), - @FindBy(className = "view-line"), + @FindBy(className = "monaco-editor"), + @FindBy(className = "view-line"), }) private WebElement editor; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java index 770de59009c15..2a200a4cdae8e 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/HttpInput.java @@ -18,23 +18,22 @@ * */ - package org.apache.dolphinscheduler.e2e.pages.common; -import lombok.Getter; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; + +import lombok.Getter; + import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import java.time.Duration; @Getter public class HttpInput { + @FindBys({ @FindBy(className = "input-url-name"), @FindBy(tagName = "input") @@ -43,8 +42,6 @@ public class HttpInput { private WebDriver driver; - - public HttpInput(WebDriver driver) { PageFactory.initElements(driver, this); this.driver = driver; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java index 7b00a9bd29730..86ebb54d174b3 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/NavBarPage.java @@ -26,20 +26,18 @@ import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; +import lombok.Getter; + import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.Getter; - -import java.time.Duration; @Getter public class NavBarPage { + protected final RemoteWebDriver driver; @FindBy(xpath = "//div[contains(@class, 'tab-horizontal')]//div[contains(@role,'menubar')]//span[contains(text(), 'Project')]") @@ -72,21 +70,26 @@ public T goToNav(Class nav) { } if (nav == SecurityPage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(securityTab)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(securityTab)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", securityTab()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/tenant-manage")); return nav.cast(new SecurityPage(driver)); } if (nav == ResourcePage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(resourceTab)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(resourceTab)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", resourceTab()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/resource/file-manage")); return nav.cast(new ResourcePage(driver)); } if (nav == DataSourcePage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(dataSourceTab)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(dataSourceTab)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", dataSourceTab()); WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/datasource")); return nav.cast(new DataSourcePage(driver)); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java index 7f84ac29de7fa..ae1170eb62bb9 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/datasource/DataSourcePage.java @@ -1,204 +1,201 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.dolphinscheduler.e2e.pages.datasource; - -import lombok.Getter; - -import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; -import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; - -import java.security.Key; -import java.time.Duration; -import java.util.List; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.FindBys; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.ui.ExpectedCondition; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - - -@Getter -public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem { - - @FindBy(className = "btn-create-data-source") - private WebElement buttonCreateDataSource; - - @FindBy(className = "data-source-items") - private List dataSourceItemsList; - - @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), - }) - private WebElement buttonConfirm; - - @FindBys({ - @FindBy(className = "dialog-source-modal"), - }) - private WebElement dataSourceModal; - - private final CreateDataSourceForm createDataSourceForm; - - public DataSourcePage(RemoteWebDriver driver) { - super(driver); - - createDataSourceForm = new CreateDataSourceForm(); - } - - public DataSourcePage createDataSource(String dataSourceType, String dataSourceName, String dataSourceDescription, String ip, String port, String userName, String password, String database, - String jdbcParams) { - buttonCreateDataSource().click(); - - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated( - new By.ByClassName("dialog-source-modal"))); - - dataSourceModal().findElement(By.className(dataSourceType.toUpperCase()+"-box")).click(); - - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase())); - - createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName); - createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription); - createDataSourceForm().inputIP().sendKeys(ip); - createDataSourceForm().inputPort().sendKeys(Keys.CONTROL + "a"); - createDataSourceForm().inputPort().sendKeys(Keys.BACK_SPACE); - createDataSourceForm().inputPort().sendKeys(port); - createDataSourceForm().inputUserName().sendKeys(userName); - createDataSourceForm().inputPassword().sendKeys(password); - createDataSourceForm().inputDataBase().sendKeys(database); - - if (!"".equals(jdbcParams)) { - createDataSourceForm().inputJdbcParams().sendKeys(jdbcParams); - } - - createDataSourceForm().buttonSubmit().click(); - - return this; - } - - public DataSourcePage delete(String name) { - dataSourceItemsList() - .stream() - .filter(it -> it.getText().contains(name)) - .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No delete button in data source list")) - .click(); - - ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); - - return this; - } - - @Getter - public class CreateDataSourceForm { - CreateDataSourceForm() { - PageFactory.initElements(driver, this); - } - - @FindBy(className = "n-base-select-option__content") - private List selectDataSourceType; - - @FindBys({ - @FindBy(className = "btn-data-source-type-drop-down"), - @FindBy(className = "n-base-selection"), - }) - private WebElement btnDataSourceTypeDropdown; - - @FindBys({ - @FindBy(className = "input-data-source-name"), - @FindBy(tagName = "input"), - }) - private WebElement inputDataSourceName; - - @FindBys({ - @FindBy(className = "input-data-source-description"), - @FindBy(tagName = "textarea"), - }) - private WebElement inputDataSourceDescription; - - @FindBys({ - @FindBy(className = "input-ip"), - @FindBy(tagName = "input"), - }) - private WebElement inputIP; - - @FindBys({ - @FindBy(className = "input-port"), - @FindBy(tagName = "input"), - }) - private WebElement inputPort; - - @FindBys({ - @FindBy(className = "input-username"), - @FindBy(tagName = "input"), - }) - private WebElement inputUserName; - - @FindBys({ - @FindBy(className = "input-password"), - @FindBy(tagName = "input"), - }) - private WebElement inputPassword; - - @FindBys({ - @FindBy(className = "input-data-base"), - @FindBy(tagName = "input"), - }) - private WebElement inputDataBase; - - @FindBys({ - @FindBy(className = "input-jdbc-params"), - @FindBy(tagName = "textarea"), - }) - private WebElement inputJdbcParams; - - @FindBy(className = "btn-submit") - private WebElement buttonSubmit; - - @FindBy(className = "btn-cancel") - private WebElement buttonCancel; - - @FindBy(className = "btn-test-connection") - private WebElement btnTestConnection; - - @FindBys({ - @FindBy(className = "input-zeppelin_rest_endpoint"), - @FindBy(tagName = "input"), - }) - private WebElement inputZeppelinRestEndpoint; - - @FindBys({ - @FindBy(className = "input-kubeConfig"), - @FindBy(tagName = "textarea"), - }) - private WebElement inputKubeConfig; - - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.dolphinscheduler.e2e.pages.datasource; + +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; + +import java.util.List; + +import lombok.Getter; + +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.FindBys; +import org.openqa.selenium.support.PageFactory; +import org.openqa.selenium.support.ui.ExpectedConditions; + +@Getter +public class DataSourcePage extends NavBarPage implements NavBarPage.NavBarItem { + + @FindBy(className = "btn-create-data-source") + private WebElement buttonCreateDataSource; + + @FindBy(className = "data-source-items") + private List dataSourceItemsList; + + @FindBys({ + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), + }) + private WebElement buttonConfirm; + + @FindBys({ + @FindBy(className = "dialog-source-modal"), + }) + private WebElement dataSourceModal; + + private final CreateDataSourceForm createDataSourceForm; + + public DataSourcePage(RemoteWebDriver driver) { + super(driver); + + createDataSourceForm = new CreateDataSourceForm(); + } + + public DataSourcePage createDataSource(String dataSourceType, String dataSourceName, String dataSourceDescription, + String ip, String port, String userName, String password, String database, + String jdbcParams) { + buttonCreateDataSource().click(); + + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated( + new By.ByClassName("dialog-source-modal"))); + + dataSourceModal().findElement(By.className(dataSourceType.toUpperCase() + "-box")).click(); + + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement( + driver.findElement(By.className("dialog-create-data-source")), dataSourceType.toUpperCase())); + + createDataSourceForm().inputDataSourceName().sendKeys(dataSourceName); + createDataSourceForm().inputDataSourceDescription().sendKeys(dataSourceDescription); + createDataSourceForm().inputIP().sendKeys(ip); + createDataSourceForm().inputPort().sendKeys(Keys.CONTROL + "a"); + createDataSourceForm().inputPort().sendKeys(Keys.BACK_SPACE); + createDataSourceForm().inputPort().sendKeys(port); + createDataSourceForm().inputUserName().sendKeys(userName); + createDataSourceForm().inputPassword().sendKeys(password); + createDataSourceForm().inputDataBase().sendKeys(database); + + if (!"".equals(jdbcParams)) { + createDataSourceForm().inputJdbcParams().sendKeys(jdbcParams); + } + + createDataSourceForm().buttonSubmit().click(); + + return this; + } + + public DataSourcePage delete(String name) { + dataSourceItemsList() + .stream() + .filter(it -> it.getText().contains(name)) + .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No delete button in data source list")) + .click(); + + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); + + return this; + } + + @Getter + public class CreateDataSourceForm { + + CreateDataSourceForm() { + PageFactory.initElements(driver, this); + } + + @FindBy(className = "n-base-select-option__content") + private List selectDataSourceType; + + @FindBys({ + @FindBy(className = "btn-data-source-type-drop-down"), + @FindBy(className = "n-base-selection"), + }) + private WebElement btnDataSourceTypeDropdown; + + @FindBys({ + @FindBy(className = "input-data-source-name"), + @FindBy(tagName = "input"), + }) + private WebElement inputDataSourceName; + + @FindBys({ + @FindBy(className = "input-data-source-description"), + @FindBy(tagName = "textarea"), + }) + private WebElement inputDataSourceDescription; + + @FindBys({ + @FindBy(className = "input-ip"), + @FindBy(tagName = "input"), + }) + private WebElement inputIP; + + @FindBys({ + @FindBy(className = "input-port"), + @FindBy(tagName = "input"), + }) + private WebElement inputPort; + + @FindBys({ + @FindBy(className = "input-username"), + @FindBy(tagName = "input"), + }) + private WebElement inputUserName; + + @FindBys({ + @FindBy(className = "input-password"), + @FindBy(tagName = "input"), + }) + private WebElement inputPassword; + + @FindBys({ + @FindBy(className = "input-data-base"), + @FindBy(tagName = "input"), + }) + private WebElement inputDataBase; + + @FindBys({ + @FindBy(className = "input-jdbc-params"), + @FindBy(tagName = "textarea"), + }) + private WebElement inputJdbcParams; + + @FindBy(className = "btn-submit") + private WebElement buttonSubmit; + + @FindBy(className = "btn-cancel") + private WebElement buttonCancel; + + @FindBy(className = "btn-test-connection") + private WebElement btnTestConnection; + + @FindBys({ + @FindBy(className = "input-zeppelin_rest_endpoint"), + @FindBy(tagName = "input"), + }) + private WebElement inputZeppelinRestEndpoint; + + @FindBys({ + @FindBy(className = "input-kubeConfig"), + @FindBy(tagName = "textarea"), + }) + private WebElement inputKubeConfig; + + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java index c2fedeccfbb4b..79c46ba1f4e3d 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectDetailPage.java @@ -19,22 +19,23 @@ */ package org.apache.dolphinscheduler.e2e.pages.project; -import lombok.SneakyThrows; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; +import lombok.Getter; +import lombok.SneakyThrows; + import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; - -import lombok.Getter; import org.openqa.selenium.support.ui.ExpectedConditions; @Getter public final class ProjectDetailPage extends NavBarPage { + @FindBy(css = ".tab-vertical .n-submenu:nth-of-type(2) .n-menu-item:nth-of-type(2) > .n-menu-item-content") private WebElement menuProcessDefinition; @@ -52,12 +53,14 @@ public ProjectDetailPage(RemoteWebDriver driver) { public T goToTab(Class tab) { if (tab == WorkflowDefinitionTab.class) { menuProcessDefinition().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow-definition")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/workflow-definition")); return tab.cast(new WorkflowDefinitionTab(driver)); } if (tab == WorkflowInstanceTab.class) { menuProcessInstances().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/workflow/instances")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/workflow/instances")); return tab.cast(new WorkflowInstanceTab(driver)); } if (tab == TaskInstanceTab.class) { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java index 8be97f5db9080..94ca6ea5f8eba 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/ProjectPage.java @@ -19,11 +19,16 @@ */ package org.apache.dolphinscheduler.e2e.pages.project; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem; import java.util.List; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; @@ -31,15 +36,10 @@ import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.Getter; -import static org.assertj.core.api.Assertions.assertThat; -import static org.testcontainers.shaded.org.awaitility.Awaitility.await; @Getter public final class ProjectPage extends NavBarPage implements NavBarItem { + @FindBy(className = "btn-create-project") private WebElement buttonCreateProject; @@ -77,7 +77,6 @@ public ProjectPage createProjectUntilSuccess(String project) { return this; } - public ProjectPage delete(String project) { projectList() .stream() @@ -104,6 +103,7 @@ public ProjectDetailPage goTo(String project) { @Getter public class CreateProjectForm { + CreateProjectForm() { PageFactory.initElements(driver, this); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java index d1d81b70e42f8..592fd0e0b2cd8 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/TaskInstanceTab.java @@ -20,18 +20,19 @@ package org.apache.dolphinscheduler.e2e.pages.project.workflow; -import lombok.Getter; -import lombok.RequiredArgsConstructor; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; + +import java.util.List; +import java.util.stream.Collectors; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.FindBys; - -import java.util.List; -import java.util.stream.Collectors; @Getter public final class TaskInstanceTab extends NavBarPage implements ProjectDetailPage.Tab { @@ -45,14 +46,15 @@ public TaskInstanceTab(RemoteWebDriver driver) { public List instances() { return instanceList() - .stream() - .filter(WebElement::isDisplayed) - .map(Row::new) - .collect(Collectors.toList()); + .stream() + .filter(WebElement::isDisplayed) + .map(Row::new) + .collect(Collectors.toList()); } @RequiredArgsConstructor public static class Row { + private final WebElement row; public String taskInstanceName() { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java index d5a7b386c55b5..ee38a0ff7dc51 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java @@ -27,6 +27,8 @@ import java.util.List; import java.util.stream.Collectors; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; @@ -35,10 +37,9 @@ import org.openqa.selenium.support.FindBys; import org.testcontainers.shaded.org.awaitility.Awaitility; -import lombok.Getter; - @Getter public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDetailPage.Tab { + @FindBy(className = "btn-create-process") private WebElement buttonCreateProcess; @@ -61,8 +62,8 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe private WebElement buttonConfirm; @FindBys({ - @FindBy(className = "n-dialog__action"), - @FindBy(className = "n-button--default-type"), + @FindBy(className = "n-dialog__action"), + @FindBy(className = "n-button--default-type"), }) private WebElement publishSuccessButtonCancel; @@ -91,13 +92,13 @@ public WorkflowForm createSubProcessWorkflow() { public WorkflowDefinitionTab publish(String workflow) { workflowList() - .stream() - .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow)) - .flatMap(it -> it.findElements(By.className("btn-publish")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition")) - .click(); + .stream() + .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow)) + .flatMap(it -> it.findElements(By.className("btn-publish")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition")) + .click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); @@ -108,13 +109,13 @@ public WorkflowDefinitionTab publish(String workflow) { public WorkflowRunDialog run(String workflow) { workflowList() - .stream() - .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow)) - .flatMap(it -> it.findElements(By.className("btn-run")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("Can not find run button in workflow definition")) - .click(); + .stream() + .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow)) + .flatMap(it -> it.findElements(By.className("btn-run")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("Can not find run button in workflow definition")) + .click(); return new WorkflowRunDialog(this); } @@ -136,19 +137,18 @@ public WorkflowDefinitionTab cancelPublishAll() { public WorkflowDefinitionTab delete(String workflow) { Awaitility.await().untilAsserted(() -> assertThat(workflowList()) - .as("Workflow list should contain newly-created workflow") - .anyMatch( - it -> it.getText().contains(workflow) - )); + .as("Workflow list should contain newly-created workflow") + .anyMatch( + it -> it.getText().contains(workflow))); workflowList() - .stream() - .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow)) - .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("Can not find delete button in workflow definition")) - .click(); + .stream() + .filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow)) + .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("Can not find delete button in workflow definition")) + .click(); return this; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java index ce622b03978be..ec8a1766cdf61 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java @@ -21,15 +21,16 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskForm; -import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm; import java.nio.charset.StandardCharsets; -import java.time.Duration; import java.util.List; -import java.util.concurrent.TimeUnit; + +import lombok.Getter; +import lombok.SneakyThrows; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; @@ -38,17 +39,14 @@ import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; +import org.openqa.selenium.support.ui.ExpectedConditions; import com.google.common.io.Resources; -import lombok.Getter; -import lombok.SneakyThrows; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - @SuppressWarnings("UnstableApiUsage") @Getter public final class WorkflowForm { + private WebDriver driver; private final WorkflowSaveDialog saveForm; private final WorkflowFormatDialog formatDialog; @@ -95,7 +93,8 @@ public T addTask(TaskType type) { public WebElement getTask(String taskName) { List tasks = WebDriverWaitFactory.createWebDriverWait(driver) - .until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("svg > g > g[class^='x6-graph-svg-stage'] > g[data-shape^='dag-task']"))); + .until(ExpectedConditions.visibilityOfAllElementsLocatedBy( + By.cssSelector("svg > g > g[class^='x6-graph-svg-stage'] > g[data-shape^='dag-task']"))); WebElement task = tasks.stream() .filter(t -> t.getText().contains(taskName)) @@ -110,7 +109,8 @@ public WebElement getTask(String taskName) { public WorkflowSaveDialog submit() { buttonSave().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(.,'Basic Information')]"))); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(.,'Basic Information')]"))); return new WorkflowSaveDialog(this); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowFormatDialog.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowFormatDialog.java index f0ecf53b4655e..19778fe616480 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowFormatDialog.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowFormatDialog.java @@ -19,22 +19,19 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow; +import java.util.List; + import lombok.Getter; -import org.openqa.selenium.By; + import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.ByChained; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import java.util.List; -import java.util.stream.Stream; @Getter public final class WorkflowFormatDialog { + private final WebDriver driver; private final WorkflowForm parent; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java index 2b7fa28274f90..e853311f33b84 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowInstanceTab.java @@ -25,25 +25,26 @@ import java.util.List; import java.util.stream.Collectors; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; import org.openqa.selenium.support.pagefactory.ByChained; @Getter public final class WorkflowInstanceTab extends NavBarPage implements ProjectDetailPage.Tab { + @FindBy(className = "items-workflow-instances") private List instanceList; @FindBys({ - @FindBy(className = "btn-selected"), - @FindBy(className = "n-checkbox-box"), + @FindBy(className = "btn-selected"), + @FindBy(className = "n-checkbox-box"), }) private WebElement checkBoxSelectAll; @@ -62,10 +63,10 @@ public WorkflowInstanceTab(RemoteWebDriver driver) { public List instances() { return instanceList() - .stream() - .filter(WebElement::isDisplayed) - .map(Row::new) - .collect(Collectors.toList()); + .stream() + .filter(WebElement::isDisplayed) + .map(Row::new) + .collect(Collectors.toList()); } public WorkflowInstanceTab deleteAll() { @@ -84,6 +85,7 @@ public WorkflowInstanceTab deleteAll() { @RequiredArgsConstructor public static class Row { + private final WebElement row; public String workflowInstanceName() { @@ -108,11 +110,11 @@ public int executionTime() { public Row rerun() { row.findElements(new ByChained(By.className("btn-rerun"), By.className("n-button__content"))) - .stream() - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("Cannot find rerun button")) - .click(); + .stream() + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("Cannot find rerun button")) + .click(); return this; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java index ac8c22e5da012..bbf6ace88cd16 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java @@ -21,20 +21,17 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; - -import lombok.Getter; - -import java.time.Duration; - import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; @Getter public final class WorkflowRunDialog { + private final WorkflowDefinitionTab parent; @FindBy(className = "btn-submit") @@ -47,9 +44,12 @@ public WorkflowRunDialog(WorkflowDefinitionTab parent) { } public WorkflowDefinitionTab submit() { - By runDialogTitleXpath = By.xpath(String.format("//*[contains(text(), '%s')]", "Please set the parameters before starting")); - WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.visibilityOfElementLocated(runDialogTitleXpath)); - WebDriverWaitFactory.createWebDriverWait(parent.driver()).until(ExpectedConditions.elementToBeClickable(buttonSubmit())); + By runDialogTitleXpath = + By.xpath(String.format("//*[contains(text(), '%s')]", "Please set the parameters before starting")); + WebDriverWaitFactory.createWebDriverWait(parent.driver()) + .until(ExpectedConditions.visibilityOfElementLocated(runDialogTitleXpath)); + WebDriverWaitFactory.createWebDriverWait(parent.driver()) + .until(ExpectedConditions.elementToBeClickable(buttonSubmit())); buttonSubmit().click(); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java index d61b6a8fb7672..f29d71e27ec1e 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowSaveDialog.java @@ -19,26 +19,21 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow; -import lombok.Getter; - import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import lombok.Getter; + import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.ByChained; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import java.util.List; -import java.util.stream.Stream; @Getter public final class WorkflowSaveDialog { + private final WebDriver driver; private final WorkflowForm parent; @@ -82,10 +77,10 @@ public WorkflowSaveDialog addGlobalParam(String key, String value) { globalParamsItems().findElements(By.tagName("input")).get(0).sendKeys(key); globalParamsItems().findElements(By.tagName("input")).get(1).sendKeys(value); } else { - globalParamsItems().findElements(By.tagName("button")).get(len-1).click(); + globalParamsItems().findElements(By.tagName("button")).get(len - 1).click(); globalParamsItems().findElements(By.tagName("input")).get(len).sendKeys(key); - globalParamsItems().findElements(By.tagName("input")).get(len+1).sendKeys(value); + globalParamsItems().findElements(By.tagName("input")).get(len + 1).sendKeys(value); } return this; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/HttpTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/HttpTaskForm.java index 5869c6de9cc92..ab77ac3f516ea 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/HttpTaskForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/HttpTaskForm.java @@ -22,14 +22,15 @@ import org.apache.dolphinscheduler.e2e.pages.common.HttpInput; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; + import org.openqa.selenium.WebDriver; -public class HttpTaskForm extends TaskNodeForm{ +public class HttpTaskForm extends TaskNodeForm { + private WebDriver driver; private HttpInput httpInput; - public HttpTaskForm(WorkflowForm parent) { super(parent); this.httpInput = new HttpInput(parent.driver()); diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java index 960f7672fdf2a..528c8b80d6d27 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/JavaTaskForm.java @@ -22,9 +22,11 @@ import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; + import org.openqa.selenium.WebDriver; -public class JavaTaskForm extends TaskNodeForm{ +public class JavaTaskForm extends TaskNodeForm { + private CodeEditor codeEditor; private WebDriver driver; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/ShellTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/ShellTaskForm.java index fb91bb7e96040..9f11f1f85ceb3 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/ShellTaskForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/ShellTaskForm.java @@ -23,11 +23,12 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; import lombok.Getter; -import org.openqa.selenium.JavascriptExecutor; + import org.openqa.selenium.WebDriver; @Getter public final class ShellTaskForm extends TaskNodeForm { + private CodeEditor codeEditor; private WebDriver driver; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java index 6f328ddf232c8..3cf288e1eb0b3 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SubWorkflowTaskForm.java @@ -22,20 +22,20 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; +import java.util.List; + import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import java.time.Duration; -import java.util.List; @Getter public final class SubWorkflowTaskForm extends TaskNodeForm { + @FindBys({ @FindBy(className = "select-child-node"), @FindBy(className = "n-base-selection"), @@ -47,7 +47,6 @@ public final class SubWorkflowTaskForm extends TaskNodeForm { private WebDriver driver; - public SubWorkflowTaskForm(WorkflowForm parent) { super(parent); @@ -55,12 +54,14 @@ public SubWorkflowTaskForm(WorkflowForm parent) { } public SubWorkflowTaskForm childNode(String node) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown)); - + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(btnSelectChildNodeDropdown)); + btnSelectChildNodeDropdown().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(By.className( - "n-base-select-option__content"))); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.visibilityOfElementLocated(By.className( + "n-base-select-option__content"))); selectChildNode() .stream() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java index 480f5b410b14b..0948be7d99125 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskForm.java @@ -19,19 +19,19 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; -import lombok.Getter; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; + +import java.util.List; + +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import java.time.Duration; -import java.util.List; @Getter public final class SwitchTaskForm extends TaskNodeForm { @@ -51,14 +51,14 @@ public SwitchTaskForm(WorkflowForm parent) { } public SwitchTaskForm elseBranch(String elseBranchName) { - ((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", inputElseBranch()); + ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", inputElseBranch()); final By optionsLocator = By.className("option-else-branches"); WebDriverWaitFactory.createWebDriverWait(parent().driver()) .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); - List webElements = parent().driver().findElements(optionsLocator); + List webElements = parent().driver().findElements(optionsLocator); webElements.stream() .filter(it -> it.getText().contains(elseBranchName)) .findFirst() @@ -71,19 +71,20 @@ public SwitchTaskForm elseBranch(String elseBranchName) { } public SwitchTaskForm addIfBranch(String switchScript, String ifBranchName) { - ((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", buttonAddBranch); + ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", buttonAddBranch); SwitchTaskIfBranch switchTaskIfBranch = new SwitchTaskIfBranch(this); switchTaskIfBranch.codeEditor().content(switchScript); - ((JavascriptExecutor)parent().driver()).executeScript("arguments[0].click();", switchTaskIfBranch.inputIfBranch()); + ((JavascriptExecutor) parent().driver()).executeScript("arguments[0].click();", + switchTaskIfBranch.inputIfBranch()); final By optionsLocator = By.className("option-if-branches"); WebDriverWaitFactory.createWebDriverWait(parent().driver()) .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); - List webElements = parent().driver().findElements(optionsLocator); + List webElements = parent().driver().findElements(optionsLocator); webElements.stream() .filter(it -> it.getText().contains(ifBranchName)) .findFirst() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskIfBranch.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskIfBranch.java index 593778f4319ce..c3675768c9dea 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskIfBranch.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/SwitchTaskIfBranch.java @@ -19,8 +19,10 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; -import lombok.Getter; import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; + +import lombok.Getter; + import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -29,6 +31,7 @@ @Getter public final class SwitchTaskIfBranch { + private final WebDriver driver; private final SwitchTaskForm parent; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java index 5d0a944b02da2..62a4d4893afbe 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java @@ -19,9 +19,13 @@ */ package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; -import lombok.Getter; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; + +import java.util.List; + +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; @@ -30,13 +34,10 @@ import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import java.time.Duration; -import java.util.List; @Getter public abstract class TaskNodeForm { + @FindBys({ @FindBy(className = "input-node-name"), @FindBy(tagName = "input") @@ -85,7 +86,6 @@ public abstract class TaskNodeForm { }) private WebElement selectResource; - private final WorkflowForm parent; TaskNodeForm(WorkflowForm parent) { @@ -168,7 +168,8 @@ public TaskNodeForm selectResource(String resourceName) { final By optionsLocator = By.className("n-tree-node-content__text"); - WebDriverWaitFactory.createWebDriverWait(parent().driver()).until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); + WebDriverWaitFactory.createWebDriverWait(parent().driver()) + .until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); parent().driver() .findElements(optionsLocator) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java index f2d594f155e61..5f373b8190c52 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java @@ -1,331 +1,333 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.dolphinscheduler.e2e.pages.resource; - -import lombok.Getter; - -import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; -import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; -import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; - -import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.LocalFileDetector; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.FindBys; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.ui.ExpectedCondition; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import java.io.File; -import java.time.Duration; -import java.util.List; -import static org.assertj.core.api.Assertions.assertThat; -import static org.testcontainers.shaded.org.awaitility.Awaitility.await; - - -@Getter -public class FileManagePage extends NavBarPage implements ResourcePage.Tab { - @FindBy(className = "btn-create-directory") - private WebElement buttonCreateDirectory; - - @FindBy(className = "btn-create-file") - private WebElement buttonCreateFile; - - @FindBy(className = "btn-upload-resource") - private WebElement buttonUploadFile; - - private final CreateDirectoryBox createDirectoryBox; - - private final RenameBox renameBox; - - private final UploadFileBox uploadFileBox; - - private final EditFileBox editFileBox; - - @FindBy(className = "items") - private List fileList; - - @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), - }) - private WebElement buttonConfirm; - - @FindBys({ - @FindBy(className = "monaco-editor"), - @FindBy(className = "view-line"), - }) - private WebElement editor; - - public FileManagePage(RemoteWebDriver driver) { - super(driver); - - createDirectoryBox = new CreateDirectoryBox(); - - renameBox = new RenameBox(); - - uploadFileBox = new UploadFileBox(); - - editFileBox = new EditFileBox(); - - } - - public FileManagePage createDirectory(String name) { - buttonCreateDirectory().click(); - - createDirectoryBox().inputDirectoryName().sendKeys(name); - createDirectoryBox().buttonSubmit().click(); - - return this; - } - - public FileManagePage cancelCreateDirectory(String name) { - buttonCreateDirectory().click(); - - createDirectoryBox().inputDirectoryName().sendKeys(name); - createDirectoryBox().buttonCancel().click(); - - return this; - } - - public FileManagePage rename(String currentName, String AfterName) { - fileList() - .stream() - .filter(it -> it.getText().contains(currentName)) - .flatMap(it -> it.findElements(By.className("btn-rename")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No rename button in file manage list")) - .click(); - - renameBox().inputName().sendKeys(Keys.CONTROL + "a"); - renameBox().inputName().sendKeys(Keys.BACK_SPACE); - renameBox().inputName().sendKeys(AfterName); - renameBox().buttonSubmit().click(); - - return this; - } - - public FileManagePage createSubDirectory(String directoryName, String subDirectoryName) { - fileList() - .stream() - .filter(it -> it.getText().contains(directoryName)) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName))) - .click(); - - buttonCreateDirectory().click(); - - createDirectoryBox().inputDirectoryName().sendKeys(subDirectoryName); - createDirectoryBox().buttonSubmit().click(); - - return this; - } - - public FileManagePage delete(String name) { - fileList() - .stream() - .filter(it -> it.getText().contains(name)) - .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No delete button in file manage list")) - .click(); - - ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); - - return this; - } - - // todo: add file type - public FileManagePage createFile(String fileName, String scripts) { - - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(buttonCreateFile())); - - buttonCreateFile().click(); - - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create")); - - CreateFileBox createFileBox = new CreateFileBox(); - createFileBox.inputFileName().sendKeys(fileName); - createFileBox.codeEditor().content(scripts); - createFileBox.buttonSubmit().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage")); - return this; - } - - public FileManagePage createFileUntilSuccess(String fileName, String scripts) { - - createFile(fileName, scripts); - - await() - .untilAsserted(() -> - assertThat(fileList()) - .as("File list should contain newly-created file: " + fileName) - .extracting(WebElement::getText) - .anyMatch(it -> it.contains(fileName))); - return this; - } - - public FileManagePage editFile(String fileName, String scripts) { - fileList() - .stream() - .filter(it -> it.getText().contains(fileName)) - .flatMap(it -> it.findElements(By.className("btn-edit")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No edit button in file manage list")) - .click(); - - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/edit")); - - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName)); - - editFileBox().codeEditor().content(scripts); - editFileBox().buttonSubmit().click(); - - return this; - } - - public FileManagePage uploadFile(String filePath) { - buttonUploadFile().click(); - - driver.setFileDetector(new LocalFileDetector()); - - uploadFileBox().buttonUpload().sendKeys(filePath); - uploadFileBox().buttonSubmit().click(); - - return this; - } - - public FileManagePage downloadFile(String fileName) { - fileList() - .stream() - .filter(it -> it.getText().contains(fileName)) - .flatMap(it -> it.findElements(By.className("btn-download")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No download button in file manage list")) - .click(); - - return this; - } - - @Getter - public class CreateDirectoryBox { - CreateDirectoryBox() { - PageFactory.initElements(driver, this); - } - - @FindBys({ - @FindBy(className = "input-directory-name"), - @FindBy(tagName = "input"), - }) - private WebElement inputDirectoryName; - - @FindBy(className = "btn-submit") - private WebElement buttonSubmit; - - @FindBy(className = "btn-cancel") - private WebElement buttonCancel; - } - - @Getter - public class RenameBox { - RenameBox() { - PageFactory.initElements(driver, this); - } - - @FindBys({ - @FindBy(className = "input-name"), - @FindBy(tagName = "input"), - }) - private WebElement inputName; - - @FindBy(className = "btn-submit") - private WebElement buttonSubmit; - - @FindBy(className = "btn-cancel") - private WebElement buttonCancel; - } - - @Getter - public class CreateFileBox { - CreateFileBox() { - PageFactory.initElements(driver, this); - } - - @FindBys({ - @FindBy(className = "input-file-name"), - @FindBy(tagName = "input"), - }) - private WebElement inputFileName; - - private final CodeEditor codeEditor = new CodeEditor(driver); - - @FindBy(className = "btn-submit") - private WebElement buttonSubmit; - - @FindBy(className = "btn-cancel") - private WebElement buttonCancel; - } - - @Getter - public class EditFileBox { - EditFileBox() { - PageFactory.initElements(driver, this); - } - - CodeEditor codeEditor = new CodeEditor(driver); - - @FindBy(className = "btn-submit") - private WebElement buttonSubmit; - - @FindBy(className = "btn-cancel") - private WebElement buttonCancel; - } - - @Getter - public class UploadFileBox { - UploadFileBox() { - PageFactory.initElements(driver, this); - } - - @FindBys({ - @FindBy(className = "btn-upload"), - @FindBy(tagName = "input"), - }) - private WebElement buttonUpload; - - @FindBy(className = "btn-submit") - private WebElement buttonSubmit; - - @FindBy(className = "btn-cancel") - private WebElement buttonCancel; - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.dolphinscheduler.e2e.pages.resource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; +import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; + +import java.util.List; + +import lombok.Getter; + +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.LocalFileDetector; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.FindBys; +import org.openqa.selenium.support.PageFactory; +import org.openqa.selenium.support.ui.ExpectedConditions; + +@Getter +public class FileManagePage extends NavBarPage implements ResourcePage.Tab { + + @FindBy(className = "btn-create-directory") + private WebElement buttonCreateDirectory; + + @FindBy(className = "btn-create-file") + private WebElement buttonCreateFile; + + @FindBy(className = "btn-upload-resource") + private WebElement buttonUploadFile; + + private final CreateDirectoryBox createDirectoryBox; + + private final RenameBox renameBox; + + private final UploadFileBox uploadFileBox; + + private final EditFileBox editFileBox; + + @FindBy(className = "items") + private List fileList; + + @FindBys({ + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), + }) + private WebElement buttonConfirm; + + @FindBys({ + @FindBy(className = "monaco-editor"), + @FindBy(className = "view-line"), + }) + private WebElement editor; + + public FileManagePage(RemoteWebDriver driver) { + super(driver); + + createDirectoryBox = new CreateDirectoryBox(); + + renameBox = new RenameBox(); + + uploadFileBox = new UploadFileBox(); + + editFileBox = new EditFileBox(); + + } + + public FileManagePage createDirectory(String name) { + buttonCreateDirectory().click(); + + createDirectoryBox().inputDirectoryName().sendKeys(name); + createDirectoryBox().buttonSubmit().click(); + + return this; + } + + public FileManagePage cancelCreateDirectory(String name) { + buttonCreateDirectory().click(); + + createDirectoryBox().inputDirectoryName().sendKeys(name); + createDirectoryBox().buttonCancel().click(); + + return this; + } + + public FileManagePage rename(String currentName, String AfterName) { + fileList() + .stream() + .filter(it -> it.getText().contains(currentName)) + .flatMap(it -> it.findElements(By.className("btn-rename")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No rename button in file manage list")) + .click(); + + renameBox().inputName().sendKeys(Keys.CONTROL + "a"); + renameBox().inputName().sendKeys(Keys.BACK_SPACE); + renameBox().inputName().sendKeys(AfterName); + renameBox().buttonSubmit().click(); + + return this; + } + + public FileManagePage createSubDirectory(String directoryName, String subDirectoryName) { + fileList() + .stream() + .filter(it -> it.getText().contains(directoryName)) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException(String.format("No %s in file manage list", directoryName))) + .click(); + + buttonCreateDirectory().click(); + + createDirectoryBox().inputDirectoryName().sendKeys(subDirectoryName); + createDirectoryBox().buttonSubmit().click(); + + return this; + } + + public FileManagePage delete(String name) { + fileList() + .stream() + .filter(it -> it.getText().contains(name)) + .flatMap(it -> it.findElements(By.className("btn-delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No delete button in file manage list")) + .click(); + + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); + + return this; + } + + // todo: add file type + public FileManagePage createFile(String fileName, String scripts) { + + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(buttonCreateFile())); + + buttonCreateFile().click(); + + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file/create")); + + CreateFileBox createFileBox = new CreateFileBox(); + createFileBox.inputFileName().sendKeys(fileName); + createFileBox.codeEditor().content(scripts); + createFileBox.buttonSubmit().click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource/file-manage")); + return this; + } + + public FileManagePage createFileUntilSuccess(String fileName, String scripts) { + + createFile(fileName, scripts); + + await() + .untilAsserted(() -> assertThat(fileList()) + .as("File list should contain newly-created file: " + fileName) + .extracting(WebElement::getText) + .anyMatch(it -> it.contains(fileName))); + return this; + } + + public FileManagePage editFile(String fileName, String scripts) { + fileList() + .stream() + .filter(it -> it.getText().contains(fileName)) + .flatMap(it -> it.findElements(By.className("btn-edit")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No edit button in file manage list")) + .click(); + + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/edit")); + + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.textToBePresentInElement(driver.findElement(By.tagName("body")), fileName)); + + editFileBox().codeEditor().content(scripts); + editFileBox().buttonSubmit().click(); + + return this; + } + + public FileManagePage uploadFile(String filePath) { + buttonUploadFile().click(); + + driver.setFileDetector(new LocalFileDetector()); + + uploadFileBox().buttonUpload().sendKeys(filePath); + uploadFileBox().buttonSubmit().click(); + + return this; + } + + public FileManagePage downloadFile(String fileName) { + fileList() + .stream() + .filter(it -> it.getText().contains(fileName)) + .flatMap(it -> it.findElements(By.className("btn-download")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No download button in file manage list")) + .click(); + + return this; + } + + @Getter + public class CreateDirectoryBox { + + CreateDirectoryBox() { + PageFactory.initElements(driver, this); + } + + @FindBys({ + @FindBy(className = "input-directory-name"), + @FindBy(tagName = "input"), + }) + private WebElement inputDirectoryName; + + @FindBy(className = "btn-submit") + private WebElement buttonSubmit; + + @FindBy(className = "btn-cancel") + private WebElement buttonCancel; + } + + @Getter + public class RenameBox { + + RenameBox() { + PageFactory.initElements(driver, this); + } + + @FindBys({ + @FindBy(className = "input-name"), + @FindBy(tagName = "input"), + }) + private WebElement inputName; + + @FindBy(className = "btn-submit") + private WebElement buttonSubmit; + + @FindBy(className = "btn-cancel") + private WebElement buttonCancel; + } + + @Getter + public class CreateFileBox { + + CreateFileBox() { + PageFactory.initElements(driver, this); + } + + @FindBys({ + @FindBy(className = "input-file-name"), + @FindBy(tagName = "input"), + }) + private WebElement inputFileName; + + private final CodeEditor codeEditor = new CodeEditor(driver); + + @FindBy(className = "btn-submit") + private WebElement buttonSubmit; + + @FindBy(className = "btn-cancel") + private WebElement buttonCancel; + } + + @Getter + public class EditFileBox { + + EditFileBox() { + PageFactory.initElements(driver, this); + } + + CodeEditor codeEditor = new CodeEditor(driver); + + @FindBy(className = "btn-submit") + private WebElement buttonSubmit; + + @FindBy(className = "btn-cancel") + private WebElement buttonCancel; + } + + @Getter + public class UploadFileBox { + + UploadFileBox() { + PageFactory.initElements(driver, this); + } + + @FindBys({ + @FindBy(className = "btn-upload"), + @FindBy(tagName = "input"), + }) + private WebElement buttonUpload; + + @FindBy(className = "btn-submit") + private WebElement buttonSubmit; + + @FindBy(className = "btn-cancel") + private WebElement buttonCancel; + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java index 23264147f8c97..bd79de08297b6 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java @@ -1,63 +1,61 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.dolphinscheduler.e2e.pages.resource; - -import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; -import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; - -import java.time.Duration; - -import org.openqa.selenium.JavascriptExecutor; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.RemoteWebDriver; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.Getter; - - -@Getter -public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem { - @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content") - private WebElement fileManageTab; - - public ResourcePage(RemoteWebDriver driver) { - super(driver); - - PageFactory.initElements(driver, this); - } - - public T goToTab(Class tab) { - if (tab == FileManagePage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource")); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(fileManageTab)); - ((JavascriptExecutor) driver).executeScript("arguments[0].click();", fileManageTab()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/file-manage")); - return tab.cast(new FileManagePage(driver)); - } - - throw new UnsupportedOperationException("Unknown tab: " + tab.getName()); - } - - public interface Tab { - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.dolphinscheduler.e2e.pages.resource; + +import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; + +import lombok.Getter; + +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.PageFactory; +import org.openqa.selenium.support.ui.ExpectedConditions; + +@Getter +public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem { + + @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content") + private WebElement fileManageTab; + + public ResourcePage(RemoteWebDriver driver) { + super(driver); + + PageFactory.initElements(driver, this); + } + + public T goToTab(Class tab) { + if (tab == FileManagePage.class) { + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/resource")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(fileManageTab)); + ((JavascriptExecutor) driver).executeScript("arguments[0].click();", fileManageTab()); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/file-manage")); + return tab.cast(new FileManagePage(driver)); + } + + throw new UnsupportedOperationException("Unknown tab: " + tab.getName()); + } + + public interface Tab { + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/ClusterPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/ClusterPage.java index f95439768abe6..8cf54969565c2 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/ClusterPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/ClusterPage.java @@ -23,6 +23,8 @@ import java.util.List; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; @@ -31,13 +33,10 @@ import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.Getter; @Getter public final class ClusterPage extends NavBarPage implements SecurityPage.Tab { + @FindBy(className = "btn-create-cluster") private WebElement buttonCreateCluster; @@ -45,8 +44,8 @@ public final class ClusterPage extends NavBarPage implements SecurityPage.Tab { private List clusterList; @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), }) private WebElement buttonConfirm; @@ -79,7 +78,6 @@ public ClusterPage update(String oldName, String name, String config, String des .orElseThrow(() -> new RuntimeException("No edit button in cluster list")) .click(); - editClusterForm().inputClusterName().sendKeys(Keys.CONTROL + "a"); editClusterForm().inputClusterName().sendKeys(Keys.BACK_SPACE); editClusterForm().inputClusterName().sendKeys(name); @@ -114,31 +112,32 @@ public ClusterPage delete(String name) { @Getter public class ClusterForm { + ClusterForm() { PageFactory.initElements(driver, this); } @FindBys({ - @FindBy(className = "input-cluster-name"), - @FindBy(tagName = "input"), + @FindBy(className = "input-cluster-name"), + @FindBy(tagName = "input"), }) private WebElement inputClusterName; @FindBys({ - @FindBy(className = "input-cluster-config"), - @FindBy(tagName = "textarea"), + @FindBy(className = "input-cluster-config"), + @FindBy(tagName = "textarea"), }) private WebElement inputClusterConfig; @FindBys({ - @FindBy(className = "input-cluster-desc"), - @FindBy(tagName = "input"), + @FindBy(className = "input-cluster-desc"), + @FindBy(tagName = "input"), }) private WebElement inputClusterDesc; @FindBys({ - @FindBy(className = "n-base-selection-tags"), - @FindBy(className = "n-tag__content"), + @FindBy(className = "n-base-selection-tags"), + @FindBy(className = "n-tag__content"), }) private WebElement selectedWorkerGroup; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java index c318c257e3e01..8dd85ae60151f 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java @@ -22,9 +22,10 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; -import java.time.Duration; import java.util.List; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; @@ -33,13 +34,11 @@ import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; - -import lombok.Getter; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; @Getter public final class EnvironmentPage extends NavBarPage implements SecurityPage.Tab { + @FindBy(className = "btn-create-environment") private WebElement buttonCreateEnvironment; @@ -47,8 +46,8 @@ public final class EnvironmentPage extends NavBarPage implements SecurityPage.Ta private List environmentList; @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), }) private WebElement buttonConfirm; @@ -68,8 +67,9 @@ public EnvironmentPage create(String name, String config, String desc, String wo createEnvironmentForm().inputEnvironmentDesc().sendKeys(desc); editEnvironmentForm().btnSelectWorkerGroupDropdown().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( - "n-base-select-option__content"))); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + "n-base-select-option__content"))); editEnvironmentForm().selectWorkerGroupList() .stream() .filter(it -> it.getText().contains(workerGroup)) @@ -85,14 +85,14 @@ public EnvironmentPage create(String name, String config, String desc, String wo public EnvironmentPage update(String oldName, String name, String config, String desc, String workerGroup) { environmentList() .stream() - .filter(it -> it.findElement(By.className("environment-name")).getAttribute("innerHTML").contains(oldName)) + .filter(it -> it.findElement(By.className("environment-name")).getAttribute("innerHTML") + .contains(oldName)) .flatMap(it -> it.findElements(By.className("edit")).stream()) .filter(WebElement::isDisplayed) .findFirst() .orElseThrow(() -> new RuntimeException("No edit button in environment list")) .click(); - editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.CONTROL + "a"); editEnvironmentForm().inputEnvironmentName().sendKeys(Keys.BACK_SPACE); editEnvironmentForm().inputEnvironmentName().sendKeys(name); @@ -107,8 +107,9 @@ public EnvironmentPage update(String oldName, String name, String config, String if (editEnvironmentForm().selectedWorkerGroup().getAttribute("innerHTML").equals(workerGroup)) { editEnvironmentForm().btnSelectWorkerGroupDropdown().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( - "n-base-select-option__content"))); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + "n-base-select-option__content"))); editEnvironmentForm().selectWorkerGroupList() .stream() .filter(it -> it.getText().contains(workerGroup)) @@ -140,25 +141,26 @@ public EnvironmentPage delete(String name) { @Getter public class EnvironmentForm { + EnvironmentForm() { PageFactory.initElements(driver, this); } @FindBys({ - @FindBy(className = "input-environment-name"), - @FindBy(tagName = "input"), + @FindBy(className = "input-environment-name"), + @FindBy(tagName = "input"), }) private WebElement inputEnvironmentName; @FindBys({ - @FindBy(className = "input-environment-config"), - @FindBy(tagName = "textarea"), + @FindBy(className = "input-environment-config"), + @FindBy(tagName = "textarea"), }) private WebElement inputEnvironmentConfig; @FindBys({ - @FindBy(className = "input-environment-desc"), - @FindBy(tagName = "input"), + @FindBy(className = "input-environment-desc"), + @FindBy(tagName = "input"), }) private WebElement inputEnvironmentDesc; @@ -172,8 +174,8 @@ public class EnvironmentForm { private List selectWorkerGroupList; @FindBys({ - @FindBy(className = "n-base-selection-tags"), - @FindBy(className = "n-tag__content"), + @FindBy(className = "n-base-selection-tags"), + @FindBy(className = "n-tag__content"), }) private WebElement selectedWorkerGroup; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/NamespacePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/NamespacePage.java index 0d10e345fe46f..31b805c125a1b 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/NamespacePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/NamespacePage.java @@ -23,16 +23,17 @@ import java.util.List; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; -import lombok.Getter; - @Getter public final class NamespacePage extends NavBarPage implements SecurityPage.Tab { + @FindBy(id = "btnCreateNamespace") private WebElement buttonCreateNamespace; @@ -59,7 +60,8 @@ public NamespacePage create(String namespaceName, String namespaceValue) { public NamespacePage update(String namespaceName, String editNamespaceName, String editNamespaceValue) { namespaceList() .stream() - .filter(it -> it.findElement(By.className("namespaceName")).getAttribute("innerHTML").contains(namespaceName)) + .filter(it -> it.findElement(By.className("namespaceName")).getAttribute("innerHTML") + .contains(namespaceName)) .flatMap(it -> it.findElements(By.className("edit")).stream()) .filter(WebElement::isDisplayed) .findFirst() @@ -75,6 +77,7 @@ public NamespacePage update(String namespaceName, String editNamespaceName, Stri @Getter public class NamespaceForm { + NamespaceForm() { PageFactory.initElements(driver, this); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java index 2eb93d3517367..bbe9a17199085 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/QueuePage.java @@ -21,9 +21,10 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; -import java.security.Key; import java.util.List; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebElement; @@ -32,10 +33,9 @@ import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import lombok.Getter; - @Getter public final class QueuePage extends NavBarPage implements SecurityPage.Tab { + @FindBy(className = "btn-create-queue") private WebElement buttonCreateQueue; @@ -84,13 +84,14 @@ public QueuePage update(String queueName, String editQueueName, String editQueue @Getter public class QueueForm { + QueueForm() { PageFactory.initElements(driver, this); } @FindBys({ - @FindBy(className = "input-queue-name"), - @FindBy(tagName = "input"), + @FindBy(className = "input-queue-name"), + @FindBy(tagName = "input"), }) private WebElement inputQueueName; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java index 11cb748f7bd2c..093d2201d3117 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/SecurityPage.java @@ -24,17 +24,13 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem; +import lombok.Getter; + import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.Getter; - -import java.time.Duration; @Getter public class SecurityPage extends NavBarPage implements NavBarItem { @@ -70,58 +66,74 @@ public SecurityPage(RemoteWebDriver driver) { public T goToTab(Class tab) { if (tab == TenantPage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuTenantManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menuTenantManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTenantManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/tenant-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/tenant-manage")); return tab.cast(new TenantPage(driver)); } if (tab == UserPage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menUserManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menUserManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menUserManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/user-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/user-manage")); return tab.cast(new UserPage(driver)); } if (tab == WorkerGroupPage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menWorkerGroupManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menWorkerGroupManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/worker-group-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/worker-group-manage")); return tab.cast(new WorkerGroupPage(driver)); } if (tab == QueuePage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuQueueManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menuQueueManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuQueueManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/yarn-queue-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/yarn-queue-manage")); return tab.cast(new QueuePage(driver)); } if (tab == EnvironmentPage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuEnvironmentManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menuEnvironmentManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuEnvironmentManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/environment-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/environment-manage")); return tab.cast(new EnvironmentPage(driver)); } if (tab == ClusterPage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuClusterManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menuClusterManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuClusterManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/cluster-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/cluster-manage")); return tab.cast(new ClusterPage(driver)); } if (tab == TokenPage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuTokenManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menuTokenManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuTokenManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/token-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/token-manage")); return tab.cast(new TokenPage(driver)); } if (tab == NamespacePage.class) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(menuNamespaceManage)); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(menuNamespaceManage)); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", menuNamespaceManage()); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.urlContains("/security/k8s-namespace-manage")); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.urlContains("/security/k8s-namespace-manage")); return tab.cast(new NamespacePage(driver)); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java index e6b9f877c15a7..d1225bd0bec31 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TenantPage.java @@ -19,14 +19,15 @@ package org.apache.dolphinscheduler.e2e.pages.security; -import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; import org.apache.dolphinscheduler.e2e.models.tenant.ITenant; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import java.util.List; +import java.util.stream.Collectors; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; -import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; @@ -36,13 +37,9 @@ import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import lombok.Getter; -import org.openqa.selenium.support.pagefactory.ByChained; -import static org.assertj.core.api.Assertions.assertThat; -import static org.testcontainers.shaded.org.awaitility.Awaitility.await; - @Getter public final class TenantPage extends NavBarPage implements SecurityPage.Tab { + @FindBy(className = "btn-create-tenant") private WebElement buttonCreateTenant; @@ -132,6 +129,7 @@ public TenantPage delete(String tenant) { @Getter public class TenantForm { + TenantForm() { PageFactory.initElements(driver, this); } @@ -160,6 +158,7 @@ public class TenantForm { @RequiredArgsConstructor public static class Row { + private final WebElement row; public String tenantCode() { diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java index 7be82a840aca8..9ba0ceb69da1a 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/TokenPage.java @@ -23,9 +23,10 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage.Tab; -import java.time.Duration; import java.util.List; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebElement; @@ -34,14 +35,12 @@ import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; - -import lombok.Getter; import com.google.common.base.Strings; @Getter public final class TokenPage extends NavBarPage implements Tab { + @FindBy(className = "btn-create-token") private WebElement buttonCreateToken; @@ -49,8 +48,8 @@ public final class TokenPage extends NavBarPage implements Tab { private List tokenList; @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), }) private WebElement buttonConfirm; @@ -70,10 +69,12 @@ public TokenPage(RemoteWebDriver driver) { public TokenPage create(String userName) { buttonCreateToken().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown())); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(createTokenForm().selectUserNameDropdown())); createTokenForm().selectUserNameDropdown().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( - "n-base-select-option__content"))); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + "n-base-select-option__content"))); createTokenForm().selectUserNameList() .stream() .filter(it -> it.getText().contains(userName)) @@ -82,7 +83,8 @@ public TokenPage create(String userName) { userName))) .click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken())); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(createTokenForm().buttonGenerateToken())); createTokenForm().buttonGenerateToken().click(); createTokenForm().buttonSubmit().click(); @@ -92,16 +94,18 @@ public TokenPage create(String userName) { public TokenPage update(String userName) { tokenList().stream() - .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName)) - .flatMap(it -> it.findElements(By.className("edit")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No edit button in token list")) - .click(); - - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); + .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName)) + .flatMap(it -> it.findElements(By.className("edit")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No edit button in token list")) + .click(); + + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); editTokenForm().buttonGenerateToken().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.elementToBeClickable(editTokenForm().buttonGenerateToken())); editTokenForm().buttonSubmit().click(); @@ -110,23 +114,23 @@ public TokenPage update(String userName) { public String getToken(String userName) { return tokenList().stream() - .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName)) - .flatMap(it -> it.findElements(By.className("token")).stream()) - .filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML"))) - .map(it -> it.getAttribute("innerHTML")) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("No token for such user: " + userName)); + .filter(it -> it.findElement(By.className("username")).getAttribute("innerHTML").contains(userName)) + .flatMap(it -> it.findElements(By.className("token")).stream()) + .filter(it -> !Strings.isNullOrEmpty(it.getAttribute("innerHTML"))) + .map(it -> it.getAttribute("innerHTML")) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("No token for such user: " + userName)); } public TokenPage delete(String userName) { tokenList() - .stream() - .filter(it -> it.getText().contains(userName)) - .flatMap(it -> it.findElements(By.className("delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No delete button in token list")) - .click(); + .stream() + .filter(it -> it.getText().contains(userName)) + .flatMap(it -> it.findElements(By.className("delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No delete button in token list")) + .click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); @@ -135,13 +139,14 @@ public TokenPage delete(String userName) { @Getter public class TokenForm { + TokenForm() { PageFactory.initElements(driver, this); } @FindBys({ - @FindBy(className = "input-username"), - @FindBy(className = "n-base-selection"), + @FindBy(className = "input-username"), + @FindBy(className = "n-base-selection"), }) private WebElement selectUserNameDropdown; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java index 1ee52e8a281ee..bd6d2d7d49988 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java @@ -23,9 +23,10 @@ import org.apache.dolphinscheduler.e2e.models.users.IUser; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; -import java.time.Duration; import java.util.List; +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; @@ -34,13 +35,11 @@ import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; - -import lombok.Getter; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.WebDriverWait; @Getter public final class UserPage extends NavBarPage implements SecurityPage.Tab { + @FindBy(className = "btn-create-user") private WebElement buttonCreateUser; @@ -48,15 +47,14 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab { private List userList; @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), }) private WebElement buttonConfirm; private final UserForm createUserForm = new UserForm(); private final UserForm editUserForm = new UserForm(); - public UserPage(RemoteWebDriver driver) { super(driver); } @@ -69,15 +67,16 @@ public UserPage create(String user, String password, String email, String phone, createUserForm().btnSelectTenantDropdown().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( - "n-base-select-option__content"))); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + "n-base-select-option__content"))); createUserForm().selectTenant() - .stream() - .filter(it -> it.getText().contains(tenant)) - .findFirst() - .orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant))) - .click(); + .stream() + .filter(it -> it.getText().contains(tenant)) + .findFirst() + .orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant))) + .click(); createUserForm().inputEmail().sendKeys(email); createUserForm().inputPhone().sendKeys(phone); @@ -101,21 +100,22 @@ public UserPage update(String user, String editPhone, String tenant) { userList().stream() - .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) - .flatMap(it -> it.findElements(By.className("edit")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No edit button in user list")) - .click(); - - editUserForm().inputUserName().sendKeys(Keys.CONTROL+"a"); + .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) + .flatMap(it -> it.findElements(By.className("edit")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No edit button in user list")) + .click(); + + editUserForm().inputUserName().sendKeys(Keys.CONTROL + "a"); editUserForm().inputUserName().sendKeys(Keys.BACK_SPACE); editUserForm().inputUserName().sendKeys(editUser); createUserForm().btnSelectTenantDropdown().click(); - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( - "n-base-select-option__content"))); + WebDriverWaitFactory.createWebDriverWait(driver) + .until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName( + "n-base-select-option__content"))); createUserForm().selectTenant() .stream() @@ -124,11 +124,11 @@ public UserPage update(String user, .orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant))) .click(); - editUserForm().inputEmail().sendKeys(Keys.CONTROL+"a"); + editUserForm().inputEmail().sendKeys(Keys.CONTROL + "a"); editUserForm().inputEmail().sendKeys(Keys.BACK_SPACE); editUserForm().inputEmail().sendKeys(editEmail); - editUserForm().inputPhone().sendKeys(Keys.CONTROL+"a"); + editUserForm().inputPhone().sendKeys(Keys.CONTROL + "a"); editUserForm().inputPhone().sendKeys(Keys.BACK_SPACE); editUserForm().inputPhone().sendKeys(editPhone); @@ -139,13 +139,13 @@ public UserPage update(String user, public UserPage delete(String user) { userList() - .stream() - .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) - .flatMap(it -> it.findElements(By.className("delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No delete button in user list")) - .click(); + .stream() + .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) + .flatMap(it -> it.findElements(By.className("delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No delete button in user list")) + .click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); @@ -154,25 +154,26 @@ public UserPage delete(String user) { @Getter public class UserForm { + UserForm() { PageFactory.initElements(driver, this); } @FindBys({ - @FindBy(className = "input-username"), - @FindBy(tagName = "input"), + @FindBy(className = "input-username"), + @FindBy(tagName = "input"), }) private WebElement inputUserName; @FindBys({ - @FindBy(className = "input-password"), - @FindBy(tagName = "input"), + @FindBy(className = "input-password"), + @FindBy(tagName = "input"), }) private WebElement inputUserPassword; @FindBys({ - @FindBy(className = "select-tenant"), - @FindBy(className = "n-base-selection"), + @FindBy(className = "select-tenant"), + @FindBy(className = "n-base-selection"), }) private WebElement btnSelectTenantDropdown; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java index ced1e5a709483..736db769d9d39 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/WorkerGroupPage.java @@ -19,8 +19,12 @@ package org.apache.dolphinscheduler.e2e.pages.security; -import lombok.Getter; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; + +import java.util.List; + +import lombok.Getter; + import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; @@ -30,11 +34,9 @@ import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; -import java.util.List; - - @Getter public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Tab { + @FindBy(className = "btn-create-worker-group") private WebElement buttonCreateWorkerGroup; @@ -42,16 +44,14 @@ public final class WorkerGroupPage extends NavBarPage implements SecurityPage.Ta private List workerGroupList; @FindBys({ - @FindBy(className = "n-popconfirm__action"), - @FindBy(className = "n-button--primary-type"), + @FindBy(className = "n-popconfirm__action"), + @FindBy(className = "n-button--primary-type"), }) private WebElement buttonConfirm; private final WorkerGroupForm createWorkerForm = new WorkerGroupForm(); private final WorkerGroupForm editWorkerForm = new WorkerGroupForm(); - - public WorkerGroupPage(RemoteWebDriver driver) { super(driver); } @@ -87,16 +87,15 @@ public WorkerGroupPage update(String workerGroupName, String editWorkerGroupName return this; } - public WorkerGroupPage delete(String Worker) { workerGroupList() - .stream() - .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(Worker)) - .flatMap(it -> it.findElements(By.className("delete")).stream()) - .filter(WebElement::isDisplayed) - .findFirst() - .orElseThrow(() -> new RuntimeException("No delete button in workerGroup list")) - .click(); + .stream() + .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(Worker)) + .flatMap(it -> it.findElements(By.className("delete")).stream()) + .filter(WebElement::isDisplayed) + .findFirst() + .orElseThrow(() -> new RuntimeException("No delete button in workerGroup list")) + .click(); ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm()); @@ -105,19 +104,20 @@ public WorkerGroupPage delete(String Worker) { @Getter public class WorkerGroupForm { + WorkerGroupForm() { PageFactory.initElements(driver, this); } @FindBys({ - @FindBy(className = "input-worker-group-name"), - @FindBy(tagName = "input"), + @FindBy(className = "input-worker-group-name"), + @FindBy(tagName = "input"), }) private WebElement inputWorkerGroupName; @FindBys({ - @FindBy(className = "select-worker-address"), - @FindBy(className = "n-base-selection"), + @FindBy(className = "select-worker-address"), + @FindBy(className = "n-base-selection"), }) private WebElement btnSelectWorkerAddress; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java index caa3a2b819c4a..aa471a5618606 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java @@ -17,13 +17,14 @@ package org.apache.dolphinscheduler.e2e.core; -import lombok.experimental.UtilityClass; - import java.nio.file.Path; import java.nio.file.Paths; +import lombok.experimental.UtilityClass; + @UtilityClass public final class Constants { + /** * tmp directory path */ diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinScheduler.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinScheduler.java index 8d49ca3b91127..2feab903d7ee0 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinScheduler.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinScheduler.java @@ -37,5 +37,6 @@ @TestMethodOrder(OrderAnnotation.class) @ExtendWith(DolphinSchedulerExtension.class) public @interface DolphinScheduler { + String[] composeFiles(); } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java index eeadc41e25fde..b73a487e6fc4c 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java @@ -37,6 +37,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; + import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; @@ -54,10 +56,9 @@ import com.google.common.base.Strings; import com.google.common.net.HostAndPort; -import lombok.extern.slf4j.Slf4j; - @Slf4j final class DolphinSchedulerExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback { + private final boolean LOCAL_MODE = Objects.equals(System.getProperty("local"), "true"); private final boolean M1_CHIP_FLAG = Objects.equals(System.getProperty("m1_chip"), "true"); @@ -101,10 +102,10 @@ public void beforeAll(ExtensionContext context) throws IOException { driver = new RemoteWebDriver(browser.getSeleniumAddress(), new ChromeOptions()); driver.manage().timeouts() - .implicitlyWait(Duration.ofSeconds(10)) - .pageLoadTimeout(Duration.ofSeconds(10)); + .implicitlyWait(Duration.ofSeconds(10)) + .pageLoadTimeout(Duration.ofSeconds(10)); driver.manage().window() - .maximize(); + .maximize(); driver.get(new URL("http", address.getHost(), address.getPort(), rootPath).toString()); @@ -112,9 +113,9 @@ public void beforeAll(ExtensionContext context) throws IOException { final Class clazz = context.getRequiredTestClass(); Stream.of(clazz.getDeclaredFields()) - .filter(it -> Modifier.isStatic(it.getModifiers())) - .filter(f -> WebDriver.class.isAssignableFrom(f.getType())) - .forEach(it -> setDriver(clazz, it)); + .filter(it -> Modifier.isStatic(it.getModifiers())) + .filter(f -> WebDriver.class.isAssignableFrom(f.getType())) + .forEach(it -> setDriver(clazz, it)); WebDriverHolder.setWebDriver(driver); } @@ -128,7 +129,8 @@ private void runInDockerContainer(ExtensionContext context) { compose = createDockerCompose(context); compose.start(); - address = HostAndPort.fromParts("host.testcontainers.internal", compose.getServicePort(serviceName, DOCKER_PORT)); + address = + HostAndPort.fromParts("host.testcontainers.internal", compose.getServicePort(serviceName, DOCKER_PORT)); rootPath = "/dolphinscheduler/ui/"; } @@ -183,8 +185,8 @@ public void afterAll(ExtensionContext context) { public void beforeEach(ExtensionContext context) { final Object instance = context.getRequiredTestInstance(); Stream.of(instance.getClass().getDeclaredFields()) - .filter(f -> WebDriver.class.isAssignableFrom(f.getType())) - .forEach(it -> setDriver(instance, it)); + .filter(f -> WebDriver.class.isAssignableFrom(f.getType())) + .forEach(it -> setDriver(instance, it)); } private void setDriver(Object object, Field field) { @@ -200,13 +202,13 @@ private ComposeContainer createDockerCompose(ExtensionContext context) { final Class clazz = context.getRequiredTestClass(); final DolphinScheduler annotation = clazz.getAnnotation(DolphinScheduler.class); final List files = Stream.of(annotation.composeFiles()) - .map(it -> DolphinScheduler.class.getClassLoader().getResource(it)) - .filter(Objects::nonNull) - .map(URL::getPath) - .map(File::new) - .collect(Collectors.toList()); + .map(it -> DolphinScheduler.class.getClassLoader().getResource(it)) + .filter(Objects::nonNull) + .map(URL::getPath) + .map(File::new) + .collect(Collectors.toList()); - ComposeContainer compose = new ComposeContainer(files) + ComposeContainer compose = new ComposeContainer(files) .withPull(true) .withTailChildContainers(true) .withLocalCompose(true) @@ -216,7 +218,6 @@ private ComposeContainer createDockerCompose(ExtensionContext context) { .withLogConsumer(serviceName, outputFrame -> LOGGER.info(outputFrame.getUtf8String())) .waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(300))); - return compose; } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/TestDescription.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/TestDescription.java index 59ef66b7f6aef..fbf277f2a46b0 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/TestDescription.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/TestDescription.java @@ -24,12 +24,13 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import org.junit.jupiter.api.extension.ExtensionContext; - import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.extension.ExtensionContext; + @RequiredArgsConstructor final class TestDescription implements org.testcontainers.lifecycle.TestDescription { + private static final String UNKNOWN_NAME = "unknown"; private final ExtensionContext context; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java index 946fe071abe75..a423f75973b70 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java @@ -18,6 +18,7 @@ package org.apache.dolphinscheduler.e2e.core; import java.time.Duration; + import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.ui.WebDriverWait; diff --git a/dolphinscheduler-e2e/pom.xml b/dolphinscheduler-e2e/pom.xml index 67312404869ae..c4bc984de3ae1 100644 --- a/dolphinscheduler-e2e/pom.xml +++ b/dolphinscheduler-e2e/pom.xml @@ -31,8 +31,8 @@ - 8 - 8 + 11 + 11 UTF-8 5.8.1 diff --git a/pom.xml b/pom.xml index ee2327fce8f63..f5050e5ebd155 100755 --- a/pom.xml +++ b/pom.xml @@ -707,6 +707,14 @@ import\s+io\.kubernetes\.client\.[^\*\s]*(|\*);(\r\n|\r|\n) $1 + + src/main/java/**/*.java + src/test/java/**/*.java + dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/**/*.java + dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/**/*.java + dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/**/*.java + dolphinscheduler-api-test/dolphinscheduler-api-test-core/src/main/java/**/*.java + From 8338815a8c67f0124827968f6ccd34c501c8de39 Mon Sep 17 00:00:00 2001 From: Wenjun Ruan Date: Mon, 1 Jul 2024 09:20:56 +0800 Subject: [PATCH 07/18] Force check ci on prapare/release branch (#16216) --- .github/workflows/api-test.yml | 2 ++ .github/workflows/codeql.yaml | 2 ++ .github/workflows/e2e-k8s.yml | 2 ++ .github/workflows/e2e.yml | 2 ++ .github/workflows/frontend.yml | 3 ++- .github/workflows/owasp-dependency-check.yaml | 3 ++- .github/workflows/unit-test.yml | 3 ++- 7 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/api-test.yml b/.github/workflows/api-test.yml index 8fdfe8872ad28..c635b1bc8b43a 100644 --- a/.github/workflows/api-test.yml +++ b/.github/workflows/api-test.yml @@ -20,6 +20,8 @@ on: push: branches: - dev + - '[0-9]+.[0-9]+.[0-9]+-prepare' + - '[0-9]+.[0-9]+.[0-9]+-release' name: API-Test diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 8810a33c96f4a..79859e3df613a 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -23,6 +23,8 @@ on: pull_request: branches: - 'dev' + - '[0-9]+.[0-9]+.[0-9]+-prepare' + - '[0-9]+.[0-9]+.[0-9]+-release' concurrency: group: codeql-${{ github.event.pull_request.number || github.ref }} diff --git a/.github/workflows/e2e-k8s.yml b/.github/workflows/e2e-k8s.yml index 351aea8802cc4..9074d97a8c309 100644 --- a/.github/workflows/e2e-k8s.yml +++ b/.github/workflows/e2e-k8s.yml @@ -20,6 +20,8 @@ on: push: branches: - dev + - '[0-9]+.[0-9]+.[0-9]+-prepare' + - '[0-9]+.[0-9]+.[0-9]+-release' name: E2E-K8S diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d9a3cd795e09f..1d2aa325716ff 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -20,6 +20,8 @@ on: push: branches: - dev + - '[0-9]+.[0-9]+.[0-9]+-prepare' + - '[0-9]+.[0-9]+.[0-9]+-release' name: E2E diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index 87d178185add2..1cb5f5a84b4a6 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -20,7 +20,8 @@ name: Frontend on: push: branches: - - dev + - '[0-9]+.[0-9]+.[0-9]+-prepare' + - '[0-9]+.[0-9]+.[0-9]+-release' paths: - '.github/workflows/frontend.yml' - 'dolphinscheduler-ui/**' diff --git a/.github/workflows/owasp-dependency-check.yaml b/.github/workflows/owasp-dependency-check.yaml index 0e56049d93d28..b4ee52c57d8d4 100644 --- a/.github/workflows/owasp-dependency-check.yaml +++ b/.github/workflows/owasp-dependency-check.yaml @@ -20,7 +20,8 @@ name: OWASP Dependency Check on: push: branches: - - dev + - '[0-9]+.[0-9]+.[0-9]+-prepare' + - '[0-9]+.[0-9]+.[0-9]+-release' pull_request: paths: - '**/pom.xml' diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index d0c88b9ca602f..ad42ee57df5fc 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -24,7 +24,8 @@ on: - '**/*.md' - 'dolphinscheduler-ui' branches: - - dev + - '[0-9]+.[0-9]+.[0-9]+-prepare' + - '[0-9]+.[0-9]+.[0-9]+-release' env: LOG_DIR: /tmp/dolphinscheduler From 1fe8a6e868188481a46e3a352368ceac6cf79e39 Mon Sep 17 00:00:00 2001 From: xiangzihao <460888207@qq.com> Date: Mon, 1 Jul 2024 12:36:10 +0800 Subject: [PATCH 08/18] [Feature-16229] Add python using file e2e test case (#16240) * feature 16229 * resolve conflicts --- .github/actions/workflow-telemetry-action | 1 + .github/workflows/e2e.yml | 13 + .gitmodules | 3 + dolphinscheduler-dist/release-docs/LICENSE | 2 +- .../e2e/cases/tasks/PythonTaskE2ETest.java | 338 ++++++++++++++++++ .../e2e/cases/tasks/ShellTaskE2ETest.java | 28 ++ .../cases/workflow/BaseWorkflowE2ETest.java | 27 -- .../e2e/models/environment/IEnvironment.java | 30 ++ .../models/environment/PythonEnvironment.java | 52 +++ .../e2e/pages/common/CodeEditor.java | 80 ++++- .../pages/project/workflow/WorkflowForm.java | 6 + .../project/workflow/WorkflowRunDialog.java | 9 +- .../project/workflow/task/PythonTaskForm.java | 49 +++ .../project/workflow/task/TaskNodeForm.java | 3 + .../e2e/pages/security/EnvironmentPage.java | 11 + .../resources/docker/python-task/Dockerfile | 25 ++ .../docker/python-task/docker-compose.yaml | 40 +++ .../dolphinscheduler/e2e/core/Constants.java | 4 + .../e2e/core/DolphinSchedulerExtension.java | 29 +- .../e2e/core/WebDriverWaitFactory.java | 2 +- dolphinscheduler-e2e/lombok.config | 2 +- dolphinscheduler-e2e/pom.xml | 8 +- .../src/main/resources/application.yaml | 2 +- dolphinscheduler-ui/package.json | 2 +- dolphinscheduler-ui/pnpm-lock.yaml | 2 +- 25 files changed, 717 insertions(+), 51 deletions(-) create mode 160000 .github/actions/workflow-telemetry-action create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/PythonTaskE2ETest.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/IEnvironment.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/PythonEnvironment.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/PythonTaskForm.java create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/Dockerfile create mode 100644 dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/docker-compose.yaml diff --git a/.github/actions/workflow-telemetry-action b/.github/actions/workflow-telemetry-action new file mode 160000 index 0000000000000..f974e0c5942f8 --- /dev/null +++ b/.github/actions/workflow-telemetry-action @@ -0,0 +1 @@ +Subproject commit f974e0c5942f8f37973c4cc395704165fbe629ba diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 1d2aa325716ff..24ebdb50474fb 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -29,6 +29,8 @@ concurrency: group: e2e-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true +permissions: + pull-requests: write jobs: paths-filter: @@ -124,12 +126,23 @@ jobs: class: org.apache.dolphinscheduler.e2e.cases.PostgresDataSourceE2ETest - name: ShellTaskE2ETest class: org.apache.dolphinscheduler.e2e.cases.tasks.ShellTaskE2ETest + - name: PythonTaskE2ETest + class: org.apache.dolphinscheduler.e2e.cases.tasks.PythonTaskE2ETest env: RECORDING_PATH: /tmp/recording-${{ matrix.case.name }} steps: - uses: actions/checkout@v4 with: submodules: true + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + java-version: 11 + distribution: 'adopt' + - name: Collect Workflow Telemetry + uses: ./.github/actions/workflow-telemetry-action + with: + comment_on_pr: false - name: Cache local Maven repository uses: actions/cache@v3 with: diff --git a/.gitmodules b/.gitmodules index bb2ed9794603e..0467f266493d6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ path = .github/actions/auto-assign-action url = https://github.com/kentaro-m/auto-assign-action.git branch = 288f36f +[submodule ".github/actions/workflow-telemetry-action"] + path = .github/actions/workflow-telemetry-action + url = https://github.com/catchpoint/workflow-telemetry-action diff --git a/dolphinscheduler-dist/release-docs/LICENSE b/dolphinscheduler-dist/release-docs/LICENSE index 290d0ab3f37e4..1fbd3e6e521ba 100644 --- a/dolphinscheduler-dist/release-docs/LICENSE +++ b/dolphinscheduler-dist/release-docs/LICENSE @@ -746,7 +746,7 @@ MIT licenses axios 0.27.2: https://github.com/axios/axios MIT date-fns 2.29.3: https://github.com/date-fns/date-fns MIT lodash 4.17.21: https://github.com/lodash/lodash MIT - monaco-editor 0.34.0: https://github.com/microsoft/monaco-editor MIT + monaco-editor 0.50.0: https://github.com/microsoft/monaco-editor MIT naive-ui 2.30.7: https://github.com/TuSimple/naive-ui MIT nprogress 0.2.0: https://github.com/rstacruz/nprogress MIT pinia 2.0.22: https://github.com/vuejs/pinia MIT diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/PythonTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/PythonTaskE2ETest.java new file mode 100644 index 0000000000000..239da7dfeb0e6 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/PythonTaskE2ETest.java @@ -0,0 +1,338 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.cases.tasks; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest; +import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverHolder; +import org.apache.dolphinscheduler.e2e.models.environment.PythonEnvironment; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; +import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.PythonTaskForm; +import org.apache.dolphinscheduler.e2e.pages.resource.FileManagePage; +import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; +import org.apache.dolphinscheduler.e2e.pages.security.EnvironmentPage; +import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; +import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; +import org.apache.dolphinscheduler.e2e.pages.security.UserPage; + +import java.util.Date; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; + +@DolphinScheduler(composeFiles = "docker/python-task/docker-compose.yaml") +public class PythonTaskE2ETest extends BaseWorkflowE2ETest { + + private static final PythonEnvironment pythonEnvironment = new PythonEnvironment(); + + @BeforeAll + public static void setup() { + browser = WebDriverHolder.getWebDriver(); + + TenantPage tenantPage = new LoginPage(browser) + .login(adminUser) + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class); + + if (tenantPage.tenants().stream().noneMatch(tenant -> tenant.tenantCode().equals(adminUser.getTenant()))) { + tenantPage + .create(adminUser.getTenant()) + .goToNav(SecurityPage.class) + .goToTab(UserPage.class) + .update(adminUser); + } + tenantPage + .goToNav(SecurityPage.class) + .goToTab(EnvironmentPage.class) + .createEnvironmentUntilSuccess(pythonEnvironment.getEnvironmentName(), + pythonEnvironment.getEnvironmentConfig(), + pythonEnvironment.getEnvironmentDesc(), + pythonEnvironment.getEnvironmentWorkerGroup()); + + tenantPage + .goToNav(ProjectPage.class) + .createProjectUntilSuccess(projectName); + } + + @Test + @Order(10) + void testRunPythonTasks_SuccessCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + // todo: use yaml to define the workflow + String workflowName = "PythonSuccessCase"; + String taskName = "PythonSuccessTask"; + String pythonScripts = "print(\"success\")"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.PYTHON) + .script(pythonScripts) + .name(taskName) + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + @Order(20) + void testRunPythonTasks_WorkflowParamsCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + // todo: use yaml to define the workflow + String workflowName = "PythonWorkflowParamsCase"; + String taskName = "PythonWorkflowParamsTask"; + String pythonScripts = "import sys\n" + + "\n" + + "if '${name}' == 'tom':\n" + + " print('success')\n" + + "else:\n" + + " sys.exit(2)"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.PYTHON) + .script(pythonScripts) + .name(taskName) + .submit() + + .submit() + .name(workflowName) + .addGlobalParam("name", "tom") + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + @Order(30) + void testRunPythonTasks_LocalParamsCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "PythonLocalParamsCase"; + String taskName = "PythonLocalParamsSuccess"; + String pythonScripts = "import sys\n" + + "\n" + + "if '${name}' == 'tom':\n" + + " print('success')\n" + + "else:\n" + + " sys.exit(2)"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.PYTHON) + .script(pythonScripts) + .name(taskName) + .addParam("name", "tom") + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + @Order(40) + void testRunPythonTasks_GlobalParamsOverrideLocalParamsCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "PythonLocalParamsOverrideWorkflowParamsCase"; + String taskName = "PythonLocalParamsOverrideWorkflowParamsSuccess"; + String pythonScripts = "import sys\n" + + "\n" + + "if '${name}' == 'jerry':\n" + + " print('success')\n" + + "else:\n" + + " sys.exit(2)"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.PYTHON) + .script(pythonScripts) + .name(taskName) + .addParam("name", "tom") + .submit() + + .submit() + .name(workflowName) + .addGlobalParam("name", "jerry") + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + @Order(50) + void testRunPythonTasks_UsingResourceFile() { + long current_timestamp = new Date().getTime(); + String testFileName = String.format("echo_%s", current_timestamp); + new ResourcePage(browser) + .goToNav(ResourcePage.class) + .goToTab(FileManagePage.class) + .createFileUntilSuccess(testFileName, "echo 123"); + + final WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "PythonUsingResourceFileWorkflowCase"; + String taskName = "PythonUsingResourceFileSuccessTask"; + String pythonScripts = "import sys\n" + + "\n" + + "file_content = \"\"\n" + + "\n" + + "with open('${file_name}', 'r', encoding='UTF8') as f:\n" + + " file_content = f.read()\n" + + "\n" + + "if len(file_content) != 0:\n" + + " print(f'file_content: {file_content}')\n" + + "else:\n" + + " sys.exit(2)\n" + + " "; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.PYTHON) + .script(pythonScripts) + .name(taskName) + .selectResource(testFileName) + .addParam("file_name", String.format("%s.sh", testFileName)) + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + + @Test + @Order(60) + void testRunPythonTasks_FailedCase() { + WorkflowDefinitionTab workflowDefinitionPage = + new ProjectPage(browser) + .goToNav(ProjectPage.class) + .goTo(projectName) + .goToTab(WorkflowDefinitionTab.class); + + String workflowName = "PythonFailedWorkflowCase"; + String taskName = "PythonFailedTask"; + String pythonScripts = "import sys\n" + + "sys.exit(1)"; + workflowDefinitionPage + .createWorkflow() + .addTask(WorkflowForm.TaskType.PYTHON) + .script(pythonScripts) + .name(taskName) + .submit() + + .submit() + .name(workflowName) + .submit(); + + untilWorkflowDefinitionExist(workflowName); + + workflowDefinitionPage.publish(workflowName); + + runWorkflow(workflowName); + untilWorkflowInstanceExist(workflowName); + WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceFailed(workflowName); + assertThat(workflowInstance.executionTime()).isEqualTo(1); + + TaskInstanceTab.Row taskInstance = untilTaskInstanceFailed(workflowName, taskName); + assertThat(taskInstance.retryTimes()).isEqualTo(0); + } + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java index 975c4faa78b20..12f8a4b14ef44 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/tasks/ShellTaskE2ETest.java @@ -21,6 +21,8 @@ import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest; import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; +import org.apache.dolphinscheduler.e2e.core.WebDriverHolder; +import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; @@ -29,7 +31,11 @@ import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; import org.apache.dolphinscheduler.e2e.pages.resource.FileManagePage; import org.apache.dolphinscheduler.e2e.pages.resource.ResourcePage; +import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; +import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; +import org.apache.dolphinscheduler.e2e.pages.security.UserPage; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @@ -38,6 +44,28 @@ @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") public class ShellTaskE2ETest extends BaseWorkflowE2ETest { + @BeforeAll + public static void setup() { + browser = WebDriverHolder.getWebDriver(); + + TenantPage tenantPage = new LoginPage(browser) + .login(adminUser) + .goToNav(SecurityPage.class) + .goToTab(TenantPage.class); + + if (tenantPage.tenants().stream().noneMatch(tenant -> tenant.tenantCode().equals(adminUser.getTenant()))) { + tenantPage + .create(adminUser.getTenant()) + .goToNav(SecurityPage.class) + .goToTab(UserPage.class) + .update(adminUser); + } + + tenantPage + .goToNav(ProjectPage.class) + .createProjectUntilSuccess(projectName); + } + @Test void testRunShellTasks_SuccessCase() { WorkflowDefinitionTab workflowDefinitionPage = diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java index e73f39ceb86b1..550f83d7191c1 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/workflow/BaseWorkflowE2ETest.java @@ -20,17 +20,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.testcontainers.shaded.org.awaitility.Awaitility.await; -import org.apache.dolphinscheduler.e2e.core.WebDriverHolder; import org.apache.dolphinscheduler.e2e.models.users.AdminUser; -import org.apache.dolphinscheduler.e2e.pages.LoginPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; -import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; -import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; -import org.apache.dolphinscheduler.e2e.pages.security.UserPage; import java.util.List; import java.util.Objects; @@ -39,7 +34,6 @@ import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeAll; import org.openqa.selenium.remote.RemoteWebDriver; @Slf4j @@ -51,27 +45,6 @@ public abstract class BaseWorkflowE2ETest { protected static RemoteWebDriver browser; - @BeforeAll - public static void setup() { - browser = WebDriverHolder.getWebDriver(); - - TenantPage tenantPage = new LoginPage(browser) - .login(adminUser) - .goToNav(SecurityPage.class) - .goToTab(TenantPage.class); - - if (tenantPage.tenants().stream().noneMatch(tenant -> tenant.tenantCode().equals(adminUser.getTenant()))) { - tenantPage - .create(adminUser.getTenant()) - .goToNav(SecurityPage.class) - .goToTab(UserPage.class) - .update(adminUser); - } - tenantPage - .goToNav(ProjectPage.class) - .createProjectUntilSuccess(projectName); - } - protected void untilWorkflowDefinitionExist(String workflowName) { WorkflowDefinitionTab workflowDefinitionPage = new ProjectPage(browser) .goToNav(ProjectPage.class) diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/IEnvironment.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/IEnvironment.java new file mode 100644 index 0000000000000..7469dfa271e0a --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/IEnvironment.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.models.environment; + +public interface IEnvironment { + + String getEnvironmentName(); + + String getEnvironmentConfig(); + + String getEnvironmentDesc(); + + String getEnvironmentWorkerGroup(); + +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/PythonEnvironment.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/PythonEnvironment.java new file mode 100644 index 0000000000000..63bf7e3cbba3a --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/models/environment/PythonEnvironment.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dolphinscheduler.e2e.models.environment; + +import lombok.Data; + +@Data +public class PythonEnvironment implements IEnvironment { + + private String environmentName; + + private String environmentConfig; + + private String environmentDesc; + + private String environmentWorkerGroup; + + @Override + public String getEnvironmentName() { + return "python-e2e"; + } + + @Override + public String getEnvironmentConfig() { + return "export PYTHON_LAUNCHER=/usr/bin/python3"; + } + + @Override + public String getEnvironmentDesc() { + return "pythonEnvDesc"; + } + + @Override + public String getEnvironmentWorkerGroup() { + return "default"; + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java index d1f4cc58ee7d5..19954bc8a19f9 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java @@ -19,10 +19,18 @@ */ package org.apache.dolphinscheduler.e2e.pages.common; +import org.apache.dolphinscheduler.e2e.core.Constants; import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; +import java.util.List; + import lombok.Getter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.platform.commons.util.StringUtils; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; @@ -32,13 +40,17 @@ import org.openqa.selenium.support.ui.ExpectedConditions; @Getter +@Slf4j public final class CodeEditor { @FindBys({ @FindBy(className = "monaco-editor"), @FindBy(className = "view-line"), }) - private WebElement editor; + private List editor; + + @FindBy(className = "pre-tasks-model") + private WebElement scrollBar; private WebDriver driver; @@ -47,14 +59,72 @@ public CodeEditor(WebDriver driver) { this.driver = driver; } + @SneakyThrows public CodeEditor content(String content) { - WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editor)); - - editor.click(); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions.elementToBeClickable(editor.get(0))); Actions actions = new Actions(this.driver); - actions.moveToElement(editor).sendKeys(content).perform(); + + List contentList = List.of(content.split(Constants.LINE_SEPARATOR)); + + try { + ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView();", scrollBar); + } catch (org.openqa.selenium.NoSuchElementException ignored) { + log.warn("scroll bar not found, skipping..."); + } + + for (int i = 0; i < contentList.size(); i++) { + String editorLineText; + String inputContent = contentList.get(i); + if (i == 0) { + actions.moveToElement(editor.get(i)) + .click() + .sendKeys(inputContent) + .sendKeys(Constants.LINE_SEPARATOR) + .perform(); + continue; + } else { + editorLineText = editor.get(i).getText(); + } + + if (StringUtils.isNotBlank(inputContent)) { + if (editorLineText.isEmpty()) { + actions.moveToElement(editor.get(i)) + .click() + .sendKeys(inputContent) + .sendKeys(Constants.LINE_SEPARATOR) + .perform(); + Thread.sleep(Constants.DEFAULT_SLEEP_MILLISECONDS); + } else { + for (int p = 0; p < editorLineText.strip().length(); p++) { + clearLine(actions, editor.get(i)); + } + if (!editorLineText.isEmpty()) { + clearLine(actions, editor.get(i)); + } + actions.moveToElement(editor.get(i)) + .click() + .sendKeys(inputContent) + .sendKeys(Constants.LINE_SEPARATOR) + .perform(); + Thread.sleep(Constants.DEFAULT_SLEEP_MILLISECONDS); + } + } else { + actions.moveToElement(editor.get(i)) + .click() + .sendKeys(Constants.LINE_SEPARATOR) + .perform(); + Thread.sleep(Constants.DEFAULT_SLEEP_MILLISECONDS); + } + } return this; } + + private void clearLine(Actions actions, WebElement element) { + actions.moveToElement(element) + .click() + .sendKeys(Keys.BACK_SPACE) + .perform(); + } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java index ec8a1766cdf61..319a59d37dacf 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowForm.java @@ -22,6 +22,7 @@ import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.PythonTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTaskForm; import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SwitchTaskForm; @@ -75,6 +76,8 @@ public T addTask(TaskType type) { final String dragAndDrop = String.join("\n", Resources.readLines(Resources.getResource("dragAndDrop.js"), StandardCharsets.UTF_8)); js.executeScript(dragAndDrop, task, canvas); + WebDriverWaitFactory.createWebDriverWait(driver).until(ExpectedConditions + .visibilityOfElementLocated(By.xpath("//*[contains(text(), 'Current node settings')]"))); switch (type) { case SHELL: @@ -87,6 +90,8 @@ public T addTask(TaskType type) { return (T) new HttpTaskForm(this); case JAVA: return (T) new JavaTaskForm(this); + case PYTHON: + return (T) new PythonTaskForm(this); } throw new UnsupportedOperationException("Unknown task type"); } @@ -126,5 +131,6 @@ public enum TaskType { SWITCH, HTTP, JAVA, + PYTHON } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java index bbf6ace88cd16..4d5ea9329646d 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowRunDialog.java @@ -26,6 +26,7 @@ import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.ui.ExpectedConditions; @@ -34,7 +35,10 @@ public final class WorkflowRunDialog { private final WorkflowDefinitionTab parent; - @FindBy(className = "btn-submit") + @FindBys({ + @FindBy(xpath = "//div[contains(text(), 'Please set the parameters before starting')]/../.."), + @FindBy(className = "btn-submit") + }) private WebElement buttonSubmit; public WorkflowRunDialog(WorkflowDefinitionTab parent) { @@ -52,7 +56,8 @@ public WorkflowDefinitionTab submit() { .until(ExpectedConditions.elementToBeClickable(buttonSubmit())); buttonSubmit().click(); - + WebDriverWaitFactory.createWebDriverWait(parent.driver()) + .until(ExpectedConditions.invisibilityOfElementLocated(runDialogTitleXpath)); return parent(); } } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/PythonTaskForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/PythonTaskForm.java new file mode 100644 index 0000000000000..0ebabda411aa4 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/PythonTaskForm.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; + +import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; +import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; + +import lombok.Getter; + +import org.openqa.selenium.WebDriver; + +@Getter +public final class PythonTaskForm extends TaskNodeForm { + + private CodeEditor codeEditor; + + private WebDriver driver; + + public PythonTaskForm(WorkflowForm parent) { + super(parent); + + this.codeEditor = new CodeEditor(parent.driver()); + + this.driver = parent.driver(); + } + + public PythonTaskForm script(String script) { + codeEditor.content(script); + + return this; + } +} diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java index 62a4d4893afbe..de4bac3567583 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/task/TaskNodeForm.java @@ -28,6 +28,7 @@ import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -178,6 +179,8 @@ public TaskNodeForm selectResource(String resourceName) { .findFirst() .orElseThrow(() -> new RuntimeException("No such resource: " + resourceName)) .click(); + + parent.driver().switchTo().activeElement().sendKeys(Keys.ESCAPE); return this; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java index 8dd85ae60151f..d8fc86eb04d78 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/EnvironmentPage.java @@ -19,6 +19,9 @@ package org.apache.dolphinscheduler.e2e.pages.security; +import static org.assertj.core.api.Assertions.assertThat; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; @@ -82,6 +85,14 @@ public EnvironmentPage create(String name, String config, String desc, String wo return this; } + public EnvironmentPage createEnvironmentUntilSuccess(String name, String config, String desc, String workerGroup) { + create(name, config, desc, workerGroup); + await().untilAsserted(() -> assertThat(environmentList()) + .as("environment list should contain newly-created environment") + .anyMatch(it -> it.getText().contains(name))); + return this; + } + public EnvironmentPage update(String oldName, String name, String config, String desc, String workerGroup) { environmentList() .stream() diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/Dockerfile b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/Dockerfile new file mode 100644 index 0000000000000..92103973f18f4 --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/Dockerfile @@ -0,0 +1,25 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +FROM apache/dolphinscheduler-standalone-server:ci + +RUN apt update \ + && apt install -y software-properties-common \ + && add-apt-repository ppa:deadsnakes/ppa \ + && apt update \ + && apt-get install -y python3.8 libpython3.8-dev python3.8-dev python3.8-distutils \ + && rm -rf /var/lib/apt/lists/* diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/docker-compose.yaml b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/docker-compose.yaml new file mode 100644 index 0000000000000..3a287cce3dd8c --- /dev/null +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/resources/docker/python-task/docker-compose.yaml @@ -0,0 +1,40 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +version: "3.8" + +services: + dolphinscheduler: + image: apache/dolphinscheduler-standalone-server:ci-python + build: + context: . + dockerfile: ./Dockerfile + environment: + MASTER_MAX_CPU_LOAD_AVG: 100 + WORKER_TENANT_AUTO_CREATE: 'true' + ports: + - "12345:12345" + networks: + - e2e + healthcheck: + test: [ "CMD", "curl", "http://localhost:12345/dolphinscheduler/actuator/health" ] + interval: 5s + timeout: 5s + retries: 120 + +networks: + e2e: diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java index aa471a5618606..1eb0fb4bafd62 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/Constants.java @@ -39,4 +39,8 @@ public final class Constants { * chrome download path in selenium/standalone-chrome-debug container */ public static final String SELENIUM_CONTAINER_CHROME_DOWNLOAD_PATH = "/home/seluser/Downloads"; + + public static final String LINE_SEPARATOR = "\n"; + + public static final long DEFAULT_SLEEP_MILLISECONDS = 500; } diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java index b73a487e6fc4c..973af59e12ff5 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/DolphinSchedulerExtension.java @@ -47,6 +47,7 @@ import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.remote.RemoteWebDriver; import org.testcontainers.Testcontainers; +import org.testcontainers.containers.BindMode; import org.testcontainers.containers.BrowserWebDriverContainer; import org.testcontainers.containers.ComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; @@ -98,12 +99,15 @@ public void beforeAll(ExtensionContext context) throws IOException { browser.withAccessToHost(true); } browser.start(); - - driver = new RemoteWebDriver(browser.getSeleniumAddress(), new ChromeOptions()); + ChromeOptions chromeOptions = new ChromeOptions(); + chromeOptions.addArguments("--allow-running-insecure-content"); + chromeOptions.addArguments(String.format("--unsafely-treat-insecure-origin-as-secure=http://%s:%s", + address.getHost(), address.getPort())); + driver = new RemoteWebDriver(browser.getSeleniumAddress(), chromeOptions); driver.manage().timeouts() - .implicitlyWait(Duration.ofSeconds(10)) - .pageLoadTimeout(Duration.ofSeconds(10)); + .implicitlyWait(Duration.ofSeconds(1)) + .pageLoadTimeout(Duration.ofSeconds(5)); driver.manage().window() .maximize(); @@ -141,11 +145,20 @@ private void setBrowserContainerByOsName() { imageName = DockerImageName.parse("seleniarm/standalone-chromium:124.0-chromedriver-124.0") .asCompatibleSubstituteFor("selenium/standalone-chrome"); + if (!Files.exists(Constants.HOST_CHROME_DOWNLOAD_PATH)) { + try { + Files.createDirectories(Constants.HOST_CHROME_DOWNLOAD_PATH); + } catch (IOException e) { + log.error("Failed to create chrome download directory: {}", Constants.HOST_CHROME_DOWNLOAD_PATH); + throw new RuntimeException(e); + } + } + browser = new BrowserWebDriverContainer<>(imageName) .withCapabilities(new ChromeOptions()) .withCreateContainerCmdModifier(cmd -> cmd.withUser("root")) .withFileSystemBind(Constants.HOST_CHROME_DOWNLOAD_PATH.toFile().getAbsolutePath(), - Constants.SELENIUM_CONTAINER_CHROME_DOWNLOAD_PATH) + Constants.SELENIUM_CONTAINER_CHROME_DOWNLOAD_PATH, BindMode.READ_WRITE) .withRecordingMode(RECORD_ALL, record.toFile(), MP4) .withStartupTimeout(Duration.ofSeconds(300)); } else { @@ -153,7 +166,7 @@ private void setBrowserContainerByOsName() { .withCapabilities(new ChromeOptions()) .withCreateContainerCmdModifier(cmd -> cmd.withUser("root")) .withFileSystemBind(Constants.HOST_CHROME_DOWNLOAD_PATH.toFile().getAbsolutePath(), - Constants.SELENIUM_CONTAINER_CHROME_DOWNLOAD_PATH) + Constants.SELENIUM_CONTAINER_CHROME_DOWNLOAD_PATH, BindMode.READ_WRITE) .withRecordingMode(RECORD_ALL, record.toFile(), MP4) .withStartupTimeout(Duration.ofSeconds(300)); } @@ -194,7 +207,7 @@ private void setDriver(Object object, Field field) { field.setAccessible(true); field.set(object, driver); } catch (IllegalAccessException e) { - LOGGER.error("Failed to inject web driver to field: {}", field.getName(), e); + log.error("Failed to inject web driver to field: {}", field.getName(), e); } } @@ -215,7 +228,7 @@ private ComposeContainer createDockerCompose(ExtensionContext context) { .withExposedService( serviceName, DOCKER_PORT, Wait.forListeningPort().withStartupTimeout(Duration.ofSeconds(300))) - .withLogConsumer(serviceName, outputFrame -> LOGGER.info(outputFrame.getUtf8String())) + .withLogConsumer(serviceName, outputFrame -> log.info(outputFrame.getUtf8String())) .waitingFor(serviceName, Wait.forHealthcheck().withStartupTimeout(Duration.ofSeconds(300))); return compose; diff --git a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java index a423f75973b70..2d9f47eb23a8b 100644 --- a/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java +++ b/dolphinscheduler-e2e/dolphinscheduler-e2e-core/src/main/java/org/apache/dolphinscheduler/e2e/core/WebDriverWaitFactory.java @@ -26,7 +26,7 @@ public class WebDriverWaitFactory { private static final Duration DEFAULT_INTERVAL = Duration.ofMillis(500); - private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(60); + private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); /** * Create a WebDriverWait instance with default timeout 60s and interval 100ms. diff --git a/dolphinscheduler-e2e/lombok.config b/dolphinscheduler-e2e/lombok.config index 0056b8f78b64f..cc34fa2311d75 100644 --- a/dolphinscheduler-e2e/lombok.config +++ b/dolphinscheduler-e2e/lombok.config @@ -16,5 +16,5 @@ # lombok.accessors.fluent=true -lombok.log.fieldname=LOGGER +lombok.log.fieldname=log lombok.accessors.fluent=true diff --git a/dolphinscheduler-e2e/pom.xml b/dolphinscheduler-e2e/pom.xml index c4bc984de3ae1..3ee8886acb13c 100644 --- a/dolphinscheduler-e2e/pom.xml +++ b/dolphinscheduler-e2e/pom.xml @@ -36,13 +36,15 @@ UTF-8 5.8.1 - 4.13.0 + 4.21.0 1.18.20 3.20.2 1.5.30 1.7.36 2.17.2 31.0.1-jre + 2.22.2 + 1.19.8 @@ -119,7 +121,7 @@ org.testcontainers testcontainers-bom - 1.19.8 + ${testcontainers.version} import pom @@ -131,7 +133,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.22.2 + ${maven-surefire-plugin.version} diff --git a/dolphinscheduler-standalone-server/src/main/resources/application.yaml b/dolphinscheduler-standalone-server/src/main/resources/application.yaml index e88cafa8ccec8..2da687d285ea0 100644 --- a/dolphinscheduler-standalone-server/src/main/resources/application.yaml +++ b/dolphinscheduler-standalone-server/src/main/resources/application.yaml @@ -179,7 +179,7 @@ master: server-load-protection: enabled: true # Master max system cpu usage, when the master's system cpu usage is smaller then this value, master server can execute workflow. - max-system-cpu-usage-percentage-thresholds: 0.9 + max-system-cpu-usage-percentage-thresholds: 1 # Master max jvm cpu usage, when the master's jvm cpu usage is smaller then this value, master server can execute workflow. max-jvm-cpu-usage-percentage-thresholds: 0.9 # Master max System memory usage , when the master's system memory usage is smaller then this value, master server can execute workflow. diff --git a/dolphinscheduler-ui/package.json b/dolphinscheduler-ui/package.json index 9bdd454e0f682..d48b6705f3131 100644 --- a/dolphinscheduler-ui/package.json +++ b/dolphinscheduler-ui/package.json @@ -19,7 +19,7 @@ "echarts": "^5.3.3", "js-cookie": "^3.0.1", "lodash": "^4.17.21", - "monaco-editor": "^0.34.0", + "monaco-editor": "^0.50.0", "naive-ui": "2.33.5", "nprogress": "^0.2.0", "pinia": "^2.0.22", diff --git a/dolphinscheduler-ui/pnpm-lock.yaml b/dolphinscheduler-ui/pnpm-lock.yaml index 5621ef47eccce..3fc9f1c79d1c8 100644 --- a/dolphinscheduler-ui/pnpm-lock.yaml +++ b/dolphinscheduler-ui/pnpm-lock.yaml @@ -42,7 +42,7 @@ specifiers: eslint-plugin-vue: ^9.5.1 js-cookie: ^3.0.1 lodash: ^4.17.21 - monaco-editor: ^0.34.0 + monaco-editor: ^0.50.0 naive-ui: 2.33.5 nprogress: ^0.2.0 pinia: ^2.0.22 From ed2c10815b941cbdae28661a2aee444c22f34554 Mon Sep 17 00:00:00 2001 From: Wenjun Ruan Date: Mon, 1 Jul 2024 22:05:57 +0800 Subject: [PATCH 09/18] Fix JDBCRegistry refresh lock error (#16252) --- .../plugin/registry/jdbc/mapper/JdbcRegistryLockMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/mapper/JdbcRegistryLockMapper.java b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/mapper/JdbcRegistryLockMapper.java index 0f529a8786706..2d11c90a24144 100644 --- a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/mapper/JdbcRegistryLockMapper.java +++ b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/mapper/JdbcRegistryLockMapper.java @@ -38,7 +38,7 @@ public interface JdbcRegistryLockMapper extends BaseMapper { @Update({"