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 11:04:48 UTC

svn commit: r1132231 [2/2] - in /incubator/mesos/trunk: include/ src/ src/common/ src/examples/ src/examples/java/ src/exec/ src/local/ src/master/ src/messaging/ src/sched/ src/slave/ src/tests/

Modified: incubator/mesos/trunk/src/sched/sched.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/sched/sched.cpp?rev=1132231&r1=1132230&r2=1132231&view=diff
==============================================================================
--- incubator/mesos/trunk/src/sched/sched.cpp (original)
+++ incubator/mesos/trunk/src/sched/sched.cpp Sun Jun  5 09:04:47 2011
@@ -77,10 +77,10 @@ protected:
                   << taskId << " after "
                   << STATUS_UPDATE_TIMEOUT << ", assuming task was lost";
           Message<M2F_STATUS_UPDATE> out;
-          *out.mutable_framework_id() = frameworkId;
+          out.mutable_framework_id()->MergeFrom(frameworkId);
           TaskStatus* status = out.mutable_status();
-          *status->mutable_task_id() = taskId;
-          *status->mutable_slave_id() = slaveId;
+          status->mutable_task_id()->MergeFrom(taskId);
+          status->mutable_slave_id()->MergeFrom(slaveId);
           status->set_state(TASK_LOST);
           send(sched, out);
           break;
@@ -165,13 +165,13 @@ protected:
         if (frameworkId == "") {
           // Touched for the very first time.
           Message<F2M_REGISTER_FRAMEWORK> out;
-          *out.mutable_framework() = framework;
+          out.mutable_framework()->MergeFrom(framework);
           send(master, out);
         } else {
           // Not the first time, or failing over.
           Message<F2M_REREGISTER_FRAMEWORK> out;
-          *out.mutable_framework() = framework;
-          *out.mutable_framework_id() = frameworkId;
+          out.mutable_framework()->MergeFrom(framework);
+          out.mutable_framework_id()->MergeFrom(frameworkId);
           out.set_generation(generation++);
           send(master, out);
         }
@@ -314,7 +314,7 @@ protected:
       return;
 
     Message<F2M_UNREGISTER_FRAMEWORK> out;
-    *out.mutable_framework_id() = frameworkId;
+    out.mutable_framework_id()->MergeFrom(frameworkId);
     send(master, out);
   }
 
@@ -324,8 +324,8 @@ protected:
       return;
 
     Message<F2M_KILL_TASK> out;
-    *out.mutable_framework_id() = frameworkId;
-    *out.mutable_task_id() = taskId;
+    out.mutable_framework_id()->MergeFrom(frameworkId);
+    out.mutable_task_id()->MergeFrom(taskId);
     send(master, out);
   }
 
@@ -337,8 +337,8 @@ protected:
       return;
 
     Message<F2M_RESOURCE_OFFER_REPLY> out;
-    *out.mutable_framework_id() = frameworkId;
-    *out.mutable_offer_id() = offerId;
+    out.mutable_framework_id()->MergeFrom(frameworkId);
+    out.mutable_offer_id()->MergeFrom(offerId);
 
     foreachpair (const string& key, const string& value, params) {
       Param* param = out.mutable_params()->add_param();
@@ -356,8 +356,7 @@ protected:
       timers[task.task_id()] = timer;
       spawn(timer);
 
-      // Copy the task over.
-      *(out.add_task()) = task;
+      out.add_task()->MergeFrom(task);
     }
 
     // Remove the offer since we saved all the PIDs we might use.
@@ -372,7 +371,7 @@ protected:
       return;
 
     Message<F2M_REVIVE_OFFERS> out;
-    *out.mutable_framework_id() = frameworkId;
+    out.mutable_framework_id()->MergeFrom(frameworkId);
     send(master, out);
   }
 
@@ -396,16 +395,16 @@ protected:
 
       // TODO(benh): This is kind of wierd, M2S?
       Message<M2S_FRAMEWORK_MESSAGE> out;
-      *out.mutable_framework_id() = frameworkId;
-      *out.mutable_message() = message;
+      out.mutable_framework_id()->MergeFrom(frameworkId);
+      out.mutable_message()->MergeFrom(message);
       send(slave, out);
     } else {
       VLOG(1) << "Cannot send directly to slave " << message.slave_id()
 	      << "; sending through master";
 
       Message<F2M_FRAMEWORK_MESSAGE> out;
-      *out.mutable_framework_id() = frameworkId;
-      *out.mutable_message() = message;
+      out.mutable_framework_id()->MergeFrom(frameworkId);
+      out.mutable_message()->MergeFrom(message);
       send(master, out);
     }
   }
@@ -592,7 +591,7 @@ int MesosSchedulerDriver::start()
   FrameworkInfo framework;
   framework.set_user(passwd->pw_name);
   framework.set_name(sched->getFrameworkName(this));
-  *framework.mutable_executor() = sched->getExecutorInfo(this);
+  framework.mutable_executor()->MergeFrom(sched->getExecutorInfo(this));
 
   // Something invoked stop while we were in the scheduler, bail.
   if (!running)

Modified: incubator/mesos/trunk/src/slave/slave.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/slave/slave.cpp?rev=1132231&r1=1132230&r2=1132231&view=diff
==============================================================================
--- incubator/mesos/trunk/src/slave/slave.cpp (original)
+++ incubator/mesos/trunk/src/slave/slave.cpp Sun Jun  5 09:04:47 2011
@@ -20,7 +20,6 @@ using namespace mesos;
 using namespace mesos::internal;
 using namespace mesos::internal::slave;
 
-using boost::lexical_cast;
 using boost::unordered_map;
 using boost::unordered_set;
 
@@ -33,17 +32,6 @@ using std::string;
 using std::vector;
 
 
-namespace {
-
-
-// Default values for CPU cores and memory to include in configuration
-const int32_t DEFAULT_CPUS = 1;
-const int32_t DEFAULT_MEM = 1 * Gigabyte;
-
-
-} /* namespace */
-
-
 Slave::Slave(const Resources& _resources, bool _local,
              IsolationModule *_isolationModule)
   : resources(_resources), local(_local),
