Browse Source

[test] port linux package packaging tests (#31943)

Add packaging tests for the linux package distributions to the java test
project and remove them from bats. Most of the tests that lived in
30_deb_package.bats and 40_rpm_package.bats are applicable to both
package types and are combined into a single type of test case. Others
are separated out into separate cases to make their intent more clear

For #26741
Andy Bristol 7 years ago
parent
commit
aae0133847
24 changed files with 1113 additions and 502 deletions
  1. 3 10
      qa/vagrant/build.gradle
  2. 20 2
      qa/vagrant/src/main/java/org/elasticsearch/packaging/PackagingTests.java
  3. 127 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DebPreservationTestCase.java
  4. 31 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultDebBasicTests.java
  5. 30 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultDebPreservationTests.java
  6. 30 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultRpmBasicTests.java
  7. 30 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultRpmPreservationTests.java
  8. 30 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssDebBasicTests.java
  9. 30 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssDebPreservationTests.java
  10. 30 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssRpmBasicTests.java
  11. 30 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssRpmPreservationTests.java
  12. 73 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/PackageDependenciesTests.java
  13. 168 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/PackageTestCase.java
  14. 141 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/test/RpmPreservationTestCase.java
  15. 5 6
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Archives.java
  16. 4 11
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Cleanup.java
  17. 1 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/FileMatcher.java
  18. 19 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/FileUtils.java
  19. 28 6
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Installation.java
  20. 259 0
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Packages.java
  21. 23 13
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Platforms.java
  22. 1 1
      qa/vagrant/src/main/java/org/elasticsearch/packaging/util/ServerUtils.java
  23. 0 233
      qa/vagrant/src/test/resources/packaging/tests/30_deb_package.bats
  24. 0 220
      qa/vagrant/src/test/resources/packaging/tests/40_rpm_package.bats

+ 3 - 10
qa/vagrant/build.gradle

@@ -28,7 +28,8 @@ plugins {
 
 
 dependencies {
 dependencies {
   compile "junit:junit:${versions.junit}"
   compile "junit:junit:${versions.junit}"
-  compile "org.hamcrest:hamcrest-all:${versions.hamcrest}"
+  compile "org.hamcrest:hamcrest-core:${versions.hamcrest}"
+  compile "org.hamcrest:hamcrest-library:${versions.hamcrest}"
   compile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
   compile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
 
 
   compile "org.apache.httpcomponents:httpcore:${versions.httpcore}"
   compile "org.apache.httpcomponents:httpcore:${versions.httpcore}"
@@ -91,13 +92,5 @@ tasks.thirdPartyAudit.excludes = [
         'org.apache.log4j.Priority',
         'org.apache.log4j.Priority',
         // commons-logging provided dependencies
         // commons-logging provided dependencies
         'javax.servlet.ServletContextEvent',
         'javax.servlet.ServletContextEvent',
-        'javax.servlet.ServletContextListener',
-        // from randomized testing
-        'org.apache.tools.ant.BuildException',
-        'org.apache.tools.ant.DirectoryScanner',
-        'org.apache.tools.ant.Task',
-        'org.apache.tools.ant.types.FileSet',
-        'org.easymock.EasyMock',
-        'org.easymock.IArgumentMatcher',
-        'org.jmock.core.Constraint'
+        'javax.servlet.ServletContextListener'
 ]
 ]

+ 20 - 2
qa/vagrant/src/main/java/org/elasticsearch/packaging/PackagingTests.java

@@ -19,10 +19,19 @@
 
 
 package org.elasticsearch.packaging;
 package org.elasticsearch.packaging;
 
 
+import org.elasticsearch.packaging.test.DefaultDebPreservationTests;
+import org.elasticsearch.packaging.test.DefaultDebBasicTests;
+import org.elasticsearch.packaging.test.DefaultRpmPreservationTests;
+import org.elasticsearch.packaging.test.DefaultRpmBasicTests;
+import org.elasticsearch.packaging.test.OssDebPreservationTests;
+import org.elasticsearch.packaging.test.OssDebBasicTests;
+import org.elasticsearch.packaging.test.OssRpmPreservationTests;
+import org.elasticsearch.packaging.test.OssRpmBasicTests;
 import org.elasticsearch.packaging.test.OssTarTests;
 import org.elasticsearch.packaging.test.OssTarTests;
 import org.elasticsearch.packaging.test.OssZipTests;
 import org.elasticsearch.packaging.test.OssZipTests;
 import org.elasticsearch.packaging.test.DefaultTarTests;
 import org.elasticsearch.packaging.test.DefaultTarTests;
 import org.elasticsearch.packaging.test.DefaultZipTests;
 import org.elasticsearch.packaging.test.DefaultZipTests;
+import org.elasticsearch.packaging.test.PackageDependenciesTests;
 
 
 import org.junit.runner.RunWith;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite;
@@ -31,8 +40,17 @@ import org.junit.runners.Suite.SuiteClasses;
 @RunWith(Suite.class)
 @RunWith(Suite.class)
 @SuiteClasses({
 @SuiteClasses({
     DefaultTarTests.class,
     DefaultTarTests.class,
-    DefaultZipTests.class,
     OssTarTests.class,
     OssTarTests.class,
-    OssZipTests.class
+    DefaultZipTests.class,
+    OssZipTests.class,
+    PackageDependenciesTests.class,
+    DefaultRpmBasicTests.class,
+    OssRpmBasicTests.class,
+    DefaultDebBasicTests.class,
+    OssDebBasicTests.class,
+    DefaultDebPreservationTests.class,
+    OssDebPreservationTests.class,
+    DefaultRpmPreservationTests.class,
+    OssRpmPreservationTests.class
 })
 })
 public class PackagingTests {}
 public class PackagingTests {}

+ 127 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DebPreservationTestCase.java

@@ -0,0 +1,127 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import com.carrotsearch.randomizedtesting.annotations.TestCaseOrdering;
+import org.elasticsearch.packaging.util.Distribution;
+import org.elasticsearch.packaging.util.Installation;
+import org.elasticsearch.packaging.util.Shell;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static org.elasticsearch.packaging.util.Cleanup.cleanEverything;
+import static org.elasticsearch.packaging.util.FileUtils.assertPathsDontExist;
+import static org.elasticsearch.packaging.util.FileUtils.assertPathsExist;
+import static org.elasticsearch.packaging.util.Packages.SYSVINIT_SCRIPT;
+import static org.elasticsearch.packaging.util.Packages.assertInstalled;
+import static org.elasticsearch.packaging.util.Packages.assertRemoved;
+import static org.elasticsearch.packaging.util.Packages.install;
+import static org.elasticsearch.packaging.util.Packages.remove;
+import static org.elasticsearch.packaging.util.Packages.packageStatus;
+import static org.elasticsearch.packaging.util.Packages.verifyPackageInstallation;
+import static org.elasticsearch.packaging.util.Platforms.isDPKG;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeThat;
+import static org.junit.Assume.assumeTrue;
+
+@TestCaseOrdering(TestCaseOrdering.AlphabeticOrder.class)
+public abstract class DebPreservationTestCase extends PackagingTestCase {
+
+    private static Installation installation;
+
+    protected abstract Distribution distribution();
+
+    @BeforeClass
+    public static void cleanup() {
+        installation = null;
+        cleanEverything();
+    }
+
+    @Before
+    public void onlyCompatibleDistributions() {
+        assumeTrue("only dpkg platforms", isDPKG());
+        assumeTrue("only compatible distributions", distribution().packaging.compatible);
+    }
+
+    public void test10Install() {
+        assertRemoved(distribution());
+        installation = install(distribution());
+        assertInstalled(distribution());
+        verifyPackageInstallation(installation, distribution());
+    }
+
+    public void test20Remove() {
+        assumeThat(installation, is(notNullValue()));
+
+        remove(distribution());
+
+        // some config files were not removed
+
+        assertPathsExist(
+            installation.config,
+            installation.config("elasticsearch.yml"),
+            installation.config("jvm.options"),
+            installation.config("log4j2.properties")
+        );
+
+        // keystore was removed
+
+        assertPathsDontExist(
+            installation.config("elasticsearch.keystore"),
+            installation.config(".elasticsearch.keystore.initial_md5sum")
+        );
+
+        // doc files were removed
+
+        assertPathsDontExist(
+            Paths.get("/usr/share/doc/" + distribution().flavor.name),
+            Paths.get("/usr/share/doc/" + distribution().flavor.name + "/copyright")
+        );
+
+        // sysvinit service file was not removed
+        assertTrue(Files.exists(SYSVINIT_SCRIPT));
+
+        // defaults file was not removed
+        assertTrue(Files.exists(installation.envFile));
+    }
+
+    public void test30Purge() {
+        assumeThat(installation, is(notNullValue()));
+
+        final Shell sh = new Shell();
+        sh.run("dpkg --purge " + distribution().flavor.name);
+
+        assertRemoved(distribution());
+
+        assertPathsDontExist(
+            installation.config,
+            installation.envFile,
+            SYSVINIT_SCRIPT
+        );
+
+        assertThat(packageStatus(distribution()).exitCode, is(1));
+    }
+}

+ 31 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultDebBasicTests.java

@@ -0,0 +1,31 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class DefaultDebBasicTests extends PackageTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.DEFAULT_DEB;
+    }
+
+}

+ 30 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultDebPreservationTests.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class DefaultDebPreservationTests extends DebPreservationTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.DEFAULT_DEB;
+    }
+}

