From 8366d6e0c45541b09b64ebc3e1395946dde08cdb Mon Sep 17 00:00:00 2001 From: nicktorwald Date: Thu, 9 May 2019 01:25:33 +0700 Subject: [PATCH] Add a simple DataSource implementation Implement the DataSource interface to be more compatible with JDBC spec. Add JDBC standard and Tarantool specific properties (getters/setters) to follow enterprise features (according to JavaBeans spec). Fix a JDBC URL scheme. Now correct scheme has the format like 'jdbc:tarantool://' where `tarantool` is JDBC sub-protocol. Old scheme version `tarantool://` was not JDBC-compatible. Closes: #175 --- README.md | 4 +- src/it/java/org/tarantool/TestSql.java | 2 +- .../org/tarantool/jdbc/SQLConnection.java | 2 +- .../java/org/tarantool/jdbc/SQLConstant.java | 10 + .../tarantool/jdbc/SQLDatabaseMetadata.java | 2 +- .../java/org/tarantool/jdbc/SQLDriver.java | 5 +- .../java/org/tarantool/jdbc/SQLProperty.java | 6 +- .../org/tarantool/jdbc/ds/SQLDataSource.java | 159 ++++++++++++++++ .../jdbc/ds/TarantoolDataSource.java | 40 ++++ .../org/tarantool/jdbc/AbstractJdbcIT.java | 2 +- .../jdbc/JdbcDatabaseMetaDataIT.java | 2 +- .../org/tarantool/jdbc/JdbcDriverTest.java | 26 +-- .../jdbc/JdbcExceptionHandlingTest.java | 6 +- .../tarantool/jdbc/ds/JdbcDataSourceIT.java | 175 ++++++++++++++++++ 14 files changed, 416 insertions(+), 25 deletions(-) create mode 100644 src/main/java/org/tarantool/jdbc/SQLConstant.java create mode 100644 src/main/java/org/tarantool/jdbc/ds/SQLDataSource.java create mode 100644 src/main/java/org/tarantool/jdbc/ds/TarantoolDataSource.java create mode 100644 src/test/java/org/tarantool/jdbc/ds/JdbcDataSourceIT.java diff --git a/README.md b/README.md index 8a94d0ef..d3a07fde 100644 --- a/README.md +++ b/README.md @@ -138,13 +138,13 @@ To configure socket channel provider you should implements SocketChannelProvider For example: ``` -tarantool://localhost:3301?user=test&password=test&socketProvider=abc.xyz.MySocketProvider +jdbc:tarantool://localhost:3301?user=test&password=test&socketProvider=abc.xyz.MySocketProvider ``` Here is an example how you can use the driver covered by Spring `DriverManagerDataSource`: ```java -NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("tarantool://localhost:3301?user=test&password=test")); +NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("jdbc:tarantool://localhost:3301?user=test&password=test")); RowMapper rowMapper = new RowMapper() { @Override public Object mapRow(ResultSet resultSet, int i) throws SQLException { diff --git a/src/it/java/org/tarantool/TestSql.java b/src/it/java/org/tarantool/TestSql.java index a0ca3949..e1af289a 100644 --- a/src/it/java/org/tarantool/TestSql.java +++ b/src/it/java/org/tarantool/TestSql.java @@ -36,7 +36,7 @@ // // public static void main(String[] args) throws IOException, SQLException { // -// NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("tarantool://localhost:3301?username=test&password=test&socketProvider=org.tarantool.TestSql$TestSocketProvider")); +// NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("jdbc:tarantool://localhost:3301?username=test&password=test&socketProvider=org.tarantool.TestSql$TestSocketProvider")); // RowMapper rowMapper = new RowMapper() { // @Override // public Object mapRow(ResultSet resultSet, int i) throws SQLException { diff --git a/src/main/java/org/tarantool/jdbc/SQLConnection.java b/src/main/java/org/tarantool/jdbc/SQLConnection.java index bd58e277..3f299151 100644 --- a/src/main/java/org/tarantool/jdbc/SQLConnection.java +++ b/src/main/java/org/tarantool/jdbc/SQLConnection.java @@ -58,7 +58,7 @@ public class SQLConnection implements Connection { private DatabaseMetaData cachedMetadata; private int resultSetHoldability = UNSET_HOLDABILITY; - SQLConnection(String url, Properties properties) throws SQLException { + public SQLConnection(String url, Properties properties) throws SQLException { this.url = url; this.properties = properties; diff --git a/src/main/java/org/tarantool/jdbc/SQLConstant.java b/src/main/java/org/tarantool/jdbc/SQLConstant.java new file mode 100644 index 00000000..a367cf2e --- /dev/null +++ b/src/main/java/org/tarantool/jdbc/SQLConstant.java @@ -0,0 +1,10 @@ +package org.tarantool.jdbc; + +public class SQLConstant { + + private SQLConstant() { + } + + public static final String DRIVER_NAME = "Tarantool JDBC Driver"; + +} diff --git a/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java b/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java index ed354051..ee7e8710 100644 --- a/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java +++ b/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java @@ -96,7 +96,7 @@ public String getDatabaseProductVersion() throws SQLException { @Override public String getDriverName() throws SQLException { - return "tarantool-java"; + return SQLConstant.DRIVER_NAME; } @Override diff --git a/src/main/java/org/tarantool/jdbc/SQLDriver.java b/src/main/java/org/tarantool/jdbc/SQLDriver.java index 8c1f0bc4..dbc89922 100644 --- a/src/main/java/org/tarantool/jdbc/SQLDriver.java +++ b/src/main/java/org/tarantool/jdbc/SQLDriver.java @@ -57,6 +57,9 @@ protected SQLTarantoolClientImpl makeSqlClient(String address, TarantoolClientCo protected Properties parseQueryString(URI uri, Properties info) throws SQLException { Properties urlProperties = new Properties(); + // get scheme specific part (after the scheme part "jdbc:") + // to correct parse remaining URL + uri = URI.create(uri.getSchemeSpecificPart()); String userInfo = uri.getUserInfo(); if (userInfo != null) { // Get user and password from the corresponding part of the URI, i.e. before @ sign. @@ -140,7 +143,7 @@ protected SocketChannelProvider getSocketProviderInstance(String className) thro @Override public boolean acceptsURL(String url) throws SQLException { - return url.toLowerCase().startsWith("tarantool:"); + return url.toLowerCase().startsWith("jdbc:tarantool:"); } @Override diff --git a/src/main/java/org/tarantool/jdbc/SQLProperty.java b/src/main/java/org/tarantool/jdbc/SQLProperty.java index 11b2d93a..b147c221 100644 --- a/src/main/java/org/tarantool/jdbc/SQLProperty.java +++ b/src/main/java/org/tarantool/jdbc/SQLProperty.java @@ -44,7 +44,7 @@ public enum SQLProperty { LOGIN_TIMEOUT( "loginTimeout", "The number of milliseconds to wait for connection establishment. " + - "The default value is 60000 (1 minute).", + "The default system value is 60000 (1 minute).", "60000", null, false @@ -84,6 +84,10 @@ public String getDefaultValue() { return defaultValue; } + public int getDefaultIntValue() { + return Integer.parseInt(defaultValue); + } + public boolean isRequired() { return required; } diff --git a/src/main/java/org/tarantool/jdbc/ds/SQLDataSource.java b/src/main/java/org/tarantool/jdbc/ds/SQLDataSource.java new file mode 100644 index 00000000..6a474d39 --- /dev/null +++ b/src/main/java/org/tarantool/jdbc/ds/SQLDataSource.java @@ -0,0 +1,159 @@ +package org.tarantool.jdbc.ds; + +import org.tarantool.jdbc.SQLConnection; +import org.tarantool.jdbc.SQLConstant; +import org.tarantool.jdbc.SQLProperty; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.sql.SQLNonTransientException; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import javax.sql.DataSource; + +/** + * Simple {@code java.sql.DataSource} implementation. + */ +public class SQLDataSource implements TarantoolDataSource, DataSource { + + private PrintWriter logWriter; + private String name = "Tarantool basic data source"; + + private Properties properties = new Properties(); + + @Override + public Connection getConnection() throws SQLException { + return new SQLConnection(makeUrl(), new Properties(properties)); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + Properties copyProperties = new Properties(properties); + SQLProperty.USER.setString(copyProperties, username); + SQLProperty.PASSWORD.setString(copyProperties, password); + return new SQLConnection(makeUrl(), copyProperties); + } + + @Override + public PrintWriter getLogWriter() { + return logWriter; + } + + @Override + public void setLogWriter(PrintWriter out) { + logWriter = out; + } + + @Override + public void setLoginTimeout(int seconds) { + SQLProperty.LOGIN_TIMEOUT.setInt(properties, (int) TimeUnit.SECONDS.toMillis(seconds)); + } + + @Override + public int getLoginTimeout() throws SQLException { + return (int) TimeUnit.MILLISECONDS.toSeconds(SQLProperty.LOGIN_TIMEOUT.getInt(properties)); + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T unwrap(Class type) throws SQLException { + if (isWrapperFor(type)) { + return type.cast(this); + } + throw new SQLNonTransientException("SQLDataSource does not wrap " + type.getName()); + } + + @Override + public boolean isWrapperFor(Class type) { + return type.isAssignableFrom(this.getClass()); + } + + @Override + public String getServerName() { + return SQLProperty.HOST.getString(properties); + } + + @Override + public void setServerName(String serverName) { + SQLProperty.HOST.setString(properties, serverName); + } + + @Override + public int getPortNumber() throws SQLException { + return SQLProperty.PORT.getInt(properties); + } + + @Override + public void setPortNumber(int port) { + SQLProperty.PORT.setInt(properties, port); + } + + @Override + public String getUser() { + return SQLProperty.USER.getString(properties); + } + + @Override + public void setUser(String userName) { + SQLProperty.USER.setString(properties, userName); + } + + @Override + public String getPassword() { + return SQLProperty.PASSWORD.getString(properties); + } + + @Override + public void setPassword(String password) { + SQLProperty.PASSWORD.setString(properties, password); + } + + @Override + public String getDescription() { + return "Basic DataSource implementation - produces a standard Connection object. " + + SQLConstant.DRIVER_NAME + "."; + } + + @Override + public String getDataSourceName() { + return name; + } + + @Override + public void setDataSourceName(String name) { + this.name = name; + } + + @Override + public String getSocketChannelProvider() { + return SQLProperty.SOCKET_CHANNEL_PROVIDER.getString(properties); + } + + @Override + public void setSocketChannelProvider(String classFqdn) { + SQLProperty.SOCKET_CHANNEL_PROVIDER.setString(properties, classFqdn); + } + + @Override + public int getQueryTimeout() throws SQLException { + return (int) TimeUnit.MILLISECONDS.toSeconds(SQLProperty.QUERY_TIMEOUT.getInt(properties)); + } + + @Override + public void setQueryTimeout(int seconds) { + SQLProperty.QUERY_TIMEOUT.setInt(properties, (int) TimeUnit.SECONDS.toMillis(seconds)); + } + + private String makeUrl() { + return "jdbc:tarantool://" + + SQLProperty.HOST.getString(properties) + ":" + SQLProperty.PORT.getString(properties); + } + +} diff --git a/src/main/java/org/tarantool/jdbc/ds/TarantoolDataSource.java b/src/main/java/org/tarantool/jdbc/ds/TarantoolDataSource.java new file mode 100644 index 00000000..8e686432 --- /dev/null +++ b/src/main/java/org/tarantool/jdbc/ds/TarantoolDataSource.java @@ -0,0 +1,40 @@ +package org.tarantool.jdbc.ds; + +import java.sql.SQLException; + +/** + * JDBC standard Tarantool specific data source properties. + */ +public interface TarantoolDataSource { + + String getServerName() throws SQLException; + + void setServerName(String serverName) throws SQLException; + + int getPortNumber() throws SQLException; + + void setPortNumber(int port) throws SQLException; + + String getUser() throws SQLException; + + void setUser(String userName) throws SQLException; + + String getPassword() throws SQLException; + + void setPassword(String password) throws SQLException; + + String getDescription() throws SQLException; + + String getDataSourceName() throws SQLException; + + void setDataSourceName(String name) throws SQLException; + + String getSocketChannelProvider() throws SQLException; + + void setSocketChannelProvider(String classFqdn) throws SQLException; + + int getQueryTimeout() throws SQLException; + + void setQueryTimeout(int seconds) throws SQLException; + +} diff --git a/src/test/java/org/tarantool/jdbc/AbstractJdbcIT.java b/src/test/java/org/tarantool/jdbc/AbstractJdbcIT.java index 62c98890..f119bc2b 100644 --- a/src/test/java/org/tarantool/jdbc/AbstractJdbcIT.java +++ b/src/test/java/org/tarantool/jdbc/AbstractJdbcIT.java @@ -29,7 +29,7 @@ public abstract class AbstractJdbcIT { private static final Integer port = Integer.valueOf(System.getProperty("tntPort", "3301")); private static final String user = System.getProperty("tntUser", "test_admin"); private static final String pass = System.getProperty("tntPass", "4pWBZmLEgkmKK5WP"); - private static String URL = String.format("tarantool://%s:%d?user=%s&password=%s", host, port, user, pass); + private static String URL = String.format("jdbc:tarantool://%s:%d?user=%s&password=%s", host, port, user, pass); protected static final String LUA_FILE = "jdk-testing.lua"; protected static final int LISTEN = 3301; diff --git a/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java b/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java index 99ccf284..98c8ef8b 100644 --- a/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java +++ b/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java @@ -229,7 +229,7 @@ public void testGetDriverNameVersion() throws SQLException { String version = meta.getDriverVersion(); // Verify driver name. - assertEquals("tarantool-java", name); + assertEquals(SQLConstant.DRIVER_NAME, name); // Verify driver version format. // E.g. 1.7.6 or 1.7.6-SNAPSHOT. diff --git a/src/test/java/org/tarantool/jdbc/JdbcDriverTest.java b/src/test/java/org/tarantool/jdbc/JdbcDriverTest.java index b21eef2d..5e7dce7a 100644 --- a/src/test/java/org/tarantool/jdbc/JdbcDriverTest.java +++ b/src/test/java/org/tarantool/jdbc/JdbcDriverTest.java @@ -35,7 +35,7 @@ public void testParseQueryString() throws Exception { SQLProperty.PASSWORD.setString(prop, "secret"); URI uri = new URI(String.format( - "tarantool://server.local:3302?%s=%s&%s=%d", + "jdbc:tarantool://server.local:3302?%s=%s&%s=%d", SQLProperty.SOCKET_CHANNEL_PROVIDER.getName(), "some.class", SQLProperty.QUERY_TIMEOUT.getName(), 5000) ); @@ -54,7 +54,7 @@ public void testParseQueryString() throws Exception { @Test public void testParseQueryStringUserInfoInURI() throws Exception { SQLDriver drv = new SQLDriver(); - Properties result = drv.parseQueryString(new URI("tarantool://adm:secret@server.local"), null); + Properties result = drv.parseQueryString(new URI("jdbc:tarantool://adm:secret@server.local"), null); assertNotNull(result); assertEquals("server.local", SQLProperty.HOST.getString(result)); assertEquals("3301", SQLProperty.PORT.getString(result)); @@ -65,7 +65,7 @@ public void testParseQueryStringUserInfoInURI() throws Exception { @Test public void testParseQueryStringValidations() { // Check non-number port - checkParseQueryStringValidation("tarantool://0", + checkParseQueryStringValidation("jdbc:tarantool://0", new Properties() { { SQLProperty.PORT.setString(this, "nan"); @@ -74,35 +74,35 @@ public void testParseQueryStringValidations() { "Property port must be a valid number."); // Check zero port - checkParseQueryStringValidation("tarantool://0:0", null, "Port is out of range: 0"); + checkParseQueryStringValidation("jdbc:tarantool://0:0", null, "Port is out of range: 0"); // Check high port - checkParseQueryStringValidation("tarantool://0:65536", null, "Port is out of range: 65536"); + checkParseQueryStringValidation("jdbc:tarantool://0:65536", null, "Port is out of range: 65536"); // Check non-number init timeout checkParseQueryStringValidation( - String.format("tarantool://0:3301?%s=nan", SQLProperty.LOGIN_TIMEOUT.getName()), + String.format("jdbc:tarantool://0:3301?%s=nan", SQLProperty.LOGIN_TIMEOUT.getName()), null, "Property loginTimeout must be a valid number." ); // Check negative init timeout checkParseQueryStringValidation( - String.format("tarantool://0:3301?%s=-100", SQLProperty.LOGIN_TIMEOUT.getName()), + String.format("jdbc:tarantool://0:3301?%s=-100", SQLProperty.LOGIN_TIMEOUT.getName()), null, "Property loginTimeout must not be negative." ); // Check non-number operation timeout checkParseQueryStringValidation( - String.format("tarantool://0:3301?%s=nan", SQLProperty.QUERY_TIMEOUT.getName()), + String.format("jdbc:tarantool://0:3301?%s=nan", SQLProperty.QUERY_TIMEOUT.getName()), null, "Property queryTimeout must be a valid number." ); // Check negative operation timeout checkParseQueryStringValidation( - String.format("tarantool://0:3301?%s=-100", SQLProperty.QUERY_TIMEOUT.getName()), + String.format("jdbc:tarantool://0:3301?%s=-100", SQLProperty.QUERY_TIMEOUT.getName()), null, "Property queryTimeout must not be negative." ); @@ -112,7 +112,7 @@ public void testParseQueryStringValidations() { public void testGetPropertyInfo() throws SQLException { Driver drv = new SQLDriver(); Properties props = new Properties(); - DriverPropertyInfo[] info = drv.getPropertyInfo("tarantool://server.local:3302", props); + DriverPropertyInfo[] info = drv.getPropertyInfo("jdbc:tarantool://server.local:3302", props); assertNotNull(info); assertEquals(7, info.length); @@ -168,7 +168,7 @@ public void testNoResponseAfterInitialConnect() throws IOException { ServerSocket socket = new ServerSocket(); socket.bind(null, 0); try { - final String url = "tarantool://localhost:" + socket.getLocalPort(); + final String url = "jdbc:tarantool://localhost:" + socket.getLocalPort(); final Properties prop = new Properties(); SQLProperty.LOGIN_TIMEOUT.setInt(prop, 500); SQLException e = assertThrows(SQLException.class, new Executable() { @@ -185,12 +185,12 @@ public void execute() throws Throwable { } private void checkCustomSocketProviderFail(String providerClassName, String errMsg) throws SQLException { - final Driver drv = DriverManager.getDriver("tarantool:"); + final Driver drv = DriverManager.getDriver("jdbc:tarantool:"); final Properties prop = new Properties(); SQLProperty.SOCKET_CHANNEL_PROVIDER.setString(prop, providerClassName); SQLProperty.LOGIN_TIMEOUT.setInt(prop, 500); - SQLException e = assertThrows(SQLException.class, () -> drv.connect("tarantool://0:3301", prop)); + SQLException e = assertThrows(SQLException.class, () -> drv.connect("jdbc:tarantool://0:3301", prop)); assertTrue(e.getMessage().startsWith(errMsg), e.getMessage()); } diff --git a/src/test/java/org/tarantool/jdbc/JdbcExceptionHandlingTest.java b/src/test/java/org/tarantool/jdbc/JdbcExceptionHandlingTest.java index 05a0635d..08c02d96 100644 --- a/src/test/java/org/tarantool/jdbc/JdbcExceptionHandlingTest.java +++ b/src/test/java/org/tarantool/jdbc/JdbcExceptionHandlingTest.java @@ -154,7 +154,7 @@ private void checkStatementCommunicationException(final ThrowingConsumer consumer.accept(meta)); diff --git a/src/test/java/org/tarantool/jdbc/ds/JdbcDataSourceIT.java b/src/test/java/org/tarantool/jdbc/ds/JdbcDataSourceIT.java new file mode 100644 index 00000000..d635a778 --- /dev/null +++ b/src/test/java/org/tarantool/jdbc/ds/JdbcDataSourceIT.java @@ -0,0 +1,175 @@ +package org.tarantool.jdbc.ds; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTimeout; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.tarantool.TestUtils.makeInstanceEnv; + +import org.tarantool.TarantoolControl; +import org.tarantool.jdbc.SQLProperty; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.ThrowingSupplier; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.Driver; +import java.sql.SQLException; +import java.time.Duration; +import javax.sql.DataSource; + +class JdbcDataSourceIT { + + private static final String LUA_FILE = "jdk-testing.lua"; + private static final int LISTEN = 3301; + private static final int ADMIN = 3313; + private static final String INSTANCE_NAME = "data-source-testing"; + + private SQLDataSource dataSource; + + @BeforeEach + void setUp() { + TarantoolControl control = new TarantoolControl(); + control.createInstance(INSTANCE_NAME, LUA_FILE, makeInstanceEnv(LISTEN, ADMIN)); + control.start(INSTANCE_NAME); + + dataSource = new SQLDataSource(); + } + + @AfterEach + void tearDown() { + TarantoolControl control = new TarantoolControl(); + control.stop(INSTANCE_NAME); + } + + @Test + void testGetDefaultConnection() throws SQLException { + Connection connection = dataSource.getConnection(); + assertTrue(connection.isValid(2)); + connection.close(); + } + + @Test + void testGetUserConnection() throws SQLException { + Connection connection = dataSource.getConnection("test_admin", "4pWBZmLEgkmKK5WP"); + assertTrue(connection.isValid(2)); + connection.close(); + } + + @Test + void testGetWrongUserConnection() throws SQLException { + dataSource.setLoginTimeout(1); + assertThrows( + SQLException.class, + () -> dataSource.getConnection("unknown_user", "wrong_pass") + ); + } + + @Test + void testLogWriter() throws Exception { + assertNull(dataSource.getLogWriter()); + PrintWriter logWriter = new PrintWriter("jdk-testing.lua"); + dataSource.setLogWriter(logWriter); + assertEquals(logWriter, dataSource.getLogWriter()); + } + + @Test + void testLoginTimeout() throws SQLException { + assertEquals(dataSource.getLoginTimeout(), 60); + dataSource.setLoginTimeout(2); + assertEquals(2, dataSource.getLoginTimeout()); + ThrowingSupplier badInit = () -> + assertThrows( + SQLException.class, + () -> dataSource.getConnection("unknown_user", "wrong_pass") + ); + + assertTimeout(Duration.ofSeconds(4), badInit); + } + + @Test + void testRightIsWrapperFor() { + assertTrue(dataSource.isWrapperFor(DataSource.class)); + assertTrue(dataSource.isWrapperFor(TarantoolDataSource.class)); + } + + @Test + void testWrongIsWrapperFor() { + assertFalse(dataSource.isWrapperFor(Integer.class)); + assertFalse(dataSource.isWrapperFor(Driver.class)); + } + + @Test + void testRightUnwrap() throws SQLException { + assertNotNull(dataSource.unwrap(DataSource.class)); + assertNotNull(dataSource.unwrap(TarantoolDataSource.class)); + } + + @Test + void testWrongUnwrap() { + assertThrows(SQLException.class, () -> dataSource.unwrap(Integer.class)); + assertThrows(SQLException.class, () -> dataSource.unwrap(Driver.class)); + } + + @Test + void testServerNameProperty() { + assertEquals(SQLProperty.HOST.getDefaultValue(), dataSource.getServerName()); + String expectedNewServerName = "my-server-name"; + dataSource.setServerName(expectedNewServerName); + assertEquals(expectedNewServerName, dataSource.getServerName()); + } + + @Test + void testPortNumberProperty() throws SQLException { + assertEquals(SQLProperty.PORT.getDefaultIntValue(), dataSource.getPortNumber()); + int expectedNewPort = 4001; + dataSource.setPortNumber(expectedNewPort); + assertEquals(expectedNewPort, dataSource.getPortNumber()); + } + + @Test + void testUserProperty() { + assertEquals(SQLProperty.USER.getDefaultValue(), dataSource.getUser()); + String expectedNewUser = "myUserName"; + dataSource.setUser(expectedNewUser); + assertEquals(expectedNewUser, dataSource.getUser()); + } + + @Test + void testPasswordProperty() { + assertEquals(SQLProperty.PASSWORD.getDefaultValue(), dataSource.getPassword()); + String expectedNewPassword = "newPassword"; + dataSource.setPassword(expectedNewPassword); + assertEquals(expectedNewPassword, dataSource.getPassword()); + } + + @Test + void testSocketChannelProviderProperty() { + assertEquals(SQLProperty.SOCKET_CHANNEL_PROVIDER.getDefaultValue(), dataSource.getSocketChannelProvider()); + String expectedProviderClassName = "z.x.z.MyClass"; + dataSource.setSocketChannelProvider(expectedProviderClassName); + assertEquals(expectedProviderClassName, dataSource.getSocketChannelProvider()); + } + + @Test + void testRequestTimeoutProperty() throws SQLException { + assertEquals(SQLProperty.QUERY_TIMEOUT.getDefaultIntValue(), dataSource.getQueryTimeout()); + int expectedNewTimeout = 45; + dataSource.setQueryTimeout(expectedNewTimeout); + assertEquals(expectedNewTimeout, dataSource.getQueryTimeout()); + } + + @Test + void testDataSourceNameProperty() { + String expectedDataSourceName = "dataSourceName"; + dataSource.setDataSourceName(expectedDataSourceName); + assertEquals(expectedDataSourceName, dataSource.getDataSourceName()); + } + +}