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");
 }