Adding automation tests
Project: http://git-wip-us.apache.org/repos/asf/gora/repo Commit: http://git-wip-us.apache.org/repos/asf/gora/commit/84cde806 Tree: http://git-wip-us.apache.org/repos/asf/gora/tree/84cde806 Diff: http://git-wip-us.apache.org/repos/asf/gora/diff/84cde806 Branch: refs/heads/master Commit: 84cde80693c5baf593b684c93bd6e8a650c2426f Parents: 0380911 Author: madhawa <[email protected]> Authored: Sun Jan 29 08:51:10 2017 +0530 Committer: madhawa <[email protected]> Committed: Sun Jan 29 10:17:49 2017 +0530 ---------------------------------------------------------------------- .../apache/gora/mongodb/store/MongoStore.java | 25 +- .../mongodb/store/MongoStoreParameters.java | 1 + .../GoraMongodbAuthenticationTestDriver.java | 234 +++++++++++++++++++ .../PLAIN_AuthenticationTest.java | 39 ++++ .../SCRAM_SHA_1_AuthenticationTest.java | 38 +++ 5 files changed, 329 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/gora/blob/84cde806/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java ---------------------------------------------------------------------- diff --git a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java index 183005b..3b0d6a3 100644 --- a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java +++ b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStore.java @@ -153,7 +153,7 @@ DataStoreBase<K, T> { } // If configuration contains a login + secret, try to authenticated with DB List<MongoCredential> credentials = new ArrayList<>(); - if (params.getAuthenticationType() != null) { + if (params.getLogin() != null && params.getSecret() != null) { credentials.add(createCredential(params.getAuthenticationType(), params.getLogin(), params.getDbname(), params.getSecret())); } // Build server address @@ -180,21 +180,30 @@ DataStoreBase<K, T> { return new MongoClient(addrs, credentials, optBuilder.build()); } + /** + * This method creates credentials according to the Authentication type. + * + * @param authenticationType authentication Type (Authentication Mechanism) + * @param username username + * @param database database + * @param password password + * @return Mongo Crendential + * @see <a href="http://api.mongodb.com/java/current/com/mongodb/AuthenticationMechanism.html">AuthenticationMechanism in MongoDB Java Driver</a> + */ private MongoCredential createCredential(String authenticationType, String username, String database, String password) { MongoCredential credential = null; - if (authenticationType.equals(PLAIN.getMechanismName())) { + if (PLAIN.getMechanismName().equals(authenticationType)) { credential = MongoCredential.createPlainCredential(username, database, password.toCharArray()); - } else if (authenticationType.equals(SCRAM_SHA_1.getMechanismName())) { + } else if (SCRAM_SHA_1.getMechanismName().equals(authenticationType)) { credential = MongoCredential.createScramSha1Credential(username, database, password.toCharArray()); - } else if (authenticationType.equals(MONGODB_CR.getMechanismName())) { + } else if (MONGODB_CR.getMechanismName().equals(authenticationType)) { credential = MongoCredential.createMongoCRCredential(username, database, password.toCharArray()); - } else if (authenticationType.equals(GSSAPI.getMechanismName())) { + } else if (GSSAPI.getMechanismName().equals(authenticationType)) { credential = MongoCredential.createGSSAPICredential(username); - } else if (authenticationType.equals(MONGODB_X509.getMechanismName())) { + } else if (MONGODB_X509.getMechanismName().equals(authenticationType)) { credential = MongoCredential.createMongoX509Credential(username); } else { - LOG.error("Error while initializing MongoDB store: Invalid Authentication type."); - throw new RuntimeException("Error while initializing MongoDB store: Invalid Authentication type."); + credential = MongoCredential.createCredential(username, database, password.toCharArray()); } return credential; } http://git-wip-us.apache.org/repos/asf/gora/blob/84cde806/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStoreParameters.java ---------------------------------------------------------------------- diff --git a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStoreParameters.java b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStoreParameters.java index e69ec65..b278b89 100644 --- a/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStoreParameters.java +++ b/gora-mongodb/src/main/java/org/apache/gora/mongodb/store/MongoStoreParameters.java @@ -52,6 +52,7 @@ public class MongoStoreParameters { /** * Property pointing to the authentication type to connect to the server + * @see <a href="http://api.mongodb.com/java/current/com/mongodb/AuthenticationMechanism.html">AuthenticationMechanism in MongoDB Java Driver</a> */ public static final String PROP_MONGO_AUTHENTICATION_TYPE = "gora.mongodb.authentication.type"; http://git-wip-us.apache.org/repos/asf/gora/blob/84cde806/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/GoraMongodbAuthenticationTestDriver.java ---------------------------------------------------------------------- diff --git a/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/GoraMongodbAuthenticationTestDriver.java b/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/GoraMongodbAuthenticationTestDriver.java new file mode 100644 index 0000000..38e8616 --- /dev/null +++ b/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/GoraMongodbAuthenticationTestDriver.java @@ -0,0 +1,234 @@ +/** + * 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 + * <p/> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p/> + * 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.gora.mongodb.authentications; + +import de.flapdoodle.embed.mongo.*; +import de.flapdoodle.embed.mongo.config.*; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.config.IRuntimeConfig; +import de.flapdoodle.embed.process.config.io.ProcessOutput; +import de.flapdoodle.embed.process.io.IStreamProcessor; +import de.flapdoodle.embed.process.io.LogWatchStreamProcessor; +import de.flapdoodle.embed.process.io.NamedOutputStreamProcessor; +import de.flapdoodle.embed.process.runtime.Network; +import org.apache.gora.GoraTestDriver; +import org.apache.gora.mongodb.store.MongoStore; +import org.apache.gora.mongodb.store.MongoStoreParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collections; +import java.util.HashSet; + +import static de.flapdoodle.embed.process.io.Processors.console; +import static de.flapdoodle.embed.process.io.Processors.namedConsole; +import static java.util.Arrays.asList; +import static org.apache.commons.lang3.StringUtils.isEmpty; + +/** + * Driver to set up an embedded MongoDB database instance for use in our * unit tests. + * This class is specially written to automate authentication mechanisms. + * We use embedded mongodb which is available from + * https://github.com/flapdoodle-oss/embedmongo.flapdoodle.de + */ +class GoraMongodbAuthenticationTestDriver extends GoraTestDriver { + private static final Logger log = LoggerFactory.getLogger(GoraMongodbAuthenticationTestDriver.class); + private static final int INIT_TIMEOUT_MS = 30000; + private static final String USER_ADDED_TOKEN = "Successfully added user"; + private ThreadLocal<Boolean> started = new ThreadLocal<>(); + private int port; + private MongodExecutable _mongodExe; + private MongodProcess _mongod; + private MongodStarter runtime; + private IMongodConfig mongodConfig; + private String adminUsername = "madhawa"; + private String adminPassword = "123"; + private Version.Main useVersion; + private String authMechanisms; + private boolean auth = false; + + GoraMongodbAuthenticationTestDriver(String authMechanisms, Version.Main useVersion) throws IOException { + super(MongoStore.class); + this.authMechanisms = authMechanisms; + this.useVersion = useVersion; + started.set(false); + if (!this.authMechanisms.equals("MONGODB-CR")) { + auth = true; + } + + } + + private void doStart() throws Exception { + IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder() + .defaultsWithLogger(Command.MongoD, log) + .processOutput(ProcessOutput.getDefaultInstanceSilent()) + .build(); + runtime = MongodStarter.getInstance(runtimeConfig); + try { + log.info("Starting the mongo server without authentications"); + startWithAuth(); + log.info("Adding admin user"); + addAdmin(); + if (this.authMechanisms.equals("SCRAM-SHA-1")) { + setSCRAM_SHA_1Credentials(); + } + if (this.authMechanisms.equals("MONGODB-CR")) { + setMongoDB_CRCredentials(); + tearDownClass(); + auth = true; + startWithAuth(); + addAdmin(); + } + // Store Mongo server "host:port" in Hadoop configuration + // so that MongoStore will be able to get it latter + conf.set(MongoStoreParameters.PROP_MONGO_SERVERS, "127.0.0.1:" + port); + conf.set(MongoStoreParameters.PROP_MONGO_DB, "admin"); + conf.set(MongoStoreParameters.PROP_MONGO_AUTHENTICATION_TYPE, this.authMechanisms); + conf.set(MongoStoreParameters.PROP_MONGO_LOGIN, adminUsername); + conf.set(MongoStoreParameters.PROP_MONGO_SECRET, adminPassword); + } catch (Exception e) { + log.error("Error starting embedded Mongodb server... tearing down test driver."); + tearDownClass(); + } + } + + private void startWithAuth() throws IOException { + try { + if(!started.get()) { + prepareExecutable(); + _mongod = _mongodExe.start(); + started.set(true); + } + } catch (Exception e) { + log.error("Error starting embedded Mongodb server... tearing down test driver."); + tearDownClass(); + } + } + + private void prepareExecutable() throws IOException { + final MongoCmdOptionsBuilder cmdBuilder = new MongoCmdOptionsBuilder(); + cmdBuilder.enableAuth(auth); + final IMongoCmdOptions cmdOptions = cmdBuilder.build(); + MongodConfigBuilder builder = new MongodConfigBuilder() + .version(useVersion) + .cmdOptions(cmdOptions) + .net(new Net(port, Network.localhostIsIPv6())); + if (auth) { + builder.setParameter("authenticationMechanisms", authMechanisms); + } + + mongodConfig = builder.build(); + _mongodExe = runtime.prepare(mongodConfig); + } + + private void addAdmin() throws IOException, InterruptedException { + final String scriptText = "db.createUser(\n" + + " {\n" + + " user: \"madhawa\",\n" + + " pwd: \"123\",\n" + + " roles: [ { role: \"root\", db: \"admin\" } ]\n" + + " }\n" + + ");"; + runScriptAndWait(scriptText, USER_ADDED_TOKEN, new String[]{"couldn't add user", "failed to load", "login failed"}, "admin", null, null); + } + + private void setMongoDB_CRCredentials() throws Exception { + final String scriptText1 = "var schema = db.system.version.findOne({\"_id\" : \"authSchema\"});\nschema.currentVersion = 3;\ndb.system.version.save(schema);\n"; + // final String scriptText1 = "db.system.version.remove({});\ndb.system.version.insert({ \"_id\" : \"authSchema\", \"currentVersion\" : 3 });"; + runScriptAndWait(scriptText1, "Successfully added authSchema", null, "admin", adminUsername, adminPassword); + } + + private void setSCRAM_SHA_1Credentials() throws Exception { + final String scriptText1 = "db.adminCommand({authSchemaUpgrade: 1});\n"; + runScriptAndWait(scriptText1, "Successfully added authSchema", null, "admin", adminUsername, adminPassword); + } + + private void runScriptAndWait(String scriptText, String token, String[] failures, String dbName, String username, String password) throws IOException { + IStreamProcessor mongoOutput; + if (!isEmpty(token)) { + mongoOutput = new LogWatchStreamProcessor( + token, + (failures != null) ? new HashSet<>(asList(failures)) : Collections.emptySet(), + namedConsole("[mongo shell output]")); + } else { + mongoOutput = new NamedOutputStreamProcessor("[mongo shell output]", console()); + } + IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder() + .defaults(Command.Mongo) + .processOutput(new ProcessOutput( + mongoOutput, + namedConsole("[mongo shell error]"), + console())) + .build(); + MongoShellStarter starter = MongoShellStarter.getInstance(runtimeConfig); + + final File scriptFile = writeTmpScriptFile(scriptText); + final MongoShellConfigBuilder builder = new MongoShellConfigBuilder(); + if (!isEmpty(dbName)) { + builder.dbName(dbName); + } + if (!isEmpty(username)) { + builder.username(username); + } + if (!isEmpty(password)) { + builder.password(password); + } + starter.prepare(builder + .scriptName(scriptFile.getAbsolutePath()) + .version(mongodConfig.version()) + .net(mongodConfig.net()) + .build()).start(); + if (mongoOutput instanceof LogWatchStreamProcessor) { + ((LogWatchStreamProcessor) mongoOutput).waitForResult(INIT_TIMEOUT_MS); + } + } + + private File writeTmpScriptFile(String scriptText) throws IOException { + File scriptFile = File.createTempFile("tempfile", ".js"); + scriptFile.deleteOnExit(); + PrintWriter writer = new PrintWriter(scriptFile, "UTF-8"); + writer.write(scriptText); + writer.close(); + return scriptFile; + } + + @Override + public void setUpClass() throws Exception { + port = Network.getFreeServerPort(); + log.info("Starting embedded Mongodb server on {} port.", port); + doStart(); + } + + /** + * Tear the server down + */ + @Override + public void tearDownClass() { + log.info("Shutting down mongodb server..."); + if(started.get()) { + _mongod.stop(); + _mongodExe.stop(); + started.set(false); + } + } + + +} http://git-wip-us.apache.org/repos/asf/gora/blob/84cde806/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/PLAIN_AuthenticationTest.java ---------------------------------------------------------------------- diff --git a/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/PLAIN_AuthenticationTest.java b/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/PLAIN_AuthenticationTest.java new file mode 100644 index 0000000..9b25dac --- /dev/null +++ b/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/PLAIN_AuthenticationTest.java @@ -0,0 +1,39 @@ +/** + * 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.gora.mongodb.authentications; + +import de.flapdoodle.embed.mongo.distribution.Version; +import org.apache.gora.mongodb.GoraMongodbTestDriver; +import org.apache.gora.mongodb.store.TestMongoStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Perform {@link TestMongoStore} tests on MongoDB 3.2.x server with Plain Authentication mechanism. + */ +public class PLAIN_AuthenticationTest extends TestMongoStore { + private static Logger log = LoggerFactory + .getLogger(PLAIN_AuthenticationTest.class); + static { + try { + setTestDriver(new GoraMongodbAuthenticationTestDriver("PLAIN", Version.Main.V3_2)); + } catch (Exception e) { + log.error("MongoDb Test Driver initialization failed. "+ e.getMessage()); + } + } +} http://git-wip-us.apache.org/repos/asf/gora/blob/84cde806/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/SCRAM_SHA_1_AuthenticationTest.java ---------------------------------------------------------------------- diff --git a/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/SCRAM_SHA_1_AuthenticationTest.java b/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/SCRAM_SHA_1_AuthenticationTest.java new file mode 100644 index 0000000..ebbf11e --- /dev/null +++ b/gora-mongodb/src/test/java/org/apache/gora/mongodb/authentications/SCRAM_SHA_1_AuthenticationTest.java @@ -0,0 +1,38 @@ +/** + * 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.gora.mongodb.authentications; + +import de.flapdoodle.embed.mongo.distribution.Version; +import org.apache.gora.mongodb.store.TestMongoStore; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + +/** + * Perform {@link TestMongoStore} tests on MongoDB 3.2.x server with SCRAM-SHA-1 Authentication mechanism + */ +public class SCRAM_SHA_1_AuthenticationTest extends TestMongoStore { + static { + try { + setTestDriver(new GoraMongodbAuthenticationTestDriver("SCRAM-SHA-1", Version.Main.V3_2)); + } catch (Exception e) { + log.error("MongoDb Test Driver initialization failed. "+ e.getMessage()); + } + } +}
