From 2eb1f3612039669e62d0a1cf28607b81516ce0fc Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Thu, 24 Aug 2023 18:43:08 +0530 Subject: [PATCH 01/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .github/workflows/ci.yml | 37 +++++++------------ .../TestOzoneFSWithObjectStoreCreate.java | 8 ++-- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70cb55e4aea4..4e6b9292ade6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,14 +25,13 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} outputs: - basic-checks: ${{ steps.selective-checks.outputs.basic-checks }} - needs-basic-checks: ${{ steps.selective-checks.outputs.needs-basic-checks }} - needs-build: ${{ steps.selective-checks.outputs.needs-build }} - needs-compile: ${{ steps.selective-checks.outputs.needs-compile }} - needs-compose-tests: ${{ steps.selective-checks.outputs.needs-compose-tests }} - needs-dependency-check: ${{ steps.selective-checks.outputs.needs-dependency-check }} + needs-basic-checks: false + needs-build: false + needs-compile: false + needs-compose-tests: false + needs-dependency-check: false needs-integration-tests: ${{ steps.selective-checks.outputs.needs-integration-tests }} - needs-kubernetes-tests: ${{ steps.selective-checks.outputs.needs-kubernetes-tests }} + needs-kubernetes-tests: false steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" uses: actions/checkout@v3 @@ -322,20 +321,11 @@ jobs: needs: - build-info runs-on: ubuntu-20.04 - timeout-minutes: 150 + timeout-minutes: 600 if: needs.build-info.outputs.needs-integration-tests == 'true' strategy: matrix: - profile: - - client - - contract - - filesystem - - hdds - - om - - ozone - - scm - - shell - - flaky + profile: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] fail-fast: false steps: - name: Checkout project @@ -355,14 +345,15 @@ jobs: distribution: 'temurin' java-version: 8 - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} - if: matrix.profile != 'flaky' - - name: Execute flaky tests - run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} -Dsurefire.rerunFailingTestsCount=5 -Dsurefire.fork.timeout=3600 - if: matrix.profile == 'flaky' + run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneFSWithObjectStoreCreate,TestOzoneFileSystem,TestOzoneFileSystemWithFSO,TestObjectStoreWithFSO + env: + ITERATIONS: 10 - name: Summary of failures run: cat target/${{ github.job }}/summary.txt if: always() + - name: Number of failures + run: cat target/${{ github.job }}/failures + if: always() - name: Archive build results uses: actions/upload-artifact@v3 if: always() diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java index a72fd5a11a78..5109ce647453 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java @@ -183,7 +183,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { keys.add("/dir1/dir2/dir3/dir4/"); for (int i = 1; i <= 3; i++) { int length = 10; - String fileName = parentDir.concat("/file" + i + "/"); + String fileName = parentDir.concat("file" + i + "/"); keys.add(fileName); OzoneOutputStream ozoneOutputStream = ozoneBucket.createKey(fileName, length); @@ -195,7 +195,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { // check for (int i = 1; i <= 3; i++) { - String fileName = parentDir.concat("/file" + i + "/"); + String fileName = parentDir.concat("file" + i + "/"); Path p = new Path(fileName); Assert.assertTrue(o3fs.getFileStatus(p).isFile()); checkAncestors(p); @@ -203,7 +203,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { // Delete keys with object store api delete for (int i = 1; i <= 3; i++) { - String fileName = parentDir.concat("/file" + i + "/"); + String fileName = parentDir.concat("file" + i + "/"); ozoneBucket.deleteKey(fileName); } @@ -220,7 +220,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { for (int i = 1; i <= 3; i++) { int length = 10; - String fileName = parentDir.concat("/file" + i + "/"); + String fileName = parentDir.concat("file" + i + "/"); OzoneOutputStream ozoneOutputStream = ozoneBucket.createKey(fileName, length); byte[] b = new byte[10]; From 56462ad122930a9c9e58991ffcb9a4810a3d771a Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Fri, 25 Aug 2023 19:40:01 +0530 Subject: [PATCH 02/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e6b9292ade6..75486c25ba96 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -345,7 +345,7 @@ jobs: distribution: 'temurin' java-version: 8 - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneFSWithObjectStoreCreate,TestOzoneFileSystem,TestOzoneFileSystemWithFSO,TestObjectStoreWithFSO + run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneFSWithObjectStoreCreate env: ITERATIONS: 10 - name: Summary of failures From 9a06841e1f70009bb82ec9b76b0b3810ac358d0f Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Fri, 25 Aug 2023 20:47:24 +0530 Subject: [PATCH 03/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75486c25ba96..4e6b9292ade6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -345,7 +345,7 @@ jobs: distribution: 'temurin' java-version: 8 - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneFSWithObjectStoreCreate + run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneFSWithObjectStoreCreate,TestOzoneFileSystem,TestOzoneFileSystemWithFSO,TestObjectStoreWithFSO env: ITERATIONS: 10 - name: Summary of failures From 0cb01317393028f22fcb20882b827fcb6e4699cd Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 30 Aug 2023 09:14:52 +0530 Subject: [PATCH 04/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .github/workflows/ci.yml | 270 +----------------- .../TestOzoneFSWithObjectStoreCreate.java | 210 -------------- 2 files changed, 6 insertions(+), 474 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e6b9292ade6..1aa9391fcca4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,12 +25,13 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} outputs: + basic-checks: ${{ steps.selective-checks.outputs.basic-checks }} needs-basic-checks: false - needs-build: false + needs-build: true needs-compile: false needs-compose-tests: false needs-dependency-check: false - needs-integration-tests: ${{ steps.selective-checks.outputs.needs-integration-tests }} + needs-integration-tests: true needs-kubernetes-tests: false steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" @@ -114,214 +115,11 @@ jobs: rm -rf ~/.m2/repository/org/apache/ozone/hdds* rm -rf ~/.m2/repository/org/apache/ozone/ozone* if: always() - compile: - needs: - - build-info - - build - runs-on: ubuntu-20.04 - timeout-minutes: 30 - if: needs.build-info.outputs.needs-compile == 'true' - strategy: - matrix: - java: [ 11, 17 ] - fail-fast: false - steps: - - name: Download Ozone source tarball - uses: actions/download-artifact@v3 - with: - name: ozone-src - - name: Untar sources - run: | - tar --strip-components 1 -xzvf ozone*-src.tar.gz - - name: Cache for maven dependencies - uses: actions/cache@v3 - with: - path: ~/.m2/repository - key: maven-repo-${{ hashFiles('**/pom.xml') }}-${{ matrix.java }} - restore-keys: | - maven-repo-${{ hashFiles('**/pom.xml') }} - maven-repo- - - name: Setup java - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: ${{ matrix.java }} - - name: Compile Ozone using Java ${{ matrix.java }} - run: hadoop-ozone/dev-support/checks/build.sh -Dskip.npx -Dskip.installnpx -Djavac.version=${{ matrix.java }} - env: - OZONE_WITH_COVERAGE: false - - name: Delete temporary build artifacts before caching - run: | - #Never cache local artifacts - rm -rf ~/.m2/repository/org/apache/ozone/hdds* - rm -rf ~/.m2/repository/org/apache/ozone/ozone* - if: always() - basic: - needs: - - build-info - runs-on: ubuntu-20.04 - timeout-minutes: 90 - if: needs.build-info.outputs.needs-basic-checks == 'true' - strategy: - matrix: - check: ${{ fromJson(needs.build-info.outputs.basic-checks) }} - fail-fast: false - steps: - - name: Checkout project - uses: actions/checkout@v3 - if: matrix.check != 'bats' - - name: Checkout project with history - uses: actions/checkout@v3 - with: - fetch-depth: 0 - if: matrix.check == 'bats' - - name: Cache for maven dependencies - uses: actions/cache@v3 - with: - path: ~/.m2/repository - key: maven-repo-${{ hashFiles('**/pom.xml') }}-8-${{ matrix.check }} - restore-keys: | - maven-repo-${{ hashFiles('**/pom.xml') }}-8 - maven-repo-${{ hashFiles('**/pom.xml') }} - maven-repo- - if: ${{ !contains('author,bats,docs', matrix.check) }} - - name: Setup java - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: 8 - - name: Execute tests - run: hadoop-ozone/dev-support/checks/${{ matrix.check }}.sh - - name: Summary of failures - run: cat target/${{ matrix.check }}/summary.txt - if: ${{ !cancelled() }} - - name: Archive build results - uses: actions/upload-artifact@v3 - if: ${{ !cancelled() }} - with: - name: ${{ matrix.check }} - path: target/${{ matrix.check }} - continue-on-error: true - - name: Delete temporary build artifacts before caching - run: | - #Never cache local artifacts - rm -rf ~/.m2/repository/org/apache/ozone/hdds* - rm -rf ~/.m2/repository/org/apache/ozone/ozone* - if: always() - dependency: - needs: - - build-info - - build - runs-on: ubuntu-20.04 - timeout-minutes: 5 - if: needs.build-info.outputs.needs-dependency-check == 'true' - steps: - - name: Checkout project - uses: actions/checkout@v3 - - name: Download compiled Ozone binaries - uses: actions/download-artifact@v3 - with: - name: ozone-bin - - name: Untar binaries - run: | - mkdir dist - tar -C dist --strip-components 1 -xzf ozone*.tar.gz - - name: Execute tests - run: | - export OZONE_DIST_DIR=`pwd`/dist - ./hadoop-ozone/dev-support/checks/dependency.sh - - name: Archive build results - uses: actions/upload-artifact@v3 - if: always() - with: - name: dependency - path: target/dependency - continue-on-error: true - acceptance: - needs: - - build-info - - build - runs-on: ubuntu-20.04 - timeout-minutes: 150 - if: needs.build-info.outputs.needs-compose-tests == 'true' - strategy: - matrix: - suite: - - secure - - unsecure - - compat - - EC - - HA-secure - - HA-unsecure - - MR - - misc - - cert-rotation - fail-fast: false - steps: - - name: Checkout project - uses: actions/checkout@v3 - - name: Download compiled Ozone binaries - uses: actions/download-artifact@v3 - with: - name: ozone-bin - - name: Untar binaries - run: | - mkdir -p hadoop-ozone/dist/target - tar xzvf ozone*.tar.gz -C hadoop-ozone/dist/target - sudo chmod -R a+rwX hadoop-ozone/dist/target - - name: Execute tests - run: | - pushd hadoop-ozone/dist/target/ozone-* - sudo mkdir .aws && sudo chmod 777 .aws && sudo chown 1000 .aws - popd - ./hadoop-ozone/dev-support/checks/acceptance.sh - env: - KEEP_IMAGE: false - OZONE_ACCEPTANCE_SUITE: ${{ matrix.suite }} - OZONE_VOLUME_OWNER: 1000 - - name: Archive build results - uses: actions/upload-artifact@v3 - if: always() - with: - name: acceptance-${{ matrix.suite }} - path: target/acceptance - continue-on-error: true - kubernetes: - needs: - - build-info - - build - runs-on: ubuntu-20.04 - timeout-minutes: 60 - if: needs.build-info.outputs.needs-kubernetes-tests == 'true' - steps: - - name: Checkout project - uses: actions/checkout@v3 - - name: Download compiled Ozone binaries - uses: actions/download-artifact@v3 - with: - name: ozone-bin - - name: Untar binaries - run: | - mkdir -p hadoop-ozone/dist/target - tar xzvf ozone*.tar.gz -C hadoop-ozone/dist/target - - name: Execute tests - run: | - pushd hadoop-ozone/dist/target/ozone-* - sudo mkdir .aws && sudo chmod 777 .aws && sudo chown 1000 .aws - popd - ./hadoop-ozone/dev-support/checks/kubernetes.sh - - name: Archive build results - uses: actions/upload-artifact@v3 - if: always() - with: - name: kubernetes - path: target/kubernetes - continue-on-error: true integration: needs: - build-info runs-on: ubuntu-20.04 - timeout-minutes: 600 + timeout-minutes: 300 if: needs.build-info.outputs.needs-integration-tests == 'true' strategy: matrix: @@ -345,15 +143,11 @@ jobs: distribution: 'temurin' java-version: 8 - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneFSWithObjectStoreCreate,TestOzoneFileSystem,TestOzoneFileSystemWithFSO,TestObjectStoreWithFSO - env: - ITERATIONS: 10 + run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=org.apache.hadoop.fs.ozone.TestOzoneFSWithObjectStoreCreate + if: always() - name: Summary of failures run: cat target/${{ github.job }}/summary.txt if: always() - - name: Number of failures - run: cat target/${{ github.job }}/failures - if: always() - name: Archive build results uses: actions/upload-artifact@v3 if: always() @@ -367,55 +161,3 @@ jobs: rm -rf ~/.m2/repository/org/apache/ozone/hdds* rm -rf ~/.m2/repository/org/apache/ozone/ozone* if: always() - coverage: - runs-on: ubuntu-20.04 - timeout-minutes: 30 - if: github.repository == 'apache/ozone' && github.event_name != 'pull_request' - needs: - - acceptance - - basic - - integration - steps: - - name: Checkout project - uses: actions/checkout@v3 - - name: Cache for maven dependencies - uses: actions/cache@v3 - with: - path: ~/.m2/repository - key: maven-repo-${{ hashFiles('**/pom.xml') }}-8-${{ github.job }} - restore-keys: | - maven-repo-${{ hashFiles('**/pom.xml') }}-8 - maven-repo-${{ hashFiles('**/pom.xml') }} - maven-repo- - - name: Download artifacts - uses: actions/download-artifact@v3 - with: - path: target/artifacts - - name: Untar binaries - run: | - mkdir -p hadoop-ozone/dist/target - tar xzvf target/artifacts/ozone-bin/ozone*.tar.gz -C hadoop-ozone/dist/target - - name: Calculate combined coverage - run: ./hadoop-ozone/dev-support/checks/coverage.sh - - name: Setup java 11 - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: 11 - - name: Upload coverage to Sonar - run: ./hadoop-ozone/dev-support/checks/sonar.sh - env: - SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Archive build results - uses: actions/upload-artifact@v3 - with: - name: coverage - path: target/coverage - continue-on-error: true - - name: Delete temporary build artifacts before caching - run: | - #Never cache local artifacts - rm -rf ~/.m2/repository/org/apache/ozone/hdds* - rm -rf ~/.m2/repository/org/apache/ozone/ozone* - if: always() diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java index 5109ce647453..37e69cf480e1 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java @@ -125,45 +125,6 @@ public void teardown() { IOUtils.closeQuietly(o3fs); } - @Test - public void test() throws Exception { - - OzoneVolume ozoneVolume = - client.getObjectStore().getVolume(volumeName); - - OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); - - String key1 = "///dir1/dir2/file1"; - String key2 = "///dir1/dir2/file2"; - int length = 10; - OzoneOutputStream ozoneOutputStream = ozoneBucket.createKey(key1, length); - byte[] b = new byte[10]; - Arrays.fill(b, (byte)96); - ozoneOutputStream.write(b); - ozoneOutputStream.close(); - - ozoneOutputStream = ozoneBucket.createKey(key2, length); - ozoneOutputStream.write(b); - ozoneOutputStream.close(); - - // Adding "/" here otherwise Path will be considered as relative path and - // workingDir will be added. - key1 = "///dir1/dir2/file1"; - Path p = new Path(key1); - Assert.assertTrue(o3fs.getFileStatus(p).isFile()); - - p = p.getParent(); - checkAncestors(p); - - - key2 = "///dir1/dir2/file2"; - p = new Path(key2); - Assert.assertTrue(o3fs.getFileStatus(p).isFile()); - checkAncestors(p); - - } - - @Test public void testObjectStoreCreateWithO3fs() throws Exception { OzoneVolume ozoneVolume = @@ -247,177 +208,6 @@ public void testObjectStoreCreateWithO3fs() throws Exception { } - - @Test - public void testKeyCreationFailDuetoDirectoryCreationBeforeCommit() - throws Exception { - OzoneVolume ozoneVolume = - client.getObjectStore().getVolume(volumeName); - - OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); - - OzoneOutputStream ozoneOutputStream = - ozoneBucket.createKey("/a/b/c", 10); - byte[] b = new byte[10]; - Arrays.fill(b, (byte)96); - ozoneOutputStream.write(b); - - // Before close create directory with same name. - o3fs.mkdirs(new Path("/a/b/c")); - - try { - ozoneOutputStream.close(); - fail("testKeyCreationFailDuetoDirectoryCreationBeforeCommit"); - } catch (IOException ex) { - Assert.assertTrue(ex instanceof OMException); - Assert.assertEquals(NOT_A_FILE, - ((OMException) ex).getResult()); - } - - } - - - @Test - public void testMPUFailDuetoDirectoryCreationBeforeComplete() - throws Exception { - OzoneVolume ozoneVolume = - client.getObjectStore().getVolume(volumeName); - - OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); - - String keyName = "/dir1/dir2/mpukey"; - OmMultipartInfo omMultipartInfo = - ozoneBucket.initiateMultipartUpload(keyName); - Assert.assertNotNull(omMultipartInfo); - - OzoneOutputStream ozoneOutputStream = - ozoneBucket.createMultipartKey(keyName, 10, 1, - omMultipartInfo.getUploadID()); - byte[] b = new byte[10]; - Arrays.fill(b, (byte)96); - ozoneOutputStream.write(b); - - // Before close, create directory with same name. - o3fs.mkdirs(new Path(keyName)); - - // This should succeed, as we check during creation of part or during - // complete MPU. - ozoneOutputStream.close(); - - Map partsMap = new HashMap<>(); - partsMap.put(1, ozoneOutputStream.getCommitUploadPartInfo().getPartName()); - - // Should fail, as we have directory with same name. - try { - ozoneBucket.completeMultipartUpload(keyName, - omMultipartInfo.getUploadID(), partsMap); - fail("testMPUFailDuetoDirectoryCreationBeforeComplete failed"); - } catch (OMException ex) { - Assert.assertTrue(ex instanceof OMException); - Assert.assertEquals(NOT_A_FILE, ex.getResult()); - } - - // Delete directory - o3fs.delete(new Path(keyName), true); - - // And try again for complete MPU. This should succeed. - ozoneBucket.completeMultipartUpload(keyName, - omMultipartInfo.getUploadID(), partsMap); - - try (FSDataInputStream ozoneInputStream = o3fs.open(new Path(keyName))) { - byte[] buffer = new byte[10]; - // This read will not change the offset inside the file - int readBytes = ozoneInputStream.read(0, buffer, 0, 10); - String readData = new String(buffer, 0, readBytes, UTF_8); - Assert.assertEquals(new String(b, 0, b.length, UTF_8), readData); - } - - } - - @Test - public void testCreateDirectoryFirstThenKeyAndFileWithSameName() - throws Exception { - o3fs.mkdirs(new Path("/t1/t2")); - - try { - o3fs.create(new Path("/t1/t2")); - fail("testCreateDirectoryFirstThenFileWithSameName failed"); - } catch (FileAlreadyExistsException ex) { - Assert.assertTrue(ex.getMessage().contains(NOT_A_FILE.name())); - } - - OzoneVolume ozoneVolume = - client.getObjectStore().getVolume(volumeName); - OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); - ozoneBucket.createDirectory("t1/t2"); - try { - ozoneBucket.createKey("t1/t2", 0); - fail("testCreateDirectoryFirstThenFileWithSameName failed"); - } catch (OMException ex) { - Assert.assertTrue(ex instanceof OMException); - Assert.assertEquals(NOT_A_FILE, ex.getResult()); - } - } - - - @Test - public void testListKeysWithNotNormalizedPath() throws Exception { - - OzoneVolume ozoneVolume = - client.getObjectStore().getVolume(volumeName); - - OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); - - String key1 = "/dir1///dir2/file1/"; - String key2 = "/dir1///dir2/file2/"; - String key3 = "/dir1///dir2/file3/"; - - LinkedList keys = new LinkedList<>(); - keys.add("dir1/"); - keys.add("dir1/dir2/"); - keys.add(OmUtils.normalizeKey(key1, false)); - keys.add(OmUtils.normalizeKey(key2, false)); - keys.add(OmUtils.normalizeKey(key3, false)); - - int length = 10; - byte[] input = new byte[length]; - Arrays.fill(input, (byte)96); - - createKey(ozoneBucket, key1, 10, input); - createKey(ozoneBucket, key2, 10, input); - createKey(ozoneBucket, key3, 10, input); - - // Iterator with key name as prefix. - - Iterator ozoneKeyIterator = - ozoneBucket.listKeys("/dir1//"); - - checkKeyList(ozoneKeyIterator, keys); - - // Iterator with with normalized key prefix. - ozoneKeyIterator = - ozoneBucket.listKeys("dir1/"); - - checkKeyList(ozoneKeyIterator, keys); - - // Iterator with key name as previous key. - ozoneKeyIterator = ozoneBucket.listKeys(null, - "/dir1///dir2/file1/"); - - // Remove keys before //dir1/dir2/file1 - keys.remove("dir1/"); - keys.remove("dir1/dir2/"); - keys.remove("dir1/dir2/file1"); - - checkKeyList(ozoneKeyIterator, keys); - - // Iterator with normalized key as previous key. - ozoneKeyIterator = ozoneBucket.listKeys(null, - OmUtils.normalizeKey(key1, false)); - - checkKeyList(ozoneKeyIterator, keys); - } - private void checkKeyList(Iterator ozoneKeyIterator, List keys) { From d2563bc7e60b5976d46b7af9dbf30d06a4b66d3c Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 30 Aug 2023 17:24:20 +0530 Subject: [PATCH 05/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .../fs/ozone/TestOzoneFSWithObjectStoreCreate.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java index 37e69cf480e1..e8c1fdc44601 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java @@ -252,7 +252,15 @@ private void createKey(OzoneBucket ozoneBucket, String key, int length, private void checkPath(Path path) { try { o3fs.getFileStatus(path); - fail("testObjectStoreCreateWithO3fs failed for Path" + path); + FileStatus[] fileStatuses = o3fs.listStatus(new Path("/")); + StringBuilder sb = new StringBuilder(); + if (null != fileStatuses) { + for (FileStatus fStatus : fileStatuses) { + sb.append(fStatus.getPath().toString()); + sb.append(","); + } + } + fail("testObjectStoreCreateWithO3fs failed for Path" + sb.toString()); } catch (IOException ex) { Assert.assertTrue(ex instanceof FileNotFoundException); Assert.assertTrue(ex.getMessage().contains("No such file or directory")); From 0fd54fc5d6edaf4caeb58a8667e6c29a4cd337f9 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 30 Aug 2023 17:56:14 +0530 Subject: [PATCH 06/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .../TestOzoneFSWithObjectStoreCreate.java | 228 +++++++++++++++++- 1 file changed, 215 insertions(+), 13 deletions(-) diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java index e8c1fdc44601..a72fd5a11a78 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFSWithObjectStoreCreate.java @@ -125,6 +125,45 @@ public void teardown() { IOUtils.closeQuietly(o3fs); } + @Test + public void test() throws Exception { + + OzoneVolume ozoneVolume = + client.getObjectStore().getVolume(volumeName); + + OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); + + String key1 = "///dir1/dir2/file1"; + String key2 = "///dir1/dir2/file2"; + int length = 10; + OzoneOutputStream ozoneOutputStream = ozoneBucket.createKey(key1, length); + byte[] b = new byte[10]; + Arrays.fill(b, (byte)96); + ozoneOutputStream.write(b); + ozoneOutputStream.close(); + + ozoneOutputStream = ozoneBucket.createKey(key2, length); + ozoneOutputStream.write(b); + ozoneOutputStream.close(); + + // Adding "/" here otherwise Path will be considered as relative path and + // workingDir will be added. + key1 = "///dir1/dir2/file1"; + Path p = new Path(key1); + Assert.assertTrue(o3fs.getFileStatus(p).isFile()); + + p = p.getParent(); + checkAncestors(p); + + + key2 = "///dir1/dir2/file2"; + p = new Path(key2); + Assert.assertTrue(o3fs.getFileStatus(p).isFile()); + checkAncestors(p); + + } + + @Test public void testObjectStoreCreateWithO3fs() throws Exception { OzoneVolume ozoneVolume = @@ -144,7 +183,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { keys.add("/dir1/dir2/dir3/dir4/"); for (int i = 1; i <= 3; i++) { int length = 10; - String fileName = parentDir.concat("file" + i + "/"); + String fileName = parentDir.concat("/file" + i + "/"); keys.add(fileName); OzoneOutputStream ozoneOutputStream = ozoneBucket.createKey(fileName, length); @@ -156,7 +195,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { // check for (int i = 1; i <= 3; i++) { - String fileName = parentDir.concat("file" + i + "/"); + String fileName = parentDir.concat("/file" + i + "/"); Path p = new Path(fileName); Assert.assertTrue(o3fs.getFileStatus(p).isFile()); checkAncestors(p); @@ -164,7 +203,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { // Delete keys with object store api delete for (int i = 1; i <= 3; i++) { - String fileName = parentDir.concat("file" + i + "/"); + String fileName = parentDir.concat("/file" + i + "/"); ozoneBucket.deleteKey(fileName); } @@ -181,7 +220,7 @@ public void testObjectStoreCreateWithO3fs() throws Exception { for (int i = 1; i <= 3; i++) { int length = 10; - String fileName = parentDir.concat("file" + i + "/"); + String fileName = parentDir.concat("/file" + i + "/"); OzoneOutputStream ozoneOutputStream = ozoneBucket.createKey(fileName, length); byte[] b = new byte[10]; @@ -208,6 +247,177 @@ public void testObjectStoreCreateWithO3fs() throws Exception { } + + @Test + public void testKeyCreationFailDuetoDirectoryCreationBeforeCommit() + throws Exception { + OzoneVolume ozoneVolume = + client.getObjectStore().getVolume(volumeName); + + OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); + + OzoneOutputStream ozoneOutputStream = + ozoneBucket.createKey("/a/b/c", 10); + byte[] b = new byte[10]; + Arrays.fill(b, (byte)96); + ozoneOutputStream.write(b); + + // Before close create directory with same name. + o3fs.mkdirs(new Path("/a/b/c")); + + try { + ozoneOutputStream.close(); + fail("testKeyCreationFailDuetoDirectoryCreationBeforeCommit"); + } catch (IOException ex) { + Assert.assertTrue(ex instanceof OMException); + Assert.assertEquals(NOT_A_FILE, + ((OMException) ex).getResult()); + } + + } + + + @Test + public void testMPUFailDuetoDirectoryCreationBeforeComplete() + throws Exception { + OzoneVolume ozoneVolume = + client.getObjectStore().getVolume(volumeName); + + OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); + + String keyName = "/dir1/dir2/mpukey"; + OmMultipartInfo omMultipartInfo = + ozoneBucket.initiateMultipartUpload(keyName); + Assert.assertNotNull(omMultipartInfo); + + OzoneOutputStream ozoneOutputStream = + ozoneBucket.createMultipartKey(keyName, 10, 1, + omMultipartInfo.getUploadID()); + byte[] b = new byte[10]; + Arrays.fill(b, (byte)96); + ozoneOutputStream.write(b); + + // Before close, create directory with same name. + o3fs.mkdirs(new Path(keyName)); + + // This should succeed, as we check during creation of part or during + // complete MPU. + ozoneOutputStream.close(); + + Map partsMap = new HashMap<>(); + partsMap.put(1, ozoneOutputStream.getCommitUploadPartInfo().getPartName()); + + // Should fail, as we have directory with same name. + try { + ozoneBucket.completeMultipartUpload(keyName, + omMultipartInfo.getUploadID(), partsMap); + fail("testMPUFailDuetoDirectoryCreationBeforeComplete failed"); + } catch (OMException ex) { + Assert.assertTrue(ex instanceof OMException); + Assert.assertEquals(NOT_A_FILE, ex.getResult()); + } + + // Delete directory + o3fs.delete(new Path(keyName), true); + + // And try again for complete MPU. This should succeed. + ozoneBucket.completeMultipartUpload(keyName, + omMultipartInfo.getUploadID(), partsMap); + + try (FSDataInputStream ozoneInputStream = o3fs.open(new Path(keyName))) { + byte[] buffer = new byte[10]; + // This read will not change the offset inside the file + int readBytes = ozoneInputStream.read(0, buffer, 0, 10); + String readData = new String(buffer, 0, readBytes, UTF_8); + Assert.assertEquals(new String(b, 0, b.length, UTF_8), readData); + } + + } + + @Test + public void testCreateDirectoryFirstThenKeyAndFileWithSameName() + throws Exception { + o3fs.mkdirs(new Path("/t1/t2")); + + try { + o3fs.create(new Path("/t1/t2")); + fail("testCreateDirectoryFirstThenFileWithSameName failed"); + } catch (FileAlreadyExistsException ex) { + Assert.assertTrue(ex.getMessage().contains(NOT_A_FILE.name())); + } + + OzoneVolume ozoneVolume = + client.getObjectStore().getVolume(volumeName); + OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); + ozoneBucket.createDirectory("t1/t2"); + try { + ozoneBucket.createKey("t1/t2", 0); + fail("testCreateDirectoryFirstThenFileWithSameName failed"); + } catch (OMException ex) { + Assert.assertTrue(ex instanceof OMException); + Assert.assertEquals(NOT_A_FILE, ex.getResult()); + } + } + + + @Test + public void testListKeysWithNotNormalizedPath() throws Exception { + + OzoneVolume ozoneVolume = + client.getObjectStore().getVolume(volumeName); + + OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName); + + String key1 = "/dir1///dir2/file1/"; + String key2 = "/dir1///dir2/file2/"; + String key3 = "/dir1///dir2/file3/"; + + LinkedList keys = new LinkedList<>(); + keys.add("dir1/"); + keys.add("dir1/dir2/"); + keys.add(OmUtils.normalizeKey(key1, false)); + keys.add(OmUtils.normalizeKey(key2, false)); + keys.add(OmUtils.normalizeKey(key3, false)); + + int length = 10; + byte[] input = new byte[length]; + Arrays.fill(input, (byte)96); + + createKey(ozoneBucket, key1, 10, input); + createKey(ozoneBucket, key2, 10, input); + createKey(ozoneBucket, key3, 10, input); + + // Iterator with key name as prefix. + + Iterator ozoneKeyIterator = + ozoneBucket.listKeys("/dir1//"); + + checkKeyList(ozoneKeyIterator, keys); + + // Iterator with with normalized key prefix. + ozoneKeyIterator = + ozoneBucket.listKeys("dir1/"); + + checkKeyList(ozoneKeyIterator, keys); + + // Iterator with key name as previous key. + ozoneKeyIterator = ozoneBucket.listKeys(null, + "/dir1///dir2/file1/"); + + // Remove keys before //dir1/dir2/file1 + keys.remove("dir1/"); + keys.remove("dir1/dir2/"); + keys.remove("dir1/dir2/file1"); + + checkKeyList(ozoneKeyIterator, keys); + + // Iterator with normalized key as previous key. + ozoneKeyIterator = ozoneBucket.listKeys(null, + OmUtils.normalizeKey(key1, false)); + + checkKeyList(ozoneKeyIterator, keys); + } + private void checkKeyList(Iterator ozoneKeyIterator, List keys) { @@ -252,15 +462,7 @@ private void createKey(OzoneBucket ozoneBucket, String key, int length, private void checkPath(Path path) { try { o3fs.getFileStatus(path); - FileStatus[] fileStatuses = o3fs.listStatus(new Path("/")); - StringBuilder sb = new StringBuilder(); - if (null != fileStatuses) { - for (FileStatus fStatus : fileStatuses) { - sb.append(fStatus.getPath().toString()); - sb.append(","); - } - } - fail("testObjectStoreCreateWithO3fs failed for Path" + sb.toString()); + fail("testObjectStoreCreateWithO3fs failed for Path" + path); } catch (IOException ex) { Assert.assertTrue(ex instanceof FileNotFoundException); Assert.assertTrue(ex.getMessage().contains("No such file or directory")); From 4d61435b60a4bb35a675b5bce35abae8fc225111 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 30 Aug 2023 19:45:16 +0530 Subject: [PATCH 07/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .github/workflows/ci.yml | 289 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 278 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1aa9391fcca4..70cb55e4aea4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,13 +26,13 @@ jobs: GITHUB_CONTEXT: ${{ toJson(github) }} outputs: basic-checks: ${{ steps.selective-checks.outputs.basic-checks }} - needs-basic-checks: false - needs-build: true - needs-compile: false - needs-compose-tests: false - needs-dependency-check: false - needs-integration-tests: true - needs-kubernetes-tests: false + needs-basic-checks: ${{ steps.selective-checks.outputs.needs-basic-checks }} + needs-build: ${{ steps.selective-checks.outputs.needs-build }} + needs-compile: ${{ steps.selective-checks.outputs.needs-compile }} + needs-compose-tests: ${{ steps.selective-checks.outputs.needs-compose-tests }} + needs-dependency-check: ${{ steps.selective-checks.outputs.needs-dependency-check }} + needs-integration-tests: ${{ steps.selective-checks.outputs.needs-integration-tests }} + needs-kubernetes-tests: ${{ steps.selective-checks.outputs.needs-kubernetes-tests }} steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" uses: actions/checkout@v3 @@ -115,15 +115,227 @@ jobs: rm -rf ~/.m2/repository/org/apache/ozone/hdds* rm -rf ~/.m2/repository/org/apache/ozone/ozone* if: always() + compile: + needs: + - build-info + - build + runs-on: ubuntu-20.04 + timeout-minutes: 30 + if: needs.build-info.outputs.needs-compile == 'true' + strategy: + matrix: + java: [ 11, 17 ] + fail-fast: false + steps: + - name: Download Ozone source tarball + uses: actions/download-artifact@v3 + with: + name: ozone-src + - name: Untar sources + run: | + tar --strip-components 1 -xzvf ozone*-src.tar.gz + - name: Cache for maven dependencies + uses: actions/cache@v3 + with: + path: ~/.m2/repository + key: maven-repo-${{ hashFiles('**/pom.xml') }}-${{ matrix.java }} + restore-keys: | + maven-repo-${{ hashFiles('**/pom.xml') }} + maven-repo- + - name: Setup java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: ${{ matrix.java }} + - name: Compile Ozone using Java ${{ matrix.java }} + run: hadoop-ozone/dev-support/checks/build.sh -Dskip.npx -Dskip.installnpx -Djavac.version=${{ matrix.java }} + env: + OZONE_WITH_COVERAGE: false + - name: Delete temporary build artifacts before caching + run: | + #Never cache local artifacts + rm -rf ~/.m2/repository/org/apache/ozone/hdds* + rm -rf ~/.m2/repository/org/apache/ozone/ozone* + if: always() + basic: + needs: + - build-info + runs-on: ubuntu-20.04 + timeout-minutes: 90 + if: needs.build-info.outputs.needs-basic-checks == 'true' + strategy: + matrix: + check: ${{ fromJson(needs.build-info.outputs.basic-checks) }} + fail-fast: false + steps: + - name: Checkout project + uses: actions/checkout@v3 + if: matrix.check != 'bats' + - name: Checkout project with history + uses: actions/checkout@v3 + with: + fetch-depth: 0 + if: matrix.check == 'bats' + - name: Cache for maven dependencies + uses: actions/cache@v3 + with: + path: ~/.m2/repository + key: maven-repo-${{ hashFiles('**/pom.xml') }}-8-${{ matrix.check }} + restore-keys: | + maven-repo-${{ hashFiles('**/pom.xml') }}-8 + maven-repo-${{ hashFiles('**/pom.xml') }} + maven-repo- + if: ${{ !contains('author,bats,docs', matrix.check) }} + - name: Setup java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: 8 + - name: Execute tests + run: hadoop-ozone/dev-support/checks/${{ matrix.check }}.sh + - name: Summary of failures + run: cat target/${{ matrix.check }}/summary.txt + if: ${{ !cancelled() }} + - name: Archive build results + uses: actions/upload-artifact@v3 + if: ${{ !cancelled() }} + with: + name: ${{ matrix.check }} + path: target/${{ matrix.check }} + continue-on-error: true + - name: Delete temporary build artifacts before caching + run: | + #Never cache local artifacts + rm -rf ~/.m2/repository/org/apache/ozone/hdds* + rm -rf ~/.m2/repository/org/apache/ozone/ozone* + if: always() + dependency: + needs: + - build-info + - build + runs-on: ubuntu-20.04 + timeout-minutes: 5 + if: needs.build-info.outputs.needs-dependency-check == 'true' + steps: + - name: Checkout project + uses: actions/checkout@v3 + - name: Download compiled Ozone binaries + uses: actions/download-artifact@v3 + with: + name: ozone-bin + - name: Untar binaries + run: | + mkdir dist + tar -C dist --strip-components 1 -xzf ozone*.tar.gz + - name: Execute tests + run: | + export OZONE_DIST_DIR=`pwd`/dist + ./hadoop-ozone/dev-support/checks/dependency.sh + - name: Archive build results + uses: actions/upload-artifact@v3 + if: always() + with: + name: dependency + path: target/dependency + continue-on-error: true + acceptance: + needs: + - build-info + - build + runs-on: ubuntu-20.04 + timeout-minutes: 150 + if: needs.build-info.outputs.needs-compose-tests == 'true' + strategy: + matrix: + suite: + - secure + - unsecure + - compat + - EC + - HA-secure + - HA-unsecure + - MR + - misc + - cert-rotation + fail-fast: false + steps: + - name: Checkout project + uses: actions/checkout@v3 + - name: Download compiled Ozone binaries + uses: actions/download-artifact@v3 + with: + name: ozone-bin + - name: Untar binaries + run: | + mkdir -p hadoop-ozone/dist/target + tar xzvf ozone*.tar.gz -C hadoop-ozone/dist/target + sudo chmod -R a+rwX hadoop-ozone/dist/target + - name: Execute tests + run: | + pushd hadoop-ozone/dist/target/ozone-* + sudo mkdir .aws && sudo chmod 777 .aws && sudo chown 1000 .aws + popd + ./hadoop-ozone/dev-support/checks/acceptance.sh + env: + KEEP_IMAGE: false + OZONE_ACCEPTANCE_SUITE: ${{ matrix.suite }} + OZONE_VOLUME_OWNER: 1000 + - name: Archive build results + uses: actions/upload-artifact@v3 + if: always() + with: + name: acceptance-${{ matrix.suite }} + path: target/acceptance + continue-on-error: true + kubernetes: + needs: + - build-info + - build + runs-on: ubuntu-20.04 + timeout-minutes: 60 + if: needs.build-info.outputs.needs-kubernetes-tests == 'true' + steps: + - name: Checkout project + uses: actions/checkout@v3 + - name: Download compiled Ozone binaries + uses: actions/download-artifact@v3 + with: + name: ozone-bin + - name: Untar binaries + run: | + mkdir -p hadoop-ozone/dist/target + tar xzvf ozone*.tar.gz -C hadoop-ozone/dist/target + - name: Execute tests + run: | + pushd hadoop-ozone/dist/target/ozone-* + sudo mkdir .aws && sudo chmod 777 .aws && sudo chown 1000 .aws + popd + ./hadoop-ozone/dev-support/checks/kubernetes.sh + - name: Archive build results + uses: actions/upload-artifact@v3 + if: always() + with: + name: kubernetes + path: target/kubernetes + continue-on-error: true integration: needs: - build-info runs-on: ubuntu-20.04 - timeout-minutes: 300 + timeout-minutes: 150 if: needs.build-info.outputs.needs-integration-tests == 'true' strategy: matrix: - profile: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + profile: + - client + - contract + - filesystem + - hdds + - om + - ozone + - scm + - shell + - flaky fail-fast: false steps: - name: Checkout project @@ -143,8 +355,11 @@ jobs: distribution: 'temurin' java-version: 8 - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=org.apache.hadoop.fs.ozone.TestOzoneFSWithObjectStoreCreate - if: always() + run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} + if: matrix.profile != 'flaky' + - name: Execute flaky tests + run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} -Dsurefire.rerunFailingTestsCount=5 -Dsurefire.fork.timeout=3600 + if: matrix.profile == 'flaky' - name: Summary of failures run: cat target/${{ github.job }}/summary.txt if: always() @@ -161,3 +376,55 @@ jobs: rm -rf ~/.m2/repository/org/apache/ozone/hdds* rm -rf ~/.m2/repository/org/apache/ozone/ozone* if: always() + coverage: + runs-on: ubuntu-20.04 + timeout-minutes: 30 + if: github.repository == 'apache/ozone' && github.event_name != 'pull_request' + needs: + - acceptance + - basic + - integration + steps: + - name: Checkout project + uses: actions/checkout@v3 + - name: Cache for maven dependencies + uses: actions/cache@v3 + with: + path: ~/.m2/repository + key: maven-repo-${{ hashFiles('**/pom.xml') }}-8-${{ github.job }} + restore-keys: | + maven-repo-${{ hashFiles('**/pom.xml') }}-8 + maven-repo-${{ hashFiles('**/pom.xml') }} + maven-repo- + - name: Download artifacts + uses: actions/download-artifact@v3 + with: + path: target/artifacts + - name: Untar binaries + run: | + mkdir -p hadoop-ozone/dist/target + tar xzvf target/artifacts/ozone-bin/ozone*.tar.gz -C hadoop-ozone/dist/target + - name: Calculate combined coverage + run: ./hadoop-ozone/dev-support/checks/coverage.sh + - name: Setup java 11 + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: 11 + - name: Upload coverage to Sonar + run: ./hadoop-ozone/dev-support/checks/sonar.sh + env: + SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Archive build results + uses: actions/upload-artifact@v3 + with: + name: coverage + path: target/coverage + continue-on-error: true + - name: Delete temporary build artifacts before caching + run: | + #Never cache local artifacts + rm -rf ~/.m2/repository/org/apache/ozone/hdds* + rm -rf ~/.m2/repository/org/apache/ozone/ozone* + if: always() From b0ce1915b8cb6e773775a32740e9e65495397198 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 6 Sep 2023 15:30:07 +0530 Subject: [PATCH 08/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .github/workflows/ci.yml | 35 +++++++++--------------- hadoop-ozone/dev-support/checks/junit.sh | 4 +++ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70cb55e4aea4..b18fdc26ed4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,13 +26,13 @@ jobs: GITHUB_CONTEXT: ${{ toJson(github) }} outputs: basic-checks: ${{ steps.selective-checks.outputs.basic-checks }} - needs-basic-checks: ${{ steps.selective-checks.outputs.needs-basic-checks }} - needs-build: ${{ steps.selective-checks.outputs.needs-build }} - needs-compile: ${{ steps.selective-checks.outputs.needs-compile }} - needs-compose-tests: ${{ steps.selective-checks.outputs.needs-compose-tests }} - needs-dependency-check: ${{ steps.selective-checks.outputs.needs-dependency-check }} + needs-basic-checks: false + needs-build: false + needs-compile: false + needs-compose-tests: false + needs-dependency-check: false needs-integration-tests: ${{ steps.selective-checks.outputs.needs-integration-tests }} - needs-kubernetes-tests: ${{ steps.selective-checks.outputs.needs-kubernetes-tests }} + needs-kubernetes-tests: false steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" uses: actions/checkout@v3 @@ -256,7 +256,6 @@ jobs: - HA-unsecure - MR - misc - - cert-rotation fail-fast: false steps: - name: Checkout project @@ -326,16 +325,7 @@ jobs: if: needs.build-info.outputs.needs-integration-tests == 'true' strategy: matrix: - profile: - - client - - contract - - filesystem - - hdds - - om - - ozone - - scm - - shell - - flaky + profile: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] fail-fast: false steps: - name: Checkout project @@ -355,14 +345,15 @@ jobs: distribution: 'temurin' java-version: 8 - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} - if: matrix.profile != 'flaky' - - name: Execute flaky tests - run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} -Dsurefire.rerunFailingTestsCount=5 -Dsurefire.fork.timeout=3600 - if: matrix.profile == 'flaky' + run: hadoop-ozone/dev-support/checks/integration.sh -Dtest='TestOzoneFSWithObjectStoreCreate' + env: + ITERATIONS: 10 - name: Summary of failures run: cat target/${{ github.job }}/summary.txt if: always() + - name: Number of failures + run: cat target/${{ github.job }}/failures + if: always() - name: Archive build results uses: actions/upload-artifact@v3 if: always() diff --git a/hadoop-ozone/dev-support/checks/junit.sh b/hadoop-ozone/dev-support/checks/junit.sh index 74cefe6a975d..85cb21a00f38 100644 --- a/hadoop-ozone/dev-support/checks/junit.sh +++ b/hadoop-ozone/dev-support/checks/junit.sh @@ -76,6 +76,10 @@ for i in $(seq 1 ${ITERATIONS}); do fi done +if [[ ${ITERATIONS} -gt 1 ]]; then + grep -c "exit code: [^0]" "${REPORT_DIR}/summary.txt" > "${REPORT_DIR}/failures" +fi + if [[ "${OZONE_WITH_COVERAGE}" == "true" ]]; then #Archive combined jacoco records mvn -B -N jacoco:merge -Djacoco.destFile=$REPORT_DIR/jacoco-combined.exec From 4056b12ac8ead65342e06534942e862f0b6048d3 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 6 Sep 2023 18:27:24 +0530 Subject: [PATCH 09/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .../hadoop/ozone/om/KeyManagerImpl.java | 30 ++++++++++++------- .../ozone/om/OzoneListStatusHelper.java | 4 ++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java index 8bce4eb70f59..b34673f2eef8 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java @@ -1389,11 +1389,14 @@ public void refresh(OmKeyInfo key) throws IOException { refreshPipeline(Arrays.asList(key)); } - public static boolean isKeyDeleted(String key, Table keyTable) { + public static boolean isKeyDeleted(String key, Table keyTable) + throws IOException { CacheValue omKeyInfoCacheValue = keyTable.getCacheValue(new CacheKey(key)); - return omKeyInfoCacheValue != null - && omKeyInfoCacheValue.getCacheValue() == null; + if (null == omKeyInfoCacheValue) { + return null == keyTable.getSkipCache(key); + } + return omKeyInfoCacheValue.getCacheValue() == null; } /** @@ -1426,7 +1429,11 @@ private void listStatusFindKeyInTableCache( } OzoneFileStatus fileStatus = new OzoneFileStatus( cacheOmKeyInfo, scmBlockSize, !OzoneFSUtils.isFile(cacheKey)); - cacheKeyMap.put(cacheKey, fileStatus); + cacheKeyMap.putIfAbsent(cacheKey, fileStatus); + } else if (cacheOmKeyInfo == null + && cacheKey.startsWith(startCacheKey) + && cacheKey.compareTo(startCacheKey) >= 0) { + cacheKeyMap.putIfAbsent(cacheKey, null); } } } @@ -1542,6 +1549,9 @@ public List listStatus(OmKeyArgs args, boolean recursive, for (OzoneFileStatus fileStatus : cacheKeyMap.values()) { // No need to check if a key is deleted or not here, this is handled // when adding entries to cacheKeyMap from DB. + if (fileStatus == null) { + continue; + } fileStatusList.add(fileStatus); countEntries++; if (countEntries >= numEntries) { @@ -1612,7 +1622,7 @@ private void findKeyInDbWithIterator(boolean recursive, String startKey, if (recursive) { // for recursive list all the entries - if (!isKeyDeleted(entryInDb, keyTable)) { + if (!cacheKeyMap.containsKey(entryInDb)) { cacheKeyMap.putIfAbsent(entryInDb, new OzoneFileStatus(omKeyInfo, scmBlockSize, !OzoneFSUtils.isFile(entryKeyName))); countEntries++; @@ -1626,23 +1636,23 @@ private void findKeyInDbWithIterator(boolean recursive, String startKey, .getImmediateChild(entryKeyName, keyName); boolean isFile = OzoneFSUtils.isFile(immediateChild); if (isFile) { - if (!isKeyDeleted(entryInDb, keyTable)) { - cacheKeyMap.put(entryInDb, + if (!cacheKeyMap.containsKey(entryInDb)) { + cacheKeyMap.putIfAbsent(entryInDb, new OzoneFileStatus(omKeyInfo, scmBlockSize, !isFile)); countEntries++; } } else { // if entry is a directory - if (!isKeyDeleted(entryInDb, keyTable)) { + if (!cacheKeyMap.containsKey(entryInDb)) { if (!entryKeyName.equals(immediateChild)) { OmKeyInfo fakeDirEntry = createDirectoryKey( omKeyInfo, immediateChild); - cacheKeyMap.put(entryInDb, + cacheKeyMap.putIfAbsent(entryInDb, new OzoneFileStatus(fakeDirEntry, scmBlockSize, true)); } else { // If entryKeyName matches dir name, we have the info - cacheKeyMap.put(entryInDb, + cacheKeyMap.putIfAbsent(entryInDb, new OzoneFileStatus(omKeyInfo, 0, true)); } countEntries++; diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java index 758206f200b7..a1c12399f412 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java @@ -215,7 +215,9 @@ public Collection listStatusFSO(OmKeyArgs args, HeapEntry entry = heapIterator.next(); OzoneFileStatus status = entry.getStatus(prefixKey, scmBlockSize, volumeName, bucketName, replication); - map.putIfAbsent(entry.key, status); + if (!map.containsKey(entry.key)) { + map.putIfAbsent(entry.key, status); + } } } From 782b197ebe4488dc0051098252af06ff6297a715 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 6 Sep 2023 19:27:34 +0530 Subject: [PATCH 10/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .../hadoop/ozone/om/KeyManagerImpl.java | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java index b34673f2eef8..8bce4eb70f59 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java @@ -1389,14 +1389,11 @@ public void refresh(OmKeyInfo key) throws IOException { refreshPipeline(Arrays.asList(key)); } - public static boolean isKeyDeleted(String key, Table keyTable) - throws IOException { + public static boolean isKeyDeleted(String key, Table keyTable) { CacheValue omKeyInfoCacheValue = keyTable.getCacheValue(new CacheKey(key)); - if (null == omKeyInfoCacheValue) { - return null == keyTable.getSkipCache(key); - } - return omKeyInfoCacheValue.getCacheValue() == null; + return omKeyInfoCacheValue != null + && omKeyInfoCacheValue.getCacheValue() == null; } /** @@ -1429,11 +1426,7 @@ private void listStatusFindKeyInTableCache( } OzoneFileStatus fileStatus = new OzoneFileStatus( cacheOmKeyInfo, scmBlockSize, !OzoneFSUtils.isFile(cacheKey)); - cacheKeyMap.putIfAbsent(cacheKey, fileStatus); - } else if (cacheOmKeyInfo == null - && cacheKey.startsWith(startCacheKey) - && cacheKey.compareTo(startCacheKey) >= 0) { - cacheKeyMap.putIfAbsent(cacheKey, null); + cacheKeyMap.put(cacheKey, fileStatus); } } } @@ -1549,9 +1542,6 @@ public List listStatus(OmKeyArgs args, boolean recursive, for (OzoneFileStatus fileStatus : cacheKeyMap.values()) { // No need to check if a key is deleted or not here, this is handled // when adding entries to cacheKeyMap from DB. - if (fileStatus == null) { - continue; - } fileStatusList.add(fileStatus); countEntries++; if (countEntries >= numEntries) { @@ -1622,7 +1612,7 @@ private void findKeyInDbWithIterator(boolean recursive, String startKey, if (recursive) { // for recursive list all the entries - if (!cacheKeyMap.containsKey(entryInDb)) { + if (!isKeyDeleted(entryInDb, keyTable)) { cacheKeyMap.putIfAbsent(entryInDb, new OzoneFileStatus(omKeyInfo, scmBlockSize, !OzoneFSUtils.isFile(entryKeyName))); countEntries++; @@ -1636,23 +1626,23 @@ private void findKeyInDbWithIterator(boolean recursive, String startKey, .getImmediateChild(entryKeyName, keyName); boolean isFile = OzoneFSUtils.isFile(immediateChild); if (isFile) { - if (!cacheKeyMap.containsKey(entryInDb)) { - cacheKeyMap.putIfAbsent(entryInDb, + if (!isKeyDeleted(entryInDb, keyTable)) { + cacheKeyMap.put(entryInDb, new OzoneFileStatus(omKeyInfo, scmBlockSize, !isFile)); countEntries++; } } else { // if entry is a directory - if (!cacheKeyMap.containsKey(entryInDb)) { + if (!isKeyDeleted(entryInDb, keyTable)) { if (!entryKeyName.equals(immediateChild)) { OmKeyInfo fakeDirEntry = createDirectoryKey( omKeyInfo, immediateChild); - cacheKeyMap.putIfAbsent(entryInDb, + cacheKeyMap.put(entryInDb, new OzoneFileStatus(fakeDirEntry, scmBlockSize, true)); } else { // If entryKeyName matches dir name, we have the info - cacheKeyMap.putIfAbsent(entryInDb, + cacheKeyMap.put(entryInDb, new OzoneFileStatus(omKeyInfo, 0, true)); } countEntries++; From 23a598a5d0c506da77abd9a9b4b838045d502900 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Wed, 6 Sep 2023 20:49:52 +0530 Subject: [PATCH 11/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .../java/org/apache/hadoop/ozone/om/KeyManagerImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java index 8bce4eb70f59..b8d8f248d061 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java @@ -1216,6 +1216,7 @@ private OmKeyInfo createFakeDirIfShould(String volume, String bucket, Table keyTable = metadataManager.getKeyTable(layout); Iterator, CacheValue>> cacheIterator = keyTable.cacheIterator(); + Set deletedKeys = new HashSet<>(); while (cacheIterator.hasNext()) { Map.Entry, CacheValue> cacheEntry = cacheIterator.next(); @@ -1228,6 +1229,11 @@ private OmKeyInfo createFakeDirIfShould(String volume, String bucket, LOG.debug("Fake dir {} required for {}", targetKey, cacheKey); return createDirectoryKey(cacheValue.getCacheValue(), dirKey); } + // deletedKeys may contain deleted entry while iterating cache iterator + // To avoid flush of cache while iterating table iterator. + if (!exists) { + deletedKeys.add(cacheKey); + } } try (TableIterator> @@ -1242,7 +1248,7 @@ private OmKeyInfo createFakeDirIfShould(String volume, String bucket, // in different volume/bucket, such as "/vol1/bucket2/dir2/key2". if (key.startsWith(targetKey)) { if (!Objects.equals(key, targetKey) - && !isKeyDeleted(key, keyTable)) { + && !deletedKeys.contains(key)) { LOG.debug("Fake dir {} required for {}", targetKey, key); return createDirectoryKey(keyValue.getValue(), dirKey); } From 08982cb33a7c7617e8ab6956d3752f3f1135a9d7 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Thu, 7 Sep 2023 09:45:43 +0530 Subject: [PATCH 12/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .github/workflows/ci.yml | 35 ++++++++++++------- hadoop-ozone/dev-support/checks/junit.sh | 4 --- .../hadoop/ozone/om/KeyManagerImpl.java | 3 +- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b18fdc26ed4c..70cb55e4aea4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,13 +26,13 @@ jobs: GITHUB_CONTEXT: ${{ toJson(github) }} outputs: basic-checks: ${{ steps.selective-checks.outputs.basic-checks }} - needs-basic-checks: false - needs-build: false - needs-compile: false - needs-compose-tests: false - needs-dependency-check: false + needs-basic-checks: ${{ steps.selective-checks.outputs.needs-basic-checks }} + needs-build: ${{ steps.selective-checks.outputs.needs-build }} + needs-compile: ${{ steps.selective-checks.outputs.needs-compile }} + needs-compose-tests: ${{ steps.selective-checks.outputs.needs-compose-tests }} + needs-dependency-check: ${{ steps.selective-checks.outputs.needs-dependency-check }} needs-integration-tests: ${{ steps.selective-checks.outputs.needs-integration-tests }} - needs-kubernetes-tests: false + needs-kubernetes-tests: ${{ steps.selective-checks.outputs.needs-kubernetes-tests }} steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" uses: actions/checkout@v3 @@ -256,6 +256,7 @@ jobs: - HA-unsecure - MR - misc + - cert-rotation fail-fast: false steps: - name: Checkout project @@ -325,7 +326,16 @@ jobs: if: needs.build-info.outputs.needs-integration-tests == 'true' strategy: matrix: - profile: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] + profile: + - client + - contract + - filesystem + - hdds + - om + - ozone + - scm + - shell + - flaky fail-fast: false steps: - name: Checkout project @@ -345,15 +355,14 @@ jobs: distribution: 'temurin' java-version: 8 - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -Dtest='TestOzoneFSWithObjectStoreCreate' - env: - ITERATIONS: 10 + run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} + if: matrix.profile != 'flaky' + - name: Execute flaky tests + run: hadoop-ozone/dev-support/checks/integration.sh -P${{ matrix.profile }} -Dsurefire.rerunFailingTestsCount=5 -Dsurefire.fork.timeout=3600 + if: matrix.profile == 'flaky' - name: Summary of failures run: cat target/${{ github.job }}/summary.txt if: always() - - name: Number of failures - run: cat target/${{ github.job }}/failures - if: always() - name: Archive build results uses: actions/upload-artifact@v3 if: always() diff --git a/hadoop-ozone/dev-support/checks/junit.sh b/hadoop-ozone/dev-support/checks/junit.sh index 85cb21a00f38..74cefe6a975d 100644 --- a/hadoop-ozone/dev-support/checks/junit.sh +++ b/hadoop-ozone/dev-support/checks/junit.sh @@ -76,10 +76,6 @@ for i in $(seq 1 ${ITERATIONS}); do fi done -if [[ ${ITERATIONS} -gt 1 ]]; then - grep -c "exit code: [^0]" "${REPORT_DIR}/summary.txt" > "${REPORT_DIR}/failures" -fi - if [[ "${OZONE_WITH_COVERAGE}" == "true" ]]; then #Archive combined jacoco records mvn -B -N jacoco:merge -Djacoco.destFile=$REPORT_DIR/jacoco-combined.exec diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java index b8d8f248d061..a73d61cd5b76 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java @@ -1230,7 +1230,8 @@ private OmKeyInfo createFakeDirIfShould(String volume, String bucket, return createDirectoryKey(cacheValue.getCacheValue(), dirKey); } // deletedKeys may contain deleted entry while iterating cache iterator - // To avoid flush of cache while iterating table iterator. + // To avoid race condition of flush of cache while iterating + // table iterator. if (!exists) { deletedKeys.add(cacheKey); } From 667d5707c7f381b317f20e349dfcbed0a0acd159 Mon Sep 17 00:00:00 2001 From: deveshsingh Date: Fri, 8 Sep 2023 12:21:30 +0530 Subject: [PATCH 13/13] HDDS-7941. Intermittent failure in testObjectStoreCreateWithO3fs. --- .../java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java index a1c12399f412..9230616dc9ea 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneListStatusHelper.java @@ -216,7 +216,7 @@ public Collection listStatusFSO(OmKeyArgs args, OzoneFileStatus status = entry.getStatus(prefixKey, scmBlockSize, volumeName, bucketName, replication); if (!map.containsKey(entry.key)) { - map.putIfAbsent(entry.key, status); + map.put(entry.key, status); } } }