|
5 | 5 |
|
6 | 6 | package com.artipie.asto.etcd; |
7 | 7 |
|
| 8 | +import com.artipie.asto.Content; |
8 | 9 | import com.artipie.asto.Key; |
9 | 10 | import com.artipie.asto.Storage; |
10 | 11 | import com.artipie.asto.blocking.BlockingStorage; |
| 12 | +import com.github.dockerjava.api.DockerClient; |
11 | 13 | import io.etcd.jetcd.Client; |
12 | | -import io.etcd.jetcd.launcher.EtcdCluster; |
| 14 | +import io.etcd.jetcd.launcher.EtcdContainer; |
13 | 15 | import io.etcd.jetcd.test.EtcdClusterExtension; |
| 16 | +import java.nio.charset.StandardCharsets; |
14 | 17 | import java.util.concurrent.CompletionException; |
15 | 18 | import org.hamcrest.MatcherAssert; |
16 | 19 | import org.hamcrest.Matchers; |
17 | 20 | import org.hamcrest.core.IsEqual; |
| 21 | +import org.junit.jupiter.api.AfterAll; |
18 | 22 | import org.junit.jupiter.api.Assertions; |
| 23 | +import org.junit.jupiter.api.BeforeAll; |
19 | 24 | import org.junit.jupiter.api.BeforeEach; |
20 | | -import org.junit.jupiter.api.Disabled; |
21 | 25 | import org.junit.jupiter.api.Test; |
22 | | -import org.junit.jupiter.api.extension.RegisterExtension; |
| 26 | +import org.junit.jupiter.api.condition.DisabledOnOs; |
| 27 | +import org.junit.jupiter.api.condition.OS; |
| 28 | +import org.testcontainers.DockerClientFactory; |
23 | 29 |
|
24 | 30 | /** |
25 | 31 | * Test case for etcd-storage. |
26 | 32 | * @since 1.0 |
27 | | - * @todo #306:90min The test is disabled, |
28 | | - * the CI can't start ETCD extension which depends on testcontainer with |
29 | | - * etcd Docker image. Let's fix this issue on CI and enable the test. |
30 | 33 | * @todo #306:90min Add etcd storage to StorageExtension to run all common |
31 | 34 | * tests on EtcdStorage too. It could be not an easy task, since etcd |
32 | 35 | * test depends on etcd clust with at least one node. For this test |
33 | 36 | * it starts using testcontainers and `EtcdCluster` junit extension. |
| 37 | + * @todo #309:30min Run Etcd in windows containers while testing on windows. |
| 38 | + * Currently, when we try to run integration tests based on testcontainers within a platform |
| 39 | + * windows, we notice that Etcd container (presently based on Linux) doesn't work. We have to build |
| 40 | + * and publish an Etcd docker image based on windows to avoid this issue. |
| 41 | + * Please, build an Etcd image for windows (version 3.5.1) and write tests so as to detect before |
| 42 | + * running integration tests, the type of platform (linux or windows) in order to pull the right |
| 43 | + * docker image. After that, enable the test below for windows by removing |
| 44 | + * {@code @DisabledOnOs(OS.WINDOWS)}. |
34 | 45 | */ |
35 | | -@Disabled |
36 | | -public final class EtcdStorageITCase { |
| 46 | +@SuppressWarnings("PMD.AvoidDuplicateLiterals") |
| 47 | +@DisabledOnOs(OS.WINDOWS) |
| 48 | +final class EtcdStorageITCase { |
37 | 49 |
|
38 | 50 | /** |
39 | 51 | * Test cluster. |
40 | 52 | */ |
41 | | - @RegisterExtension |
42 | | - static final EtcdCluster ETCD = new EtcdClusterExtension("test-etcd", 1); |
| 53 | + static final EtcdClusterExtension ETCD = new EtcdClusterExtension( |
| 54 | + "test-etcd", |
| 55 | + 1, |
| 56 | + false, |
| 57 | + "--data-dir", |
| 58 | + "/data.etcd0" |
| 59 | + ); |
43 | 60 |
|
44 | 61 | /** |
45 | 62 | * Storage. |
46 | 63 | */ |
47 | 64 | private Storage storage; |
48 | 65 |
|
| 66 | + @BeforeAll |
| 67 | + static void beforeAll() throws InterruptedException { |
| 68 | + final DockerClient client = DockerClientFactory.instance().client(); |
| 69 | + client.pullImageCmd(EtcdContainer.ETCD_DOCKER_IMAGE_NAME) |
| 70 | + .start() |
| 71 | + .awaitCompletion(); |
| 72 | + ETCD.start(); |
| 73 | + } |
| 74 | + |
49 | 75 | @BeforeEach |
50 | 76 | void setUp() { |
51 | 77 | this.storage = new EtcdStorage( |
52 | 78 | Client.builder().endpoints(ETCD.getClientEndpoints()).build() |
53 | 79 | ); |
54 | 80 | } |
55 | 81 |
|
| 82 | + @AfterAll |
| 83 | + static void afterAll() { |
| 84 | + ETCD.close(); |
| 85 | + } |
| 86 | + |
| 87 | + @Test |
| 88 | + void listsItems() { |
| 89 | + final Key one = new Key.From("one"); |
| 90 | + final Key two = new Key.From("a/two"); |
| 91 | + final Key three = new Key.From("a/three"); |
| 92 | + this.storage.save( |
| 93 | + one, |
| 94 | + new Content.From("data 1".getBytes(StandardCharsets.UTF_8)) |
| 95 | + ).join(); |
| 96 | + this.storage.save( |
| 97 | + two, |
| 98 | + new Content.From("data 2".getBytes(StandardCharsets.UTF_8)) |
| 99 | + ).join(); |
| 100 | + this.storage.save( |
| 101 | + three, |
| 102 | + new Content.From("data 3".getBytes(StandardCharsets.UTF_8)) |
| 103 | + ).join(); |
| 104 | + MatcherAssert.assertThat( |
| 105 | + "Should list all items", |
| 106 | + new BlockingStorage(this.storage).list(Key.ROOT), |
| 107 | + Matchers.hasItems(one, two, three) |
| 108 | + ); |
| 109 | + MatcherAssert.assertThat( |
| 110 | + "Should list prefixed items", |
| 111 | + new BlockingStorage(this.storage).list(new Key.From("a")), |
| 112 | + Matchers.hasItems(two, three) |
| 113 | + ); |
| 114 | + } |
| 115 | + |
56 | 116 | @Test |
57 | 117 | void readAndWrite() { |
58 | 118 | final Key key = new Key.From("one", "two", "three"); |
@@ -114,8 +174,8 @@ void failsIfNothingToDelete() { |
114 | 174 | () -> bsto.delete(key) |
115 | 175 | ); |
116 | 176 | MatcherAssert.assertThat( |
117 | | - cex.getCause().getMessage(), |
118 | | - Matchers.stringContainsInOrder("Key", key.toString(), "was not found") |
| 177 | + cex.getCause().getCause().getMessage(), |
| 178 | + new IsEqual<>(String.format("No value for key: %s", key)) |
119 | 179 | ); |
120 | 180 | } |
121 | 181 | } |
0 commit comments