PostgresVersionCondition.java

  1. /*
  2.  * Licensed under the Apache License, Version 2.0 (the "License");
  3.  * you may not use this file except in compliance with the License.
  4.  * You may obtain a copy of the License at
  5.  *
  6.  * http://www.apache.org/licenses/LICENSE-2.0
  7.  *
  8.  * Unless required by applicable law or agreed to in writing, software
  9.  * distributed under the License is distributed on an "AS IS" BASIS,
  10.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11.  * See the License for the specific language governing permissions and
  12.  * limitations under the License.
  13.  */

  14. package de.softwareforge.testing.postgres.junit5;

  15. import static com.google.common.base.Preconditions.checkNotNull;
  16. import static java.lang.String.format;

  17. import de.softwareforge.testing.postgres.embedded.EmbeddedPostgres;

  18. import java.io.IOException;
  19. import java.util.List;

  20. import com.google.auto.value.AutoValue;
  21. import com.google.common.base.Joiner;
  22. import com.google.common.base.Splitter;
  23. import com.google.common.collect.ComparisonChain;
  24. import org.junit.jupiter.api.extension.ConditionEvaluationResult;
  25. import org.junit.jupiter.api.extension.ExecutionCondition;
  26. import org.junit.jupiter.api.extension.ExtensionContext;
  27. import org.junit.platform.commons.support.AnnotationSupport;

  28. /**
  29.  * {@link ExecutionCondition} for {@link RequirePostgresVersion}.
  30.  *
  31.  * @see RequirePostgresVersion
  32.  * @since 4.1
  33.  */
  34. public final class PostgresVersionCondition implements ExecutionCondition {

  35.     @Override
  36.     public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
  37.         return AnnotationSupport.findAnnotation(context.getElement(), RequirePostgresVersion.class)
  38.                 .map(this::checkPostgresVersion)
  39.                 .orElse(ConditionEvaluationResult.enabled("No version annotation found"));

  40.     }

  41.     private ConditionEvaluationResult checkPostgresVersion(RequirePostgresVersion requirePostgresVersion) {
  42.         Version atLeastVersion = Version.valueOf(requirePostgresVersion.atLeast());
  43.         Version lessThanVersion = Version.valueOf(requirePostgresVersion.lessThan());

  44.         if (atLeastVersion.ignore() && lessThanVersion.ignore()) {
  45.             return ConditionEvaluationResult.enabled("No PostgreSQL version range set");
  46.         }

  47.         try (EmbeddedPostgres pg = EmbeddedPostgres.forVersionCheck()) {
  48.             Version postgresVersion = Version.valueOf(pg.getPostgresVersion());

  49.             if (!atLeastVersion.ignore() && postgresVersion.compareTo(atLeastVersion) < 0) {
  50.                 return ConditionEvaluationResult.disabled(
  51.                         format("Located PostgreSQL version is %s, at least version %s is required", postgresVersion, atLeastVersion));
  52.             }

  53.             if (!lessThanVersion.ignore() && lessThanVersion.compareTo(postgresVersion) < 0) {
  54.                 return ConditionEvaluationResult.disabled(
  55.                         format("Located PostgreSQL version is %s, must be less than %s", postgresVersion, lessThanVersion));
  56.             }

  57.             return ConditionEvaluationResult.enabled(
  58.                     format("Located PostgreSQL version is %s, version range is %s - %s", postgresVersion, atLeastVersion, lessThanVersion));

  59.         } catch (IOException e) {
  60.             return ConditionEvaluationResult.disabled("IOException while checking postgres version", e.getMessage());
  61.         }
  62.     }

  63.     @AutoValue
  64.     abstract static class Version implements Comparable<Version> {

  65.         abstract int major();

  66.         abstract int minor();

  67.         abstract int patch();

  68.         private static Version valueOf(String value) {
  69.             checkNotNull(value, "value is null");

  70.             List<String> values = Splitter.on('.').trimResults().splitToList(value);
  71.             return new AutoValue_PostgresVersionCondition_Version(parseValue(values, 0),
  72.                     parseValue(values, 1),
  73.                     parseValue(values, 2));
  74.         }

  75.         private static int parseValue(List<String> values, int pos) {
  76.             if (values.size() > pos && !values.get(pos).isEmpty()) {
  77.                 try {
  78.                     return Integer.parseInt(values.get(pos));
  79.                 } catch (NumberFormatException e) {
  80.                     return 0;
  81.                 }
  82.             } else {
  83.                 return 0;
  84.             }
  85.         }

  86.         private boolean ignore() {
  87.             return major() == 0 && minor() == 0 && patch() == 0;
  88.         }

  89.         @Override
  90.         public int compareTo(Version other) {
  91.             return ComparisonChain.start()
  92.                     .compare(major(), other.major())
  93.                     .compare(minor(), other.minor())
  94.                     .compare(patch(), other.patch())
  95.                     .result();
  96.         }

  97.         @Override
  98.         public String toString() {
  99.             if (ignore()) {
  100.                 return "";
  101.             } else {
  102.                 return Joiner.on('.').join(major(), minor(), patch());
  103.             }
  104.         }
  105.     }
  106. }