You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bookkeeper.apache.org by si...@apache.org on 2018/01/30 20:08:31 UTC

[bookkeeper] branch master updated: Test that old clients work with current server

This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 422620e  Test that old clients work with current server
422620e is described below

commit 422620e29b0d5b6d17dfb8e22afa78d57f26c68c
Author: Ivan Kelly <iv...@apache.org>
AuthorDate: Tue Jan 30 12:08:25 2018 -0800

    Test that old clients work with current server
    
    Test that old clients(4.2.0 onwards) can create, open, read, write ledgers on
    the latest version of the server.
    
    Master Issue: #903
    
    Author: Ivan Kelly <iv...@apache.org>
    
    Reviewers: Enrico Olivelli <eo...@gmail.com>, Sijie Guo <si...@apache.org>
    
    This closes #1083 from ivankelly/new-server-old-client
---
 .../{ => current-server-old-clients}/pom.xml       |  28 ++--
 .../backwardcompat/TestCompatOldClients.groovy     | 174 +++++++++++++++++++++
 .../src/test/resources/arquillian.xml              |  28 ++++
 tests/backward-compat/pom.xml                      |   1 +
 .../bookkeeper/tests/BookKeeperClusterUtils.java   |  17 ++
 5 files changed, 232 insertions(+), 16 deletions(-)

diff --git a/tests/backward-compat/pom.xml b/tests/backward-compat/current-server-old-clients/pom.xml
similarity index 56%
copy from tests/backward-compat/pom.xml
copy to tests/backward-compat/current-server-old-clients/pom.xml
index 11a9b45..618cbb8 100644
--- a/tests/backward-compat/pom.xml
+++ b/tests/backward-compat/current-server-old-clients/pom.xml
@@ -15,25 +15,21 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <packaging>pom</packaging>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="
+  http://maven.apache.org/POM/4.0.0
+  http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
-    <groupId>org.apache.bookkeeper.tests</groupId>
-    <artifactId>integration-tests-base-groovy</artifactId>
+    <groupId>org.apache.bookkeeper.tests.backward-compat</groupId>
+    <artifactId>tests-parent</artifactId>
     <version>4.7.0-SNAPSHOT</version>
-    <relativePath>../integration-tests-base-groovy</relativePath>
   </parent>
+
   <groupId>org.apache.bookkeeper.tests.backward-compat</groupId>
-  <artifactId>tests-parent</artifactId>
-  <name>Apache BookKeeper :: Tests :: Backward Compatibility</name>
-  <modules>
-    <module>upgrade</module>
-    <module>upgrade-direct</module>
-    <module>hierarchical-ledger-manager</module>
-    <module>hostname-bookieid</module>
-    <module>recovery-no-password</module>
-    <module>old-cookie-new-cluster</module>
-  </modules>
+  <artifactId>backward-compat-current-server-old-clients</artifactId>
+  <packaging>jar</packaging>
+  <name>Apache BookKeeper :: Tests :: Backward Compatibility :: Test old clients working on current server</name>
+
 </project>
