/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hive.metastore;
import java.io.File;
import java.lang.reflect.Field;
import junit.framework.TestCase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.hive.cli.CliSessionState;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.common.util.HiveStringUtils;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.ObjectStore;
import org.apache.hadoop.hive.ql.Driver;
import org.apache.hadoop.hive.ql.metadata.Hive;
import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
import org.apache.hadoop.hive.ql.session.SessionState;
public class TestMetastoreVersion extends TestCase {
private static final Logger LOG = LoggerFactory.getLogger(TestMetastoreVersion.class);
protected HiveConf hiveConf;
private Driver driver;
private String metaStoreRoot;
private String testMetastoreDB;
@Override
protected void setUp() throws Exception {
super.setUp();
Field defDb = HiveMetaStore.HMSHandler.class.getDeclaredField("currentUrl");
defDb.setAccessible(true);
defDb.set(null, null);
// reset defaults
ObjectStore.setSchemaVerified(false);
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "false");
System.setProperty(HiveConf.ConfVars.METASTORE_AUTO_CREATE_ALL.toString(), "true");
hiveConf = new HiveConf(this.getClass());
System.setProperty("hive.support.concurrency", "false");
System.setProperty("hive.metastore.event.listeners",
DummyListener.class.getName());
System.setProperty("hive.metastore.pre.event.listeners",
DummyPreListener.class.getName());
testMetastoreDB = System.getProperty("java.io.tmpdir") +
File.separator + "test_metastore-" + System.currentTimeMillis();
System.setProperty(HiveConf.ConfVars.METASTORECONNECTURLKEY.varname,
"jdbc:derby:" + testMetastoreDB + ";create=true");
metaStoreRoot = System.getProperty("test.tmp.dir");
}
@Override
protected void tearDown() throws Exception {
File metaStoreDir = new File(testMetastoreDB);
if (metaStoreDir.exists()) {
FileUtils.forceDeleteOnExit(metaStoreDir);
}
}
/***
* Test config defaults
*/
public void testDefaults() {
System.clearProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString());
hiveConf = new HiveConf(this.getClass());
assertFalse(hiveConf.getBoolVar(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION));
assertTrue(hiveConf.getBoolVar(HiveConf.ConfVars.METASTORE_AUTO_CREATE_ALL));
}
/***
* Test schema verification property
* @throws Exception
*/
public void testVersionRestriction () throws Exception {
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "true");
hiveConf = new HiveConf(this.getClass());
assertTrue(hiveConf.getBoolVar(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION));
assertFalse(hiveConf.getBoolVar(HiveConf.ConfVars.METASTORE_AUTO_CREATE_ALL));
// session creation should fail since the schema didn't get created
try {
SessionState.start(new CliSessionState(hiveConf));
Hive.get(hiveConf).getMSC();
fail("An exception is expected since schema is not created.");
} catch (Exception re) {
LOG.info("Exception in testVersionRestriction: " + re, re);
String msg = HiveStringUtils.stringifyException(re);
assertTrue("Expected 'Version information not found in metastore' in: " + msg, msg
.contains("Version information not found in metastore"));
}
}
/***
* Test that with no verification, and record verification enabled, hive populates the schema
* and version correctly
* @throws Exception
*/
public void testMetastoreVersion () throws Exception {
// let the schema and version be auto created
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "false");
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION_RECORD_VERSION.toString(), "true");
hiveConf = new HiveConf(this.getClass());
SessionState.start(new CliSessionState(hiveConf));
driver = new Driver(hiveConf);
driver.run("show tables");
// correct version stored by Metastore during startup
assertEquals(MetaStoreSchemaInfo.getHiveSchemaVersion(), getVersion(hiveConf));
setVersion(hiveConf, "foo");
assertEquals("foo", getVersion(hiveConf));
}
/***
* Test that with verification enabled, hive works when the correct schema is already populated
* @throws Exception
*/
public void testVersionMatching () throws Exception {
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "false");
hiveConf = new HiveConf(this.getClass());
SessionState.start(new CliSessionState(hiveConf));
driver = new Driver(hiveConf);
driver.run("show tables");
ObjectStore.setSchemaVerified(false);
hiveConf.setBoolVar(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION, true);
setVersion(hiveConf, MetaStoreSchemaInfo.getHiveSchemaVersion());
driver = new Driver(hiveConf);
CommandProcessorResponse proc = driver.run("show tables");
assertTrue(proc.getResponseCode() == 0);
}
/**
* Store garbage version in metastore and verify that hive fails when verification is on
* @throws Exception
*/
public void testVersionMisMatch () throws Exception {
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "false");
hiveConf = new HiveConf(this.getClass());
SessionState.start(new CliSessionState(hiveConf));
driver = new Driver(hiveConf);
driver.run("show tables");
ObjectStore.setSchemaVerified(false);
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "true");
hiveConf = new HiveConf(this.getClass());
setVersion(hiveConf, "fooVersion");
SessionState.start(new CliSessionState(hiveConf));
driver = new Driver(hiveConf);
CommandProcessorResponse proc = driver.run("show tables");
assertTrue(proc.getResponseCode() != 0);
}
/**
* Store higher version in metastore and verify that hive works with the compatible
* version
* @throws Exception
*/
public void testVersionCompatibility () throws Exception {
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "false");
hiveConf = new HiveConf(this.getClass());
SessionState.start(new CliSessionState(hiveConf));
driver = new Driver(hiveConf);
driver.run("show tables");
System.setProperty(HiveConf.ConfVars.METASTORE_SCHEMA_VERIFICATION.toString(), "true");
hiveConf = new HiveConf(this.getClass());
setVersion(hiveConf, "3.9000.0");
SessionState.start(new CliSessionState(hiveConf));
driver = new Driver(hiveConf);
CommandProcessorResponse proc = driver.run("show tables");
assertEquals(0, proc.getResponseCode());
}
// write the given version to metastore
private String getVersion(HiveConf conf) throws HiveMetaException {
MetaStoreSchemaInfo schemInfo = new MetaStoreSchemaInfo(metaStoreRoot, "derby");
return getMetaStoreVersion();
}
// write the given version to metastore
private void setVersion(HiveConf conf, String version) throws HiveMetaException {
MetaStoreSchemaInfo schemInfo = new MetaStoreSchemaInfo(metaStoreRoot, "derby");
setMetaStoreVersion(version, "setVersion test");
}
// Load the version stored in the metastore db
public String getMetaStoreVersion() throws HiveMetaException {
ObjectStore objStore = new ObjectStore();
objStore.setConf(hiveConf);
try {
return objStore.getMetaStoreSchemaVersion();
} catch (MetaException e) {
throw new HiveMetaException("Failed to get version", e);
}
}
// Store the given version and comment in the metastore
public void setMetaStoreVersion(String newVersion, String comment) throws HiveMetaException {
ObjectStore objStore = new ObjectStore();
objStore.setConf(hiveConf);
try {
objStore.setMetaStoreSchemaVersion(newVersion, comment);
} catch (MetaException e) {
throw new HiveMetaException("Failed to set version", e);
}
}
}