+ 30 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultRpmBasicTests.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class DefaultRpmBasicTests extends PackageTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.DEFAULT_RPM;
+    }
+}

+ 30 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/DefaultRpmPreservationTests.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class DefaultRpmPreservationTests extends RpmPreservationTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.DEFAULT_RPM;
+    }
+}

+ 30 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssDebBasicTests.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class OssDebBasicTests extends PackageTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.OSS_DEB;
+    }
+}

+ 30 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssDebPreservationTests.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class OssDebPreservationTests extends DebPreservationTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.OSS_DEB;
+    }
+}

+ 30 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssRpmBasicTests.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class OssRpmBasicTests extends PackageTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.OSS_RPM;
+    }
+}

+ 30 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/OssRpmPreservationTests.java

@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Distribution;
+
+public class OssRpmPreservationTests extends RpmPreservationTestCase {
+
+    @Override
+    protected Distribution distribution() {
+        return Distribution.OSS_RPM;
+    }
+}

+ 73 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/PackageDependenciesTests.java

@@ -0,0 +1,73 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import org.elasticsearch.packaging.util.Platforms;
+import org.elasticsearch.packaging.util.Shell;
+import org.elasticsearch.packaging.util.Shell.Result;
+
+import java.util.regex.Pattern;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.elasticsearch.packaging.util.Distribution.DEFAULT_DEB;
+import static org.elasticsearch.packaging.util.Distribution.DEFAULT_RPM;
+import static org.elasticsearch.packaging.util.Distribution.OSS_DEB;
+import static org.elasticsearch.packaging.util.Distribution.OSS_RPM;
+import static org.elasticsearch.packaging.util.FileUtils.getDistributionFile;
+import static org.junit.Assume.assumeTrue;
+
+/**
+ * Tests that linux packages correctly declare their dependencies and their conflicts
+ */
+public class PackageDependenciesTests extends PackagingTestCase {
+
+    public void testDebDependencies() {
+        assumeTrue(Platforms.isDPKG());
+
+        final Shell sh = new Shell();
+
+        final Result defaultResult = sh.run("dpkg -I " + getDistributionFile(DEFAULT_DEB));
+        final Result ossResult = sh.run("dpkg -I " + getDistributionFile(OSS_DEB));
+
+        assertTrue(Pattern.compile("(?m)^ Depends:.*bash.*").matcher(defaultResult.stdout).find());
+        assertTrue(Pattern.compile("(?m)^ Depends:.*bash.*").matcher(ossResult.stdout).find());
+
+        assertTrue(Pattern.compile("(?m)^ Conflicts: elasticsearch-oss$").matcher(defaultResult.stdout).find());
+        assertTrue(Pattern.compile("(?m)^ Conflicts: elasticsearch$").matcher(ossResult.stdout).find());
+    }
+
+    public void testRpmDependencies() {
+        assumeTrue(Platforms.isRPM());
+
+        final Shell sh = new Shell();
+
+        final Result defaultDeps = sh.run("rpm -qpR " + getDistributionFile(DEFAULT_RPM));
+        final Result ossDeps = sh.run("rpm -qpR " + getDistributionFile(OSS_RPM));
+
+        assertTrue(Pattern.compile("(?m)^/bin/bash\\s*$").matcher(defaultDeps.stdout).find());
+        assertTrue(Pattern.compile("(?m)^/bin/bash\\s*$").matcher(ossDeps.stdout).find());
+
+        final Result defaultConflicts = sh.run("rpm -qp --conflicts " + getDistributionFile(DEFAULT_RPM));
+        final Result ossConflicts = sh.run("rpm -qp --conflicts " + getDistributionFile(OSS_RPM));
+
+        assertTrue(Pattern.compile("(?m)^elasticsearch-oss\\s*$").matcher(defaultConflicts.stdout).find());
+        assertTrue(Pattern.compile("(?m)^elasticsearch\\s*$").matcher(ossConflicts.stdout).find());
+    }
+}

+ 168 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/PackageTestCase.java

