From 9e29cdc777eb602e799e0d70f1e11933bdff25d5 Mon Sep 17 00:00:00 2001 From: Kenichi Maehashi Date: Thu, 24 Sep 2015 20:47:18 +0900 Subject: [PATCH] add interface to specify YARN application name --- .../yarn/client/JubatusYarnApplication.scala | 93 +++++++++++++++++-- .../yarn/client/YarnClientController.scala | 12 ++- .../src/test/resources/.gitignore | 2 + .../src/test/resources/core-site.xml.dist | 22 +++++ .../src/test/resources/jubatus_config.json | 1 + .../src/test/resources/yarn-site.xml.dist | 53 +++++++++++ .../client/JubatusYarnApplicationSpec.scala | 91 ++++++++++++++++++ .../client/YarnClientControllerSpec.scala | 27 +++++- 8 files changed, 288 insertions(+), 13 deletions(-) create mode 100644 jubatusonyarn/jubatus-on-yarn-client/src/test/resources/.gitignore create mode 100644 jubatusonyarn/jubatus-on-yarn-client/src/test/resources/core-site.xml.dist create mode 100644 jubatusonyarn/jubatus-on-yarn-client/src/test/resources/jubatus_config.json create mode 100644 jubatusonyarn/jubatus-on-yarn-client/src/test/resources/yarn-site.xml.dist create mode 100644 jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/JubatusYarnApplicationSpec.scala diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/JubatusYarnApplication.scala b/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/JubatusYarnApplication.scala index fc38759..6d5c855 100644 --- a/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/JubatusYarnApplication.scala +++ b/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/JubatusYarnApplication.scala @@ -85,7 +85,45 @@ object JubatusYarnApplication extends HasLogger { * @return [[JubatusYarnApplication]] */ def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodeCount: Int): Future[JubatusYarnApplication] = { - start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, new Path("hdfs:///jubatus-on-yarn")) + start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, new Path("hdfs:///jubatus-on-yarn"), null) + } + + /** + * JubatusYarnApplication を起動します。 + * + * juba${aLearningMachineType_proxy} がひとつ, juba${aLearningMachineType} が ${aNodeCount} だけ起動します。 + * 各 juba${aLearningMachineType} の使用するリソースを ${aResource} に指定してください。 + * + * @param aLearningMachineName learning machine name + * @param aLearningMachineType learning machine type + * @param aZookeepers ZooKeeper locations + * @param aConfigString config json string + * @param aResource computer resources in the cluster + * @param aNodeCount number of cluster + * @param aApplicationName yarn-application name + * @return [[JubatusYarnApplication]] + */ + def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodeCount: Int, aApplicationName: String): Future[JubatusYarnApplication] = { + start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, new Path("hdfs:///jubatus-on-yarn"), aApplicationName) + } + + /** + * JubatusYarnApplication を起動します。 + * + * juba${aLearningMachineType_proxy} がひとつ, juba${aLearningMachineType} が ${aNodeCount} だけ起動します。 + * 各 juba${aLearningMachineType} の使用するリソースを ${aResource} に指定してください。 + * + * @param aLearningMachineName learning machine name + * @param aLearningMachineType learning machine type + * @param aZookeepers ZooKeeper locations + * @param aConfigString config json string + * @param aResource computer resources in the cluster + * @param aNodeCount number of cluster + * @param aBasePath base path of jar and sh files + * @return [[JubatusYarnApplication]] + */ + def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodeCount: Int, aBasePath: Path): Future[JubatusYarnApplication] = { + start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, aBasePath, null) } /** @@ -101,9 +139,10 @@ object JubatusYarnApplication extends HasLogger { * @param aResource computer resources in the cluster * @param aNodeCount number of cluster * @param aBasePath base path of jar and sh files + * @param aApplicationName yarn-application name * @return [[JubatusYarnApplication]] */ - def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodeCount: Int, aBasePath: Path): Future[JubatusYarnApplication] = Future { + def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodeCount: Int, aBasePath: Path, aApplicationName: String): Future[JubatusYarnApplication] = Future { require(aResource.memory > 0, "specify memory than 1MB.") require(aNodeCount > 0, "specify node count than 1") @@ -114,8 +153,8 @@ object JubatusYarnApplication extends HasLogger { case None => throw new IllegalStateException("Service not running.") case Some(tYarnClientController) => // ApplicationMaster 起動 - logger.info(s"startJubatusApplication $aLearningMachineName, $aLearningMachineType, $aZookeepers, $aConfigString, $aResource, $aNodeCount") - val tApplicationMasterProxy = tYarnClientController.startJubatusApplication(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, aBasePath) + logger.info(s"startJubatusApplication $aLearningMachineName, $aLearningMachineType, $aZookeepers, $aConfigString, $aResource, $aNodeCount, $aApplicationName") + val tApplicationMasterProxy = tYarnClientController.startJubatusApplication(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, aBasePath, aApplicationName) waitForStarted(ApplicationContext(tYarnClientController, tApplicationMasterProxy, tService)) } } @@ -135,7 +174,44 @@ object JubatusYarnApplication extends HasLogger { * @return [[JubatusYarnApplication]] */ def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigFile: Path, aResource: Resource, aNodeCount: Int): Future[JubatusYarnApplication] = { - start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, new Path("hdfs:///jubatus-on-yarn")) + start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, new Path("hdfs:///jubatus-on-yarn"), null) + } + + /** + * JubatusYarnApplication を起動します。 + * + * juba${aLearningMachineType_proxy} がひとつ, juba${aLearningMachineType} が ${aNodeCount} だけ起動します。 + * 各 juba${aLearningMachineType} の使用するリソースを ${aResource} に指定してください。 + * + * @param aLearningMachineName learning machine name + * @param aLearningMachineType learning machine type + * @param aZookeepers ZooKeeper locations + * @param aConfigFile config file + * @param aResource computer resources in the cluster + * @param aNodeCount number of cluster + * @param aApplicationName yarn-application name + * @return [[JubatusYarnApplication]] + */ + def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigFile: Path, aResource: Resource, aNodeCount: Int, aApplicationName: String): Future[JubatusYarnApplication] = { + start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, new Path("hdfs:///jubatus-on-yarn"), aApplicationName) + } + + /** + * JubatusYarnApplication を起動します。 + * + * juba${aLearningMachineType_proxy} がひとつ, juba${aLearningMachineType} が ${aNodeCount} だけ起動します。 + * 各 juba${aLearningMachineType} の使用するリソースを ${aResource} に指定してください。 + * + * @param aLearningMachineName learning machine name + * @param aLearningMachineType learning machine type + * @param aZookeepers ZooKeeper locations + * @param aConfigFile config file + * @param aResource computer resources in the cluster + * @param aNodeCount number of cluster + * @return [[JubatusYarnApplication]] + */ + def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigFile: Path, aResource: Resource, aNodeCount: Int, aBasePath: Path): Future[JubatusYarnApplication] = { + start(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, aBasePath, null) } /** @@ -150,9 +226,10 @@ object JubatusYarnApplication extends HasLogger { * @param aConfigFile config file * @param aResource computer resources in the cluster * @param aNodeCount number of cluster + * @param aApplicationName yarn-application name * @return [[JubatusYarnApplication]] */ - def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigFile: Path, aResource: Resource, aNodeCount: Int, aBasePath: Path): Future[JubatusYarnApplication] = Future { + def start(aLearningMachineName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigFile: Path, aResource: Resource, aNodeCount: Int, aBasePath: Path, aApplicationName: String): Future[JubatusYarnApplication] = Future { require(aResource.memory > 0, "specify memory than 1MB.") require(aNodeCount > 0, "specify node count than 1") @@ -163,8 +240,8 @@ object JubatusYarnApplication extends HasLogger { case None => throw new IllegalStateException("Service not running.") case Some(tYarnClientController) => // ApplicationMaster 起動 - logger.info(s"startJubatusApplication $aLearningMachineName, $aLearningMachineType, $aZookeepers, $aConfigFile, $aResource, $aNodeCount") - val tApplicationMasterProxy = tYarnClientController.startJubatusApplication(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, aBasePath) + logger.info(s"startJubatusApplication $aLearningMachineName, $aLearningMachineType, $aZookeepers, $aConfigFile, $aResource, $aNodeCount, $aApplicationName") + val tApplicationMasterProxy = tYarnClientController.startJubatusApplication(aLearningMachineName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, aBasePath, aApplicationName) waitForStarted(ApplicationContext(tYarnClientController, tApplicationMasterProxy, tService)) } } diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/YarnClientController.scala b/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/YarnClientController.scala index b55d614..2fd9b35 100644 --- a/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/YarnClientController.scala +++ b/jubatusonyarn/jubatus-on-yarn-client/src/main/scala/us/jubat/yarn/client/YarnClientController.scala @@ -47,7 +47,11 @@ class YarnClientController(location: Location, yarnClient: YarnClient = new Defa } def startJubatusApplication(aName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodeCount: Int, aBasePath: Path): ApplicationMasterProxy = { - val tFullName = getFullName(aName, aLearningMachineType, aZookeepers) + startJubatusApplication(aName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, aBasePath, null) + } + + def startJubatusApplication(aName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodeCount: Int, aBasePath: Path, aApplicationName: String): ApplicationMasterProxy = { + val tFullName = Option(aApplicationName).getOrElse(getFullName(aName, aLearningMachineType, aZookeepers)) logger.info(s"starting $tFullName") val tApplicationId = yarnClient.submitApplicationMaster(tFullName, aName, aLearningMachineType, aZookeepers, aConfigString, aResource, aNodeCount, location, aBasePath) @@ -56,7 +60,11 @@ class YarnClientController(location: Location, yarnClient: YarnClient = new Defa } def startJubatusApplication(aName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigFile: Path, aResource: Resource, aNodeCount: Int, aBasePath: Path): ApplicationMasterProxy = { - val tFullName = getFullName(aName, aLearningMachineType, aZookeepers) + startJubatusApplication(aName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, aBasePath, null) + } + + def startJubatusApplication(aName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigFile: Path, aResource: Resource, aNodeCount: Int, aBasePath: Path, aApplicationName: String): ApplicationMasterProxy = { + val tFullName = Option(aApplicationName).getOrElse(getFullName(aName, aLearningMachineType, aZookeepers)) logger.info(s"starting $tFullName") val tApplicationId = yarnClient.submitApplicationMaster(tFullName, aName, aLearningMachineType, aZookeepers, aConfigFile, aResource, aNodeCount, location, aBasePath) diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/.gitignore b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/.gitignore new file mode 100644 index 0000000..d4dc803 --- /dev/null +++ b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/.gitignore @@ -0,0 +1,2 @@ +core-site.xml +yarn-site.xml \ No newline at end of file diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/core-site.xml.dist b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/core-site.xml.dist new file mode 100644 index 0000000..68ab82a --- /dev/null +++ b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/core-site.xml.dist @@ -0,0 +1,22 @@ + + + + + + + + fs.defaultFS + hdfs://[host]:[port] + + + hadoop.proxyuser.mapred.groups + * + + + hadoop.proxyuser.mapred.hosts + * + + \ No newline at end of file diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/jubatus_config.json b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/jubatus_config.json new file mode 100644 index 0000000..f360a96 --- /dev/null +++ b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/jubatus_config.json @@ -0,0 +1 @@ +{"method":"AROW","parameter":{"regularization_weight":1.0},"converter":{"num_filter_types":{},"num_filter_rules":[],"string_filter_types":{},"string_filter_rules":[],"num_types":{},"num_rules":[{"key":"*","type":"num"}],"string_types":{"unigram":{"method":"ngram","char_num":"1"}},"string_rules":[{"key":"*","type":"unigram","sample_weight":"bin","global_weight":"bin"}]}} \ No newline at end of file diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/yarn-site.xml.dist b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/yarn-site.xml.dist new file mode 100644 index 0000000..59e4df2 --- /dev/null +++ b/jubatusonyarn/jubatus-on-yarn-client/src/test/resources/yarn-site.xml.dist @@ -0,0 +1,53 @@ + + + + + + + yarn.nodemanager.aux-services + mapreduce_shuffle + + + + yarn.nodemanager.aux-services.mapreduce_shuffle.class + org.apache.hadoop.mapred.ShuffleHandler + + + + yarn.log-aggregation-enable + true + + + + List of directories to store localized files in. + yarn.nodemanager.local-dirs + file:///var/lib/hadoop-yarn/cache/${user.name}/nm-local-dir + + + + Where to store container logs. + yarn.nodemanager.log-dirs + file:///var/log/hadoop-yarn/containers + + + + Classpath for typical applications. + yarn.application.classpath + + $HADOOP_CONF_DIR, + $HADOOP_COMMON_HOME/*,$HADOOP_COMMON_HOME/lib/*, + $HADOOP_HDFS_HOME/*,$HADOOP_HDFS_HOME/lib/*, + $HADOOP_MAPRED_HOME/*,$HADOOP_MAPRED_HOME/lib/*, + $HADOOP_YARN_HOME/*,$HADOOP_YARN_HOME/lib/* + + + \ No newline at end of file diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/JubatusYarnApplicationSpec.scala b/jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/JubatusYarnApplicationSpec.scala new file mode 100644 index 0000000..f56b186 --- /dev/null +++ b/jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/JubatusYarnApplicationSpec.scala @@ -0,0 +1,91 @@ +package us.jubat.yarn.client + +import org.scalatest._ +import us.jubat.yarn.common.Location +import us.jubat.yarn.common.LearningMachineType +import org.apache.hadoop.fs.Path +import scala.concurrent._ +import ExecutionContext.Implicits.global +import scala.util._ +import scala.concurrent.duration.Duration +import scala.sys.process.{Process, ProcessBuilder} +import org.apache.hadoop.conf.Configuration + +class JubatusYarnApplicationSpec extends FlatSpec with Matchers with BeforeAndAfterAll { + + val machineType = LearningMachineType.Classifier + val zookeeper = new Location("localhost", 2181) + val configString = """{"method":"AROW","parameter":{"regularization_weight":1.0},"converter":{"num_filter_types":{},"num_filter_rules":[],"string_filter_types":{},"string_filter_rules":[],"num_types":{},"num_rules":[{"key":"*","type":"num"}],"string_types":{"unigram":{"method":"ngram","char_num":"1"}},"string_rules":[{"key":"*","type":"unigram","sample_weight":"bin","global_weight":"bin"}]}}""" + val basePath = new Path("hdfs:///jubatus-on-yarn/") + val configPath = new Path("hdfs:///jubatus-on-yarn/test/jubatus_config.json") + + override def beforeAll(): Unit = { + //テストデータの配置 + val conf = new Configuration() + val fs = configPath.getFileSystem(conf) + if (!fs.exists(configPath)) { + val localPath = new Path("jubatus-on-yarn-client/src/test/resources/jubatus_config.json") + fs.copyFromLocalFile(localPath, configPath) + } + } + + // start()結果からアプリケーション名を取得する + private def getAppicationName(future: Future[JubatusYarnApplication]): String = { + var applicationName = "" + val result = future.andThen { + case Success(j) => + applicationName = j.status.yarnApplication.getName + j.kill() + case Failure(t) => + print("CREATE MODEL failed: " + t.getMessage) + t.printStackTrace() + } + Await.result(result, Duration.Inf) + return applicationName + } + + "start ()" should "check ApplicationName" in { + //config parameter is String + //specific paramter: No Path and No ApplicationName + var future = JubatusYarnApplication.start("model1", machineType, List(zookeeper), configString, Resource(1, 1, 1), 3) + var resultName = getAppicationName(future) + resultName shouldBe "model1:" + machineType.name + ":" + zookeeper.hostAddress + ":" + zookeeper.port + + //specific paramter: Path and No ApplicationName + future = JubatusYarnApplication.start("model2", machineType, List(zookeeper), configString, Resource(1, 1, 1), 3, basePath) + resultName = getAppicationName(future) + resultName shouldBe "model2:" + machineType.name + ":" + zookeeper.hostAddress + ":" + zookeeper.port + + //specific paramter: No Path and ApplicationName + future = JubatusYarnApplication.start("model3", machineType, List(zookeeper), configString, Resource(1, 1, 1), 3, "dummyApplicationName3") + resultName = getAppicationName(future) + resultName shouldBe "dummyApplicationName3" + + //specific paramter: Path and ApplicationName + future = JubatusYarnApplication.start("model4", machineType, List(zookeeper), configString, Resource(1, 1, 1), 3, basePath, "dummyApplicationName4") + resultName = getAppicationName(future) + resultName shouldBe "dummyApplicationName4" + + //config parameter is Path + //specific paramter: No Path and No ApplicationName + future = JubatusYarnApplication.start("model5", machineType, List(zookeeper), configPath, Resource(1, 1, 1), 3) + resultName = getAppicationName(future) + resultName shouldBe "model5:" + machineType.name + ":" + zookeeper.hostAddress + ":" + zookeeper.port + + //specific paramter: Path and No ApplicationName + future = JubatusYarnApplication.start("model6", machineType, List(zookeeper), configPath, Resource(1, 1, 1), 3, basePath) + resultName = getAppicationName(future) + resultName shouldBe "model6:" + machineType.name + ":" + zookeeper.hostAddress + ":" + zookeeper.port + + //specific paramter: No Path and ApplicationName + future = JubatusYarnApplication.start("model7", machineType, List(zookeeper), configPath, Resource(1, 1, 1), 3, "dummyApplicationName7") + resultName = getAppicationName(future) + resultName shouldBe "dummyApplicationName7" + + //specific paramter: Path and ApplicationName + future = JubatusYarnApplication.start("model8", machineType, List(zookeeper), configPath, Resource(1, 1, 1), 3, basePath, "dummyApplicationName8") + resultName = getAppicationName(future) + resultName shouldBe "dummyApplicationName8" + } + +} diff --git a/jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/YarnClientControllerSpec.scala b/jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/YarnClientControllerSpec.scala index e9b4b87..2463229 100644 --- a/jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/YarnClientControllerSpec.scala +++ b/jubatusonyarn/jubatus-on-yarn-client/src/test/scala/us/jubat/yarn/client/YarnClientControllerSpec.scala @@ -16,15 +16,15 @@ package us.jubat.yarn.client import java.net.InetAddress - import org.apache.hadoop.fs.Path import org.apache.hadoop.yarn.api.records.{FinalApplicationStatus, ApplicationReport, ApplicationId} import org.scalatest._ import us.jubat.yarn.common.{LearningMachineType, Location} -class YarnClientControllerSpec extends FlatSpec with Matchers { +class YarnClientControllerSpec extends FlatSpec with Matchers with BeforeAndAfter { class DummyYarnClient extends YarnClient { + override def submitApplicationMaster(aApplicationName: String, aLearningMachineInstanceName: String, aLearningMachineType: LearningMachineType, aZookeepers: List[Location], aConfigString: String, aResource: Resource, aNodes: Int, aManagementLocation: Location, aBasePath: Path): ApplicationId = { ApplicationId.newInstance(0, 0) } @@ -40,7 +40,28 @@ class YarnClientControllerSpec extends FlatSpec with Matchers { override def getFinalStatus(aApplicationId: ApplicationId): FinalApplicationStatus = ??? } - def createController() = new YarnClientController(Location(InetAddress.getLocalHost, 0), new DummyYarnClient) + def createController() = new YarnClientController(Location(InetAddress.getLocalHost, 0), new DummyYarnClient()) + + "startJubatusApplication ()" should "check applicationName" in { + + val machineType = LearningMachineType.Classifier + val zookeeper1 = new Location("localhost",2188) + val zookeeper2 = new Location("127.0.0.2",2189) + + val tController = createController() + + var result = tController.startJubatusApplication("model1", machineType, List(zookeeper1,zookeeper2), "configString", Resource(0, 0, 0), 3, null) + result.name shouldBe "model1:" + machineType.name + ":" + zookeeper1.hostAddress + ":" + zookeeper1.port + "," + zookeeper2.hostAddress + ":" + zookeeper2.port + + result = tController.startJubatusApplication("model2", machineType, List(zookeeper1,zookeeper2), "configString", Resource(0, 0, 0), 3, null, "dummyApplicationName2") + result.name shouldBe "dummyApplicationName2" + + result = tController.startJubatusApplication("model3", machineType, List(zookeeper1,zookeeper2), new Path("/tmp/dummyFile"), Resource(0, 0, 0), 3, null) + result.name shouldBe "model3:" + machineType.name + ":" + zookeeper1.hostAddress + ":" + zookeeper1.port + "," + zookeeper2.hostAddress + ":" + zookeeper2.port + + result = tController.startJubatusApplication("model4", machineType, List(zookeeper1,zookeeper2), new Path("/tmp/dummyFile"), Resource(0, 0, 0), 3, null, "dummyApplicationName4") + result.name shouldBe "dummyApplicationName4" + } // "start one" should "not throw exception" in { // val tController = createController()