1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package de.softwareforge.testing.postgres.junit5;
16
17 import static com.google.common.base.Preconditions.checkNotNull;
18 import static java.lang.String.format;
19
20 import de.softwareforge.testing.postgres.embedded.EmbeddedPostgres;
21
22 import java.io.IOException;
23 import java.util.List;
24
25 import com.google.auto.value.AutoValue;
26 import com.google.common.base.Joiner;
27 import com.google.common.base.Splitter;
28 import com.google.common.collect.ComparisonChain;
29 import org.junit.jupiter.api.extension.ConditionEvaluationResult;
30 import org.junit.jupiter.api.extension.ExecutionCondition;
31 import org.junit.jupiter.api.extension.ExtensionContext;
32 import org.junit.platform.commons.support.AnnotationSupport;
33
34
35
36
37
38
39
40 public final class PostgresVersionCondition implements ExecutionCondition {
41
42 @Override
43 public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
44 return AnnotationSupport.findAnnotation(context.getElement(), RequirePostgresVersion.class)
45 .map(this::checkPostgresVersion)
46 .orElse(ConditionEvaluationResult.enabled("No version annotation found"));
47
48 }
49
50 private ConditionEvaluationResult checkPostgresVersion(RequirePostgresVersion requirePostgresVersion) {
51 Version atLeastVersion = Version.valueOf(requirePostgresVersion.atLeast());
52 Version lessThanVersion = Version.valueOf(requirePostgresVersion.lessThan());
53
54 if (atLeastVersion.ignore() && lessThanVersion.ignore()) {
55 return ConditionEvaluationResult.enabled("No PostgreSQL version range set");
56 }
57
58 try (EmbeddedPostgres pg = EmbeddedPostgres.forVersionCheck()) {
59 Version postgresVersion = Version.valueOf(pg.getPostgresVersion());
60
61 if (!atLeastVersion.ignore() && postgresVersion.compareTo(atLeastVersion) < 0) {
62 return ConditionEvaluationResult.disabled(
63 format("Located PostgreSQL version is %s, at least version %s is required", postgresVersion, atLeastVersion));
64 }
65
66 if (!lessThanVersion.ignore() && lessThanVersion.compareTo(postgresVersion) < 0) {
67 return ConditionEvaluationResult.disabled(
68 format("Located PostgreSQL version is %s, must be less than %s", postgresVersion, lessThanVersion));
69 }
70
71 return ConditionEvaluationResult.enabled(
72 format("Located PostgreSQL version is %s, version range is %s - %s", postgresVersion, atLeastVersion, lessThanVersion));
73
74 } catch (IOException e) {
75 return ConditionEvaluationResult.disabled("IOException while checking postgres version", e.getMessage());
76 }
77 }
78
79 @AutoValue
80 abstract static class Version implements Comparable<Version> {
81
82 abstract int major();
83
84 abstract int minor();
85
86 abstract int patch();
87
88 private static Version valueOf(String value) {
89 checkNotNull(value, "value is null");
90
91 List<String> values = Splitter.on('.').trimResults().splitToList(value);
92 return new AutoValue_PostgresVersionCondition_Version(parseValue(values, 0),
93 parseValue(values, 1),
94 parseValue(values, 2));
95 }
96
97 private static int parseValue(List<String> values, int pos) {
98 if (values.size() > pos && !values.get(pos).isEmpty()) {
99 try {
100 return Integer.parseInt(values.get(pos));
101 } catch (NumberFormatException e) {
102 return 0;
103 }
104 } else {
105 return 0;
106 }
107 }
108
109 private boolean ignore() {
110 return major() == 0 && minor() == 0 && patch() == 0;
111 }
112
113 @Override
114 public int compareTo(Version other) {
115 return ComparisonChain.start()
116 .compare(major(), other.major())
117 .compare(minor(), other.minor())
118 .compare(patch(), other.patch())
119 .result();
120 }
121
122 @Override
123 public String toString() {
124 if (ignore()) {
125 return "";
126 } else {
127 return Joiner.on('.').join(major(), minor(), patch());
128 }
129 }
130 }
131 }