@@ -0,0 +1,168 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import com.carrotsearch.randomizedtesting.annotations.TestCaseOrdering;
+import org.elasticsearch.packaging.util.Distribution;
+import org.elasticsearch.packaging.util.Installation;
+import org.elasticsearch.packaging.util.Shell;
+
+import org.elasticsearch.packaging.util.Shell.Result;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.elasticsearch.packaging.util.Cleanup.cleanEverything;
+import static org.elasticsearch.packaging.util.FileUtils.assertPathsDontExist;
+import static org.elasticsearch.packaging.util.Packages.SYSTEMD_SERVICE;
+import static org.elasticsearch.packaging.util.Packages.assertInstalled;
+import static org.elasticsearch.packaging.util.Packages.assertRemoved;
+import static org.elasticsearch.packaging.util.Packages.install;
+import static org.elasticsearch.packaging.util.Packages.remove;
+import static org.elasticsearch.packaging.util.Packages.startElasticsearch;
+import static org.elasticsearch.packaging.util.Packages.verifyPackageInstallation;
+import static org.elasticsearch.packaging.util.Platforms.getOsRelease;
+import static org.elasticsearch.packaging.util.Platforms.isSystemd;
+import static org.elasticsearch.packaging.util.ServerUtils.runElasticsearchTests;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.isEmptyString;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeThat;
+import static org.junit.Assume.assumeTrue;
+
+@TestCaseOrdering(TestCaseOrdering.AlphabeticOrder.class)
+public abstract class PackageTestCase extends PackagingTestCase {
+
+    private static Installation installation;
+
+    protected abstract Distribution distribution();
+
+    @BeforeClass
+    public static void cleanup() {
+        installation = null;
+        cleanEverything();
+    }
+
+    @Before
+    public void onlyCompatibleDistributions() {
+        assumeTrue("only compatible distributions", distribution().packaging.compatible);
+    }
+
+    public void test10InstallPackage() {
+        assertRemoved(distribution());
+        installation = install(distribution());
+        assertInstalled(distribution());
+        verifyPackageInstallation(installation, distribution());
+    }
+
+    public void test20PluginsCommandWhenNoPlugins() {
+        assumeThat(installation, is(notNullValue()));
+
+        final Shell sh = new Shell();
+        assertThat(sh.run(installation.bin("elasticsearch-plugin") + " list").stdout, isEmptyString());
+    }
+
+    public void test30InstallDoesNotStartServer() {
+        assumeThat(installation, is(notNullValue()));
+
+        final Shell sh = new Shell();
+        assertThat(sh.run("ps aux").stdout, not(containsString("org.elasticsearch.bootstrap.Elasticsearch")));
+    }
+
+    public void test40StartServer() throws IOException {
+        assumeThat(installation, is(notNullValue()));
+
+        startElasticsearch();
+        runElasticsearchTests();
+        verifyPackageInstallation(installation, distribution()); // check startup script didn't change permissions
+    }
+
+    public void test50Remove() {
+        assumeThat(installation, is(notNullValue()));
+
+        remove(distribution());
+
+        // removing must stop the service
+        final Shell sh = new Shell();
+        assertThat(sh.run("ps aux").stdout, not(containsString("org.elasticsearch.bootstrap.Elasticsearch")));
+
+        if (isSystemd()) {
+
+            final int statusExitCode;
+
+            // Before version 231 systemctl returned exit code 3 for both services that were stopped, and nonexistent
+            // services [1]. In version 231 and later it returns exit code 4 for non-existent services.
+            //
+            // The exception is Centos 7 and oel 7 where it returns exit code 4 for non-existent services from a systemd reporting a version
+            // earlier than 231. Centos 6 does not have an /etc/os-release, but that's fine because it also doesn't use systemd.
+            //
+            // [1] https://github.com/systemd/systemd/pull/3385
+            if (getOsRelease().contains("ID=\"centos\"") || getOsRelease().contains("ID=\"ol\"")) {
+                statusExitCode = 4;
+            } else {
+
+                final Result versionResult = sh.run("systemctl --version");
+                final Matcher matcher = Pattern.compile("^systemd (\\d+)\n").matcher(versionResult.stdout);
+                matcher.find();
+                final int version = Integer.parseInt(matcher.group(1));
+
+                statusExitCode = version < 231
+                    ? 3
+                    : 4;
+            }
+
+            assertThat(sh.runIgnoreExitCode("systemctl status elasticsearch.service").exitCode, is(statusExitCode));
+            assertThat(sh.runIgnoreExitCode("systemctl is-enabled elasticsearch.service").exitCode, is(1));
+
+        }
+
+        assertPathsDontExist(
+            installation.bin,
+            installation.lib,
+            installation.modules,
+            installation.plugins,
+            installation.logs,
+            installation.pidDir
+        );
+
+        assertFalse(Files.exists(SYSTEMD_SERVICE));
+    }
+
+    public void test60Reinstall() {
+        assumeThat(installation, is(notNullValue()));
+
+        installation = install(distribution());
+        assertInstalled(distribution());
+        verifyPackageInstallation(installation, distribution());
+
+        remove(distribution());
+        assertRemoved(distribution());
+    }
+}

+ 141 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/test/RpmPreservationTestCase.java

@@ -0,0 +1,141 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.test;
+
+import com.carrotsearch.randomizedtesting.annotations.TestCaseOrdering;
+import org.elasticsearch.packaging.util.Distribution;
+import org.elasticsearch.packaging.util.Installation;
+import org.elasticsearch.packaging.util.Shell;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.stream.Stream;
+
+import static org.elasticsearch.packaging.util.Cleanup.cleanEverything;
+import static org.elasticsearch.packaging.util.FileUtils.append;
+import static org.elasticsearch.packaging.util.FileUtils.assertPathsDontExist;
+import static org.elasticsearch.packaging.util.Packages.SYSTEMD_SERVICE;
+import static org.elasticsearch.packaging.util.Packages.SYSVINIT_SCRIPT;
+import static org.elasticsearch.packaging.util.Packages.assertInstalled;
+import static org.elasticsearch.packaging.util.Packages.assertRemoved;
+import static org.elasticsearch.packaging.util.Packages.install;
+import static org.elasticsearch.packaging.util.Packages.remove;
+import static org.elasticsearch.packaging.util.Packages.verifyPackageInstallation;
+import static org.elasticsearch.packaging.util.Platforms.isRPM;
+import static org.elasticsearch.packaging.util.Platforms.isSystemd;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeThat;
+import static org.junit.Assume.assumeTrue;
+
+@TestCaseOrdering(TestCaseOrdering.AlphabeticOrder.class)
+public abstract class RpmPreservationTestCase extends PackagingTestCase {
+
+    private static Installation installation;
+
+    protected abstract Distribution distribution();
+
+    @BeforeClass
+    public static void cleanup() {
+        installation = null;
+        cleanEverything();
+    }
+
+    @Before
+    public void onlyCompatibleDistributions() {
+        assumeTrue("only rpm platforms", isRPM());
+        assumeTrue("only compatible distributions", distribution().packaging.compatible);
+    }
+
+    public void test10Install() {
+        assertRemoved(distribution());
+        installation = install(distribution());
+        assertInstalled(distribution());
+        verifyPackageInstallation(installation, distribution());
+    }
+
+    public void test20Remove() {
+        assumeThat(installation, is(notNullValue()));
+
+        remove(distribution());
+
+        // config was removed
+        assertFalse(Files.exists(installation.config));
+
+        // sysvinit service file was removed
+        assertFalse(Files.exists(SYSVINIT_SCRIPT));
+
+        // defaults file was removed
+        assertFalse(Files.exists(installation.envFile));
+    }
+
+    public void test30PreserveConfig() {
+        final Shell sh = new Shell();
+
+        installation = install(distribution());
+        assertInstalled(distribution());
+        verifyPackageInstallation(installation, distribution());
+
+        sh.run("echo foobar | " + installation.executables().elasticsearchKeystore + " add --stdin foo.bar");
+        Stream.of(
+            installation.config("elasticsearch.yml"),
+            installation.config("jvm.options"),
+            installation.config("log4j2.properties")
+        ).forEach(path -> append(path, "# foo"));
+
+        remove(distribution());
+        assertRemoved(distribution());
+
+        if (isSystemd()) {
+            assertThat(sh.runIgnoreExitCode("systemctl is-enabled elasticsearch.service").exitCode, is(1));
+        }
+
+        assertPathsDontExist(
+            installation.bin,
+            installation.lib,
+            installation.modules,
+            installation.plugins,
+            installation.logs,
+            installation.pidDir,
+            installation.envFile,
+            SYSVINIT_SCRIPT,
+            SYSTEMD_SERVICE
+        );
+
+        assertTrue(Files.exists(installation.config));
+        assertTrue(Files.exists(installation.config("elasticsearch.keystore")));
+
+        Stream.of(
+            "elasticsearch.yml",
+            "jvm.options",
+            "log4j2.properties"
+        ).forEach(configFile -> {
+            final Path original = installation.config(configFile);
+            final Path saved = installation.config(configFile + ".rpmsave");
+            assertFalse(original + " should not exist", Files.exists(original));
+            assertTrue(saved + " should exist", Files.exists(saved));
+        });
+    }
+}

+ 5 - 6
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Archives.java

@@ -35,7 +35,7 @@ import static org.elasticsearch.packaging.util.FileMatcher.p660;
 import static org.elasticsearch.packaging.util.FileMatcher.p755;
 import static org.elasticsearch.packaging.util.FileMatcher.p755;
 import static org.elasticsearch.packaging.util.FileUtils.getCurrentVersion;
 import static org.elasticsearch.packaging.util.FileUtils.getCurrentVersion;
 import static org.elasticsearch.packaging.util.FileUtils.getDefaultArchiveInstallPath;
 import static org.elasticsearch.packaging.util.FileUtils.getDefaultArchiveInstallPath;
-import static org.elasticsearch.packaging.util.FileUtils.getPackagingArchivesDir;
+import static org.elasticsearch.packaging.util.FileUtils.getDistributionFile;
 import static org.elasticsearch.packaging.util.FileUtils.lsGlob;
 import static org.elasticsearch.packaging.util.FileUtils.lsGlob;
 
 
 import static org.elasticsearch.packaging.util.FileUtils.mv;
 import static org.elasticsearch.packaging.util.FileUtils.mv;
