summaryrefslogtreecommitdiffstats
path: root/node-admin
diff options
context:
space:
mode:
authorValerij Fredriksen <valerij92@gmail.com>2020-04-04 17:19:33 +0200
committerValerij Fredriksen <valerijf@verizonmedia.com>2020-04-04 23:25:52 +0200
commit84b1401cb1a92885205a39a13b76f98df7762f08 (patch)
treeac1ead1c2ef89e6962d24c168af26e404b97c714 /node-admin
parentb75b9ceb0ea1ac9a2689a7c4c7b57c3829d264d3 (diff)
Implement YumTester
Diffstat (limited to 'node-admin')
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTester.java120
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTesterTest.java61
2 files changed, 181 insertions, 0 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTester.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTester.java
new file mode 100644
index 00000000000..4d04e1199c5
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTester.java
@@ -0,0 +1,120 @@
+// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.task.util.yum;
+
+import com.yahoo.vespa.hosted.node.admin.task.util.process.TestChildProcess2;
+import com.yahoo.vespa.hosted.node.admin.task.util.process.TestTerminal;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * A {@link Yum} tester that simplifies testing interaction with yum.
+ *
+ * @author freva
+ */
+public class YumTester extends Yum {
+
+ private final TestTerminal terminal;
+
+ public YumTester(TestTerminal terminal) {
+ super(terminal);
+ this.terminal = terminal;
+ }
+
+ public GenericYumCommandExpectation expectInstall(String... packages) {
+ return new GenericYumCommandExpectation("install", packages);
+ }
+
+ public GenericYumCommandExpectation expectUpdate(String... packages) {
+ return new GenericYumCommandExpectation("upgrade", packages);
+ }
+
+ public GenericYumCommandExpectation expectRemove(String... packages) {
+ return new GenericYumCommandExpectation("remove", packages);
+ }
+
+ public InstallFixedCommandExpectation expectInstallFixedVersion(String yumPackage) {
+ return new InstallFixedCommandExpectation(yumPackage);
+ }
+
+ public QueryInstalledExpectation expectQueryInstalled(String packageName) {
+ return new QueryInstalledExpectation(packageName);
+ }
+
+
+ public class GenericYumCommandExpectation {
+ private final String command;
+ protected final List<YumPackageName> packages;
+ private List<String> enableRepos = List.of();
+
+ private GenericYumCommandExpectation(String command, String... packages) {
+ this.command = command;
+ this.packages = Stream.of(packages).map(YumPackageName::fromString).collect(Collectors.toList());
+ }
+
+ public GenericYumCommandExpectation withEnableRepo(String... repo) {
+ this.enableRepos = List.of(repo);
+ return this;
+ }
+
+ /** Mock the return value of the converge(TaskContext) method for this operation (true iff system was modified) */
+ public YumTester andReturn(boolean value) {
+ if (value) return execute("Success");
+ switch (command) {
+ case "install": return execute("Nothing to do");
+ case "upgrade": return execute("No packages marked for update");
+ case "remove": return execute("No Packages marked for removal");
+ default: throw new IllegalArgumentException("Unknown command: " + command);
+ }
+ }
+
+ private YumTester execute(String output) {
+ StringBuilder cmd = new StringBuilder();
+ cmd.append("yum ").append(command).append(" --assumeyes");
+ enableRepos.forEach(repo -> cmd.append(" --enablerepo=").append(repo));
+ packages.forEach(pkg -> cmd.append(" ").append(pkg.toName()));
+ cmd.append(" 2>&1");
+
+ terminal.expectCommand(cmd.toString(), 0, output);
+ return YumTester.this;
+ }
+ }
+
+ public class InstallFixedCommandExpectation extends GenericYumCommandExpectation {
+ private InstallFixedCommandExpectation(String yumPackage) {
+ super("install", yumPackage);
+ }
+
+ @Override
+ public YumTester andReturn(boolean value) {
+ // Pretend package is already correctly version locked to simplify expectations
+ terminal.expectCommand("yum --quiet versionlock list 2>&1", 0, packages.get(0).toVersionLockName());
+ return super.andReturn(value);
+ }
+ }
+
+ public class QueryInstalledExpectation {
+ private final String packageName;
+
+ public QueryInstalledExpectation(String packageName) {
+ this.packageName = packageName;
+ }
+
+ /** Package name to return or null if package is not installed */
+ public YumTester andReturn(YumPackageName yumPackage) {
+ TestChildProcess2 process = new TestChildProcess2(
+ yumPackage == null ? 1 : 0,
+ yumPackage == null ? "not installed" : String.join("\n",
+ yumPackage.getName(),
+ yumPackage.getEpoch().orElse("(none)"),
+ yumPackage.getVersion().orElseThrow(() -> new IllegalArgumentException("Version must be set")),
+ yumPackage.getRelease().orElseThrow(() -> new IllegalArgumentException("Release must be set")),
+ yumPackage.getArchitecture().orElse("(none)")));
+
+ terminal.expectCommand("rpm -q " + packageName + " --queryformat \"%{NAME}\\\\n%{EPOCH}\\\\n%{VERSION}\\\\n%{RELEASE}\\\\n%{ARCH}\" 2>&1", process);
+ return YumTester.this;
+ }
+ }
+
+}
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTesterTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTesterTest.java
new file mode 100644
index 00000000000..ef380046b75
--- /dev/null
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/YumTesterTest.java
@@ -0,0 +1,61 @@
+// Copyright 2020 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.task.util.yum;
+
+import com.yahoo.vespa.hosted.node.admin.component.TestTaskContext;
+import com.yahoo.vespa.hosted.node.admin.task.util.process.TestTerminal;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author freva
+ */
+public class YumTesterTest {
+
+ private static final String[] packages = {"pkg1", "pkg2"};
+ private static final String[] repos = {"repo1", "repo2"};
+ private static final YumPackageName minimalPackage = YumPackageName.fromString("my-pkg-1.13.1-0.el7");
+ private static final YumPackageName fullPackage = YumPackageName.fromString("2:my-pkg-1.13.1-0.el7.x86_64");
+
+ private final TestTerminal terminal = new TestTerminal();
+ private final YumTester yum = new YumTester(terminal);
+ private final TestTaskContext context = new TestTaskContext();
+
+ @Test
+ public void generic_yum_methods() {
+ assertYumMethod(yum -> yum.expectInstall(packages).withEnableRepo(repos),
+ yum -> yum.install(List.of(packages)).enableRepo(repos).converge(context));
+
+ assertYumMethod(yum -> yum.expectUpdate(packages).withEnableRepo(repos),
+ yum -> yum.upgrade(List.of(packages)).enableRepo(repos).converge(context));
+
+ assertYumMethod(yum -> yum.expectRemove(packages).withEnableRepo(repos),
+ yum -> yum.remove(List.of(packages)).enableRepo(repos).converge(context));
+
+ assertYumMethod(yum -> yum.expectInstallFixedVersion(minimalPackage.toName()).withEnableRepo(repos),
+ yum -> yum.installFixedVersion(minimalPackage).enableRepo(repos).converge(context));
+ }
+
+ @Test
+ public void expect_query_installed() {
+ Stream.of(minimalPackage, fullPackage, null).forEach(pkg -> {
+ yum.expectQueryInstalled(packages[0]).andReturn(pkg);
+ assertEquals(Optional.ofNullable(pkg), yum.queryInstalled(context, packages[0]));
+ terminal.verifyAllCommandsExecuted();
+ });
+ }
+
+ private void assertYumMethod(Function<YumTester, YumTester.GenericYumCommandExpectation> yumTesterExpectationFunction,
+ Function<Yum, Boolean> yumFunction) {
+ List.of(true, false).forEach(wantedReturnValue -> {
+ yumTesterExpectationFunction.apply(yum).andReturn(wantedReturnValue);
+ assertEquals(wantedReturnValue, yumFunction.apply(yum));
+ terminal.verifyAllCommandsExecuted();
+ });
+ }
+} \ No newline at end of file