View Javadoc
1   /*
2    *  Copyright 2022 Red Hat
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.jboss.hal.testsuite.configuration.datasource;
17  
18  import org.jboss.arquillian.core.api.annotation.Inject;
19  import org.jboss.arquillian.graphene.page.Page;
20  import org.jboss.dmr.ModelNode;
21  import org.jboss.dmr.Property;
22  import org.jboss.hal.resources.Ids;
23  import org.jboss.hal.testsuite.Console;
24  import org.jboss.hal.testsuite.CrudOperations;
25  import org.jboss.hal.testsuite.Random;
26  import org.jboss.hal.testsuite.container.WildFlyContainer;
27  import org.jboss.hal.testsuite.fragment.FormFragment;
28  import org.jboss.hal.testsuite.model.CredentialReference;
29  import org.jboss.hal.testsuite.model.ResourceVerifier;
30  import org.jboss.hal.testsuite.page.configuration.DataSourcePage;
31  import org.jboss.hal.testsuite.test.Manatoko;
32  import org.junit.jupiter.api.BeforeAll;
33  import org.junit.jupiter.api.BeforeEach;
34  import org.junit.jupiter.api.Test;
35  import org.testcontainers.junit.jupiter.Container;
36  import org.testcontainers.junit.jupiter.Testcontainers;
37  import org.wildfly.extras.creaper.commands.datasources.AddDataSource;
38  import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
39  import org.wildfly.extras.creaper.core.online.operations.Address;
40  
41  import static org.jboss.hal.dmr.ModelDescriptionConstants.ATTRIBUTES;
42  import static org.jboss.hal.dmr.ModelDescriptionConstants.BACKGROUND_VALIDATION;
43  import static org.jboss.hal.dmr.ModelDescriptionConstants.CLEAR_TEXT;
44  import static org.jboss.hal.dmr.ModelDescriptionConstants.CONNECTION_PROPERTIES;
45  import static org.jboss.hal.dmr.ModelDescriptionConstants.JNDI_NAME;
46  import static org.jboss.hal.dmr.ModelDescriptionConstants.MAX_POOL_SIZE;
47  import static org.jboss.hal.dmr.ModelDescriptionConstants.MIN_POOL_SIZE;
48  import static org.jboss.hal.dmr.ModelDescriptionConstants.NAME;
49  import static org.jboss.hal.dmr.ModelDescriptionConstants.USER_NAME;
50  import static org.jboss.hal.dmr.ModelDescriptionConstants.VALID_CONNECTION_CHECKER_CLASS_NAME;
51  import static org.jboss.hal.dmr.ModelDescriptionConstants.VALUE;
52  import static org.jboss.hal.testsuite.container.WildFlyConfiguration.DEFAULT;
53  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.BACKGROUND_VALIDATION_MILLIS;
54  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.BLOCKING_TIMEOUT_WAIT_MILLIS;
55  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.CONNECTION;
56  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.DATA_SOURCE_UPDATE;
57  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.SPY;
58  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.TRACKING;
59  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.URL_DELIMITER;
60  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.USE_TRY_LOCK;
61  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.VALID_CONNECTION_CHECKER_PROPERTIES;
62  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.dataSourceAddress;
63  import static org.jboss.hal.testsuite.fixtures.DataSourceFixtures.h2ConnectionUrl;
64  
65  @Manatoko
66  @Testcontainers
67  class DataSourceConfigurationTest {
68  
69      @Container static WildFlyContainer wildFly = WildFlyContainer.standalone(DEFAULT);
70      static OnlineManagementClient client;
71  
72      @BeforeAll
73      static void setupModel() throws Exception {
74          client = wildFly.managementClient();
75          client.apply(new AddDataSource.Builder<>(DATA_SOURCE_UPDATE)
76                  .driverName("h2")
77                  .jndiName(Random.jndiName(DATA_SOURCE_UPDATE))
78                  .connectionUrl(h2ConnectionUrl(DATA_SOURCE_UPDATE))
79                  .build());
80      }
81  
82      @Inject CrudOperations crud;
83      @Page DataSourcePage page;
84      @Inject Console console;
85      FormFragment form;
86  
87      @BeforeEach
88      void prepare() {
89          page.navigate(NAME, DATA_SOURCE_UPDATE);
90      }
91  
92      @Test
93      void attributes() throws Exception {
94          page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, ATTRIBUTES, Ids.TAB));
95          form = page.getAttributesForm();
96  
97          String jndiName = Random.jndiName();
98          crud.update(dataSourceAddress(DATA_SOURCE_UPDATE), form, JNDI_NAME, jndiName);
99      }
100 
101     @Test
102     void connection() throws Exception {
103         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, CONNECTION, Ids.TAB));
104         form = page.getConnectionForm();
105 
106         String urlDelimiter = Random.name();
107         crud.update(dataSourceAddress(DATA_SOURCE_UPDATE), form, URL_DELIMITER, urlDelimiter);
108     }
109 
110     @Test
111     void connectionAttributesProperties() throws Exception {
112         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, CONNECTION, Ids.TAB));
113         form = page.getConnectionForm();
114 
115         ModelNode properties = Random.properties();
116         String urlDelimiter = Random.name();
117 
118         // there are two test related to xa-datasource-properties, because the backend uses a composite operation
119         // to write the attribute and add the properties.
120         form.edit();
121         form.text(URL_DELIMITER, urlDelimiter);
122         form.properties(CONNECTION_PROPERTIES).removeTags();
123         form.properties(CONNECTION_PROPERTIES).add(properties);
124         form.save();
125 
126         console.verifySuccess();
127         new ResourceVerifier(dataSourceAddress(DATA_SOURCE_UPDATE), client)
128                 .verifyAttribute(URL_DELIMITER, urlDelimiter);
129         for (Property key : properties.asPropertyList()) {
130             String value = key.getValue().asString();
131             Address address = dataSourceAddress(DATA_SOURCE_UPDATE).and(CONNECTION_PROPERTIES, key.getName());
132             new ResourceVerifier(address, client).verifyAttribute(VALUE, value);
133         }
134     }
135 
136     @Test
137     void connectionProperties() throws Exception {
138         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, CONNECTION, Ids.TAB));
139         form = page.getConnectionForm();
140 
141         ModelNode properties = Random.properties();
142 
143         form.edit();
144         form.properties(CONNECTION_PROPERTIES).removeTags();
145         form.properties(CONNECTION_PROPERTIES).add(properties);
146         form.save();
147 
148         console.verifySuccess();
149         for (Property key : properties.asPropertyList()) {
150             String value = key.getValue().asString();
151             Address address = dataSourceAddress(DATA_SOURCE_UPDATE).and(CONNECTION_PROPERTIES, key.getName());
152             new ResourceVerifier(address, client).verifyAttribute(VALUE, value);
153         }
154     }
155 
156     @Test
157     void connectionPropertiesSpecialCharacters() throws Exception {
158         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, CONNECTION, Ids.TAB));
159         form = page.getConnectionForm();
160 
161         ModelNode properties = new ModelNode();
162         properties.get("key1").set("jdbc:sybase:Tds:localhost:5000/mydatabase?JCONNECT_VERSION=6");
163         properties.get("key2").set("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=MyDatabase");
164         properties.get("key3").set("jdbc:oracle:thin:@localhost:1521:orcalesid");
165         properties.get("key4").set("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
166         properties.get("key4").set("value!@#$%&-?=man");
167 
168         form.edit();
169         form.properties(CONNECTION_PROPERTIES).removeTags();
170         form.properties(CONNECTION_PROPERTIES).add(properties);
171         form.save();
172 
173         console.verifySuccess();
174         for (Property key : properties.asPropertyList()) {
175             String value = key.getValue().asString();
176             Address address = dataSourceAddress(DATA_SOURCE_UPDATE).and(CONNECTION_PROPERTIES, key.getName());
177             new ResourceVerifier(address, client).verifyAttribute(VALUE, value);
178         }
179     }
180 
181     @Test
182     void pool() throws Exception {
183         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, "pool", Ids.TAB));
184         form = page.getPoolForm();
185 
186         int minPoolSize = Random.number(1, 10);
187         int maxPoolSize = Random.number(10, 100);
188         // noinspection Duplicates
189         crud.update(dataSourceAddress(DATA_SOURCE_UPDATE), form,
190                 f -> {
191                     f.number(MIN_POOL_SIZE, minPoolSize);
192                     f.number(MAX_POOL_SIZE, maxPoolSize);
193                 },
194                 resourceVerifier -> {
195                     resourceVerifier.verifyAttribute(MIN_POOL_SIZE, minPoolSize);
196                     resourceVerifier.verifyAttribute(MAX_POOL_SIZE, maxPoolSize);
197                 });
198     }
199 
200     @Test
201     void security() throws Exception {
202         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, "security", Ids.TAB));
203         form = page.getSecurityForm();
204 
205         String username = Random.name();
206         crud.update(dataSourceAddress(DATA_SOURCE_UPDATE), form, USER_NAME, username);
207     }
208 
209     @Test
210     void credentialReference() throws Exception {
211         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, "credential-reference", Ids.TAB));
212         form = page.getCredentialReferenceForm();
213         String clearText = Random.name();
214 
215         crud.createSingleton(dataSourceAddress(DATA_SOURCE_UPDATE), form,
216                 f -> f.text(CLEAR_TEXT, clearText),
217                 resourceVerifier -> resourceVerifier.verifyAttribute(CredentialReference.fqName(CLEAR_TEXT),
218                         clearText));
219     }
220 
221     @Test
222     void validation() throws Exception {
223         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, "validations", Ids.TAB));
224         form = page.getValidationForm();
225 
226         String className = Random.name();
227         ModelNode properties = Random.properties();
228         long millis = Random.number(1000L, 2000L);
229 
230         crud.update(dataSourceAddress(DATA_SOURCE_UPDATE), form,
231                 f -> {
232                     f.text(VALID_CONNECTION_CHECKER_CLASS_NAME, className);
233                     f.properties(VALID_CONNECTION_CHECKER_PROPERTIES).add(properties);
234                     f.flip(BACKGROUND_VALIDATION, true);
235                     f.number(BACKGROUND_VALIDATION_MILLIS, millis);
236                 },
237                 resourceVerifier -> {
238                     resourceVerifier.verifyAttribute(VALID_CONNECTION_CHECKER_CLASS_NAME, className);
239                     resourceVerifier.verifyAttribute(VALID_CONNECTION_CHECKER_PROPERTIES, properties);
240                     resourceVerifier.verifyAttribute(BACKGROUND_VALIDATION, true);
241                     resourceVerifier.verifyAttribute(BACKGROUND_VALIDATION_MILLIS, millis);
242                 });
243     }
244 
245     @Test
246     void timeouts() throws Exception {
247         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, "timeout", Ids.TAB));
248         form = page.getTimeoutsForm();
249 
250         long locks = Random.number(10L, 20L);
251         long millis = Random.number(1000L, 2000L);
252         // noinspection Duplicates
253         crud.update(dataSourceAddress(DATA_SOURCE_UPDATE), form,
254                 f -> {
255                     f.number(USE_TRY_LOCK, locks);
256                     f.number(BLOCKING_TIMEOUT_WAIT_MILLIS, millis);
257                 },
258                 resourceVerifier -> {
259                     resourceVerifier.verifyAttribute(USE_TRY_LOCK, locks);
260                     resourceVerifier.verifyAttribute(BLOCKING_TIMEOUT_WAIT_MILLIS, millis);
261                 });
262     }
263 
264     @Test
265     void statementsTracking() throws Exception {
266         page.getTabs().select(Ids.build(Ids.DATA_SOURCE_CONFIGURATION, "statements", Ids.TAB));
267         form = page.getStatementsTrackingForm();
268 
269         crud.update(dataSourceAddress(DATA_SOURCE_UPDATE), form,
270                 f -> {
271                     f.flip(SPY, true);
272                     f.flip(TRACKING, true);
273                 },
274                 resourceVerifier -> {
275                     resourceVerifier.verifyAttribute(SPY, true);
276                     resourceVerifier.verifyAttribute(TRACKING, true);
277                 });
278     }
279 }