@@ -51,22 +39,18 @@ Slave::Slave(const Resources& _resources
 
 
 Slave::Slave(const Configuration& _conf, bool _local,
-             IsolationModule *_module)
-  : conf(_conf), local(_local), isolationModule(_module), heart(NULL)
-{
-  resources.set_cpus(conf.get<int32_t>("cpus", DEFAULT_CPUS));
-  resources.set_mem(conf.get<int32_t>("mem", DEFAULT_MEM));
-}
+             IsolationModule* _isolationModule)
+  : conf(_conf), local(_local),
+    isolationModule(_isolationModule), heart(NULL) {}
 
 
 void Slave::registerOptions(Configurator* configurator)
 {
-  configurator->addOption<int32_t>("cpus", 'c',
-                                   "CPU cores for use by tasks",
-                                   DEFAULT_CPUS);
-  configurator->addOption<int64_t>("mem", 'm',
-                                   "Memory for use by tasks, in MB\n",
-                                   DEFAULT_MEM);
+  // TODO(benh): Is there a way to specify units for the resources?
+  configurator->addOption<string>("resources",
+                                  "Total consumable resources on machine\n");
+//   configurator->addOption<string>("attributes",
+//                                   "Attributes of machine\n");
   configurator->addOption<string>("work_dir",
                                   "Where to place framework work directories\n"
                                   "(default: MESOS_HOME/work)");
@@ -94,22 +78,48 @@ Slave::~Slave()
 
 state::SlaveState *Slave::getState()
 {
+  Resources resources(resources);
+  Resource::Scalar cpus;
+  Resource::Scalar mem;
+  cpus.set_value(-1);
+  mem.set_value(-1);
+  cpus = resources.getScalar("cpus", cpus);
+  mem = resources.getScalar("mem", mem);
+
   state::SlaveState *state =
     new state::SlaveState(BUILD_DATE, BUILD_USER, slaveId.value(),
-                          resources.cpus(), resources.mem(),
-                          self(), master);
+                          cpus.value(), mem.value(), self(), master);
 
   foreachpair(_, Framework *f, frameworks) {
+    Resources resources(f->resources);
+    Resource::Scalar cpus;
+    Resource::Scalar mem;
+    cpus.set_value(-1);
+    mem.set_value(-1);
+    cpus = resources.getScalar("cpus", cpus);
+    mem = resources.getScalar("mem", mem);
+
     state::Framework *framework =
       new state::Framework(f->frameworkId.value(), f->info.name(),
                            f->info.executor().uri(), f->executorStatus,
-                           f->resources.cpus(), f->resources.mem());
+                           cpus.value(), mem.value());
+
     state->frameworks.push_back(framework);
+
     foreachpair(_, Task *t, f->tasks) {
+      Resources resources(t->resources());
+      Resource::Scalar cpus;
+      Resource::Scalar mem;
+      cpus.set_value(-1);
+      mem.set_value(-1);
+      cpus = resources.getScalar("cpus", cpus);
+      mem = resources.getScalar("mem", mem);
+
       state::Task *task =
         new state::Task(t->task_id().value(), t->name(),
                         TaskState_descriptor()->FindValueByNumber(t->state())->name(),
-                        t->resources().cpus(), t->resources().mem());
+                        cpus.value(), mem.value());
+
       framework->tasks.push_back(task);
     }
   }