diff --git a/tests/backward-compat/current-server-old-clients/src/test/groovy/org/apache/bookkeeper/tests/backwardcompat/TestCompatOldClients.groovy b/tests/backward-compat/current-server-old-clients/src/test/groovy/org/apache/bookkeeper/tests/backwardcompat/TestCompatOldClients.groovy
new file mode 100644
index 0000000..9c237cc
--- /dev/null
+++ b/tests/backward-compat/current-server-old-clients/src/test/groovy/org/apache/bookkeeper/tests/backwardcompat/TestCompatOldClients.groovy
@@ -0,0 +1,174 @@
+/*
+* 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.bookkeeper.tests.backwardcompat
+
+import com.github.dockerjava.api.DockerClient
+
+import org.apache.bookkeeper.tests.BookKeeperClusterUtils
+import org.apache.bookkeeper.tests.MavenClassLoader
+
+import org.jboss.arquillian.junit.Arquillian
+import org.jboss.arquillian.test.api.ArquillianResource
+
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+@RunWith(Arquillian.class)
+class TestCompatOldClients {
+    private static final Logger LOG = LoggerFactory.getLogger(TestCompatOldClients.class)
+    private static byte[] PASSWD = "foobar".getBytes()
+
+    // 4.1.0 doesn't work because metadata format changed
+    private def oldClientVersions = ["4.2.0", "4.2.1", "4.2.2", "4.2.3", "4.2.4",
+                                     "4.3.0", "4.3.1", "4.3.2", "4.4.0", "4.5.0", "4.5.1",
+                                     "4.6.0", "4.6.1"]
+
+    @ArquillianResource
+    DockerClient docker
+
+    private String currentVersion = System.getProperty("currentVersion")
+
+    @Before
+    public void before() throws Exception {
+        // First test to run, formats metadata and bookies
+        if (BookKeeperClusterUtils.metadataFormatIfNeeded(docker, currentVersion)) {
+            BookKeeperClusterUtils.formatAllBookies(docker, currentVersion)
+        }
+        // If already started, this has no effect
+        Assert.assertTrue(BookKeeperClusterUtils.startAllBookiesWithVersion(docker, currentVersion))
+    }
+
+    private void testFencingOldClient(String oldClientVersion, String fencingVersion) {
+        String zookeeper = BookKeeperClusterUtils.zookeeperConnectString(docker)
+
+        def oldCL = MavenClassLoader.forBookKeeperVersion(oldClientVersion)
+        def oldBK = oldCL.newBookKeeper(zookeeper)
+        def fencingCL = MavenClassLoader.forBookKeeperVersion(fencingVersion)
+        def fencingBK = fencingCL.newBookKeeper(zookeeper)
+
+        try {
+            def numEntries = 5
+            def ledger0 = oldBK.createLedger(3, 2,
+                                             oldCL.digestType("CRC32"),
+                                             PASSWD)
+            for (int i = 0; i < numEntries; i++) {
+                ledger0.addEntry(("foobar" + i).getBytes())
+            }
+            ledger0.close()
+
+
+            def ledger1 = fencingBK.openLedger(ledger0.getId(), fencingCL.digestType("CRC32"), PASSWD)
+
+            // cannot write any more
+            try {
+                ledger0.addEntry("shouldn't work".getBytes())
+                Assert.fail("Shouldn't have been able to add any more")
+            } catch (Exception e) {
+                Assert.assertEquals(e.getClass().getName(),
+                                    "org.apache.bookkeeper.client.BKException\$BKLedgerClosedException")
+            }
+
+            // should be able to open it and read it back
+            def ledger2 = oldBK.openLedger(ledger0.getId(), oldCL.digestType("CRC32"), PASSWD)
+            def entries = ledger2.readEntries(0, ledger2.getLastAddConfirmed())
+            Assert.assertEquals(numEntries, ledger2.getLastAddConfirmed() + 1 /* counts from 0 */)
+            int j = 0
+            while (entries.hasMoreElements()) {
+                def e = entries.nextElement()
+                Assert.assertEquals(new String(e.getEntry()), "foobar"+ j)
+                j++
+            }
+            ledger2.close()
+        } finally {
+            oldBK.close()
+            oldCL.close()
+            fencingCL.close()
+            fencingCL.close()
+        }
+    }
+
+    @Test
+    public void testNewClientFencesOldClient() throws Exception {
+        oldClientVersions.each{
+            testFencingOldClient(it, currentVersion)
+        }
+    }
+
+    @Test
+    public void testOldClientFencesOldClient() throws Exception {
+        oldClientVersions.each{
+            testFencingOldClient(it, it)
+        }
+    }
+
+    private void testReads(String writeVersion, String readerVersion) throws Exception {
+        String zookeeper = BookKeeperClusterUtils.zookeeperConnectString(docker)
+
+        def writeCL = MavenClassLoader.forBookKeeperVersion(writeVersion)
+        def writeBK = writeCL.newBookKeeper(zookeeper)
+        def readCL = MavenClassLoader.forBookKeeperVersion(readerVersion)
+        def readBK = readCL.newBookKeeper(zookeeper)
+        try {
+            def numEntries = 5
+            def ledger0 = writeBK.createLedger(3, 2,
+                                               writeCL.digestType("CRC32"),
+                                               PASSWD)
+            for (int i = 0; i < numEntries; i++) {
+                ledger0.addEntry(("foobar" + i).getBytes())
+            }
+            ledger0.close()
+
+
+            def ledger1 = readBK.openLedger(ledger0.getId(), readCL.digestType("CRC32"), PASSWD)
+
+            def entries = ledger1.readEntries(0, ledger1.getLastAddConfirmed())
+            Assert.assertEquals(numEntries, ledger1.getLastAddConfirmed() + 1 /* counts from 0 */)
+            int j = 0
+            while (entries.hasMoreElements()) {
+                def e = entries.nextElement()
+                Assert.assertEquals(new String(e.getEntry()), "foobar"+ j)
+                j++
+            }
+            ledger1.close()
+        } finally {
+            readBK.close()
+            readCL.close()
+            writeBK.close()
+            writeCL.close()
+        }
+    }
+
+    @Test
+    public void testOldClientReadsNewClient() throws Exception {
+        oldClientVersions.each{
+            testReads(currentVersion, it)
+        }
+    }
+
+    @Test
+    public void testNewClientReadsNewClient() throws Exception {
+        oldClientVersions.each{
+            testReads(it, currentVersion)
+        }
+    }
+}
diff --git a/tests/backward-compat/current-server-old-clients/src/test/resources/arquillian.xml b/tests/backward-compat/current-server-old-clients/src/test/resources/arquillian.xml
new file mode 100644
index 0000000..f914ff2
--- /dev/null
+++ b/tests/backward-compat/current-server-old-clients/src/test/resources/arquillian.xml
@@ -0,0 +1,28 @@
+<?xml version="1.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.
+-->
+<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xmlns="http://jboss.org/schema/arquillian"
+            xsi:schemaLocation="http://jboss.org/schema/arquillian
+                                http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
+
+  <extension qualifier="docker">
+    <property name="definitionFormat">CUBE</property>
+    <property name="dockerContainersResource">cube-definitions/3-node-all-version-unstarted.yaml</property>
+  </extension>
+
+</arquillian>
diff --git a/tests/backward-compat/pom.xml b/tests/backward-compat/pom.xml
index 11a9b45..a136ed2 100644
--- a/tests/backward-compat/pom.xml
+++ b/tests/backward-compat/pom.xml
@@ -35,5 +35,6 @@
     <module>hostname-bookieid</module>
     <module>recovery-no-password</module>
     <module>old-cookie-new-cluster</module>
