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 07:39:59 UTC
svn commit: r1131843 - in /incubator/mesos/trunk/src: Makefile.in
configuration.cpp configuration.hpp params.hpp tests/external_test.cpp
tests/external_test.hpp tests/main.cpp tests/test_configuration.cpp
tests/testing_utils.cpp tests/testing_utils.hpp
Author: benh
Date: Sun Jun 5 05:39:58 2011
New Revision: 1131843
URL: http://svn.apache.org/viewvc?rev=1131843&view=rev
Log:
Various improvements on top of Ali's configuration framework:
- Configuring still works if MESOS_HOME and MESOS_CONF aren't given
- Renamed parse* methods to load*
- Made command line and environment var names get converted to lowercase
for consistency
- Made Configuration throw exceptions when bad things happen so that we
can report them to users / callers
- Added a testing util function for creating a work directory for a
test, and started using it in config file test
- Fixed a bunch of C++ style / formatting throughout
Added:
incubator/mesos/trunk/src/tests/testing_utils.cpp
Modified:
incubator/mesos/trunk/src/Makefile.in
incubator/mesos/trunk/src/configuration.cpp
incubator/mesos/trunk/src/configuration.hpp
incubator/mesos/trunk/src/params.hpp
incubator/mesos/trunk/src/tests/external_test.cpp
incubator/mesos/trunk/src/tests/external_test.hpp
incubator/mesos/trunk/src/tests/main.cpp
incubator/mesos/trunk/src/tests/test_configuration.cpp
incubator/mesos/trunk/src/tests/testing_utils.hpp
Modified: incubator/mesos/trunk/src/Makefile.in
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/Makefile.in?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/Makefile.in (original)
+++ incubator/mesos/trunk/src/Makefile.in Sun Jun 5 05:39:58 2011
@@ -93,7 +93,7 @@ LIBS += -lglog -lgtest -lprocess -lev -l
NEXUS_EXES = nexus-master nexus-slave nexus-local nexus-launcher \
test-framework test-executor cpp-test-framework cpp-test-executor \
- memhog memhog-executor scheduled-memhog
+ memhog memhog-executor
ifeq ($(OS_NAME),solaris)
NEXUS_EXES += nexus-projd
@@ -108,13 +108,15 @@ NEXUS_LIB = libnexus++.a
NEXUS_LIBS = $(SCHED_LIB) $(EXEC_LIB) $(NEXUS_LIB)
MASTER_OBJ = master.o allocator_factory.o simple_allocator.o
-SLAVE_OBJ = slave.o launcher.o isolation_module.o \
+SLAVE_OBJ = slave.o launcher.o isolation_module_factory.o \
process_based_isolation_module.o
-COMMON_OBJ = fatal.o hash_pid.o messages.o lock.o master_detector.o url_processor.o zookeeper.o
+COMMON_OBJ = fatal.o hash_pid.o messages.o lock.o master_detector.o \
+ url_processor.o zookeeper.o configuration.o
EXEC_LIB_OBJ = nexus_exec.o
SCHED_LIB_OBJ = nexus_sched.o nexus_local.o params.o
TEST_OBJ = tests/main.o tests/test_master.o tests/test_resources.o \
- tests/external_test.o tests/test_sample_frameworks.o
+ tests/external_test.o tests/test_sample_frameworks.o \
+ tests/testing_utils.o tests/test_configuration.o
ifeq ($(OS_NAME),solaris)
SLAVE_OBJ += solaris_project_isolation_module.o
@@ -224,10 +226,7 @@ memhog: memhog.cpp $(NEXUS_LIB) third_pa
memhog-executor: memhog_executor.cpp $(NEXUS_LIB) third_party/libprocess/libprocess.a
$(CXX) $(CXXFLAGS) -o $@ $< -L. $(LDFLAGS) -lnexus++ $(LIBS)
-scheduled-memhog: scheduled_memhog.cpp $(NEXUS_LIB) third_party/libprocess/libprocess.a
- $(CXX) $(CXXFLAGS) -o $@ $< -L. $(LDFLAGS) -lnexus++ $(LIBS)
-
-java: $(JAVA_LIB) swig/java/nexus.jar swig/java/TestFramework.class swig/java/TestExecutor.class
+java: $(JAVA_LIB) swig/java/nexus.jar swig/java/TestFramework.class swig/java/TestExecutor.class swig/java/TestExceptionFramework.class swig/java/TestExceptionExecutor.class
python: $(PYTHON_LIB)
@@ -236,8 +235,8 @@ ruby: $(RUBY_LIB)
swig/java/nexus.jar: $(JAVA_LIB)
ifdef JAVA_HOME
$(JAVA_HOME)/bin/javac -sourcepath swig/java -d swig/java swig/java/nexus/*.java
-# patch -N swig/java/nexus/nexusJNI.java < swig/java/nexusJNI.java.patch1 || echo -n
-# patch swig/java/nexus/nexusJNI.java < swig/java/nexusJNI.java.patch2 || echo -n
+ patch -N swig/java/nexus/nexusJNI.java < swig/java/nexusJNI.java.patch1 || echo -n
+ patch swig/java/nexus/nexusJNI.java < swig/java/nexusJNI.java.patch2 || echo -n
$(JAVA_HOME)/bin/jar cf $@ -C swig/java nexus
endif
@@ -259,6 +258,16 @@ ifdef JAVA_HOME
$(JAVA_HOME)/bin/javac -cp swig/java/nexus.jar -sourcepath swig/java -d swig/java swig/java/TestExecutor.java
endif
+swig/java/TestExceptionFramework.class: $(JAVA_LIB) swig/java/nexus.jar swig/java/TestExceptionFramework.java
+ifdef JAVA_HOME
+ $(JAVA_HOME)/bin/javac -cp swig/java/nexus.jar -sourcepath swig/java -d swig/java swig/java/TestExceptionFramework.java
+endif
+
+swig/java/TestExceptionExecutor.class: $(JAVA_LIB) swig/java/nexus.jar swig/java/TestExceptionExecutor.java
+ifdef JAVA_HOME
+ $(JAVA_HOME)/bin/javac -cp swig/java/nexus.jar -sourcepath swig/java -d swig/java swig/java/TestExceptionExecutor.java
+endif
+
$(PYTHON_LIB): swig/nexus.i $(NEXUS_LIB)
ifdef PYTHON_HEADERS
$(SWIG) -c++ -python -threads -I../include -o swig/python/nexus_wrap.cpp -outdir swig/python swig/nexus.i
Modified: incubator/mesos/trunk/src/configuration.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configuration.cpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configuration.cpp (original)
+++ incubator/mesos/trunk/src/configuration.cpp Sun Jun 5 05:39:58 2011
@@ -1,83 +1,74 @@
+#include <libgen.h>
#include <stdlib.h>
#include <unistd.h>
+#include <algorithm>
#include <iostream>
-#include "configuration.hpp"
+#include <boost/foreach.hpp>
+#include "configuration.hpp"
#include "params.hpp"
-#include "boost/foreach.hpp"
-using std::cout;
-using std::endl;
+extern char** environ; // libc's environment variable list; for some reason,
+ // this is not in headers on all platforms
using namespace nexus::internal;
-extern char** environ;
+
+const char* Configuration::DEFAULT_CONFIG_DIR = "conf";
+const char* Configuration::CONFIG_FILE_NAME = "mesos.conf";
+const char* Configuration::ENV_VAR_PREFIX = "MESOS_";
Configuration::Configuration()
{
- parseEnv();
- string cnf;
- const map<string,string> &map = params.getMap();
- if (map.find("CONF") != map.end())
- cnf = params["CONF"];
- else
- cnf = getMesosHome() + "/" + DEFAULT_CONF_NAME;
- parseConfig(cnf);
-}
-
-Configuration::Configuration(int argc, char **argv)
-{
- parseEnv();
- parseCmdline(argc, argv);
- string cnf;
- const map<string,string> &map = params.getMap();
- if (map.find("CONF") != map.end())
- cnf = params["CONF"];
- else
- cnf = getMesosHome() + "/" + DEFAULT_CONF_NAME;
- parseConfig(cnf);
-}
-
-Configuration::Configuration(const map<string,string> &_params)
-{
- parseEnv();
- params.parseMap(_params);
- string cnf;
- const map<string,string> &map = params.getMap();
- if (map.find("CONF") != map.end())
- cnf = params["CONF"];
- else
- cnf = getMesosHome() + "/" + DEFAULT_CONF_NAME;
- parseConfig(cnf);
-}
-
-string Configuration::getMesosHome()
-{
- string mesosHome;
- if (params.getMap().find("HOME") == params.getMap().end()) {
- mesosHome = DEFAULT_HOME;
- LOG(WARNING) << "MESOS_HOME environment variable not set. Using default "
- << mesosHome;
- } else {
- mesosHome = params["HOME"];
- }
- return mesosHome;
+ loadEnv();
+ loadConfigFileIfGiven();
+}
+
+
+Configuration::Configuration(int argc,
+ char** argv,
+ bool inferMesosHomeFromArg0)
+{
+ loadEnv();
+ loadCommandLine(argc, argv, inferMesosHomeFromArg0);
+ loadConfigFileIfGiven();
+}
+
+
+Configuration::Configuration(const map<string, string>& _params)
+{
+ loadEnv();
+ params.loadMap(_params);
+ loadConfigFileIfGiven();
+}
+
+
+void Configuration::loadConfigFileIfGiven() {
+ 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 != "")
+ loadConfigFile(confDir + "/" + CONFIG_FILE_NAME);
}
-void Configuration::parseEnv()
+
+void Configuration::loadEnv()
{
int i = 0;
- while(environ[i] != NULL) {
+ while (environ[i] != NULL) {
string line = environ[i];
- if (line.find(DEFAULT_PREFIX) == 0) {
+ if (line.find(ENV_VAR_PREFIX) == 0) {
string key, val;
- string::size_type eq = line.find_first_of("=");
- if (eq == string::npos)
- continue; // ignore problematic strings
- key = line.substr(sizeof(DEFAULT_PREFIX)-1, eq - (sizeof(DEFAULT_PREFIX)-1));
+ size_t eq = line.find_first_of("=");
+ if (eq == string::npos)
+ continue; // ignore malformed lines (they shouldn't occur in environ!)
+ 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);
params[key] = val;
}
@@ -85,42 +76,51 @@ void Configuration::parseEnv()
}
}
-void Configuration::parseMap(const map<string, string> &map)
-{
- params.parseMap(map);
-}
-void Configuration::parseCmdline(int argc, char **argv)
-{
- vector<string> args;
- map<string,string> store;
+void Configuration::loadCommandLine(int argc,
+ char** argv,
+ bool inferMesosHomeFromArg0)
+{
+ // Set home based on argument 0 if asked to do so
+ if (inferMesosHomeFromArg0) {
+ char buf[4096];
+ realpath(dirname(argv[0]), buf);
+ params["home"] = buf;
+ }
- for (int i=1; i < argc; i++)
- args.push_back(argv[i]);
+ // Convert args 1 and above to STL strings
+ vector<string> args;
+ for (int i=1; i < argc; i++) {
+ args.push_back(string(argv[i]));
+ }
- argc = args.size(); // argc -= 1
-
- for (int i=0; i < argc; i++) {
+ for (int i = 0; i < args.size(); i++) {
string key, val;
bool set = false;
- if (args[i].find("--", 0) == 0) { // handles --blah=25 and --blah
- string::size_type eq = args[i].find_first_of("=");
+ if (args[i].find("--", 0) == 0) {
+ // handle --blah=25 and --blah
+ size_t eq = args[i].find_first_of("=");
if (eq == string::npos) {
key = args[i].substr(2);
+ std::transform(key.begin(), key.end(), key.begin(), ::tolower);
val = "1";
set = true;
- } else {
+ } else {
key = args[i].substr(2, eq-2);
val = args[i].substr(eq+1);
set = true;
}
- } else if (args[i].find_first_of("-", 0) == 0) { // handles -blah 25 and -blah
- if ((i+1 >= argc) || (i+1 < argc && args[i+1].find_first_of("-",0) == 0)) {
+ } else if (args[i].find_first_of("-", 0) == 0) {
+ // handle -blah 25 and -blah
+ if ((i+1 >= args.size()) ||
+ (i+1 < args.size() && args[i+1].find_first_of("-", 0) == 0)) {
key = args[i].substr(1);
+ std::transform(key.begin(), key.end(), key.begin(), ::tolower);
val = "1";
set = true;
- } else if (i+1 < argc && args[i+1].find_first_of("-",0) != 0) {
+ } else if (i+1 < args.size() && args[i+1].find_first_of("-", 0) != 0) {
key = args[i].substr(1);
+ std::transform(key.begin(), key.end(), key.begin(), ::tolower);
val = args[i+1];
set = true;
i++; // we've consumed next parameter as "value"-parameter
@@ -132,29 +132,28 @@ void Configuration::parseCmdline(int arg
}
}
-int Configuration::parseConfig(const string &fname) {
+
+void Configuration::loadConfigFile(const string& fname) {
ifstream cfg(fname.c_str(), std::ios::in);
if (!cfg.is_open()) {
- LOG(ERROR) << "Couldn't read Mesos configuration file from: "
- << fname;
- return -1;
+ string message = "Couldn't read Mesos config file: " + fname;
+ throw new ConfigurationException(message.c_str());
}
string buf, line;
while (!cfg.eof()) {
getline(cfg, line);
- string::size_type beg = line.find_first_of("#"); // strip comments
+ size_t beg = line.find_first_of("#"); // strip comments
beg = line.find_last_not_of("#\t \n\r", beg) + 1; // strip trailing ws
buf += line.substr(0, beg) + "\n";
}
cfg.close();
- params.parseString(buf);
- return 0;
+ params.loadString(buf);
}
-Params &Configuration::getParams()
+
+Params& Configuration::getParams()
{
return params;
}
-
Modified: incubator/mesos/trunk/src/configuration.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/configuration.hpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/configuration.hpp (original)
+++ incubator/mesos/trunk/src/configuration.hpp Sun Jun 5 05:39:58 2011
@@ -15,75 +15,82 @@ using std::endl;
using std::ifstream;
using std::map;
-#define DEFAULT_HOME "./"
-#define DEFAULT_CONF_NAME "mesos.conf"
-#define DEFAULT_PREFIX "MESOS_"
-
namespace nexus { namespace internal {
+
+/**
+ * Exception type thrown by Configuration.
+ */
+struct ConfigurationException : std::exception
+{
+ const char* message;
+ ConfigurationException(const char* msg): message(msg) {}
+ const char* what() const throw () { return message; }
+};
+
+
/**
- * Class that populates a Params object, which can be retrieved with getParams().
+ * This class populates a Params object, which can be retrieved with
+ * getParams(), by reading variables from the command line, a config file
+ * or the environment.
+ *
* It currently supports 3 input types:
* (i) Environment variables. It adds all variables starting with MESOS_.
- * (ii) Command line variables. It supports "--key=val" "-key val" "-opt" "--opt"
+ * (ii) Command line variables. Supports "--key=val" "-key val" "-opt" "--opt"
* (iii) Config file. It ignores comments "#". It finds the file using
- * MESOS_CONF or via command line --CONF=file. Otherwise, it looks for
- * "mesos.conf" in MESOS_HOME or --HOME=dir.
-
+ * MESOS_CONF or via command line --conf=file. Otherwise, it looks for
+ * "mesos.conf" in MESOS_HOME/conf.
**/
-
class Configuration
{
public:
+ static const char* DEFAULT_CONFIG_DIR;
+ static const char* CONFIG_FILE_NAME;
+ static const char* ENV_VAR_PREFIX;
+
+private:
+ Params params;
+
+public:
/**
- * Constructor that populates Params from environment and config file only.
+ * Constructor that populates Params from environment and any config file
+ * located through the environment (through MESOS_HOME or MESOS_CONF).
**/
Configuration();
/**
* Constructor that populates Params from environment, command line,
- * and config file only.
+ * and any config file specified through these.
*
* @param argc number of paramters in argv
* @param argv array of c-strings from the command line
+ * @param inferMesosHomeFromArg0 whether to set mesos home to directory
+ * containing argv[0] (the program being run)
**/
- Configuration(int argc, char **argv);
+ Configuration(int argc, char** argv, bool inferMesosHomeFromArg0);
/**
* Constructor that populates Params from environment, a map,
- * and config file only.
+ * and any config file specified through these.
*
* @param argc number of paramters in argv
* @param argv array of c-strings from the command line
**/
- Configuration(const map<string,string> &_params);
+ Configuration(const map<string, string>& _params);
/**
- * Returns a Params that is populated through parse* methods.
+ * Returns the Params object parsed by this Configuration.
* @return Params populated params object
**/
- Params &getParams();
+ Params& getParams();
private:
/**
- * Returns the current Mesos home directory
- *
- * @return Home directory is extracted from Params. If it doesn't exist
- * it return the current directory as a default.
- **/
- string getMesosHome();
-
- /**
* 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
**/
- void parseEnv();
-
- /**
- * Populates its internal Params with key value params from a map.
- **/
- void parseMap(const map<string, string> &map);
+ void loadEnv();
/**
* Populates its internal Params with key/value params from command line.
@@ -93,19 +100,24 @@ private:
*
* @param argc is the number of parameters in argv
* @param argv is an array of c-strings containing params
+ * @param inferMesosHomeFromArg0 whether to set mesos home to directory
+ * containing argv[0] (the program being run)
**/
- void parseCmdline(int argc, char **argv);
+ void loadCommandLine(int argc, char** argv, bool inferMesosHomeFromArg0);
/**
* Populates its internal Params with key/value params from a config file.
- * It ignores comments starting with "#"
+ * The config file should contain key=value pairs, one per line.
+ * Comments, which should start with #, are ignored.
*
* @param fname is the name of the config file to open
**/
- int parseConfig(const string &fname);
+ void loadConfigFile(const string& fname);
- string mesosHome;
- Params params;
+ /**
+ * Load the config file set through the command line or environment, if any.
+ */
+ void loadConfigFileIfGiven();
};
} } // end nexus :: internal namespace
Modified: incubator/mesos/trunk/src/params.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/params.hpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/params.hpp (original)
+++ incubator/mesos/trunk/src/params.hpp Sun Jun 5 05:39:58 2011
@@ -27,7 +27,7 @@ using boost::lexical_cast;
struct ParseException : std::exception
{
const char* message;
- ParseException(const char *msg): message(msg) {}
+ ParseException(const char* msg): message(msg) {}
const char* what() const throw () { return message; }
};
@@ -47,17 +47,24 @@ public:
Params(const string& str)
{
- parseString(str);
+ loadString(str);
}
- void parseMap(const map<string, string>& params_)
+ /**
+ * Load key-value pairs from a map into this Params object.
+ */
+ void loadMap(const map<string, string>& params_)
{
- foreachpair(const string &k, const string &v, params_) {
+ foreachpair(const string& k, const string& v, params_) {
params[k] = v;
}
}
- void parseString(const string &str)
+ /**
+ * Load key-value pairs from a string into this Params object.
+ * The string should contain pairs of the form key=value, one per line.
+ */
+ void loadString(const string& str)
{
vector<string> lines;
split(str, "\n\r", lines);
@@ -136,6 +143,11 @@ public:
return params;
}
+ bool contains(const string& key) const
+ {
+ return params.find(key) != params.end();
+ }
+
private:
void split(const string& str, const string& delims, vector<string>& tokens)
{
Modified: incubator/mesos/trunk/src/tests/external_test.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/external_test.cpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/external_test.cpp (original)
+++ incubator/mesos/trunk/src/tests/external_test.cpp Sun Jun 5 05:39:58 2011
@@ -1,6 +1,5 @@
#include <gtest/gtest.h>
-#include <ctype.h>
#include <stdlib.h>
#include <string>
@@ -12,21 +11,7 @@
#include "testing_utils.hpp"
using std::string;
-
-namespace {
-
-// Check that a test name contains only letters, numbers and underscores, to
-// prevent messing with directories outside test_output in runExternalTest.
-bool isValidTestName(const char* name) {
- for (const char* p = name; *p != 0; p++) {
- if (!isalnum(*p) && *p != '_') {
- return false;
- }
- }
- return true;
-}
-
-}
+using namespace nexus::internal::test;
/**
@@ -36,22 +21,14 @@ bool isValidTestName(const char* name) {
* piping its output to files called stdout and stderr, and the test
* passes if the script returns 0.
*/
-void nexus::test::runExternalTest(const char* testCase, const char* testName)
+void nexus::internal::test::runExternalTest(const char* testCase,
+ const char* testName)
{
- // Check that the test name is valid
- if (!isValidTestName(testCase) || !isValidTestName(testName)) {
- FAIL() << "Invalid test name for external test (name should "
- << "only contain alphanumeric and underscore characters)";
- }
+ // Create and go into the test's work directory
+ enterTestDirectory(testCase, testName);
// Figure out the absolute path to the test script
- string script = MESOS_HOME + "/tests/external/" + testCase
+ string script = mesosHome + "/tests/external/" + testCase
+ "/" + testName + ".sh";
- // Make the work directory for this test
- string workDir = MESOS_HOME + "/test_output/" + testCase + "/" + testName;
- string command = "rm -fr '" + workDir + "'";
- ASSERT_EQ(0, system(command.c_str())) << "Command failed: " << command;
- command = "mkdir -p '" + workDir + "'";
- ASSERT_EQ(0, system(command.c_str())) << "Command failed: " << command;
// Fork a process to change directory and run the test
pid_t pid;
if ((pid = fork()) == -1) {
@@ -63,14 +40,13 @@ void nexus::test::runExternalTest(const
wait(&exitCode);
ASSERT_EQ(0, exitCode) << "External test " << testName << " failed";
} else {
- // In child process. Go into to the work directory, redirect IO to files,
+ // In child process. Redirect standard output and error to files,
// set MESOS_HOME environment variable, and exec the test script.
- chdir(workDir.c_str());
if (freopen("stdout", "w", stdout) == NULL)
fatalerror("freopen failed");
if (freopen("stderr", "w", stderr) == NULL)
fatalerror("freopen failed");
- setenv("MESOS_HOME", MESOS_HOME.c_str(), 1);
+ setenv("MESOS_HOME", mesosHome.c_str(), 1);
execl(script.c_str(), script.c_str(), (char*) NULL);
// If we get here, execl failed; report the error
fatalerror("Could not execute %s", script.c_str());
Modified: incubator/mesos/trunk/src/tests/external_test.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/external_test.hpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/external_test.hpp (original)
+++ incubator/mesos/trunk/src/tests/external_test.hpp Sun Jun 5 05:39:58 2011
@@ -12,10 +12,10 @@
*/
#define TEST_EXTERNAL(testCase, testName) \
TEST(testCase, testName) { \
- nexus::test::runExternalTest(#testCase, #testName); \
+ nexus::internal::test::runExternalTest(#testCase, #testName); \
}
-namespace nexus { namespace test {
+namespace nexus { namespace internal { namespace test {
/**
* Function called by TEST_EXTERNAL to execute external tests. See
@@ -23,6 +23,6 @@ namespace nexus { namespace test {
*/
void runExternalTest(const char* testCase, const char* testName);
-}} /* namespace nexus::test */
+}}} /* namespace nexus::internal::test */
#endif /* __EXTERNAL_TEST_HPP__ */
Modified: incubator/mesos/trunk/src/tests/main.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/main.cpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/main.cpp (original)
+++ incubator/mesos/trunk/src/tests/main.cpp Sun Jun 5 05:39:58 2011
@@ -7,17 +7,17 @@
#include <iostream>
#include <string>
-using std::string;
+#include "testing_utils.hpp"
-string MESOS_HOME;
+using namespace nexus::internal::test;
int main(int argc, char **argv) {
// Get absolute path to Mesos home direcotry (really src right now)
char buf[4096];
realpath(dirname(argv[0]), buf);
- MESOS_HOME = buf;
- std::cout << "Mesos home is " << MESOS_HOME << std::endl;
+ mesosHome = buf;
+ std::cout << "Mesos home is " << mesosHome << std::endl;
google::InitGoogleLogging("alltests");
testing::InitGoogleTest(&argc, argv);
Modified: incubator/mesos/trunk/src/tests/test_configuration.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/test_configuration.cpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/test_configuration.cpp (original)
+++ incubator/mesos/trunk/src/tests/test_configuration.cpp Sun Jun 5 05:39:58 2011
@@ -5,6 +5,7 @@
#include <boost/lexical_cast.hpp>
#include "configuration.hpp"
+#include "testing_utils.hpp"
using std::ofstream;
using std::string;
@@ -15,29 +16,31 @@ using boost::lexical_cast;
using namespace nexus;
using namespace nexus::internal;
+using namespace nexus::internal::test;
-TEST(ConfigurationTest, EnvironTest)
-{
- setenv("MESOS_TEST","working", true);
+TEST(ConfigurationTest, Environment)
+{
+ setenv("MESOS_TEST", "working", true);
Configuration c1;
unsetenv("MESOS_TEST");
- EXPECT_TRUE(c1.getParams()["TEST"] == "working");
+ EXPECT_TRUE(c1.getParams()["test"] == "working");
}
-TEST(ConfigurationTest, CmdTest)
+
+TEST(ConfigurationTest, CommandLine)
{
- #define ARGC 6
- char *argv[ARGC];
- argv[0] = (char *) "./filename";
- argv[1] = (char *) "--test1=text1";
- argv[2] = (char *) "--test2";
- argv[3] = (char *) "-test3";
- argv[4] = (char *) "text2";
- argv[5] = (char *) "-test4";
+ const int ARGC = 6;
+ char* argv[ARGC];
+ argv[0] = (char*) "./filename";
+ argv[1] = (char*) "--test1=text1";
+ argv[2] = (char*) "--test2";
+ argv[3] = (char*) "-test3";
+ argv[4] = (char*) "text2";
+ argv[5] = (char*) "-test4";
- Configuration c1(ARGC, argv);
+ Configuration c1(ARGC, argv, false);
EXPECT_TRUE(c1.getParams()["test1"] == "text1");
EXPECT_TRUE(c1.getParams()["test2"] == "1");
@@ -45,33 +48,37 @@ TEST(ConfigurationTest, CmdTest)
EXPECT_TRUE(c1.getParams()["test4"] == "1");
}
-// The below test creates files. We have to enable tests to do that safely.
-/*
-TEST(ConfigurationTest, ConfTest)
+
+TEST(ConfigurationTest, ConfigFile)
{
- ofstream file("mesos.conf");
- file << "TEST1=coffee # beans are tasty\n";
+ enterTestDirectory("ConfigurationTest", "ConfigFile");
+
+ if (mkdir("conf", 0755) != 0)
+ FAIL() << "Failed to create directory conf";
+ ofstream file("conf/mesos.conf");
+ file << "test1=coffee # beans are tasty\n";
file << "# just a comment\n";
- file << "TEST2=tea\n";
+ file << "test2=tea\n";
file.close();
- setenv("MESOS_HOME", "./", 1);
+ setenv("MESOS_HOME", ".", 1);
Configuration c1;
unsetenv("MESOS_HOME");
- EXPECT_TRUE(c1.getParams()["TEST1"] == "coffee");
- EXPECT_TRUE(c1.getParams()["TEST2"] == "tea");
+ EXPECT_TRUE(c1.getParams()["test1"] == "coffee");
+ EXPECT_TRUE(c1.getParams()["test2"] == "tea");
- ofstream file2("misus.conf");
- file2 << "TEST3=shake # sugar bomb\n";
+ if (mkdir("conf2", 0755) != 0)
+ FAIL() << "Failed to create directory conf2";
+ ofstream file2("conf2/mesos.conf");
+ file2 << "test3=shake # sugar bomb\n";
file2 << "# just a comment\n";
- file2 << "TEST4=milk\n";
+ file2 << "test4=milk\n";
file2.close();
- setenv("MESOS_CONF", "misus.conf", 1);
+ setenv("MESOS_CONF", "conf2", 1);
Configuration c2;
unsetenv("MESOS_CONF");
- EXPECT_TRUE(c2.getParams()["TEST3"] == "shake");
- EXPECT_TRUE(c2.getParams()["TEST4"] == "milk");
+ EXPECT_TRUE(c2.getParams()["test3"] == "shake");
+ EXPECT_TRUE(c2.getParams()["test4"] == "milk");
}
-*/
Added: incubator/mesos/trunk/src/tests/testing_utils.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/testing_utils.cpp?rev=1131843&view=auto
==============================================================================
--- incubator/mesos/trunk/src/tests/testing_utils.cpp (added)
+++ incubator/mesos/trunk/src/tests/testing_utils.cpp Sun Jun 5 05:39:58 2011
@@ -0,0 +1,53 @@
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <gtest/gtest.h>
+
+#include "testing_utils.hpp"
+
+using std::string;
+
+using namespace nexus::internal;
+
+
+string test::mesosHome;
+
+
+namespace {
+
+// Check that a test name contains only letters, numbers and underscores, to
+// prevent messing with directories outside test_output in runExternalTest.
+bool isValidTestName(const char* name) {
+ for (const char* p = name; *p != 0; p++) {
+ if (!isalnum(*p) && *p != '_') {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
+
+/**
+ * Create and clean up the work directory for a given test, and cd into it,
+ * given the test's test case name and test name.
+ * Test directories are placed in <mesosHome>/test_output/<testCase>/<testName>.
+ */
+void test::enterTestDirectory(const char* testCase, const char* testName)
+{
+ // Check that the test name is valid
+ if (!isValidTestName(testCase) || !isValidTestName(testName)) {
+ FAIL() << "Invalid test name for external test (name should "
+ << "only contain alphanumeric and underscore characters)";
+ }
+ // Make the work directory for this test
+ string workDir = mesosHome + "/test_output/" + testCase + "/" + testName;
+ string command = "rm -fr '" + workDir + "'";
+ ASSERT_EQ(0, system(command.c_str())) << "Command failed: " << command;
+ command = "mkdir -p '" + workDir + "'";
+ ASSERT_EQ(0, system(command.c_str())) << "Command failed: " << command;
+ // Change dir into it
+ chdir(workDir.c_str());
+}
Modified: incubator/mesos/trunk/src/tests/testing_utils.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/testing_utils.hpp?rev=1131843&r1=1131842&r2=1131843&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/testing_utils.hpp (original)
+++ incubator/mesos/trunk/src/tests/testing_utils.hpp Sun Jun 5 05:39:58 2011
@@ -3,9 +3,24 @@
#include <string>
-// The location where Mesos is installed, used by tests to locate various
-// frameworks and binaries. For now it points to the src directory, until
-// we clean up our directory structure a little. Initialized in main.cpp.
-extern std::string MESOS_HOME;
+namespace nexus { namespace internal { namespace test {
+
+/**
+ * The location where Mesos is installed, used by tests to locate various
+ * frameworks and binaries. For now it points to the src directory, until
+ * we clean up our directory structure a little. Initialized in main.cpp.
+ */
+extern std::string mesosHome;
+
+
+/**
+ * Create and clean up the work directory for a given test, and cd into it,
+ * given the test's test case name and test name.
+ * Test directories are placed in <mesosHome>/test_output/<testCase>/<testName>.
+ */
+void enterTestDirectory(const char* testCase, const char* testName);
+
+
+}}} // namespace nexus::internal::test
#endif /* __TESTING_UTILS_HPP__ */