package com.tesora.dve.variable;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.sql.SQLException;
import com.tesora.dve.variables.VariableService;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import com.tesora.dve.common.PEConstants;
import com.tesora.dve.common.catalog.PersistentGroup;
import com.tesora.dve.common.catalog.TestCatalogHelper;
import com.tesora.dve.common.catalog.UserDatabase;
import com.tesora.dve.db.DBResultConsumer;
import com.tesora.dve.distribution.BroadcastDistributionModel;
import com.tesora.dve.errmap.MySQLErrors;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.exceptions.PEMappedException;
import com.tesora.dve.exceptions.PENotFoundException;
import com.tesora.dve.queryplan.QueryPlan;
import com.tesora.dve.queryplan.QueryStepGetGlobalVariableOperation;
import com.tesora.dve.queryplan.QueryStepGetSessionVariableOperation;
import com.tesora.dve.queryplan.QueryStepOperation;
import com.tesora.dve.queryplan.QueryStepSelectAllOperation;
import com.tesora.dve.queryplan.QueryStepSetScopedVariableOperation;
import com.tesora.dve.server.bootstrap.BootstrapHost;
import com.tesora.dve.server.connectionmanager.SSConnection;
import com.tesora.dve.server.connectionmanager.SSConnectionAccessor;
import com.tesora.dve.server.connectionmanager.SSConnectionProxy;
import com.tesora.dve.server.global.HostService;
import com.tesora.dve.singleton.Singletons;
import com.tesora.dve.sql.SchemaException;
import com.tesora.dve.sql.schema.VariableScope;
import com.tesora.dve.sql.schema.VariableScopeKind;
import com.tesora.dve.sql.util.ProxyConnectionResource;
import com.tesora.dve.standalone.PETest;
import com.tesora.dve.test.simplequery.SimpleQueryTest;
import com.tesora.dve.variables.KnownVariables;
import com.tesora.dve.variables.VariableHandler;
import com.tesora.dve.variables.VariableManager;
import com.tesora.dve.worker.MysqlTextResultChunkProvider;
import com.tesora.dve.worker.UserCredentials;
public class VariableTest extends PETest {
static final String PERSISTENT_GROUP_VARIABLE = "persistent_group";
@SuppressWarnings("hiding")
public Logger logger = Logger.getLogger(VariableTest.class);
SSConnectionProxy conProxy;
SSConnection ssConnection;
UserDatabase db;
PersistentGroup sg;
QueryPlan plan;
@BeforeClass
public static void setup() throws Throwable {
TestCatalogHelper.createTestCatalog(PETest.class);
bootHost = BootstrapHost.startServices(PETest.class);
ProxyConnectionResource pcr = new ProxyConnectionResource();
SimpleQueryTest.declareSchema(pcr);
pcr.disconnect();
}
public VariableTest() {
}
@Before
public void setupUserData() throws PEException, SQLException {
populateSites(SimpleQueryTest.class, Singletons.require(HostService.class).getProperties());
conProxy = new SSConnectionProxy();
ssConnection = SSConnectionAccessor.getSSConnection(conProxy);
SSConnectionAccessor.setCatalogDAO(ssConnection, catalogDAO);
ssConnection.startConnection(new UserCredentials(bootHost.getProperties()));
ssConnection.setPersistentDatabase(catalogDAO.findDatabase("TestDB"));
db = ssConnection.getPersistentDatabase();
sg = db.getDefaultStorageGroup();
plan = new QueryPlan();
}
@After
public void testCleanup() throws PEException {
plan = null;
if(conProxy != null)
conProxy.close();
conProxy = null;
}
@Test
public void globalVariableTest() throws PEException {
assertEquals(Boolean.FALSE, KnownVariables.SLOW_QUERY_LOG.getValue(null));
KnownVariables.SLOW_QUERY_LOG.setGlobalValue(ssConnection,"yes");
assertEquals(Boolean.TRUE, KnownVariables.SLOW_QUERY_LOG.getValue(null));
}
@Test(expected = PEMappedException.class)
public void globalVariableNotExistsTest() throws PEException {
Singletons.require(VariableService.class).getVariableManager().lookupMustExist(null,"no-such-variable");
}
@Test
public void getVersionCommentTest() throws PEException {
assertEquals(Singletons.require(HostService.class).getDveServerVersionComment(),
KnownVariables.VERSION_COMMENT.getGlobalValue(null));
}
@Test
public void getVersionTest() throws PEException {
assertEquals(Singletons.require(HostService.class).getDveServerVersion(),
KnownVariables.VERSION.getGlobalValue(null));
}
@Test(expected = PEException.class)
public void setVersionCommentTest() throws PEException {
KnownVariables.VERSION_COMMENT.setGlobalValue(ssConnection,"hello");
}
@Test
public void globalVariableQSOTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.GLOBAL), "sql_logging", "yes"),
results);
assertFalse(results.hasResults());
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetGlobalVariableOperation(KnownVariables.SQL_LOGGING), results);
assertTrue(results.hasResults());
assertEquals("YES", results.getSingleColumnValue(1, 1));
}
@Test
public void sessionVariableQSOTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION), "character_set_client",
"latin1"), results);
assertFalse(results.hasResults());
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.CHARACTER_SET_CLIENT), results);
assertTrue(results.hasResults());
assertEquals("latin1", results.getSingleColumnValue(1, 1));
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION), "character_set_client",
"utf8"), results);
assertFalse(results.hasResults());
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.CHARACTER_SET_CLIENT), results);
assertTrue(results.hasResults());
assertEquals("utf8", results.getSingleColumnValue(1, 1));
}
@Test(expected = PEMappedException.class)
public void sessionVariableNotExistsTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION), "invalid-session-name",
"value1"), results);
assertFalse(results.hasResults());
}
@Test
public void setPolicyTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION), "dynamic_policy",
"OnPremisePolicy"), results);
assertFalse(results.hasResults());
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.DYNAMIC_POLICY), results);
assertTrue(results.hasResults());
assertEquals("OnPremisePolicy", results.getSingleColumnValue(1, 1));
}
@Test(expected = PENotFoundException.class)
public void setPolicyFailTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION), "dynamic_policy",
"value1"), results);
assertFalse(results.hasResults());
}
@Test
public void setStorageGroupTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION),
PERSISTENT_GROUP_VARIABLE, PEConstants.DEFAULT_GROUP_NAME), results);
assertFalse(results.hasResults());
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.PERSISTENT_GROUP), results);
assertTrue(results.hasResults());
assertEquals(PEConstants.DEFAULT_GROUP_NAME, results.getSingleColumnValue(1, 1));
}
@Test(expected = PENotFoundException.class)
public void setStorageGroupFailTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION),
PERSISTENT_GROUP_VARIABLE, "value1"), results);
assertFalse(results.hasResults());
}
@Test
public void getVariableUpperCaseTest() throws Throwable {
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.PERSISTENT_GROUP), results);
assertTrue(results.hasResults());
assertEquals(1, results.getNumRowsAffected());
}
@Test
public void clientCharSet() throws Throwable {
String origCharSet =
KnownVariables.CHARACTER_SET_CLIENT.getSessionValue(ssConnection).getName();
String newCharset = "utf8";
if (!origCharSet.toLowerCase().equals("utf8"))
newCharset = "latin1";
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSetScopedVariableOperation(new VariableScope(VariableScopeKind.SESSION),
VariableConstants.CHARACTER_SET_CLIENT_NAME, newCharset), results);
assertFalse(results.hasResults());
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.CHARACTER_SET_CLIENT), results);
assertTrue(results.hasResults());
assertEquals(newCharset, results.getSingleColumnValue(1, 1));
}
@Test
public void setValidCollation() throws Throwable {
String origCollation =
KnownVariables.COLLATION_CONNECTION.getSessionValue(ssConnection);
MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.COLLATION_CONNECTION), results);
assertTrue(results.hasResults());
assertEquals(origCollation, results.getSingleColumnValue(1, 1));
String utfCollation = "utf8_unicode_ci";
ssConnection.setSessionVariable(VariableConstants.COLLATION_CONNECTION_NAME, utfCollation);
assertEquals(utfCollation,
KnownVariables.COLLATION_CONNECTION.getSessionValue(ssConnection));
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.COLLATION_CONNECTION),
results);
assertTrue(results.hasResults());
assertEquals(utfCollation, results.getSingleColumnValue(1, 1));
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSelectAllOperation(sg,ssConnection, db, BroadcastDistributionModel.SINGLETON,
"select @@session.collation_connection"), results);
assertTrue(results.hasResults());
assertEquals(utfCollation, results.getSingleColumnValue(1, 1));
ssConnection.setSessionVariable(VariableConstants.COLLATION_CONNECTION_NAME, origCollation);
assertEquals(origCollation,
KnownVariables.COLLATION_CONNECTION.getSessionValue(ssConnection));
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepGetSessionVariableOperation(KnownVariables.COLLATION_CONNECTION), results);
assertTrue(results.hasResults());
assertEquals(origCollation, results.getSingleColumnValue(1, 1));
results = new MysqlTextResultChunkProvider();
executeQuery(new QueryStepSelectAllOperation(sg,ssConnection, db, BroadcastDistributionModel.SINGLETON,
"select @@session.collation_connection"), results);
assertTrue(results.hasResults());
assertEquals(origCollation, results.getSingleColumnValue(1, 1));
}
@Test
public void setInvalidCollation() throws Throwable {
new ExpectedSqlErrorTester() {
@Override
public void test() throws Throwable {
KnownVariables.COLLATION_CONNECTION.setSessionValue(ssConnection, "latin1_junk_ci");
}
}.assertError(SchemaException.class, MySQLErrors.unknownCollationFormatter, "latin1_junk_ci");
}
/** PE-1154 */
@Test
public void setLongQueryTime() throws Throwable {
assertEquals(new Double(10.0), KnownVariables.LONG_QUERY_TIME.getGlobalValue(ssConnection));
KnownVariables.LONG_QUERY_TIME.setGlobalValue(ssConnection,"25.5");
assertEquals(new Double(25.5), KnownVariables.LONG_QUERY_TIME.getGlobalValue(ssConnection));
}
/** PE-1156 */
@SuppressWarnings("unchecked")
@Test
public void setGroupConcatMaxLen() throws Throwable {
VariableManager vm = Singletons.require(VariableService.class).getVariableManager();
VariableHandler<Long> var = (VariableHandler<Long>) vm.lookupMustExist(null,"group_concat_max_len");
assertEquals(new Long(1024), var.getSessionValue(ssConnection));
var.setSessionValue(ssConnection, "5");
assertEquals(new Long(5), var.getSessionValue(ssConnection));
}
/** PE-1128 */
@Test
public void setAutocommit() throws Throwable {
assertEquals(Boolean.TRUE, KnownVariables.AUTOCOMMIT.getSessionValue(ssConnection));
KnownVariables.AUTOCOMMIT.setSessionValue(ssConnection, "0");
assertEquals(Boolean.FALSE, KnownVariables.AUTOCOMMIT.getSessionValue(ssConnection));
KnownVariables.AUTOCOMMIT.setSessionValue(ssConnection, "ON");
assertEquals(Boolean.TRUE, KnownVariables.AUTOCOMMIT.getSessionValue(ssConnection));
KnownVariables.AUTOCOMMIT.setSessionValue(ssConnection, "OFF");
assertEquals(Boolean.FALSE, KnownVariables.AUTOCOMMIT.getSessionValue(ssConnection));
new ExpectedSqlErrorTester() {
@Override
public void test() throws Throwable {
KnownVariables.AUTOCOMMIT.setSessionValue(ssConnection, null);
}
}.assertError(SchemaException.class, MySQLErrors.wrongValueForVariable, "autocommit", "NULL");
new ExpectedSqlErrorTester() {
@Override
public void test() throws Throwable {
KnownVariables.AUTOCOMMIT.setSessionValue(ssConnection, "");
}
}.assertError(SchemaException.class, MySQLErrors.wrongValueForVariable, "autocommit", "");
new ExpectedSqlErrorTester() {
@Override
public void test() throws Throwable {
KnownVariables.AUTOCOMMIT.setSessionValue(ssConnection, "2");
}
}.assertError(SchemaException.class, MySQLErrors.wrongValueForVariable, "autocommit", "2");
}
@Test
public void setTimeZone() throws Throwable {
// make sure the default values are properly set
// now that we support scopes - we should toss over default_time_zone in favor of time_zone with a global scope
String peTimeZoneDefault = KnownVariables.TIME_ZONE.getGlobalValue(ssConnection);
assertEquals("+00:00", peTimeZoneDefault);
assertEquals("+00:00", KnownVariables.TIME_ZONE.getSessionValue(ssConnection));
// change the session variable
KnownVariables.TIME_ZONE.setSessionValue(ssConnection, "+05:00");
assertEquals("+05:00", KnownVariables.TIME_ZONE.getSessionValue(ssConnection));
// change the default PE time zone
KnownVariables.TIME_ZONE.setGlobalValue(ssConnection,"-09:00");
// new connection should have new default
SSConnectionProxy conProxy = new SSConnectionProxy();
try {
SSConnection ssConnection = SSConnectionAccessor.getSSConnection(conProxy);
SSConnectionAccessor.setCatalogDAO(ssConnection, catalogDAO);
ssConnection.startConnection(new UserCredentials(bootHost.getProperties()));
assertEquals("-09:00", KnownVariables.TIME_ZONE.getSessionValue(ssConnection));
} finally {
conProxy.close();
}
}
/*
@Test
public void getLiteralSessionVariableTest() throws PEException {
throw new PEException("fill me in");
// assertEquals("YES", Singletons.require(HostService.class).getSessionConfigTemplate().getVariableInfo("have_innodb").getHandler()
// .getValue(ssConnection, "have_innodb"));
}
@Test(expected = PEException.class)
public void setLiteralSessionVariableFailTest() throws Throwable {
throw new Throwable ("fill me in");
// Singletons.require(HostService.class).getSessionConfigTemplate().getVariableInfo("have_innodb").getHandler()
// .setValue(ssConnection, "have_innodb", "NO");
}
*/
@Test
public void setGroupServiceVariableTest() throws PEException {
// HostService hostService = Singletons.require(HostService.class);
KnownVariables.GROUP_SERVICE.setPersistentValue(ssConnection, "HaZeLCaST");
assertEquals("HaZeLCaST",
KnownVariables.GROUP_SERVICE.getValue(null));
KnownVariables.GROUP_SERVICE.setPersistentValue(ssConnection, "Localhost");
assertEquals("Localhost",
KnownVariables.GROUP_SERVICE.getValue(null));
}
@Test(expected = PEException.class)
public void setGroupServiceVariableFailTest() throws PEException {
KnownVariables.GROUP_SERVICE.setPersistentValue(ssConnection, "InvalidValue");
}
private void executeQuery(QueryStepOperation qso, DBResultConsumer results) throws Throwable {
QueryPlan qp = new QueryPlan();
qp.addStep(qso);
qp.executeStep(ssConnection, results);
}
}