@@ -66,7 +66,7 @@ public class Archives {
     public static Installation installArchive(Distribution distribution, Path fullInstallPath, String version) {
     public static Installation installArchive(Distribution distribution, Path fullInstallPath, String version) {
         final Shell sh = new Shell();
         final Shell sh = new Shell();
 
 
-        final Path distributionFile = getPackagingArchivesDir().resolve(distribution.filename(version));
+        final Path distributionFile = getDistributionFile(distribution);
         final Path baseInstallPath = fullInstallPath.getParent();
         final Path baseInstallPath = fullInstallPath.getParent();
         final Path extractedPath = baseInstallPath.resolve("elasticsearch-" + version);
         final Path extractedPath = baseInstallPath.resolve("elasticsearch-" + version);
 
 
@@ -106,7 +106,7 @@ public class Archives {
         Platforms.onLinux(() -> setupArchiveUsersLinux(fullInstallPath));
         Platforms.onLinux(() -> setupArchiveUsersLinux(fullInstallPath));
         Platforms.onWindows(() -> setupArchiveUsersWindows(fullInstallPath));
         Platforms.onWindows(() -> setupArchiveUsersWindows(fullInstallPath));
 
 
-        return new Installation(fullInstallPath);
+        return Installation.ofArchive(fullInstallPath);
     }
     }
 
 
     private static void setupArchiveUsersLinux(Path installPath) {
     private static void setupArchiveUsersLinux(Path installPath) {
@@ -176,7 +176,6 @@ public class Archives {
         ).forEach(dir -> assertThat(dir, file(Directory, owner, owner, p755)));
         ).forEach(dir -> assertThat(dir, file(Directory, owner, owner, p755)));
 
 
         assertThat(Files.exists(es.data), is(false));
         assertThat(Files.exists(es.data), is(false));
-        assertThat(Files.exists(es.scripts), is(false));
 
 
         assertThat(es.bin, file(Directory, owner, owner, p755));
         assertThat(es.bin, file(Directory, owner, owner, p755));
         assertThat(es.lib, file(Directory, owner, owner, p755));
         assertThat(es.lib, file(Directory, owner, owner, p755));
@@ -209,7 +208,7 @@ public class Archives {
             "elasticsearch.yml",
             "elasticsearch.yml",
             "jvm.options",
             "jvm.options",
             "log4j2.properties"
             "log4j2.properties"
-        ).forEach(config -> assertThat(es.config(config), file(File, owner, owner, p660)));
+        ).forEach(configFile -> assertThat(es.config(configFile), file(File, owner, owner, p660)));
 
 
         Stream.of(
         Stream.of(
             "NOTICE.txt",
             "NOTICE.txt",
@@ -252,7 +251,7 @@ public class Archives {
             "roles.yml",
             "roles.yml",
             "role_mapping.yml",
             "role_mapping.yml",
             "log4j2.properties"
             "log4j2.properties"
-        ).forEach(config -> assertThat(es.config(config), file(File, owner, owner, p660)));
+        ).forEach(configFile -> assertThat(es.config(configFile), file(File, owner, owner, p660)));
     }
     }
 
 
     public static void runElasticsearch(Installation installation) throws IOException {
     public static void runElasticsearch(Installation installation) throws IOException {

+ 4 - 11
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Cleanup.java

@@ -27,11 +27,9 @@ import java.util.List;
 
 
 import static org.elasticsearch.packaging.util.FileUtils.getTempDir;
 import static org.elasticsearch.packaging.util.FileUtils.getTempDir;
 import static org.elasticsearch.packaging.util.FileUtils.lsGlob;
 import static org.elasticsearch.packaging.util.FileUtils.lsGlob;
-import static org.elasticsearch.packaging.util.Platforms.isAptGet;
 import static org.elasticsearch.packaging.util.Platforms.isDPKG;
 import static org.elasticsearch.packaging.util.Platforms.isDPKG;
 import static org.elasticsearch.packaging.util.Platforms.isRPM;
 import static org.elasticsearch.packaging.util.Platforms.isRPM;
 import static org.elasticsearch.packaging.util.Platforms.isSystemd;
 import static org.elasticsearch.packaging.util.Platforms.isSystemd;
-import static org.elasticsearch.packaging.util.Platforms.isYUM;
 
 
 public class Cleanup {
 public class Cleanup {
 
 
@@ -100,19 +98,14 @@ public class Cleanup {
         final Shell sh = new Shell();
         final Shell sh = new Shell();
 
 
         if (isRPM()) {
         if (isRPM()) {
-            sh.runIgnoreExitCode("rpm --quiet -e elasticsearch elasticsearch-oss");
-        }
-
-        if (isYUM()) {
-            sh.runIgnoreExitCode("yum remove -y elasticsearch elasticsearch-oss");
+            // Doing rpm erase on both packages in one command will remove neither since both cannot be installed
+            // this may leave behind config files in /etc/elasticsearch, but a later step in this cleanup will get them
+            sh.runIgnoreExitCode("rpm --quiet -e elasticsearch");
+            sh.runIgnoreExitCode("rpm --quiet -e elasticsearch-oss");
         }
         }
 
 
         if (isDPKG()) {
         if (isDPKG()) {
             sh.runIgnoreExitCode("dpkg --purge elasticsearch elasticsearch-oss");
             sh.runIgnoreExitCode("dpkg --purge elasticsearch elasticsearch-oss");
         }
         }
-
-        if (isAptGet()) {
-            sh.runIgnoreExitCode("apt-get --quiet --yes purge elasticsearch elasticsearch-oss");
-        }
     }
     }
 }
 }

+ 1 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/FileMatcher.java

@@ -47,6 +47,7 @@ public class FileMatcher extends TypeSafeMatcher<Path> {
     public enum Fileness { File, Directory }
     public enum Fileness { File, Directory }
 
 
     public static final Set<PosixFilePermission> p755 = fromString("rwxr-xr-x");
     public static final Set<PosixFilePermission> p755 = fromString("rwxr-xr-x");
+    public static final Set<PosixFilePermission> p750 = fromString("rwxr-x---");
     public static final Set<PosixFilePermission> p660 = fromString("rw-rw----");
     public static final Set<PosixFilePermission> p660 = fromString("rw-rw----");
     public static final Set<PosixFilePermission> p644 = fromString("rw-r--r--");
     public static final Set<PosixFilePermission> p644 = fromString("rw-r--r--");
 
 

+ 19 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/FileUtils.java

@@ -33,11 +33,14 @@ import java.nio.file.attribute.BasicFileAttributes;
 import java.nio.file.attribute.FileOwnerAttributeView;
 import java.nio.file.attribute.FileOwnerAttributeView;
 import java.nio.file.attribute.PosixFileAttributes;
 import java.nio.file.attribute.PosixFileAttributes;
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsNot.not;
 import static org.hamcrest.core.IsNot.not;
 import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString;
 import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 
 /**
 /**
  * Wrappers and convenience methods for common filesystem operations
  * Wrappers and convenience methods for common filesystem operations
@@ -160,4 +163,20 @@ public class FileUtils {
         assertThat(fromEnv, not(isEmptyOrNullString()));
         assertThat(fromEnv, not(isEmptyOrNullString()));
         return Paths.get(fromEnv);
         return Paths.get(fromEnv);
     }
     }
+
+    public static Path getDistributionFile(Distribution distribution) {
+        return getDistributionFile(distribution, getCurrentVersion());
+    }
+
+    public static Path getDistributionFile(Distribution distribution, String version) {
+        return getPackagingArchivesDir().resolve(distribution.filename(version));
+    }
+
+    public static void assertPathsExist(Path... paths) {
+        Arrays.stream(paths).forEach(path -> assertTrue(path + " should exist", Files.exists(path)));
+    }
+
+    public static void assertPathsDontExist(Path... paths) {
+        Arrays.stream(paths).forEach(path -> assertFalse(path + " should not exist", Files.exists(path)));
+    }
 }
 }

+ 28 - 6
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Installation.java

@@ -20,6 +20,7 @@
 package org.elasticsearch.packaging.util;
 package org.elasticsearch.packaging.util;
 
 
 import java.nio.file.Path;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 
 
 /**
 /**
  * Represents an installation of Elasticsearch
  * Represents an installation of Elasticsearch
@@ -34,9 +35,10 @@ public class Installation {
     public final Path logs;
     public final Path logs;
     public final Path plugins;
     public final Path plugins;
     public final Path modules;
     public final Path modules;
-    public final Path scripts;
+    public final Path pidDir;
+    public final Path envFile;
 
 
-    public Installation(Path home, Path config, Path data, Path logs, Path plugins, Path modules, Path scripts) {
+    public Installation(Path home, Path config, Path data, Path logs, Path plugins, Path modules, Path pidDir, Path envFile) {
         this.home = home;
         this.home = home;
         this.bin = home.resolve("bin");
         this.bin = home.resolve("bin");
         this.lib = home.resolve("lib");
         this.lib = home.resolve("lib");
@@ -46,18 +48,38 @@ public class Installation {
         this.logs = logs;
         this.logs = logs;
         this.plugins = plugins;
         this.plugins = plugins;
         this.modules = modules;
         this.modules = modules;
-        this.scripts = scripts;
+        this.pidDir = pidDir;
+        this.envFile = envFile;
     }
     }
 
 
-    public Installation(Path home) {
-        this(
+    public static Installation ofArchive(Path home) {
+        return new Installation(
             home,
             home,
             home.resolve("config"),
             home.resolve("config"),
             home.resolve("data"),
             home.resolve("data"),
             home.resolve("logs"),
             home.resolve("logs"),
             home.resolve("plugins"),
             home.resolve("plugins"),
             home.resolve("modules"),
             home.resolve("modules"),
-            home.resolve("scripts")
+            null,
+            null
+        );
+    }
+
+    public static Installation ofPackage(Distribution.Packaging packaging) {
+
+        final Path envFile = (packaging == Distribution.Packaging.RPM)
+            ? Paths.get("/etc/sysconfig/elasticsearch")
+            : Paths.get("/etc/default/elasticsearch");
+
+        return new Installation(
+            Paths.get("/usr/share/elasticsearch"),
+            Paths.get("/etc/elasticsearch"),
+            Paths.get("/var/lib/elasticsearch"),
+            Paths.get("/var/log/elasticsearch"),
+            Paths.get("/usr/share/elasticsearch/plugins"),
+            Paths.get("/usr/share/elasticsearch/modules"),
+            Paths.get("/var/run/elasticsearch"),
+            envFile
         );
         );
     }
     }
 
 

+ 259 - 0
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Packages.java

@@ -0,0 +1,259 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.packaging.util;
+
+import org.elasticsearch.packaging.util.Shell.Result;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+import static org.elasticsearch.packaging.util.FileMatcher.Fileness.Directory;
+import static org.elasticsearch.packaging.util.FileMatcher.Fileness.File;
+import static org.elasticsearch.packaging.util.FileMatcher.file;
+import static org.elasticsearch.packaging.util.FileMatcher.p644;
+import static org.elasticsearch.packaging.util.FileMatcher.p660;
+import static org.elasticsearch.packaging.util.FileMatcher.p750;
+import static org.elasticsearch.packaging.util.FileMatcher.p755;
+import static org.elasticsearch.packaging.util.FileUtils.getCurrentVersion;
+import static org.elasticsearch.packaging.util.FileUtils.getDistributionFile;
+import static org.elasticsearch.packaging.util.Platforms.isSysVInit;
+import static org.elasticsearch.packaging.util.Platforms.isSystemd;
+import static org.elasticsearch.packaging.util.ServerUtils.waitForElasticsearch;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class Packages {
+
+    public static final Path SYSVINIT_SCRIPT = Paths.get("/etc/init.d/elasticsearch");
+    public static final Path SYSTEMD_SERVICE = Paths.get("/usr/lib/systemd/system/elasticsearch.service");
+
+    public static void assertInstalled(Distribution distribution) {
+        final Result status = packageStatus(distribution);
+        assertThat(status.exitCode, is(0));
+
+        Platforms.onDPKG(() -> assertFalse(Pattern.compile("(?m)^Status:.+deinstall ok").matcher(status.stdout).find()));
+    }
+
+    public static void assertRemoved(Distribution distribution) {
+        final Result status = packageStatus(distribution);
+
+        Platforms.onRPM(() -> assertThat(status.exitCode, is(1)));
+
+        Platforms.onDPKG(() -> {
+            assertThat(status.exitCode, anyOf(is(0), is(1)));
+            if (status.exitCode == 0) {
+                assertTrue(Pattern.compile("(?m)^Status:.+deinstall ok").matcher(status.stdout).find());
+            }
+        });
+    }
+
+    public static Result packageStatus(Distribution distribution) {
+        final Shell sh = new Shell();
+        final Result result;
+
+        if (distribution.packaging == Distribution.Packaging.RPM) {
+            result = sh.runIgnoreExitCode("rpm -qe " + distribution.flavor.name);
+        } else {
+            result = sh.runIgnoreExitCode("dpkg -s " + distribution.flavor.name);
+        }
+
+        return result;
+    }
+
+    public static Installation install(Distribution distribution) {
+        return install(distribution, getCurrentVersion());
+    }
+
+    public static Installation install(Distribution distribution, String version) {
+        final Shell sh = new Shell();
+        final Path distributionFile = getDistributionFile(distribution, version);
+
+        Platforms.onRPM(() -> sh.run("rpm -i " + distributionFile));
+        Platforms.onDPKG(() -> sh.run("dpkg -i " + distributionFile));
+
+        return Installation.ofPackage(distribution.packaging);
+    }
+
+    public static void remove(Distribution distribution) {
+        final Shell sh = new Shell();
+
+        Platforms.onRPM(() -> {
+            sh.run("rpm -e " + distribution.flavor.name);
+            final Result status = packageStatus(distribution);
+            assertThat(status.exitCode, is(1));
+        });
+
+        Platforms.onDPKG(() -> {
+            sh.run("dpkg -r " + distribution.flavor.name);
+            final Result status = packageStatus(distribution);
+            assertThat(status.exitCode, is(0));
+            assertTrue(Pattern.compile("(?m)^Status:.+deinstall ok").matcher(status.stdout).find());
+        });
+    }
+
+    public static void verifyPackageInstallation(Installation installation, Distribution distribution) {
+        verifyOssInstallation(installation, distribution);
+        if (distribution.flavor == Distribution.Flavor.DEFAULT) {
+            verifyDefaultInstallation(installation);
+        }
+    }
+
+
+    private static void verifyOssInstallation(Installation es, Distribution distribution) {
+        final Shell sh = new Shell();
+
+        sh.run("id elasticsearch");
+        sh.run("getent group elasticsearch");
+
+        final Result passwdResult = sh.run("getent passwd elasticsearch");
+        final Path homeDir = Paths.get(passwdResult.stdout.trim().split(":")[5]);
+        assertFalse("elasticsearch user home directory must not exist", Files.exists(homeDir));
+
+        Stream.of(
+            es.home,
+            es.plugins,
+            es.modules
+        ).forEach(dir -> assertThat(dir, file(Directory, "root", "root", p755)));
+
+        assertThat(es.pidDir, file(Directory, "elasticsearch", "elasticsearch", p755));
+
+        Stream.of(
+            es.data,
+            es.logs
+        ).forEach(dir -> assertThat(dir, file(Directory, "elasticsearch", "elasticsearch", p750)));
+
+        // we shell out here because java's posix file permission view doesn't support special modes
+        assertThat(es.config, file(Directory, "root", "elasticsearch", p750));
+        assertThat(sh.run("find \"" + es.config + "\" -maxdepth 0 -printf \"%m\"").stdout, containsString("2750"));
+
+        Stream.of(
+            "elasticsearch.keystore",
+            "elasticsearch.yml",
+            "jvm.options",
+            "log4j2.properties"
+        ).forEach(configFile -> assertThat(es.config(configFile), file(File, "root", "elasticsearch", p660)));
+        assertThat(es.config(".elasticsearch.keystore.initial_md5sum"), file(File, "root", "elasticsearch", p644));
+
+        assertThat(sh.run("sudo -u elasticsearch " + es.bin("elasticsearch-keystore") + " list").stdout, containsString("keystore.seed"));
+
+        Stream.of(
+            es.bin,
+            es.lib
+        ).forEach(dir -> assertThat(dir, file(Directory, "root", "root", p755)));
+
+        Stream.of(
+            "elasticsearch",
+            "elasticsearch-plugin",
+            "elasticsearch-keystore",
+            "elasticsearch-translog"
+        ).forEach(executable -> assertThat(es.bin(executable), file(File, "root", "root", p755)));
+
+        Stream.of(
+            "NOTICE.txt",
+            "README.textile"
+        ).forEach(doc -> assertThat(es.home.resolve(doc), file(File, "root", "root", p644)));
+
+        assertThat(es.envFile, file(File, "root", "elasticsearch", p660));
+
+        if (distribution.packaging == Distribution.Packaging.RPM) {
+            assertThat(es.home.resolve("LICENSE.txt"), file(File, "root", "root", p644));
+        } else {
+            Path copyrightDir = Paths.get(sh.run("readlink -f /usr/share/doc/" + distribution.flavor.name).stdout.trim());
+            assertThat(copyrightDir, file(Directory, "root", "root", p755));
+            assertThat(copyrightDir.resolve("copyright"), file(File, "root", "root", p644));
+        }
+
+        if (isSystemd()) {
+            Stream.of(
+                SYSTEMD_SERVICE,
+                Paths.get("/usr/lib/tmpfiles.d/elasticsearch.conf"),
+                Paths.get("/usr/lib/sysctl.d/elasticsearch.conf")
+            ).forEach(confFile -> assertThat(confFile, file(File, "root", "root", p644)));
+
+            final String sysctlExecutable = (distribution.packaging == Distribution.Packaging.RPM)
+                ? "/usr/sbin/sysctl"
+                : "/sbin/sysctl";
+            assertThat(sh.run(sysctlExecutable + " vm.max_map_count").stdout, containsString("vm.max_map_count = 262144"));
+        }
+
+        if (isSysVInit()) {
+            assertThat(SYSVINIT_SCRIPT, file(File, "root", "root", p750));
+        }
+    }
+
+    private static void verifyDefaultInstallation(Installation es) {
+
+        Stream.of(
+            "elasticsearch-certgen",
+            "elasticsearch-certutil",
+            "elasticsearch-croneval",
+            "elasticsearch-migrate",
+            "elasticsearch-saml-metadata",
+            "elasticsearch-setup-passwords",
+            "elasticsearch-sql-cli",
+            "elasticsearch-syskeygen",
+            "elasticsearch-users",
+            "x-pack-env",
+            "x-pack-security-env",
+            "x-pack-watcher-env"
+        ).forEach(executable -> assertThat(es.bin(executable), file(File, "root", "root", p755)));
+
+        // at this time we only install the current version of archive distributions, but if that changes we'll need to pass
+        // the version through here
+        assertThat(es.bin("elasticsearch-sql-cli-" + getCurrentVersion() + ".jar"), file(File, "root", "root", p755));
+
+        Stream.of(
+            "users",
+            "users_roles",
+            "roles.yml",
+            "role_mapping.yml",
+            "log4j2.properties"
+        ).forEach(configFile -> assertThat(es.config(configFile), file(File, "root", "elasticsearch", p660)));
+    }
+
+    public static void startElasticsearch() throws IOException {
+        final Shell sh = new Shell();
+        if (isSystemd()) {
+            sh.run("systemctl daemon-reload");
+            sh.run("systemctl enable elasticsearch.service");
+            sh.run("systemctl is-enabled elasticsearch.service");
+            sh.run("systemctl start elasticsearch.service");
+        } else {
+            sh.run("service elasticsearch start");
+        }
+
+        waitForElasticsearch();
+
+        if (isSystemd()) {
+            sh.run("systemctl is-active elasticsearch.service");
+            sh.run("systemctl status elasticsearch.service");
+        } else {
+            sh.run("service elasticsearch status");
+        }
+    }
+}

+ 23 - 13
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/Platforms.java

@@ -19,23 +19,28 @@
 
 
 package org.elasticsearch.packaging.util;
 package org.elasticsearch.packaging.util;
 
 
+import java.nio.file.Paths;
+
+import static org.elasticsearch.packaging.util.FileUtils.slurp;
+
 public class Platforms {
 public class Platforms {
     public static final String OS_NAME = System.getProperty("os.name");
     public static final String OS_NAME = System.getProperty("os.name");
     public static final boolean LINUX = OS_NAME.startsWith("Linux");
     public static final boolean LINUX = OS_NAME.startsWith("Linux");
     public static final boolean WINDOWS = OS_NAME.startsWith("Windows");
     public static final boolean WINDOWS = OS_NAME.startsWith("Windows");
 
 
-    public static boolean isDPKG() {
-        if (WINDOWS) {
-            return false;
+    public static String getOsRelease() {
+        if (LINUX) {
+            return slurp(Paths.get("/etc/os-release"));
+        } else {
+            throw new RuntimeException("os-release is only supported on linux");
         }
         }
-        return new Shell().runIgnoreExitCode("which dpkg").isSuccess();
     }
     }
 
 
-    public static boolean isAptGet() {
+    public static boolean isDPKG() {
         if (WINDOWS) {
         if (WINDOWS) {
             return false;
             return false;
         }
         }
-        return new Shell().runIgnoreExitCode("which apt-get").isSuccess();
+        return new Shell().runIgnoreExitCode("which dpkg").isSuccess();
     }
     }
 
 
     public static boolean isRPM() {
     public static boolean isRPM() {
@@ -45,13 +50,6 @@ public class Platforms {
         return new Shell().runIgnoreExitCode("which rpm").isSuccess();
         return new Shell().runIgnoreExitCode("which rpm").isSuccess();
     }
     }
 
 
-    public static boolean isYUM() {
-        if (WINDOWS) {
-            return false;
-        }
-        return new Shell().runIgnoreExitCode("which yum").isSuccess();
-    }
-
     public static boolean isSystemd() {
     public static boolean isSystemd() {
         if (WINDOWS) {
         if (WINDOWS) {
             return false;
             return false;
@@ -78,6 +76,18 @@ public class Platforms {
         }
         }
     }
     }
 
 
+    public static void onRPM(PlatformAction action) {
+        if (isRPM()) {
+            action.run();
+        }
+    }
+
+    public static void onDPKG(PlatformAction action) {
+        if (isDPKG()) {
+            action.run();
+        }
+    }
+
     /**
     /**
      * Essentially a Runnable, but we make the distinction so it's more clear that these are synchronous
      * Essentially a Runnable, but we make the distinction so it's more clear that these are synchronous
      */
      */

+ 1 - 1
qa/vagrant/src/main/java/org/elasticsearch/packaging/util/ServerUtils.java

@@ -72,7 +72,7 @@ public class ServerUtils {
 
 
             } catch (HttpHostConnectException e) {
             } catch (HttpHostConnectException e) {
                 // we want to retry if the connection is refused
                 // we want to retry if the connection is refused
-                LOG.info("Got connection refused when waiting for cluster health", e);
+                LOG.debug("Got connection refused when waiting for cluster health", e);
             }
             }
 
 
             timeElapsed = System.currentTimeMillis() - startTime;
             timeElapsed = System.currentTimeMillis() - startTime;

+ 0 - 233
qa/vagrant/src/test/resources/packaging/tests/30_deb_package.bats

@@ -1,233 +0,0 @@
-#!/usr/bin/env bats
-
-# This file is used to test the installation and removal
-# of a Debian package.
-
-# WARNING: This testing file must be executed as root and can
-# dramatically change your system. It should only be executed
-# in a throw-away VM like those made by the Vagrantfile at
-# the root of the Elasticsearch source code. This should
-# cause the script to fail if it is executed any other way:
-[ -f /etc/is_vagrant_vm ] || {
-  >&2 echo "must be run on a vagrant VM"
-  exit 1
-}
-
-# The test case can be executed with the Bash Automated
-# Testing System tool available at https://github.com/sstephenson/bats
-# Thanks to Sam Stephenson!
-
-# Licensed to Elasticsearch under one or more contributor
-# license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright
-# ownership. Elasticsearch 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.
-
-# Load test utilities
-load $BATS_UTILS/utils.bash
-load $BATS_UTILS/packages.bash
-load $BATS_UTILS/plugins.bash
-
-# Cleans everything for the 1st execution
-setup() {
-    skip_not_dpkg
-    export_elasticsearch_paths
-}
-
-@test "[DEB] package depends on bash" {
-    dpkg -I elasticsearch-oss-$(cat version).deb | grep "Depends:.*bash.*"
-}
-
-@test "[DEB] package conflicts" {
-    dpkg -I elasticsearch-oss-$(cat version).deb | grep "^ Conflicts: elasticsearch$"
-    dpkg -I elasticsearch-$(cat version).deb | grep "^ Conflicts: elasticsearch-oss$"
-}
-
-##################################
-# Install DEB package
-##################################
-@test "[DEB] dpkg command is available" {
-    clean_before_test
-    dpkg --version
-}
-
-@test "[DEB] package is available" {
-    count=$(ls elasticsearch-oss-$(cat version).deb | wc -l)
-    [ "$count" -eq 1 ]
-}
-
-@test "[DEB] package is not installed" {
-    run dpkg -s 'elasticsearch-oss'
-    [ "$status" -eq 1 ]
-}
-
-@test "[DEB] temporarily remove java and ensure the install fails" {
-    move_java
-    run dpkg -i elasticsearch-oss-$(cat version).deb
-    output=$status
-    unmove_java
-    [ "$output" -eq 1 ]
-}
-
-@test "[DEB] install package" {
-    dpkg -i elasticsearch-oss-$(cat version).deb
-}
-
-@test "[DEB] package is installed" {
-    dpkg -s 'elasticsearch-oss'
-}
-
-@test "[DEB] verify package installation" {
-    verify_package_installation
-}
-
-@test "[DEB] verify elasticsearch-plugin list runs without any plugins installed" {
-    local plugins_list=`$ESHOME/bin/elasticsearch-plugin list`
-    [[ -z $plugins_list ]]
-}
-
-@test "[DEB] elasticsearch isn't started by package install" {
-    # Wait a second to give Elasticsearch a change to start if it is going to.
-    # This isn't perfect by any means but its something.
-    sleep 1
-    ! ps aux | grep elasticsearch | grep java
-    # You might be tempted to use jps instead of the above but that'd have to
-    # look like:
-    # ! sudo -u elasticsearch jps | grep -i elasticsearch
-    # which isn't really easier to read than the above.
-}
-
-@test "[DEB] test elasticsearch" {
-    start_elasticsearch_service
-    run_elasticsearch_tests
-}
-
-@test "[DEB] verify package installation after start" {
-    # Checks that the startup scripts didn't change the permissions
-    verify_package_installation
-}
-
-##################################
-# Uninstall DEB package
-##################################
-@test "[DEB] remove package" {
-    dpkg -r 'elasticsearch-oss'
-}
-
-@test "[DEB] package has been removed" {
-    run dpkg -s 'elasticsearch-oss'
-    [ "$status" -eq 0 ]
-    echo "$output" | grep -i "status" | grep -i "deinstall ok"
-}
-
-@test "[DEB] verify package removal" {
-    # The removal must stop the service
-    count=$(ps | grep Elasticsearch | wc -l)
-    [ "$count" -eq 0 ]
-
-    # The removal must disable the service
-    # see prerm file
-    if is_systemd; then
-        missing_exit_code=4
-        if [ $(systemctl --version | head -1 | awk '{print $2}') -lt 231 ]; then
-          # systemd before version 231 used exit code 3 when the service did not exist
-          missing_exit_code=3
-        fi
-        run systemctl status elasticsearch.service
-        [ "$status" -eq $missing_exit_code ]
-
-        run systemctl is-enabled elasticsearch.service
-        [ "$status" -eq 1 ]
-    fi
-
-    # Those directories are deleted when removing the package
-    # see postrm file
-    assert_file_not_exist "/var/log/elasticsearch"
-    assert_file_not_exist "/usr/share/elasticsearch/plugins"
-    assert_file_not_exist "/usr/share/elasticsearch/modules"
-    assert_file_not_exist "/var/run/elasticsearch"
-
-    # Those directories are removed by the package manager
-    assert_file_not_exist "/usr/share/elasticsearch/bin"
-    assert_file_not_exist "/usr/share/elasticsearch/lib"
-    assert_file_not_exist "/usr/share/elasticsearch/modules"
-    assert_file_not_exist "/usr/share/elasticsearch/modules/lang-painless"
-
-    # The configuration files are still here
-    assert_file_exist "/etc/elasticsearch"
-    # TODO: use ucf to handle these better for Debian-based systems
-    assert_file_not_exist "/etc/elasticsearch/elasticsearch.keystore"
-    assert_file_not_exist "/etc/elasticsearch/.elasticsearch.keystore.initial_md5sum"
-    assert_file_exist "/etc/elasticsearch/elasticsearch.yml"
-    assert_file_exist "/etc/elasticsearch/jvm.options"
-    assert_file_exist "/etc/elasticsearch/log4j2.properties"
-
-    # The env file is still here
-    assert_file_exist "/etc/default/elasticsearch"
-
-    # The service files are still here
-    assert_file_exist "/etc/init.d/elasticsearch"
-}
-
-@test "[DEB] purge package" {
-    # User installed scripts aren't removed so we'll just get them ourselves
-    rm -rf $ESSCRIPTS
-    dpkg --purge 'elasticsearch-oss'
-}
-
-@test "[DEB] verify package purge" {
-    # all remaining files are deleted by the purge
-    assert_file_not_exist "/etc/elasticsearch"
-    assert_file_not_exist "/etc/elasticsearch/elasticsearch.keystore"
-    assert_file_not_exist "/etc/elasticsearch/.elasticsearch.keystore.initial_md5sum"
-    assert_file_not_exist "/etc/elasticsearch/elasticsearch.yml"
-    assert_file_not_exist "/etc/elasticsearch/jvm.options"
-    assert_file_not_exist "/etc/elasticsearch/log4j2.properties"
-
-    assert_file_not_exist "/etc/default/elasticsearch"
-
-    assert_file_not_exist "/etc/init.d/elasticsearch"
-    assert_file_not_exist "/usr/lib/systemd/system/elasticsearch.service"
-
-    assert_file_not_exist "/usr/share/elasticsearch"
-
-    assert_file_not_exist "/usr/share/doc/elasticsearch-oss"
-    assert_file_not_exist "/usr/share/doc/elasticsearch-oss/copyright"
-}
-
-@test "[DEB] package has been completly removed" {
-    run dpkg -s 'elasticsearch-oss'
-    [ "$status" -eq 1 ]
-}
-
-@test "[DEB] reinstall package" {
-    dpkg -i elasticsearch-oss-$(cat version).deb
-}
-
-@test "[DEB] package is installed by reinstall" {
-    dpkg -s 'elasticsearch-oss'
-}
-
-@test "[DEB] verify package reinstallation" {
-    verify_package_installation
-}
-
-@test "[DEB] repurge package" {
-    dpkg --purge 'elasticsearch-oss'
-}
-
-@test "[DEB] package has been completly removed again" {
-    run dpkg -s 'elasticsearch-oss'
-    [ "$status" -eq 1 ]
-}

+ 0 - 220
qa/vagrant/src/test/resources/packaging/tests/40_rpm_package.bats

@@ -1,220 +0,0 @@
-#!/usr/bin/env bats
-
-# This file is used to test the installation of a RPM package.
-
-# WARNING: This testing file must be executed as root and can
-# dramatically change your system. It should only be executed
-# in a throw-away VM like those made by the Vagrantfile at
-# the root of the Elasticsearch source code. This should
-# cause the script to fail if it is executed any other way:
-[ -f /etc/is_vagrant_vm ] || {
-  >&2 echo "must be run on a vagrant VM"
-  exit 1
-}
-
-# The test case can be executed with the Bash Automated
-# Testing System tool available at https://github.com/sstephenson/bats
-# Thanks to Sam Stephenson!
-
-# Licensed to Elasticsearch under one or more contributor
-# license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright
-# ownership. Elasticsearch 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.
-
-# Load test utilities
-load $BATS_UTILS/utils.bash
-load $BATS_UTILS/packages.bash
-load $BATS_UTILS/plugins.bash
-
-# Cleans everything for the 1st execution
-setup() {
-    skip_not_rpm
-    export_elasticsearch_paths
-}
-
-@test "[RPM] package depends on bash" {
-    rpm -qpR elasticsearch-oss-$(cat version).rpm | grep '/bin/bash'
-}
-
-@test "[RPM] package conflicts" {
-    rpm -qp --conflicts elasticsearch-oss-$(cat version).rpm | grep "^elasticsearch\s*$"
-    rpm -qp --conflicts elasticsearch-$(cat version).rpm | grep "^elasticsearch-oss\s*$"
-}
-
-##################################
-# Install RPM package
-##################################
-@test "[RPM] rpm command is available" {
-    clean_before_test
-    rpm --version
-}
-
-@test "[RPM] package is available" {
-    count=$(ls elasticsearch-oss-$(cat version).rpm | wc -l)
-    [ "$count" -eq 1 ]
-}
-
-@test "[RPM] package is not installed" {
-    run rpm -qe 'elasticsearch-oss'
-    [ "$status" -eq 1 ]
-}
-
-@test "[RPM] temporarily remove java and ensure the install fails" {
-    move_java
-    run rpm -i elasticsearch-oss-$(cat version).rpm
-    output=$status
-    unmove_java
-    [ "$output" -eq 1 ]
-}
-
-@test "[RPM] install package" {
-    rpm -i elasticsearch-oss-$(cat version).rpm
-}
-
-@test "[RPM] package is installed" {
-    rpm -qe 'elasticsearch-oss'
-}
-
-@test "[RPM] verify package installation" {
-    verify_package_installation
-}
-
-@test "[RPM] verify elasticsearch-plugin list runs without any plugins installed" {
-    local plugins_list=`$ESHOME/bin/elasticsearch-plugin list`
-    [[ -z $plugins_list ]]
-}
-
-@test "[RPM] elasticsearch isn't started by package install" {
-    # Wait a second to give Elasticsearch a change to start if it is going to.
-    # This isn't perfect by any means but its something.
-    sleep 1
-    ! ps aux | grep elasticsearch | grep java
-}
-
-@test "[RPM] test elasticsearch" {
-    start_elasticsearch_service
-    run_elasticsearch_tests
-}
-
-@test "[RPM] verify package installation after start" {
-    # Checks that the startup scripts didn't change the permissions
-    verify_package_installation
-}
-
-@test "[RPM] remove package" {
-    # User installed scripts aren't removed so we'll just get them ourselves
-    rm -rf $ESSCRIPTS
-    rpm -e 'elasticsearch-oss'
-}
-
-@test "[RPM] package has been removed" {
-    run rpm -qe 'elasticsearch-oss'
-    [ "$status" -eq 1 ]
-}
-
-@test "[RPM] verify package removal" {
-    # The removal must stop the service
-    count=$(ps | grep Elasticsearch | wc -l)
-    [ "$count" -eq 0 ]
-
-    # The removal must disable the service
-    # see prerm file
-    if is_systemd; then
-        run systemctl is-enabled elasticsearch.service
-        [ "$status" -eq 1 ]
-    fi
-
-    # Those directories are deleted when removing the package
-    # see postrm file
-    assert_file_not_exist "/var/log/elasticsearch"
-    assert_file_not_exist "/usr/share/elasticsearch/plugins"
-    assert_file_not_exist "/var/run/elasticsearch"
-
-    # Those directories are removed by the package manager
-    assert_file_not_exist "/usr/share/elasticsearch/bin"
-    assert_file_not_exist "/usr/share/elasticsearch/lib"
-    assert_file_not_exist "/usr/share/elasticsearch/modules"
-
-    assert_file_not_exist "/etc/elasticsearch"
-
-    assert_file_not_exist "/etc/init.d/elasticsearch"
-    assert_file_not_exist "/usr/lib/systemd/system/elasticsearch.service"
-
-    assert_file_not_exist "/etc/sysconfig/elasticsearch"
-}
-
-@test "[RPM] reinstall package" {
-    rpm -i elasticsearch-oss-$(cat version).rpm
-}
-
-@test "[RPM] package is installed by reinstall" {
-    rpm -qe 'elasticsearch-oss'
-}
-
-@test "[RPM] verify package reinstallation" {
-    verify_package_installation
-}
-
-@test "[RPM] reremove package" {
-    echo foobar | "$ESHOME/bin/elasticsearch-keystore" add --stdin foo.bar
-    echo "# ping" >> "/etc/elasticsearch/elasticsearch.yml"
-    echo "# ping" >> "/etc/elasticsearch/jvm.options"
-    echo "# ping" >> "/etc/elasticsearch/log4j2.properties"
-    rpm -e 'elasticsearch-oss'
-}
-
-@test "[RPM] verify preservation" {
-    # The removal must disable the service
-    # see prerm file
-    if is_systemd; then
-        run systemctl is-enabled elasticsearch.service
-        [ "$status" -eq 1 ]
-    fi
-
-    # Those directories are deleted when removing the package
-    # see postrm file
-    assert_file_not_exist "/var/log/elasticsearch"
-    assert_file_not_exist "/usr/share/elasticsearch/plugins"
-    assert_file_not_exist "/usr/share/elasticsearch/modules"
-    assert_file_not_exist "/var/run/elasticsearch"
-
-    assert_file_not_exist "/usr/share/elasticsearch/bin"
-    assert_file_not_exist "/usr/share/elasticsearch/lib"
-    assert_file_not_exist "/usr/share/elasticsearch/modules"
-    assert_file_not_exist "/usr/share/elasticsearch/modules/lang-painless"
-
-    assert_file_exist "/etc/elasticsearch/elasticsearch.keystore"
-    assert_file_not_exist "/etc/elasticsearch/elasticsearch.yml"
-    assert_file_exist "/etc/elasticsearch/elasticsearch.yml.rpmsave"
-    assert_file_not_exist "/etc/elasticsearch/jvm.options"
-    assert_file_exist "/etc/elasticsearch/jvm.options.rpmsave"
-    assert_file_not_exist "/etc/elasticsearch/log4j2.properties"
-    assert_file_exist "/etc/elasticsearch/log4j2.properties.rpmsave"
-
-    assert_file_not_exist "/etc/init.d/elasticsearch"
-    assert_file_not_exist "/usr/lib/systemd/system/elasticsearch.service"
-
-    assert_file_not_exist "/etc/sysconfig/elasticsearch"
-}
-
-@test "[RPM] finalize package removal" {
-    # cleanup
-    rm -rf /etc/elasticsearch
-}
-
-@test "[RPM] package has been removed again" {
-    run rpm -qe 'elasticsearch-oss'
-    [ "$status" -eq 1 ]
-}