+    <module>current-server-old-clients</module>
   </modules>
 </project>
diff --git a/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/BookKeeperClusterUtils.java b/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/BookKeeperClusterUtils.java
index 437e5b2..a7f9f8c 100644
--- a/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/BookKeeperClusterUtils.java
+++ b/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/BookKeeperClusterUtils.java
@@ -80,6 +80,23 @@ public class BookKeeperClusterUtils {
         }
     }
 
+    public static boolean metadataFormatIfNeeded(DockerClient docker, String version) throws Exception {
+        try (ZooKeeper zk = BookKeeperClusterUtils.zookeeperClient(docker)) {
+            if (zk.exists("/ledgers", false) == null) {
+                String bookkeeper = "/opt/bookkeeper/" + version + "/bin/bookkeeper";
+                runOnAnyBookie(docker, bookkeeper, "shell", "metaformat", "-nonInteractive");
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    public static void formatAllBookies(DockerClient docker, String version) throws Exception {
+        String bookkeeper = "/opt/bookkeeper/" + version + "/bin/bookkeeper";
+        BookKeeperClusterUtils.runOnAllBookies(docker, bookkeeper, "shell", "bookieformat", "-nonInteractive");
+    }
+
     public static void updateBookieConf(DockerClient docker, String containerId,
                                         String version, String key, String value) throws Exception {
         String confFile = "/opt/bookkeeper/" + version + "/conf/bk_server.conf";

-- 
To stop receiving notification emails like this one, please contact
sijie@apache.org.