You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/05 10:21:28 UTC
svn commit: r1131996 - in /incubator/mesos/trunk/src:
configurator/configurator.cpp configurator/configurator.hpp
tests/external_test.cpp tests/main.cpp tests/test_configurator.cpp
Author: benh
Date: Sun Jun 5 08:21:27 2011
New Revision: 1131996
URL: http://svn.apache.org/viewvc?rev=1131996&view=rev
Log:
Various fixes:
- Configurator only looks for MESOS_HOME when running one of the Mesos
binaries (in which case the location is inferred from the binary)
- Do not complain if MESOS_HOME/conf/mesos.conf is not found (but do
report an error if the user specifies --conf and the conf directory
given does not contain a mesos.conf).
- External tests now point to the right shell scripts (but said shell
scripts are not yet fixed to use bin directory).
Modified:
incubator/mesos/trunk/src/configurator/configurator.cpp
incubator/mesos/trunk/src/configurator/configurator.hpp
incubator/mesos/trunk/src/tests/external_test.cpp
incubator/mesos/trunk/src/tests/main.cpp
incubator/mesos/trunk/src/tests/test_configurator.cpp
Modified: incubator/mesos/trunk/src/configurator/configurator.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configurator/configurator.cpp?rev=1131996&r1=1131995&r2=1131996&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configurator/configurator.cpp (original)
+++ incubator/mesos/trunk/src/configurator/configurator.cpp Sun Jun 5 08:21:27 2011
@@ -1,6 +1,7 @@
#include <libgen.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/stat.h>
#include <algorithm>
#include <iostream>
@@ -88,13 +89,19 @@ Params& Configurator::load(const map<str
void Configurator::loadConfigFileIfGiven(bool overwrite) {
- string confDir = "";
- if (params.contains("conf"))
- confDir = params["conf"];
- else if (params.contains("home")) // find conf dir relative to MESOS_HOME
- confDir = params["home"] + "/" + DEFAULT_CONFIG_DIR;
- if (confDir != "")
+ if (params.contains("conf")) {
+ // If conf param is given, always look for a config file in that directory
+ string confDir = params["conf"];
loadConfigFile(confDir + "/" + CONFIG_FILE_NAME, overwrite);
+ } else if (params.contains("home")) {
+ // Grab config file in MESOS_HOME/conf, if it exists
+ string confDir = params["home"] + "/" + DEFAULT_CONFIG_DIR;
+ string confFile = confDir + "/" + CONFIG_FILE_NAME;
+ struct stat st;
+ if (stat(confFile.c_str(), &st) == 0) {
+ loadConfigFile(confFile, overwrite);
+ }
+ }
}
@@ -112,7 +119,9 @@ void Configurator::loadEnv(bool overwrit
key = line.substr(strlen(ENV_VAR_PREFIX), eq - strlen(ENV_VAR_PREFIX));
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
val = line.substr(eq + 1);
- if (overwrite || !params.contains(key)) {
+ // Disallow setting home through the environment, because it should
+ // always be resolved from the running Mesos binary (if any)
+ if ((overwrite || !params.contains(key)) && key != "home") {
params[key] = val;
}
}
@@ -131,12 +140,15 @@ void Configurator::loadCommandLine(int a
// Copy argv[0] because dirname can modify it
int lengthOfArg0 = strlen(argv[0]);
char* copyOfArg0 = new char[lengthOfArg0 + 1];
- strcpy(copyOfArg0, argv[0]);
- // Get the directory name from it
+ strncpy(copyOfArg0, argv[0], lengthOfArg0 + 1);
+ // Get its directory, and then the parent of that directory
+ string myDir = string(dirname(copyOfArg0));
+ string parentDir = myDir + "/..";
+ // Get the real name of this parent directory
char path[PATH_MAX];
- if (realpath(dirname(copyOfArg0), path) == 0) {
+ if (realpath(parentDir.c_str(), path) == 0) {
throw ConfigurationException(
- "Could not get directory containing argv[0] -- realpath failed");
+ "Could not resolve MESOS_HOME from argv[0] -- realpath failed");
}
params["home"] = path;
delete[] copyOfArg0;
@@ -153,62 +165,57 @@ void Configurator::loadCommandLine(int a
bool set = false;
if (args[i].find("--", 0) == 0) {
// handle "--" case
-
size_t eq = args[i].find_first_of("=");
if (eq == string::npos &&
args[i].find("--no-", 0) == 0) { // handle --no-blah
key = args[i].substr(5);
val = "0";
set = true;
- isParamConsistent(key, true);
+ checkCommandLineParamFormat(key, true);
} else if (eq == string::npos) { // handle --blah
key = args[i].substr(2);
val = "1";
set = true;
- isParamConsistent(key, true);
+ checkCommandLineParamFormat(key, true);
} else { // handle --blah=25
key = args[i].substr(2, eq-2);
val = args[i].substr(eq+1);
set = true;
- isParamConsistent(key, false);
+ checkCommandLineParamFormat(key, false);
}
-
} else if (args[i].find_first_of("-", 0) == 0 &&
args[i].size() > 1) {
// handle "-" case
-
char shortName = '\0';
-
- if (args[i].find("-no-",0) == 0 && args[i].size() == 5)
+ if (args[i].find("-no-",0) == 0 && args[i].size() == 5) {
shortName = args[i][4];
- else if (args[i].size() == 2)
+ } else if (args[i].size() == 2) {
shortName = args[i][1];
-
+ }
if (shortName == '\0' || getLongName(shortName) == "") {
string message = "Short option '" + args[i] + "' unrecognized ";
throw ConfigurationException(message.c_str());
}
-
key = getLongName(shortName);
-
if (args[i].find("-no-",0) == 0) { // handle -no-b
val = "0";
set = true;
- isParamConsistent(key, true);
+ checkCommandLineParamFormat(key, true);
} else if (options[key].validator->isBool() ||
i+1 == args.size() ) { // handle -b
val = "1";
set = true;
- isParamConsistent(key, true);
+ checkCommandLineParamFormat(key, true);
} else { // handle -b 25
val = args[i+1];
set = true;
i++; // we've consumed next parameter as a "value"-parameter
}
-
}
- if (set && (overwrite || !params.contains(key))) {
- std::transform(key.begin(), key.end(), key.begin(), ::tolower);
+ std::transform(key.begin(), key.end(), key.begin(), ::tolower);
+ // Disallow setting "home" since it should only be inferred from
+ // the location of the running Mesos binary (if any)
+ if (set && (overwrite || !params.contains(key)) && key != "home") {
params[key] = val;
}
}
@@ -248,7 +255,9 @@ void Configurator::loadConfigFile(const
}
string key = StringUtils::trim(tokens[0]);
string value = StringUtils::trim(tokens[1]);
- if (overwrite || !params.contains(key)) {
+ // Disallow setting "home" since it should only be inferred from
+ // the location of the running Mesos binary (if any)
+ if ((overwrite || !params.contains(key)) && key != "home") {
params[key] = value;
}
}
Modified: incubator/mesos/trunk/src/configurator/configurator.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configurator/configurator.hpp?rev=1131996&r1=1131995&r2=1131996&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configurator/configurator.hpp (original)
+++ incubator/mesos/trunk/src/configurator/configurator.hpp Sun Jun 5 08:21:27 2011
@@ -47,7 +47,8 @@ struct ConfigurationException : std::exc
* (ii) Command line variables. Supports "--key=val" "-key val" "-opt" "--opt"
* (iii) Config file. It ignores comments "#". It finds the file mesos.conf
* in the directory specified by the "conf" option. Otherwise, it looks for
- * mesos.conf in the directory MESOS_HOME/conf.
+ * mesos.conf in the directory MESOS_HOME/conf (only if the running binary
+ * is a Mesos binary, so that MESOS_HOME can be inferred from its location).
**/
class Configurator
{
@@ -206,7 +207,7 @@ public:
* <i>Environment:</i><br>
* Parses the environment variables and populates a Params.
* It picks all environment variables that start with MESOS_.
- * The environment var MESOS_HOME=/dir would lead to key=HOME val=/dir<br>
+ * The environment var MESOS_FOO=/dir would lead to key=foo val=/dir<br>
* <i>Command line:</i><br>
* It extracts four type of command line parameters:
* "--key=val", "-key val", "--key", "-key". The two last cases will
@@ -221,7 +222,7 @@ public:
* containing argv[0] (the program being run)
* @return the loaded Params object
**/
- Params& load(int argc, char** argv, bool inferMesosHomeFromArg0=false);
+ Params& load(int argc, char** argv, bool inferMesosHomeFromArg0 = false);
/**
@@ -230,7 +231,7 @@ public:
* <i>Environment:</i><br>
* Parses the environment variables and populates a Params.
* It picks all environment variables that start with MESOS_.
- * The environment var MESOS_HOME=/dir would lead to key=home val=/dir <br>
+ * The environment var MESOS_FOO=/dir would lead to key=foo val=/dir <br>
* <i>Config file:</i><br>
* The config file should contain key=value pairs, one per line.
* Comments, which should start with #, are ignored.
@@ -246,7 +247,7 @@ public:
* <i>Environment:</i><br>
* Parses the environment variables and populates a Params.
* It picks all environment variables that start with MESOS_.
- * The environment var MESOS_HOME=/dir would lead to key=HOME val=/dir <br>
+ * The environment var MESOS_FOO=/dir would lead to key=foo val=/dir <br>
* <i>Map:</i><br>
* Containing a string to string map. <br>
* <i>Config file:</i><br>
@@ -267,11 +268,11 @@ private:
/**
* Parses the environment variables and populates a Params.
* It picks all environment variables that start with MESOS_.
- * The environment variable MESOS_HOME=/dir would lead to key=HOME val=/dir
+ * The environment variable MESOS_FOO=/dir would lead to key=foo val=/dir
* @param overwrite whether to overwrite keys that already have values
* in the internal params (true by default)
**/
- void loadEnv(bool overwrite=true);
+ void loadEnv(bool overwrite = true);
/**
* Populates its internal Params with key/value params from command line.
@@ -289,7 +290,7 @@ private:
void loadCommandLine(int argc,
char** argv,
bool inferMesosHomeFromArg0,
- bool overwrite=true);
+ bool overwrite = true);
/**
* Populates its internal Params with key/value params from a config file.
@@ -304,14 +305,14 @@ private:
* @param overwrite whether to overwrite keys that already have values
* in the internal params (false by default)
**/
- void loadConfigFile(const string& fname, bool overwrite=false);
+ void loadConfigFile(const string& fname, bool overwrite = false);
/**
* Load the config file set through the command line or environment, if any.
* @param overwrite whether to overwrite keys that already have values
* in the internal params (false by default)
*/
- void loadConfigFileIfGiven(bool overwrite=false);
+ void loadConfigFileIfGiven(bool overwrite = false);
/**
* Gets the first long name option associated with the provided short name.
@@ -320,7 +321,17 @@ private:
*/
string getLongName(char shortName) const;
- void isParamConsistent(const string& key, bool gotBool)
+ /**
+ * Check whether a command-line flag is valid, based on whether it was
+ * passed in boolean form (--flag or --no-flag) versus key-value form
+ * (--flag=value). We test whether this option was actually registered
+ * as a bool (or non-bool), and throw an error if it is passed in
+ * the wrong format.
+ *
+ * @param key the option name parsed from the flag (without --no)
+ * @param gotBool whether the option was passed as a bool
+ */
+ void checkCommandLineParamFormat(const string& key, bool gotBool)
throw(ConfigurationException)
{
if (options.find(key) != options.end() &&
Modified: incubator/mesos/trunk/src/tests/external_test.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/external_test.cpp?rev=1131996&r1=1131995&r2=1131996&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/external_test.cpp (original)
+++ incubator/mesos/trunk/src/tests/external_test.cpp Sun Jun 5 08:21:27 2011
@@ -31,7 +31,7 @@ void mesos::internal::test::runExternalT
// Create and go into the test's work directory
enterTestDirectory(testCase, testName);
// Figure out the absolute path to the test script
- string script = mesosHome + "/tests/external/" + testCase
+ string script = mesosHome + "/src/tests/external/" + testCase
+ "/" + testName + ".sh";
// Fork a process to change directory and run the test
pid_t pid;
Modified: incubator/mesos/trunk/src/tests/main.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/main.cpp?rev=1131996&r1=1131995&r2=1131996&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/main.cpp (original)
+++ incubator/mesos/trunk/src/tests/main.cpp Sun Jun 5 08:21:27 2011
@@ -17,13 +17,34 @@ using namespace mesos::internal;
using namespace mesos::internal::test;
-int main(int argc, char **argv)
+namespace {
+
+// Get absolute path to Mesos home directory based on where the alltests
+// binary is located (which should be in MESOS_HOME/bin)
+string getMesosHome(int argc, char** argv) {
+ // Copy argv[0] because dirname can modify it
+ int lengthOfArg0 = strlen(argv[0]);
+ char* copyOfArg0 = new char[lengthOfArg0 + 1];
+ strncpy(copyOfArg0, argv[0], lengthOfArg0 + 1);
+ // Get its directory, and then the parent of that directory
+ string myDir = string(dirname(copyOfArg0));
+ string parentDir = myDir + "/..";
+ // Get the real name of this parent directory
+ char path[PATH_MAX];
+ if (realpath(parentDir.c_str(), path) == 0) {
+ fatalerror("Failed to find location of MESOS_HOME using realpath");
+ }
+ return path;
+}
+
+}
+
+
+int main(int argc, char** argv)
{
- // Get absolute path to Mesos home directory (really src right now)
- char buf[4096];
- if (realpath(dirname(argv[0]), buf) == 0)
- fatalerror("Failed to find location of alltests using realpath");
- mesosHome = buf;
+ // Get absolute path to Mesos home directory based on location of alltests
+ mesos::internal::test::mesosHome = getMesosHome(argc, argv);
+ std::cout << "MESOS_HOME: " << mesosHome << std::endl;
// Clear any MESOS_ environment variables so they don't affect our tests
Configurator::clearMesosEnvironmentVars();
Modified: incubator/mesos/trunk/src/tests/test_configurator.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/test_configurator.cpp?rev=1131996&r1=1131995&r2=1131996&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/test_configurator.cpp (original)
+++ incubator/mesos/trunk/src/tests/test_configurator.cpp Sun Jun 5 08:21:27 2011
@@ -36,14 +36,13 @@ TEST(ConfiguratorTest, DefaultOptions)
{
const int ARGC = 4;
char* argv[ARGC];
- argv[0] = (char*) "./filename";
+ argv[0] = (char*) "bin/filename";
argv[1] = (char*) "--test1=501";
argv[2] = (char*) "--test2";
argv[3] = (char*) "--excp=txt";
Configurator conf;
-
EXPECT_NO_THROW(conf.addOption<int>("test1", "Testing option", 500));
EXPECT_NO_THROW(conf.addOption<bool>("test2", "Another tester", 0));
EXPECT_NO_THROW(conf.addOption<long>("test3", "Tests the default", 2010));
@@ -74,7 +73,7 @@ TEST(ConfiguratorTest, CommandLine)
{
const int ARGC = 12;
char* argv[ARGC];
- argv[0] = (char*) "./filename";
+ argv[0] = (char*) "bin/filename";
argv[1] = (char*) "--test1=text1";
argv[2] = (char*) "--test2";
argv[3] = (char*) "text2";
@@ -113,6 +112,8 @@ TEST(ConfiguratorTest, CommandLine)
// from the default config directory (MESOS_HOME/conf)
TEST_WITH_WORKDIR(ConfiguratorTest, ConfigFileWithMesosHome)
{
+ if (mkdir("bin", 0755) != 0)
+ FAIL() << "Failed to create directory bin";
if (mkdir("conf", 0755) != 0)
FAIL() << "Failed to create directory conf";
ofstream file("conf/mesos.conf");
@@ -123,7 +124,8 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Conf
setenv("MESOS_HOME", ".", 1);
Configurator conf;
- EXPECT_NO_THROW( conf.load() );
+ char* argv[1] = { (char*) "bin/foo" };
+ EXPECT_NO_THROW( conf.load(1, argv, true) );
unsetenv("MESOS_HOME");
EXPECT_EQ("coffee", conf.getParams()["test1"]);
@@ -155,6 +157,8 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Conf
// of conf directory relative in MESOS_HOME/conf.
TEST_WITH_WORKDIR(ConfiguratorTest, ConfigFileWithHomeAndDir)
{
+ if (mkdir("bin", 0755) != 0)
+ FAIL() << "Failed to create directory bin";
if (mkdir("conf2", 0755) != 0)
FAIL() << "Failed to create directory conf2";
ofstream file("conf2/mesos.conf");
@@ -162,12 +166,12 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Conf
file << "# just a comment\n";
file << "test4=milk\n";
file.close();
- setenv("MESOS_HOME", ".", 1);
+
setenv("MESOS_CONF", "conf2", 1);
Configurator conf;
- EXPECT_NO_THROW( conf.load() );
+ char* argv[1] = { (char*) "bin/foo" };
+ EXPECT_NO_THROW( conf.load(1, argv, true) );
unsetenv("MESOS_CONF");
- unsetenv("MESOS_HOME");
EXPECT_EQ("shake", conf.getParams()["test3"]);
EXPECT_EQ("milk", conf.getParams()["test4"]);
@@ -178,6 +182,8 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Conf
// we load values from the config file first and then the command line
TEST_WITH_WORKDIR(ConfiguratorTest, CommandLineConfFlag)
{
+ if (mkdir("bin", 0755) != 0)
+ FAIL() << "Failed to create directory bin";
if (mkdir("conf2", 0755) != 0)
FAIL() << "Failed to create directory conf2";
ofstream file("conf2/mesos.conf");
@@ -188,7 +194,7 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Comm
const int ARGC = 4;
char* argv[ARGC];
- argv[0] = (char*) "./filename";
+ argv[0] = (char*) "bin/filename";
argv[1] = (char*) "--conf=conf2";
argv[2] = (char*) "--b=overridden";
argv[3] = (char*) "--d=fromCmdLine";
@@ -210,6 +216,8 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Comm
TEST_WITH_WORKDIR(ConfiguratorTest, LoadingPriorities)
{
// Create a file which contains parameters a, b, c and d
+ if (mkdir("bin", 0755) != 0)
+ FAIL() << "Failed to create directory bin";
if (mkdir("conf", 0755) != 0)
FAIL() << "Failed to create directory conf";
ofstream file("conf/mesos.conf");
@@ -220,22 +228,20 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Load
file.close();
// Set environment to contain parameters a and b
- setenv("MESOS_HOME", ".", 1);
setenv("MESOS_A", "fromEnv", 1);
setenv("MESOS_B", "fromEnv", 1);
// Pass parameters a and c from the command line
const int ARGC = 3;
char* argv[ARGC];
- argv[0] = (char*) "./filename";
+ argv[0] = (char*) "bin/filename";
argv[1] = (char*) "--a=fromCmdLine";
argv[2] = (char*) "--c=fromCmdLine";
Configurator conf;
- EXPECT_NO_THROW( conf.load(ARGC, argv, false) );
+ EXPECT_NO_THROW( conf.load(ARGC, argv, true) );
// Clear the environment vars set above
- unsetenv("MESOS_HOME");
unsetenv("MESOS_A");
unsetenv("MESOS_B");
@@ -265,10 +271,10 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Conf
file << "\ttest6 = juice# #\n";
file.close();
- setenv("MESOS_HOME", ".", 1);
Configurator conf;
+ setenv("MESOS_CONF", "conf", 1);
EXPECT_NO_THROW(conf.load());
- unsetenv("MESOS_HOME");
+ unsetenv("MESOS_CONF");
EXPECT_EQ("coffee", conf.getParams()["test1"]);
EXPECT_EQ("tea", conf.getParams()["test2"]);
@@ -290,8 +296,8 @@ TEST_WITH_WORKDIR(ConfiguratorTest, Malf
file << "test2=tea\n";
file.close();
- setenv("MESOS_HOME", ".", 1);
+ setenv("MESOS_CONF", "conf", 1);
Configurator conf;
EXPECT_THROW(conf.load(), ConfigurationException);
- unsetenv("MESOS_HOME");
+ unsetenv("MESOS_CONF");
}