@@ -122,6 +132,11 @@ void Slave::operator () ()
 {
   LOG(INFO) << "Slave started at " << self();
 
+  resources =
+    Resources::parse(conf.get<string>("resources", "cpus:1;mem:1024"));
+
+  LOG(INFO) << "Resources:\n" << resources;
+
   // Get our hostname
   char buf[256];
   gethostname(buf, sizeof(buf));
@@ -139,7 +154,7 @@ void Slave::operator () ()
   SlaveInfo slave;
   slave.set_hostname(hostname);
   slave.set_public_hostname(public_hostname);
-  *slave.mutable_resources() = resources;
+  slave.mutable_resources()->MergeFrom(resources);
 
   // Initialize isolation module.
   isolationModule->initialize(this);
@@ -158,17 +173,17 @@ void Slave::operator () ()
 	if (slaveId == "") {
 	  // Slave started before master.
           Message<S2M_REGISTER_SLAVE> out;
-          *out.mutable_slave() = slave;
+          out.mutable_slave()->MergeFrom(slave);
 	  send(master, out);
 	} else {
 	  // Re-registering, so send tasks running.
           Message<S2M_REREGISTER_SLAVE> out;
-          *out.mutable_slave_id() = slaveId;
-          *out.mutable_slave() = slave;
+          out.mutable_slave_id()->MergeFrom(slaveId);
+          out.mutable_slave()->MergeFrom(slave);
 
 	  foreachpair(_, Framework *framework, frameworks) {
 	    foreachpair(_, Task *task, framework->tasks) {
-              *out.add_task() = *task;
+              out.add_task()->MergeFrom(*task);
 	    }
 	  }
 
@@ -237,18 +252,17 @@ void Slave::operator () ()
         }
 
         // Create a local task.
-        Task *t = framework->addTask(task, msg.resources());
+        Task *t = framework->addTask(task);
 
         // Either send the task to an executor or queue the task until
         // the executor has started.
         Executor *executor = getExecutor(msg.framework_id());
         if (executor != NULL) {
           Message<S2E_RUN_TASK> out;
-          *out.mutable_framework() = framework->info;
-          *out.mutable_framework_id() = framework->frameworkId;
+          out.mutable_framework()->MergeFrom(framework->info);
+          out.mutable_framework_id()->MergeFrom(framework->frameworkId);
           out.set_pid(framework->pid);
-          *out.mutable_task() = task;
-          *out.mutable_resources() = resources;
+          out.mutable_task()->MergeFrom(task);
           send(executor->pid, out);
           isolationModule->resourcesChanged(framework);
         } else {
@@ -271,8 +285,8 @@ void Slave::operator () ()
 	  Executor* executor = getExecutor(msg.framework_id());
 	  if (executor != NULL) {
 	    Message<S2E_KILL_TASK> out;
-	    *out.mutable_framework_id() = msg.framework_id();
-	    *out.mutable_task_id() = msg.task_id();
+	    out.mutable_framework_id()->MergeFrom(msg.framework_id());
+	    out.mutable_task_id()->MergeFrom(msg.task_id());
 	    send(executor->pid, out);
 	  } else {
 	    // Update the resources locally, if an executor comes up
@@ -281,10 +295,10 @@ void Slave::operator () ()
 	    isolationModule->resourcesChanged(framework);
 
 	    Message<S2M_STATUS_UPDATE> out;
-	    *out.mutable_framework_id() = msg.framework_id();
+	    out.mutable_framework_id()->MergeFrom(msg.framework_id());
 	    TaskStatus *status = out.mutable_status();
-	    *status->mutable_task_id() = msg.task_id();
-	    *status->mutable_slave_id() = slaveId;
+	    status->mutable_task_id()->MergeFrom(msg.task_id());
+	    status->mutable_slave_id()->MergeFrom(slaveId);
 	    status->set_state(TASK_LOST);
 
 	    int seq = rsend(master, framework->pid, out);
@@ -295,12 +309,12 @@ void Slave::operator () ()
 		     << " of framework " << msg.framework_id()
 		     << " because no such framework is running";
 
-	  Message<S2M_STATUS_UPDATE> out;
-	  *out.mutable_framework_id() = msg.framework_id();
-	  TaskStatus *status = out.mutable_status();
-	  *status->mutable_task_id() = msg.task_id();
-	  *status->mutable_slave_id() = slaveId;
-	  status->set_state(TASK_LOST);
+          Message<S2M_STATUS_UPDATE> out;
+	  out.mutable_framework_id()->MergeFrom(msg.framework_id());
+          TaskStatus *status = out.mutable_status();
+          status->mutable_task_id()->MergeFrom(msg.task_id());
+          status->mutable_slave_id()->MergeFrom(slaveId);
+          status->set_state(TASK_LOST);
 
 	  int seq = rsend(master, out);
 	  seqs[msg.framework_id()].insert(seq);
@@ -327,8 +341,8 @@ void Slave::operator () ()
         Executor* executor = getExecutor(msg.framework_id());
         if (executor != NULL) {
           Message<S2E_FRAMEWORK_MESSAGE> out;
-          *out.mutable_framework_id() = msg.framework_id();
-          *out.mutable_message() = message;
+          out.mutable_framework_id()->MergeFrom(msg.framework_id());
+          out.mutable_message()->MergeFrom(message);
           send(executor->pid, out);
         } else {
           VLOG(1) << "Dropping framework message for framework "
@@ -378,9 +392,9 @@ void Slave::operator () ()
           // Tell executor that it's registered and give it its queued tasks
           Message<S2E_REGISTER_REPLY> out;
           ExecutorArgs* args = out.mutable_args();
-          *args->mutable_framework_id() = framework->frameworkId;
+          args->mutable_framework_id()->MergeFrom(framework->frameworkId);
           args->set_name(framework->info.name());
-          *args->mutable_slave_id() = slaveId;
+          args->mutable_slave_id()->MergeFrom(slaveId);
           args->set_hostname(hostname);
           args->set_data(framework->info.executor().data());
           send(executor->pid, out);
@@ -415,8 +429,8 @@ void Slave::operator () ()
 	  // Reliably send message and save sequence number for
 	  // canceling later.
           Message<S2M_STATUS_UPDATE> out;
-          *out.mutable_framework_id() = msg.framework_id();
-          *out.mutable_status() = status;
+          out.mutable_framework_id()->MergeFrom(msg.framework_id());
+          out.mutable_status()->MergeFrom(status);
 	  int seq = rsend(master, framework->pid, out);
 	  seqs[msg.framework_id()].insert(seq);
 	} else {
@@ -439,9 +453,9 @@ void Slave::operator () ()
 
           // TODO(benh): This is weird, sending an M2F message.
           Message<M2F_FRAMEWORK_MESSAGE> out;
-          *out.mutable_framework_id() = msg.framework_id();
-          *out.mutable_message() = message;
-          *out.mutable_message()->mutable_slave_id() = slaveId;
+          out.mutable_framework_id()->MergeFrom(msg.framework_id());
+          out.mutable_message()->MergeFrom(message);
+          out.mutable_message()->mutable_slave_id()->MergeFrom(slaveId);
           send(framework->pid, out);
         }
         break;
@@ -521,11 +535,10 @@ void Slave::sendQueuedTasks(Framework* f
 
   foreach(const TaskDescription& task, framework->queuedTasks) {
     Message<S2E_RUN_TASK> out;
-    *out.mutable_framework() = framework->info;
-    *out.mutable_framework_id() = framework->frameworkId;
+    out.mutable_framework()->MergeFrom(framework->info);
+    out.mutable_framework_id()->MergeFrom(framework->frameworkId);
     out.set_pid(framework->pid);
-    *out.mutable_task() = task;
-    *out.mutable_resources() = resources;
+    out.mutable_task()->MergeFrom(task);
     send(executor->pid, out);
   }
 
@@ -586,8 +599,8 @@ void Slave::executorExited(const Framewo
               << "with status " << status;
 
     Message<S2M_EXITED_EXECUTOR> out;
-    *out.mutable_slave_id() = slaveId;
-    *out.mutable_framework_id() = frameworkId;
+    out.mutable_slave_id()->MergeFrom(slaveId);
+    out.mutable_framework_id()->MergeFrom(frameworkId);
     out.set_status(status);
     send(master, out);
 

Modified: incubator/mesos/trunk/src/slave/slave.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/slave/slave.hpp?rev=1132231&r1=1132230&r2=1132231&view=diff
==============================================================================
--- incubator/mesos/trunk/src/slave/slave.hpp (original)
+++ incubator/mesos/trunk/src/slave/slave.hpp Sun Jun  5 09:04:47 2011
@@ -33,6 +33,7 @@
 
 #include "common/fatal.hpp"
 #include "common/foreach.hpp"
+#include "common/resources.hpp"
 #include "common/type_utils.hpp"
 
 #include "configurator/configurator.hpp"
@@ -98,7 +99,7 @@ struct Framework
       return NULL;
   }
 
-  Task * addTask(const TaskDescription& task, const Resources& r)
+  Task * addTask(const TaskDescription& task)
   {
     // The master should enforce unique task IDs, but just in case
     // maybe we shouldn't make this a fatal error.
@@ -106,14 +107,14 @@ struct Framework
 
     Task *t = new Task();
     t->set_name(task.name());
-    *t->mutable_task_id() = task.task_id();
-    *t->mutable_framework_id() = frameworkId;
-    *t->mutable_slave_id() = task.slave_id();
-    *t->mutable_resources() = r;
+    t->mutable_task_id()->MergeFrom(task.task_id());
+    t->mutable_framework_id()->MergeFrom(frameworkId);
+    t->mutable_slave_id()->MergeFrom(task.slave_id());
+    t->mutable_resources()->MergeFrom(task.resources());
     t->set_state(TASK_STARTING);
 
     tasks[task.task_id()] = t;
-    resources += r;
+    resources += task.resources();
 
     return t;
   }
@@ -129,12 +130,14 @@ struct Framework
       }
     }
 
-    // Remove it from tasks as well
-    unordered_map<TaskID, Task *>::iterator it = tasks.find(taskId);
-    if (it != tasks.end()) {
-      resources -= it->second->resources();
-      delete it->second;
-      tasks.erase(it);
+    // Remove it from tasks as well.
+    if (tasks.count(taskId) > 0) {
+      Task* task = tasks[taskId];
+      foreach (const Resource& resource, task->resources()) {
+        resources -= resource;
+      }
+      tasks.erase(taskId);
+      delete task;
     }
   }
 };
@@ -168,7 +171,7 @@ protected:
       switch (receive(interval)) {
         case PROCESS_TIMEOUT: {
           Message<SH2M_HEARTBEAT> msg;
-          *msg.mutable_slave_id() = slaveId;
+          msg.mutable_slave_id()->MergeFrom(slaveId);
           send(master, msg);
           break;
         }

Modified: incubator/mesos/trunk/src/tests/master_test.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/master_test.cpp?rev=1132231&r1=1132230&r2=1132231&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/master_test.cpp (original)
+++ incubator/mesos/trunk/src/tests/master_test.cpp Sun Jun  5 09:04:47 2011
@@ -120,13 +120,9 @@ TEST(MasterTest, ResourceOfferWithMultip
   EXPECT_NE(0, offers.size());
   EXPECT_GE(10, offers.size());
 
-  for (int i = 0; i < offers[0].params().param_size(); i++) {
-    if (offers[0].params().param(i).key() == "cpus") {
-      EXPECT_EQ("2", offers[0].params().param(i).value());
-    } else if (offers[0].params().param(i).key() == "mem") {
-      EXPECT_EQ("1024", offers[0].params().param(i).value());
-    }
-  }
+  Resources resources(offers[0].resources());
+  EXPECT_EQ(2, resources.getScalar("cpus", Resource::Scalar()).value());
+  EXPECT_EQ(1024, resources.getScalar("mem", Resource::Scalar()).value());
 
   driver.stop();
   driver.join();
@@ -236,17 +232,17 @@ TEST(MasterTest, ResourcesReofferedAfter
   TaskDescription task;
   task.set_name("");
   task.mutable_task_id()->set_value("1");
-  *task.mutable_slave_id() = offers[0].slave_id();
+  task.mutable_slave_id()->MergeFrom(offers[0].slave_id());
 
-  Params* params = task.mutable_params();
-
-  Param* cpus = params->add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("0");
-
-  Param* mem = params->add_param();
-  mem->set_key("mem");
-  mem->set_value(lexical_cast<string>(1 * Gigabyte));
+  Resource* cpus = task.add_resources();
+  cpus->set_name("cpus");
+  cpus->set_type(Resource::SCALAR);
+  cpus->mutable_scalar()->set_value(0);
+
+  Resource* mem = task.add_resources();
+  mem->set_name("mem");
+  mem->set_type(Resource::SCALAR);
+  mem->mutable_scalar()->set_value(1 * Gigabyte);
 
   vector<TaskDescription> tasks;
   tasks.push_back(task);
@@ -254,7 +250,7 @@ TEST(MasterTest, ResourcesReofferedAfter
   trigger sched1ErrorCall;
 
   EXPECT_CALL(sched1,
-              error(&driver1, _, "Invalid task size: <0 CPUs, 1024 MEM>"))
+              error(&driver1, _, "Invalid resources for task"))
     .WillOnce(Trigger(&sched1ErrorCall));
 
   EXPECT_CALL(sched1, offerRescinded(&driver1, offerId))
@@ -306,10 +302,22 @@ TEST(MasterTest, SlaveLost)
   PID master = Process::spawn(&m);
 
   Resources resources;
-  resources.set_cpus(2);
-  resources.set_mem(1 * Gigabyte);
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(2);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
 
   ProcessBasedIsolationModule isolationModule;
+  
   Slave s(resources, true, &isolationModule);
   PID slave = Process::spawn(&s);
 
@@ -506,6 +514,21 @@ TEST(MasterTest, TaskRunning)
   Master m;
   PID master = Process::spawn(&m);
 
+  Resources resources;
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(2);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
+
   MockExecutor exec;
 
   EXPECT_CALL(exec, init(_, _))
@@ -517,10 +540,6 @@ TEST(MasterTest, TaskRunning)
   EXPECT_CALL(exec, shutdown(_))
     .Times(1);
 
-  Resources resources;
-  resources.set_cpus(2);
-  resources.set_mem(1 * Gigabyte);
-
   LocalIsolationModule isolationModule(&exec);
 
   Slave s(resources, true, &isolationModule);
@@ -562,8 +581,8 @@ TEST(MasterTest, TaskRunning)
   TaskDescription task;
   task.set_name("");
   task.mutable_task_id()->set_value("1");
-  *task.mutable_slave_id() = offers[0].slave_id();
-  *task.mutable_params() = offers[0].params();
+  task.mutable_slave_id()->MergeFrom(offers[0].slave_id());
+  task.mutable_resources()->MergeFrom(offers[0].resources());
 
   vector<TaskDescription> tasks;
   tasks.push_back(task);
@@ -592,6 +611,21 @@ TEST(MasterTest, KillTask)
   Master m;
   PID master = Process::spawn(&m);
 
+  Resources resources;
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(2);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
+
   MockExecutor exec;
 
   trigger killTaskCall;
@@ -608,10 +642,6 @@ TEST(MasterTest, KillTask)
   EXPECT_CALL(exec, shutdown(_))
     .Times(1);
 
-  Resources resources;
-  resources.set_cpus(2);
-  resources.set_mem(1 * Gigabyte);
-
   LocalIsolationModule isolationModule(&exec);
 
   Slave s(resources, true, &isolationModule);
@@ -655,9 +685,9 @@ TEST(MasterTest, KillTask)
 
   TaskDescription task;
   task.set_name("");
-  *task.mutable_task_id() = taskId;
-  *task.mutable_slave_id() = offers[0].slave_id();
-  *task.mutable_params() = offers[0].params();
+  task.mutable_task_id()->MergeFrom(taskId);
+  task.mutable_slave_id()->MergeFrom(offers[0].slave_id());
+  task.mutable_resources()->MergeFrom(offers[0].resources());
 
   vector<TaskDescription> tasks;
   tasks.push_back(task);
@@ -695,6 +725,24 @@ TEST(MasterTest, SchedulerFailoverStatus
   EXPECT_MSG(filter, _, _, _)
     .WillRepeatedly(Return(false));
 
+  Master m;
+  PID master = Process::spawn(&m);
+
+  Resources resources;
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(2);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
+
   MockExecutor exec;
 
   EXPECT_CALL(exec, init(_, _))
@@ -706,13 +754,6 @@ TEST(MasterTest, SchedulerFailoverStatus
   EXPECT_CALL(exec, shutdown(_))
     .Times(1);
 
-  Master m;
-  PID master = Process::spawn(&m);
-
-  Resources resources;
-  resources.set_cpus(2);
-  resources.set_mem(1 * Gigabyte);
-
   LocalIsolationModule isolationModule(&exec);
 
   Slave s(resources, true, &isolationModule);
@@ -764,8 +805,8 @@ TEST(MasterTest, SchedulerFailoverStatus
   TaskDescription task;
   task.set_name("");
   task.mutable_task_id()->set_value("1");
-  *task.mutable_slave_id() = offers[0].slave_id();
-  *task.mutable_params() = offers[0].params();
+  task.mutable_slave_id()->MergeFrom(offers[0].slave_id());
+  task.mutable_resources()->MergeFrom(offers[0].resources());
 
   vector<TaskDescription> tasks;
   tasks.push_back(task);
@@ -826,6 +867,24 @@ TEST(MasterTest, FrameworkMessage)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
 
+  Master m;
+  PID master = Process::spawn(&m);
+
+  Resources resources;
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(2);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
+
   MockExecutor exec;
 
   ExecutorDriver* execDriver;
@@ -847,13 +906,6 @@ TEST(MasterTest, FrameworkMessage)
   EXPECT_CALL(exec, shutdown(_))
     .Times(1);
 
-  Master m;
-  PID master = Process::spawn(&m);
-
-  Resources resources;
-  resources.set_cpus(2);
-  resources.set_mem(1 * Gigabyte);
-
   LocalIsolationModule isolationModule(&exec);
 
   Slave s(resources, true, &isolationModule);
@@ -903,8 +955,8 @@ TEST(MasterTest, FrameworkMessage)
   TaskDescription task;
   task.set_name("");
   task.mutable_task_id()->set_value("1");
-  *task.mutable_slave_id() = offers[0].slave_id();
-  *task.mutable_params() = offers[0].params();
+  task.mutable_slave_id()->MergeFrom(offers[0].slave_id());
+  task.mutable_resources()->MergeFrom(offers[0].resources());
 
   vector<TaskDescription> tasks;
   tasks.push_back(task);
@@ -950,6 +1002,24 @@ TEST(MasterTest, SchedulerFailoverFramew
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
 
+  Master m;
+  PID master = Process::spawn(&m);
+
+  Resources resources;
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(2);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
+
   MockExecutor exec;
 
   ExecutorDriver* execDriver;
@@ -963,13 +1033,6 @@ TEST(MasterTest, SchedulerFailoverFramew
   EXPECT_CALL(exec, shutdown(_))
     .Times(1);
 
-  Master m;
-  PID master = Process::spawn(&m);
-
-  Resources resources;
-  resources.set_cpus(2);
-  resources.set_mem(1 * Gigabyte);
-
   LocalIsolationModule isolationModule(&exec);
 
   Slave s(resources, true, &isolationModule);
@@ -1015,8 +1078,8 @@ TEST(MasterTest, SchedulerFailoverFramew
   TaskDescription task;
   task.set_name("");
   task.mutable_task_id()->set_value("1");
-  *task.mutable_slave_id() = offers[0].slave_id();
-  *task.mutable_params() = offers[0].params();
+  task.mutable_slave_id()->MergeFrom(offers[0].slave_id());
+  task.mutable_resources()->MergeFrom(offers[0].resources());
 
   vector<TaskDescription> tasks;
   tasks.push_back(task);
@@ -1049,7 +1112,7 @@ TEST(MasterTest, SchedulerFailoverFramew
   WAIT_UNTIL(sched2RegisteredCall);
 
   FrameworkMessage message;
-  *message.mutable_slave_id() = offers[0].slave_id();
+  message.mutable_slave_id()->MergeFrom(offers[0].slave_id());
 
   execDriver->sendFrameworkMessage(message);
 

Modified: incubator/mesos/trunk/src/tests/offer_reply_errors_test.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/offer_reply_errors_test.cpp?rev=1132231&r1=1132230&r2=1132231&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/offer_reply_errors_test.cpp (original)
+++ incubator/mesos/trunk/src/tests/offer_reply_errors_test.cpp Sun Jun  5 09:04:47 2011
@@ -96,15 +96,20 @@ TEST(MasterTest, DuplicateTaskIdsInRespo
   DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
 
-  Params params;
+  Resources resources;
 
-  Param* cpus = params.add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("1");
-
-  Param* mem = params.add_param();
-  mem->set_key("mem");
-  mem->set_value(lexical_cast<string>(1 * Gigabyte));
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(1);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
 
   vector<TaskDescription> tasks;
 
@@ -112,7 +117,7 @@ TEST(MasterTest, DuplicateTaskIdsInRespo
   task.set_name("");
   task.mutable_task_id()->set_value("1");
   task.mutable_slave_id()->set_value("200102030405-0-0");
-  *task.mutable_params() = params;
+  task.mutable_resources()->MergeFrom(resources);
 
   tasks.push_back(task);
   tasks.push_back(task);
@@ -140,15 +145,20 @@ TEST(MasterTest, TooMuchMemoryInTask)
   DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
 
-  Params params;
+  Resources resources;
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(1);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(4 * Gigabyte);
 
-  Param* cpus = params.add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("1");
-
-  Param* mem = params.add_param();
-  mem->set_key("mem");
-  mem->set_value(lexical_cast<string>(4 * Gigabyte));
+  resources += cpus;
+  resources += mem;
 
   vector<TaskDescription> tasks;
 
@@ -156,7 +166,7 @@ TEST(MasterTest, TooMuchMemoryInTask)
   task.set_name("");
   task.mutable_task_id()->set_value("1");
   task.mutable_slave_id()->set_value("200102030405-0-0");
-  *task.mutable_params() = params;
+  task.mutable_resources()->MergeFrom(resources);
 
   tasks.push_back(task);
 
@@ -179,15 +189,20 @@ TEST(MasterTest, TooMuchCpuInTask)
   DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
 
-  Params params;
+  Resources resources;
 
-  Param* cpus = params.add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("4");
-
-  Param* mem = params.add_param();
-  mem->set_key("mem");
-  mem->set_value(lexical_cast<string>(1 * Gigabyte));
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(4);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
 
   vector<TaskDescription> tasks;
 
@@ -195,7 +210,7 @@ TEST(MasterTest, TooMuchCpuInTask)
   task.set_name("");
   task.mutable_task_id()->set_value("1");
   task.mutable_slave_id()->set_value("200102030405-0-0");
-  *task.mutable_params() = params;
+  task.mutable_resources()->MergeFrom(resources);
 
   tasks.push_back(task);
 
@@ -211,61 +226,27 @@ TEST(MasterTest, TooMuchCpuInTask)
 }
 
 
-TEST(MasterTest, TooLittleCpuInTask)
+TEST(MasterTest, ZeroCpuInTask)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
 
   DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
 
-  Params params;
-
-  Param* cpus = params.add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("0");
-
-  Param* mem = params.add_param();
-  mem->set_key("mem");
-  mem->set_value(lexical_cast<string>(1 * Gigabyte));
-
-  vector<TaskDescription> tasks;
-
-  TaskDescription task;
-  task.set_name("");
-  task.mutable_task_id()->set_value("1");
-  task.mutable_slave_id()->set_value("200102030405-0-0");
-  *task.mutable_params() = params;
-
-  tasks.push_back(task);
-
-  FixedResponseScheduler sched(tasks);
-  MesosSchedulerDriver driver(&sched, master);
-
-  driver.run();
-
-  EXPECT_EQ("Invalid task size: <0 CPUs, 1024 MEM>", sched.errorMessage);
-
-  local::shutdown();
-  DateUtils::clearMockDate();
-}
-
+  Resources resources;
 
-TEST(MasterTest, TooLittleMemoryInTask)
-{
-  ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
-  DateUtils::setMockDate("200102030405");
-  PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
-
-  Params params;
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(0);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
 
-  Param* cpus = params.add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("1");
-
-  Param* mem = params.add_param();
-  mem->set_key("mem");
-  mem->set_value("1");
+  resources += cpus;
+  resources += mem;
 
   vector<TaskDescription> tasks;
 
@@ -273,7 +254,7 @@ TEST(MasterTest, TooLittleMemoryInTask)
   task.set_name("");
   task.mutable_task_id()->set_value("1");
   task.mutable_slave_id()->set_value("200102030405-0-0");
-  *task.mutable_params() = params;
+  task.mutable_resources()->MergeFrom(resources);
 
   tasks.push_back(task);
 
@@ -282,7 +263,7 @@ TEST(MasterTest, TooLittleMemoryInTask)
 
   driver.run();
 
-  EXPECT_EQ("Invalid task size: <1 CPUs, 1 MEM>", sched.errorMessage);
+  EXPECT_EQ("Invalid resources for task", sched.errorMessage);
 
   local::shutdown();
   DateUtils::clearMockDate();
@@ -296,15 +277,20 @@ TEST(MasterTest, TooMuchMemoryAcrossTask
   DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
 
-  Params params;
+  Resources resources;
 
-  Param* cpus = params.add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("1");
-
-  Param* mem = params.add_param();
-  mem->set_key("mem");
-  mem->set_value(lexical_cast<string>(2 * Gigabyte));
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(1);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(2 * Gigabyte);
+
+  resources += cpus;
+  resources += mem;
 
   vector<TaskDescription> tasks;
 
@@ -312,7 +298,7 @@ TEST(MasterTest, TooMuchMemoryAcrossTask
   task.set_name("");
   task.mutable_task_id()->set_value("1");
   task.mutable_slave_id()->set_value("200102030405-0-0");
-  *task.mutable_params() = params;
+  task.mutable_resources()->MergeFrom(resources);
 
   tasks.push_back(task);
 
@@ -339,15 +325,20 @@ TEST(MasterTest, TooMuchCpuAcrossTasks)
   DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
 
-  Params params;
+  Resources resources;
+
+  Resource cpus;
+  cpus.set_name("cpus");
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(2);
+
+  Resource mem;
+  mem.set_name("mem");
+  mem.set_type(Resource::SCALAR);
+  mem.mutable_scalar()->set_value(1 * Gigabyte);
 
-  Param* cpus = params.add_param();
-  cpus->set_key("cpus");
-  cpus->set_value("2");
-
-  Param* mem = params.add_param();
-  mem->set_key("mem");
-  mem->set_value(lexical_cast<string>(1 * Gigabyte));
+  resources += cpus;
+  resources += mem;
 
   vector<TaskDescription> tasks;
 
@@ -355,7 +346,7 @@ TEST(MasterTest, TooMuchCpuAcrossTasks)
   task.set_name("");
   task.mutable_task_id()->set_value("1");
   task.mutable_slave_id()->set_value("200102030405-0-0");
-  *task.mutable_params() = params;
+  task.mutable_resources()->MergeFrom(resources);
 
   tasks.push_back(task);
 

Modified: incubator/mesos/trunk/src/tests/resources_test.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/resources_test.cpp?rev=1132231&r1=1132230&r2=1132231&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/resources_test.cpp (original)
+++ incubator/mesos/trunk/src/tests/resources_test.cpp Sun Jun  5 09:04:47 2011
@@ -12,62 +12,309 @@ using namespace mesos::internal::master;
 using std::ostringstream;
 
 
-TEST(ResourcesTest, InitializedWithZero)
+TEST(ResourcesTest, Parsing)
 {
+  Resource cpus = Resources::parse("cpus", "45.55");
+  ASSERT_EQ(Resource::SCALAR, cpus.type());
+  EXPECT_EQ(45.55, cpus.scalar().value());
+
+  Resource ports = Resources::parse("ports", "[10000-20000, 30000-50000]");
+  ASSERT_EQ(Resource::RANGES, ports.type());
+  EXPECT_EQ(2, ports.ranges().range_size());
+
+  Resource disks = Resources::parse("disks", "{sda1}");
+  ASSERT_EQ(Resource::SET, disks.type());
+  ASSERT_EQ(1, disks.set().item_size());
+  EXPECT_EQ("sda1", disks.set().item(0));
+
+  Resources r1 = Resources::parse("cpus:45.55;"
+                                  "ports:[10000-20000, 30000-50000];"
+                                  "disks:{sda1}");
+
+  Resources r2;
+  r2 += cpus;
+  r2 += ports;
+  r2 += disks;
+
+  EXPECT_EQ(r1, r2);
+}
+
+
+TEST(ResourcesTest, Printing)
+{
+  Resources r = Resources::parse("cpus:45.55;"
+                                 "ports:[10000-20000, 30000-50000];"
+                                 "disks:{sda1}");
+
+  string output = "cpus=45.55; ports=[10000-20000, 30000-50000]; disks={sda1}";
+
+  ostringstream oss;
+  oss << r;
+
+  // TODO(benh): This test is a bit strict because it implies the
+  // ordering of things (e.g., the ordering of resources and the
+  // ordering of ranges). We should really just be checking for the
+  // existance of certain substrings in the output.
+
+  EXPECT_EQ(output, oss.str());
+}
+
+
+TEST(ResourcesTest, InitializedIsEmpty)
+{
+  Resources r;
+  EXPECT_EQ(0, r.size());
+}
+
+
+TEST(ResourcesTest, BadResourcesNotAllocatable)
+{
+  Resource cpus;
+  cpus.set_type(Resource::SCALAR);
+  cpus.mutable_scalar()->set_value(1);
   Resources r;
-  EXPECT_EQ(0, r.cpus());
-  EXPECT_EQ(0, r.mem());
+  r += cpus;
+  EXPECT_EQ(0, r.allocatable().size());
+  cpus.set_name("cpus");
+  cpus.mutable_scalar()->set_value(0);
+  r += cpus;
+  EXPECT_EQ(0, r.allocatable().size());
+}
+
+
+TEST(ResourcesTest, ScalarEquals)
+{
+  Resource cpus = Resources::parse("cpus", "3");
+  Resource mem =  Resources::parse("mem", "3072");
+
+  Resources r1;
+  r1 += cpus;
+  r1 += mem;
+
+  Resources r2;
+  r2 += cpus;
+  r2 += mem;
+
+  EXPECT_EQ(2, r1.size());
+  EXPECT_EQ(2, r2.size());
+  EXPECT_EQ(r1, r2);
+}
+
+
+TEST(ResourcesTest, ScalarSubset)
+{
+  Resource cpus1 = Resources::parse("cpus", "1");
+  Resource mem1 =  Resources::parse("mem", "3072");
+
+  Resource cpus2 = Resources::parse("cpus", "1");
+  Resource mem2 =  Resources::parse("mem", "4096");
+
+  Resources r1;
+  r1 += cpus1;
+  r1 += mem1;
+
+  Resources r2;
+  r2 += cpus2;
+  r2 += mem2;
+
+  EXPECT_TRUE(r1 <= r2);
+  EXPECT_FALSE(r2 <= r1);
 }
 
 
-TEST(ResourcesTest, Addition)
+TEST(ResourcesTest, ScalarAddition)
 {
+  Resource cpus1 = Resources::parse("cpus", "1");
+  Resource mem1 = Resources::parse("mem", "5");
+
+  Resource cpus2 = Resources::parse("cpus", "2");
+  Resource mem2 = Resources::parse("mem", "10");
+
   Resources r1;
-  r1.set_cpus(1);
-  r1.set_mem(5);
+  r1 += cpus1;
+  r1 += mem1;
+
   Resources r2;
-  r2.set_cpus(2);
-  r2.set_mem(10);
+  r2 += cpus2;
+  r2 += mem2;
+
   Resources sum = r1 + r2;
-  EXPECT_EQ(3, sum.cpus());
-  EXPECT_EQ(15, sum.mem());
-  Resources r;
-  r += r1;
-  EXPECT_EQ(1, r.cpus());
-  EXPECT_EQ(5, r.mem());
+  EXPECT_EQ(2, sum.size());
+  EXPECT_EQ(3, sum.getScalar("cpus", Resource::Scalar()).value());
+  EXPECT_EQ(15, sum.getScalar("mem", Resource::Scalar()).value());
+
+  Resources r = r1;
   r += r2;
-  EXPECT_EQ(3, r.cpus());
-  EXPECT_EQ(15, r.mem());
+  EXPECT_EQ(2, r.size());
+  EXPECT_EQ(3, r.getScalar("cpus", Resource::Scalar()).value());
+  EXPECT_EQ(15, r.getScalar("mem", Resource::Scalar()).value());
 }
 
 
-TEST(ResourcesTest, Subtraction)
+TEST(ResourcesTest, ScalarSubtraction)
 {
+  Resource cpus1 = Resources::parse("cpus", "50");
+  Resource mem1 = Resources::parse("mem", "4096");
+
+  Resource cpus2 = Resources::parse("cpus", "0.5");
+  Resource mem2 = Resources::parse("mem", "1024");
+
   Resources r1;
-  r1.set_cpus(1);
-  r1.set_mem(5);
+  r1 += cpus1;
+  r1 += mem1;
+
   Resources r2;
-  r2.set_cpus(2);
-  r2.set_mem(10);
-  Resources dif = r1 - r2;
-  EXPECT_EQ(-1, dif.cpus());
-  EXPECT_EQ(-5, dif.mem());
-  Resources r;
-  r -= r1;
-  EXPECT_EQ(-1, r.cpus());
-  EXPECT_EQ(-5, r.mem());
+  r2 += cpus2;
+  r2 += mem2;
+
+  Resources diff = r1 - r2;
+  EXPECT_EQ(2, diff.size());
+  EXPECT_EQ(49.5, diff.getScalar("cpus", Resource::Scalar()).value());
+  EXPECT_EQ(3072, diff.getScalar("mem", Resource::Scalar()).value());
+
+  Resources r = r1;
   r -= r2;
-  EXPECT_EQ(-3, r.cpus());
-  EXPECT_EQ(-15, r.mem());
+  EXPECT_EQ(49.5, diff.getScalar("cpus", Resource::Scalar()).value());
+  EXPECT_EQ(3072, diff.getScalar("mem", Resource::Scalar()).value());
+
+  r = r1;
+  r -= r1;
+  EXPECT_EQ(0, r.allocatable().size());
+}
+
+
+TEST(ResourcesTest, RangesEquals)
+{
+  Resource ports = Resources::parse("ports", "[20000-40000]");
+
+  Resources r1;
+  r1 += ports;
+
+  Resources r2;
+  r2 += ports;
+
+  EXPECT_EQ(r1, r2);
+}
+
+
+TEST(ResourcesTest, RangesSubset)
+{
+  Resource ports1 = Resources::parse("ports", "[20000-40000]");
+  Resource ports2 = Resources::parse("ports", "[20000-40000, 50000-60000]");
+
+  Resources r1;
+  r1 += ports1;
+
+  Resources r2;
+  r2 += ports2;
+
+  EXPECT_EQ(1, r1.size());
+  EXPECT_EQ(1, r2.size());
+  EXPECT_TRUE(r1 <= r2);
+  EXPECT_FALSE(r2 <= r1);
 }
 
 
-TEST(ResourcesTest, PrettyPrinting)
+TEST(ResourcesTest, RangesAddition)
 {
+  Resource ports1 = Resources::parse("ports", "[20000-40000, 21000-38000]");
+  Resource ports2 = Resources::parse("ports", "[30000-50000, 10000-20000]");
+
   Resources r;
-  r.set_cpus(3);
-  r.set_mem(1001001001);
-  ostringstream oss;
-  oss << r;
-  EXPECT_EQ("<3 CPUs, 1001001001 MEM>", oss.str());
+  r += ports1;
+  r += ports2;
+
+  EXPECT_EQ(1, r.size());
+
+  const Resource::Ranges& ranges = r.getRanges("ports", Resource::Ranges());
+
+  EXPECT_EQ(1, ranges.range_size());
+  EXPECT_EQ(10000, ranges.range(0).begin());
+  EXPECT_EQ(50000, ranges.range(0).end());
+}
+
+
+TEST(ResourcesTest, RangesSubtraction)
+{
+  Resource ports1 = Resources::parse("ports", "[20000-40000]");
+  Resource ports2 = Resources::parse("ports", "[10000-20000, 30000-50000]");
+
+  Resources r;
+  r += ports1;
+  r -= ports2;
+
+  EXPECT_EQ(1, r.size());
+
+  const Resource::Ranges& ranges = r.getRanges("ports", Resource::Ranges());
+
+  EXPECT_EQ(1, ranges.range_size());
+  EXPECT_EQ(20001, ranges.range(0).begin());
+  EXPECT_EQ(29999, ranges.range(0).end());
+}
+
+
+TEST(ResourcesTest, SetEquals)
+{
+  Resource disks = Resources::parse("disks", "{sda1}");
+
+  Resources r1;
+  r1 += disks;
+
+  Resources r2;
+  r2 += disks;
+
+  EXPECT_EQ(r1, r2);
+}
+
+
+TEST(ResourcesTest, SetSubset)
+{
+  Resource disks1 = Resources::parse("disks", "{sda1,sda2}");
+  Resource disks2 = Resources::parse("disks", "{sda1,sda2,sda3,sda4}");
+
+  Resources r1;
+  r1 += disks1;
+
+  Resources r2;
+  r2 += disks2;
+
+  EXPECT_EQ(1, r1.size());
+  EXPECT_EQ(1, r2.size());
+  EXPECT_TRUE(r1 <= r2);
+  EXPECT_FALSE(r2 <= r1);
+}
+
+
+TEST(ResourcesTest, SetAddition)
+{
+  Resource disks1 = Resources::parse("disks", "{sda1,sda2,sda3}");
+  Resource disks2 = Resources::parse("disks", "{sda1,sda2,sda3,sda4}");
+
+  Resources r;
+  r += disks1;
+  r += disks2;
+
+  EXPECT_EQ(1, r.size());
+
+  const Resource::Set& set = r.getSet("disks", Resource::Set());
+
+  EXPECT_EQ(4, set.item_size());
+}
+
+
+TEST(ResourcesTest, SetSubtraction)
+{
+  Resource disks1 = Resources::parse("disks", "{sda1,sda2,sda3,sda4}");
+  Resource disks2 = Resources::parse("disks", "{sda2,sda3,sda4}");
+
+  Resources r;
+  r += disks1;
+  r -= disks2;
+
+  EXPECT_EQ(1, r.size());
+
+  const Resource::Set& set = r.getSet("disks", Resource::Set());
+
+  EXPECT_EQ(1, set.item_size());
+  EXPECT_EQ("sda1", set.item(0));
 }

Modified: incubator/mesos/trunk/src/tests/utils.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/utils.hpp?rev=1132231&r1=1132230&r2=1132231&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/utils.hpp (original)
+++ incubator/mesos/trunk/src/tests/utils.hpp Sun Jun  5 09:04:47 2011
@@ -149,7 +149,8 @@ ACTION_P(Trigger, trigger) { trigger->va
         break;                                                          \
       usleep(10);                                                       \
       if (sleeps++ >= 200000) {                                         \
-        ADD_FAILURE() << "Waited too long for trigger!";                \
+        FAIL() << "Waited too long for trigger!";                       \
+        abort; /* TODO(benh): Don't abort here ... */                   \
         break;                                                          \
       }                                                                 \
     } while (true);                                                     \