// This is a simple end to end test that makes sure a master using log
// storage with ZooKeeper can successfully launch a task.
TEST_F(RegistrarZooKeeperTest, TaskRunning)
{
  Try<Owned<cluster::Master>> master = StartMaster();
  ASSERT_SOME(master);

  MockExecutor exec(DEFAULT_EXECUTOR_ID);
  TestContainerizer containerizer(&exec);

  Owned<MasterDetector> detector = master.get()->createDetector();
  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), &containerizer);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched, registered(&driver, _, _));

  Future<vector<Offer>> offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(offers);
  EXPECT_NE(0u, offers->size());

  TaskInfo task = createTask(offers.get()[0], "dummy", DEFAULT_EXECUTOR_ID);

  EXPECT_CALL(exec, registered(_, _, _, _));

  EXPECT_CALL(exec, launchTask(_, _))
    .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));

  Future<Nothing> resourcesUpdated;
  EXPECT_CALL(containerizer,
              update(_, Resources(offers.get()[0].resources())))
    .WillOnce(DoAll(FutureSatisfy(&resourcesUpdated),
                    Return(Nothing())));

  Future<TaskStatus> status;
  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&status));

  driver.launchTasks(offers.get()[0].id(), {task});

  AWAIT_READY(status);
  EXPECT_EQ(TASK_RUNNING, status->state());

  AWAIT_READY(resourcesUpdated);

  EXPECT_CALL(exec, shutdown(_))
    .Times(AtMost(1));

  driver.stop();
  driver.join();
}
// This test verifies that when the scheduler calls stop() before
// abort(), no pending acknowledgements are sent.
TEST_F(MesosSchedulerDriverTest, DropAckIfStopCalledBeforeAbort)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  MockExecutor exec(DEFAULT_EXECUTOR_ID);
  TestContainerizer containerizer(&exec);
  Try<PID<Slave>> slave = StartSlave(&containerizer);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched, registered(&driver, _, _));

  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(LaunchTasks(DEFAULT_EXECUTOR_INFO, 1, 1, 16, "*"))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  // When an update is received, stop the driver and then abort it.
  Future<Nothing> statusUpdate;
  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(DoAll(StopAndAbort(),
                    FutureSatisfy(&statusUpdate)));

  // Ensure no status update acknowledgements are sent from the driver
  // to the master.
  EXPECT_NO_FUTURE_CALLS(
      mesos::scheduler::Call(),
      mesos::scheduler::Call::ACKNOWLEDGE,
      _ ,
      master.get());

  EXPECT_CALL(exec, registered(_, _, _, _));

  EXPECT_CALL(exec, launchTask(_, _))
    .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING));

  EXPECT_CALL(exec, shutdown(_))
    .Times(AtMost(1));

  driver.start();

  AWAIT_READY(statusUpdate);

  // Settle the clock to ensure driver finishes processing the status
  // update and sends acknowledgement if necessary. In this test it
  // shouldn't send an acknowledgement.
  Clock::pause();
  Clock::settle();

  driver.stop();
  driver.join();

  Shutdown();
}
Esempio n. 3
0
TEST_F(test_bootup, get_socket_failure)
{
  InSequence dummy;
  m_addrinfo.ai_next = NULL;
  EXPECT_FUNCTION_CALL(m_getaddrinfo, (_, _, _, _)).WillOnce(DoAll(SetArgPointee<3>(&m_addrinfo), Return(0)));
  EXPECT_FUNCTION_CALL(m_socket, (_, _, _)).WillOnce(Return(-1));
  EXPECT_FUNCTION_CALL(m_freeaddrinfo, (&m_addrinfo));
  EXPECT_EQ(1, server(stderr, stdout, 2000, 0, 32));
}
TEST_F(V4L2ControlDelegateTest, SetSuccess) {
  uint8_t input = 10;
  int32_t conversion_result = 99;
  EXPECT_CALL(*mock_converter_, MetadataToV4L2(input, _))
      .WillOnce(DoAll(SetArgPointee<1>(conversion_result), Return(0)));
  EXPECT_CALL(*mock_device_, SetControl(control_id_, conversion_result, _))
      .WillOnce(Return(0));

  ASSERT_EQ(dut_->SetValue(input), 0);
}
TEST_F(TaggedControlOptionsTest, DefaultValue) {
  uint8_t value = 99;
  int template_id = 3;
  EXPECT_CALL(*mock_options_, DefaultValueForTemplate(template_id, _))
      .WillOnce(DoAll(SetArgPointee<1>(value), Return(0)));
  PrepareDUT();
  uint8_t actual = value + 1;
  EXPECT_EQ(dut_->DefaultValueForTemplate(template_id, &actual), 0);
  EXPECT_EQ(actual, value);
}
TEST_F(V4L2ControlDelegateTest, GetConverterFailure) {
  int32_t device_result = 99;
  EXPECT_CALL(*mock_device_, GetControl(control_id_, _))
      .WillOnce(DoAll(SetArgPointee<1>(device_result), Return(0)));
  int err = -99;
  EXPECT_CALL(*mock_converter_, V4L2ToMetadata(device_result, _))
      .WillOnce(Return(err));

  uint8_t unused = 1;
  ASSERT_EQ(dut_->GetValue(&unused), err);
}
// This test ensures that destroy can be called at the end of the
// launch loop. The composing containerizer still calls the
// underlying containerizer's destroy (because it's not sure
// if the containerizer can handle the type of container being
// launched). If the launch is not supported by any containerizers
// both the launch and destroy futures should be false.
TEST_F(ComposingContainerizerTest, DestroyAfterLaunchLoop)
{
  vector<Containerizer*> containerizers;

  MockContainerizer* mockContainerizer1 = new MockContainerizer();
  containerizers.push_back(mockContainerizer1);

  ComposingContainerizer containerizer(containerizers);
  ContainerID containerId;
  containerId.set_value("container");
  TaskInfo taskInfo;
  ExecutorInfo executorInfo;
  SlaveID slaveId;
  std::map<std::string, std::string> environment;

  Promise<bool> launchPromise;

  EXPECT_CALL(*mockContainerizer1, launch(_, _, _, _, _, _, _, _))
    .WillOnce(Return(launchPromise.future()));

  Future<Nothing> destroy;
  Promise<bool> destroyPromise;
  EXPECT_CALL(*mockContainerizer1, destroy(_))
    .WillOnce(DoAll(FutureSatisfy(&destroy),
                    Return(destroyPromise.future())));

  Future<bool> launched = containerizer.launch(
      containerId,
      taskInfo,
      executorInfo,
      "dir",
      "user",
      slaveId,
      environment,
      false);

  Resources resources = Resources::parse("cpus:1;mem:256").get();

  EXPECT_TRUE(launched.isPending());

  Future<bool> destroyed = containerizer.destroy(containerId);

  // We make sure the destroy is being called on the containerizer.
  AWAIT_READY(destroy);

  launchPromise.set(false);
  destroyPromise.set(false);

  // `launch` should return false and `destroyed` should return false
  // because none of the containerizers support the launch.
  AWAIT_EXPECT_EQ(false, launched);
  AWAIT_EXPECT_EQ(false, destroyed);
}
 void expectPushPromiseAndHeaders(
   MockHTTPTransaction& pushTxn, uint8_t pri,
   HTTPPushTransactionHandler**pushHandlerPtr) {
   EXPECT_CALL(m_txn, newPushedTransaction(_))
     .WillOnce(DoAll(SaveArg<0>(pushHandlerPtr),
                     Return(&pushTxn)));
   EXPECT_CALL(pushTxn, sendHeaders(_))
     .WillOnce(Invoke([pri] (const HTTPMessage& promise) {
           EXPECT_TRUE(promise.isRequest());
           EXPECT_EQ(promise.getPriority(), pri);
           EXPECT_EQ(promise.getHeaders().getSingleOrEmpty("hello"),
                     std::string("world"));
         }))
     .WillOnce(Invoke([] (const HTTPMessage& response) {
           EXPECT_TRUE(response.isResponse());
         }));
 }
// Tests that an agent endpoint handler forms
// correct queries against the authorizer.
TEST_P(SlaveEndpointTest, AuthorizedRequest)
{
  const string endpoint = GetParam();

  StandaloneMasterDetector detector;

  MockAuthorizer mockAuthorizer;

  Try<Owned<cluster::Slave>> agent = StartSlave(&detector, &mockAuthorizer);
  ASSERT_SOME(agent);

  Future<authorization::Request> request;
  EXPECT_CALL(mockAuthorizer, authorized(_))
    .WillOnce(DoAll(FutureArg<0>(&request),
                    Return(true)));

  Future<Response> response = http::get(
      agent.get()->pid,
      endpoint,
      None(),
      createBasicAuthHeaders(DEFAULT_CREDENTIAL));

  AWAIT_READY(request);

  const string principal = DEFAULT_CREDENTIAL.principal();
  EXPECT_EQ(principal, request.get().subject().value());

  // TODO(bbannier): Once agent endpoint handlers use more than just
  // `GET_ENDPOINT_WITH_PATH` we should factor out the request method
  // and expected authorization action and parameterize
  // `SlaveEndpointTest` on that as well in addition to the endpoint.
  EXPECT_EQ(authorization::GET_ENDPOINT_WITH_PATH, request.get().action());

  EXPECT_EQ("/" + endpoint, request.get().object().value());

  AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response)
    << response.get().body;
}
Esempio n. 10
0
// This test has been temporarily disabled due to MESOS-1257.
TEST_F(ExternalContainerizerTest, DISABLED_Launch)
{
  Try<PID<Master> > master = this->StartMaster();
  ASSERT_SOME(master);

  Flags testFlags;

  slave::Flags flags = this->CreateSlaveFlags();

  flags.isolation = "external";
  flags.containerizer_path =
    testFlags.build_dir + "/src/examples/python/test-containerizer";

  MockExternalContainerizer containerizer(flags);

  Try<PID<Slave> > slave = this->StartSlave(&containerizer, flags);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));

  Future<vector<Offer> > offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(frameworkId);
  AWAIT_READY(offers);

  EXPECT_NE(0u, offers.get().size());

  TaskInfo task;
  task.set_name("isolator_test");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->CopyFrom(offers.get()[0].slave_id());
  task.mutable_resources()->CopyFrom(offers.get()[0].resources());

  Resources resources(offers.get()[0].resources());
  Option<Bytes> mem = resources.mem();
  ASSERT_SOME(mem);
  Option<double> cpus = resources.cpus();
  ASSERT_SOME(cpus);

  const std::string& file = path::join(flags.work_dir, "ready");

  // This task induces user/system load in a child process by
  // running top in a child process for ten seconds.
  task.mutable_command()->set_value(
#ifdef __APPLE__
      // Use logging mode with 30,000 samples with no interval.
      "top -l 30000 -s 0 2>&1 > /dev/null & "
#else
      // Batch mode, with 30,000 samples with no interval.
      "top -b -d 0 -n 30000 2>&1 > /dev/null & "
#endif
      "touch " + file +  "; " // Signals that the top command is running.
      "sleep 60");

  Future<TaskStatus> status;
  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&status))
    .WillRepeatedly(Return()); // Ignore rest for now.

  Future<ContainerID> containerId;
  EXPECT_CALL(containerizer, launch(_, _, _, _, _, _, _, _))
    .WillOnce(DoAll(FutureArg<0>(&containerId),
                    Invoke(&containerizer,
                           &MockExternalContainerizer::_launch)));

  driver.launchTasks(offers.get()[0].id(), {task});

  AWAIT_READY(containerId);

  AWAIT_READY(status);

  EXPECT_EQ(TASK_RUNNING, status.get().state());

  // Wait for the task to begin inducing cpu time.
  while (!os::exists(file));

  ExecutorID executorId;
  executorId.set_value(task.task_id().value());

  // We'll wait up to 10 seconds for the child process to induce
  // 1/8 of a second of user and system cpu time in total.
  // TODO(bmahler): Also induce rss memory consumption, by re-using
  // the balloon framework.
  ResourceStatistics statistics;
  Duration waited = Duration::zero();
  do {
    Future<ResourceStatistics> usage = containerizer.usage(containerId.get());
    AWAIT_READY(usage);

    statistics = usage.get();

    // If we meet our usage expectations, we're done!
    // NOTE: We are currently getting dummy-data from the test-
    // containerizer python script matching these expectations.
    // TODO(tillt): Consider working with real data.
    if (statistics.cpus_user_time_secs() >= 0.120 &&
        statistics.cpus_system_time_secs() >= 0.05 &&
        statistics.mem_rss_bytes() >= 1024u) {
      break;
    }

    os::sleep(Milliseconds(100));
    waited += Milliseconds(100);
  } while (waited < Seconds(10));

  EXPECT_GE(statistics.cpus_user_time_secs(), 0.120);
  EXPECT_GE(statistics.cpus_system_time_secs(), 0.05);
  EXPECT_EQ(statistics.cpus_limit(), cpus.get());
  EXPECT_GE(statistics.mem_rss_bytes(), 1024u);
  EXPECT_EQ(statistics.mem_limit_bytes(), mem.get().bytes());

  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&status));

  driver.killTask(task.task_id());

  AWAIT_READY(status);

  EXPECT_EQ(TASK_KILLED, status.get().state());

  driver.stop();
  driver.join();

  this->Shutdown();
}
// This test ensures that destroy can be called while in the
// launch loop. The composing containerizer still calls the
// underlying containerizer's destroy (because it's not sure
// if the containerizer can handle the type of container being
// launched). If the launch is not supported by the 1st containerizer,
// the composing containerizer should stop the launch loop and
// set the value of destroy future to true.
TEST_F(ComposingContainerizerTest, DestroyDuringUnsupportedLaunchLoop)
{
  vector<Containerizer*> containerizers;

  MockContainerizer* mockContainerizer1 = new MockContainerizer();
  MockContainerizer* mockContainerizer2 = new MockContainerizer();

  containerizers.push_back(mockContainerizer1);
  containerizers.push_back(mockContainerizer2);

  ComposingContainerizer containerizer(containerizers);
  ContainerID containerId;
  containerId.set_value("container");
  TaskInfo taskInfo;
  ExecutorInfo executorInfo;
  SlaveID slaveId;
  std::map<std::string, std::string> environment;

  Promise<bool> launchPromise;

  EXPECT_CALL(*mockContainerizer1, launch(_, _, _, _, _, _, _, _))
    .WillOnce(Return(launchPromise.future()));

  Future<Nothing> destroy;
  Promise<bool> destroyPromise;
  EXPECT_CALL(*mockContainerizer1, destroy(_))
    .WillOnce(DoAll(FutureSatisfy(&destroy),
                    Return(destroyPromise.future())));

  Future<bool> launched = containerizer.launch(
      containerId,
      taskInfo,
      executorInfo,
      "dir",
      "user",
      slaveId,
      environment,
      false);

  Resources resources = Resources::parse("cpus:1;mem:256").get();

  EXPECT_TRUE(launched.isPending());

  Future<bool> destroyed = containerizer.destroy(containerId);

  EXPECT_CALL(*mockContainerizer2, launch(_, _, _, _, _, _, _, _))
    .Times(0);

  // We make sure the destroy is being called on the first containerizer.
  // The second containerizer shouldn't be called as well since the
  // container is already destroyed.
  AWAIT_READY(destroy);

  launchPromise.set(false);
  destroyPromise.set(false);

  // `launched` should be a failure and `destroyed` should be true
  // because the launch was stopped from being tried on the 2nd
  // containerizer because of the destroy.
  AWAIT_FAILED(launched);
  AWAIT_EXPECT_EQ(true, destroyed);
}
Esempio n. 12
0
/*----------------------------------------------------------------------------------------------
	Crawl through the database and rename/delete the given styles.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FwDbMergeStyles::Process(DWORD hWnd)
{
	BEGIN_COM_METHOD;
	Assert(m_vstuOldNames.Size() == m_vstuNewNames.Size());

	if (!m_hvoRoot)
		return E_UNEXPECTED;
	if (!m_pclsidApp)
		return E_UNEXPECTED;

	if (LogFile())
	{
		ULONG cbLog;
		StrAnsi staLog;
		staLog.Format("Changing style names in %S (%S)%n",
			DbName().Chars(), ServerName().Chars());
		LogFile()->Write(staLog.Chars(), staLog.Length(), &cbLog);
	}

	m_qprog->DoModeless((HWND)hWnd);
	StrUni stuMsg(kstidChgStyleLabel);
	m_qprog->put_Title(stuMsg.Bstr());

	ResetConnection();
	BeginTrans();
	CreateCommand();

	SetPercentComplete(0);

	// We want to affect only a subset of the formatting and style information in the database,
	// based on which program is currently running, since different programs may be using
	// different sets of styles.  This information is derived from m_hvoRoot and m_pclsidApp.
	// (Unfortunately, there's no way to derive one of these values from the other one.)  The
	// current scheme works for Data Notebook, List Editor, TE, and LexText.  Additional
	// programs may introduce even more complexities.
	// 1. Find all the owners of StStyle objects.  This should match up to LangProject (Data
	//    Notebook and List Editor), Scripture (TE), or LexDb (LexText).
	// 2. If an owner equals m_hvoRoot, then only those objects owned by m_hvoRoot have the
	//    string and paragraph formatting fixed.  Except that LexText also wants to fix all the
	//    Text objects owned by the LangProject in addition to all the objects owned by the
	//    LexDb, so those have to be added to the collection of objects.
	// 3. If none of the owners equals m_hvoRoot, we must be dealing with Data Notebook or List
	//    Editor, which share a common set of styles owned by the LangProject itself.  In
	//    this case, we want all the objects owned by the LangProject except those owned by
	//    another owner of styles (or the LangProject Text objects, since those use the
	//    LexText styles even though they're not owned by the root object).  (This isn't quite
	//    right if either TE or LexText does not actually own any styles yet, but we won't worry
	//    about this nicety.)
	// 4. After creating a temp table containing just the ids of those objects of interest, we
	//    can then process all the relevant string formatting (via a string crawler) and
	//    paragraph StyleRules (later in this method)
	// 5. Finally, we may need to fix the Style fields of the relevant UserViewField objects.
	//    These are limited by the psclsidApp argument, since the UserView objects are specific
	//    to specific applications.  If pssclidApp indicates either Data Notebook or List
	//    Editor, then UserViewField objects belonging to both of those programs are fixed.
	//    Otherwise, only those UserViewField objects belonging to the specific program
	//    identified by psclsidApp are fixed.

	ComBool fMoreRows;
	UINT cbSpaceTaken;
	ComBool fIsNull;
	int hobj = 0;
	int clid = 0;
	bool fFixOwned = false;
	int clidOwned = 0;
	int hvoLangProj = 0;
	Vector<int> vhvoOwners;
	Vector<int> vclidOwners;
	Vector<int> vhvoTexts;
	StrUni stuCmd;
	stuCmd.Format(L"SELECT DISTINCT c.Owner$, co.Class$ "
		L"FROM CmObject c "
		L"JOIN CmObject co on co.Id = c.Owner$ "
		L"WHERE c.Class$ = %d",
		kclidStStyle);
	CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtSelectWithOneRowset));
	CheckHr(GetOleDbCommand()->GetRowset(0));
	CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
	while (fMoreRows)
	{
		CheckHr(GetOleDbCommand()->GetColValue(1, reinterpret_cast <BYTE *>(&hobj),
			isizeof(hobj), &cbSpaceTaken, &fIsNull, 0));
		CheckHr(GetOleDbCommand()->GetColValue(2, reinterpret_cast <BYTE *>(&clid),
			isizeof(clid), &cbSpaceTaken, &fIsNull, 0));
		if (hobj == m_hvoRoot)
		{
			fFixOwned = true;
			clidOwned = clid;
		}
		else if (clid == kclidLangProject)
		{
			hvoLangProj = hobj;
		}
		else
		{
			vhvoOwners.Push(hobj);
			vclidOwners.Push(clid);
		}
		CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
	}
	Assert(hvoLangProj != 0);
// This may not be defined in any of our header files.
#ifndef kclidLexDb
#define kclidLexDb 5005
#endif
	if (!fFixOwned || clidOwned == kclidLexDb)
	{
		// We need the set of LangProject_Texts objects to include or exclude.
		stuCmd.Format(L"SELECT Dst FROM LangProject_Texts WHERE Src = %d", hvoLangProj);
		CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(),
			knSqlStmtSelectWithOneRowset));
		CheckHr(GetOleDbCommand()->GetRowset(0));
		CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
		while (fMoreRows)
		{
			CheckHr(GetOleDbCommand()->GetColValue(1, reinterpret_cast <BYTE *>(&hobj),
				isizeof(hobj), &cbSpaceTaken, &fIsNull, 0));
			vhvoTexts.Push(hobj);
			CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
		}
	}
	// Note that dbo.fnGetOwnedObjects$() returns the root object as the first row.
	stuCmd.Format(L"CREATE TABLE #OwnedObjIdsTbl%n"
		L"(%n"
		L"    ObjId int not null%n"
		L")%n"
		L"CREATE CLUSTERED INDEX #OwnedObjIdsTblObjId ON #OwnedObjIdsTbl ([ObjId])%n");
	CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtNoResults));

	const OLECHAR * kpszDefTableFmt =
		L"INSERT INTO #OwnedObjIdsTbl%n"
		L"SELECT ObjId%n"
		L"FROM dbo.fnGetOwnedObjects$('%d', null, 0, 0, 1, null, 0)";

	if (fFixOwned)
	{
		stuCmd.Format(kpszDefTableFmt, m_hvoRoot);
		stuCmd.FormatAppend(L";%n");
		if (vhvoTexts.Size())
		{
			stuCmd.FormatAppend(
				L"INSERT INTO #OwnedObjIdsTbl%n"
				L"SELECT ObjId%n"
				L"FROM dbo.fnGetOwnedObjects$('");
			for (int ihvo = 0; ihvo < vhvoTexts.Size(); ++ihvo)
				if (ihvo == 0)
					stuCmd.FormatAppend(L"%d", vhvoTexts[ihvo]);
				else
					stuCmd.FormatAppend(L",%d", vhvoTexts[ihvo]);
			stuCmd.FormatAppend(L"', null, 0, 0, 1, null, 0);");
		}
	}
	else
	{
	/*
	POSSIBLE SPEED ENHANCEMENT
	--------------------------
	SELECT co.Id
	FROM CmObject co
	WHERE co.Owner$=1 AND co.OwnFlid$ NOT IN (6001006, 6001014, 6001040)

	gives a list of ids which own what we want to look through.  This could then be
	handled by the following query, which runs in one-half to one-third of the time
	required by the current code.

	SELECT 1 UNION SELECT ObjId FROM dbo.fnGetOwnedObjects$('2,54728', null, 0, 0, 1, null, 0)

	whether the C++ code or the SQL code should put together the XML string is a good
	question.
	*/
		// REVIEW (SteveMiller): The temp tables below just slow things down.

		stuCmd.Clear();
		if (vhvoOwners.Size() || vhvoTexts.Size())
		{
			stuCmd.FormatAppend(L"CREATE TABLE #tblUnwanted ( ObjId int not null );%n");
			stuCmd.FormatAppend(L"INSERT INTO #tblUnwanted%n");
			stuCmd.FormatAppend(L"SELECT ObjId%n");
			stuCmd.FormatAppend(L"FROM dbo.fnGetOwnedObjects$('");
			for (int ihvo = 0; ihvo < vhvoOwners.Size(); ++ihvo)
				if (ihvo == 0)
					stuCmd.FormatAppend(L"%d", vhvoOwners[ihvo]);
				else
					stuCmd.FormatAppend(L",%d", vhvoOwners[ihvo]);
			for (int ihvo = 0; ihvo < vhvoTexts.Size(); ++ihvo)
				if (vhvoOwners.Size() < 0)
					// I don't think we can have an ownerless text, but hey...
					stuCmd.FormatAppend(L"%d", vhvoTexts[ihvo]);
				else
					stuCmd.FormatAppend(L",%d", vhvoTexts[ihvo]);
			stuCmd.FormatAppend(L"',null,0,0,1,null,0);%n");
		}
		stuCmd.FormatAppend(kpszDefTableFmt, hvoLangProj);
		if (vhvoOwners.Size() || vhvoTexts.Size())
		{
			stuCmd.FormatAppend(L"WHERE ObjId NOT IN (SELECT ObjId FROM #tblUnwanted);%n");
			stuCmd.FormatAppend(L"DROP TABLE #tblUnwanted");
		}
		stuCmd.FormatAppend(L";%n");	// terminate for Firebird
	}
	CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtNoResults));

	// Do the standard stuff for monolingual and multilingual strings.
	DoAll(kstidChgStylePhaseOne, kstidChgStylePhaseTwo,
		false,	// don't create a new transaction--this method handles it
		L"#OwnedObjIdsTbl");

	// Fix all the StyleRules of instances of StPara.
	stuMsg.Load(kstidChgStylePhaseThree);
	m_qprog->put_Message(stuMsg.Bstr());

	int nPercent = 0;
	SetPercentComplete(nPercent);

	Vector<int> vhobjFix;
	Vector<Vector<byte> > vvbFmtFix;
	vhobjFix.Clear();
	vvbFmtFix.Clear();

	Vector<byte> vbFmt;
	int cbFmt;

	ITsPropsFactoryPtr qtpf;
	qtpf.CreateInstance(CLSID_TsPropsFactory);

	int cRows;
	StrUni stuCmdCnt;
	stuCmdCnt.Format(L"SELECT COUNT(*) FROM StPara a%n"
		L"JOIN #OwnedObjIdsTbl b on b.ObjId = a.Id%n"
		L"WHERE a.StyleRules IS NOT NULL",
		m_hvoRoot);
	CheckHr(GetOleDbCommand()->ExecCommand(stuCmdCnt.Bstr(),
		knSqlStmtSelectWithOneRowset));
	CheckHr(GetOleDbCommand()->GetRowset(0));
	CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
	CheckHr(GetOleDbCommand()->GetColValue(1, reinterpret_cast <BYTE *>(&cRows),
		isizeof(hobj), &cbSpaceTaken, &fIsNull, 0));

	stuCmd.Format(L"SELECT a.Id, a.StyleRules FROM StPara a%n"
		L"JOIN #OwnedObjIdsTbl b on b.ObjId = a.Id%n"
		L"WHERE a.StyleRules IS NOT NULL",
		m_hvoRoot);
	CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtSelectWithOneRowset));
	CheckHr(GetOleDbCommand()->GetRowset(0));
	CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
	int iRow = 0;
	ComVector<ITsTextProps> vqttp;
	vqttp.Resize(1);
	while (fMoreRows)
	{
		CheckHr(GetOleDbCommand()->GetColValue(1, reinterpret_cast <BYTE *>(&hobj),
			isizeof(hobj), &cbSpaceTaken, &fIsNull, 0));
		CheckHr(GetOleDbCommand()->GetColValue(2,
			reinterpret_cast <BYTE *>(vbFmt.Begin()), vbFmt.Size(), &cbSpaceTaken, &fIsNull,
			0));
		cbFmt = cbSpaceTaken;
		if (cbFmt >= vbFmt.Size())
		{
			vbFmt.Resize(cbFmt + 1);
			CheckHr(GetOleDbCommand()->GetColValue(2,
				reinterpret_cast <BYTE *>(vbFmt.Begin()),
				vbFmt.Size(), &cbSpaceTaken, &fIsNull, 0));
			cbFmt = cbSpaceTaken;
		}
		vbFmt.Resize(cbFmt);

		ITsTextPropsPtr qttp;
		bool fModify = false;
		int cb = vbFmt.Size();
		CheckHr(qtpf->DeserializePropsRgb(vbFmt.Begin(), &cb, (ITsTextProps **)&qttp));

		// use a vector with exactly 1 item
		vqttp[0] = qttp;
		// Note: using "Normal" doesn't work all the time. For more complex scenarios where the
		// default style depends on the context of the deleted style, a replace should be done
		// instead of a delete. See FwStylesDlg.DeleteAndRenameStylesInDB() in FwStylesDlg.cs.
		fModify = ProcessFormatting(vqttp, g_pszwStyleNormal);
		if (fModify)
		{
			vhobjFix.Push(hobj);
			int cbNeeded;
			HRESULT hr;
			CheckHr(hr = vqttp[0]->SerializeRgb(vbFmt.Begin(), vbFmt.Size(), &cbNeeded));
			if (hr == S_FALSE)
			{
				vbFmt.Resize(cbNeeded);
				hr = vqttp[0]->SerializeRgb(vbFmt.Begin(), vbFmt.Size(), &cbNeeded);
			}
			vbFmt.Resize(cbNeeded);
			vvbFmtFix.Push(vbFmt);
		}
		CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));

		iRow++;
		SetPercentComplete((iRow * 50) / cRows);
	}
	int ceFix = vhobjFix.Size();
	SetPercentComplete(50);
	for (int ieFix = 0; ieFix < ceFix; ++ieFix)
	{
		stuCmd.Format(L"UPDATE StPara SET StyleRules=? WHERE [Id] = %d", vhobjFix[ieFix]);
		// Set the parameter and execute the command.
		CheckHr(GetOleDbCommand()->SetParameter(1, DBPARAMFLAGS_ISINPUT, NULL,
			DBTYPE_BYTES, reinterpret_cast<BYTE *>(vvbFmtFix[ieFix].Begin()),
			vvbFmtFix[ieFix].Size()));
		CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtNoResults));

		SetPercentComplete(50 + ((ieFix * 50) / ceFix));
	}
	SetPercentComplete(100);

	stuCmd.Assign(L"DROP TABLE #OwnedObjIdsTbl");
	CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtNoResults));

	// Fix style names in the view specs.
	// SQL gives us the power to just rename all items in one query. But that
	// won't correctly handle the situation of, for instance, renaming A to B, B to C, and
	// C to A. So we fix one item at a time and then update the database.

	static const GUID clsidNotebook =	// {39886581-4DD5-11D4-8078-0000C0FB81B5}
		{ 0x39886581, 0x4DD5, 0x11D4, { 0x80, 0x78, 0x00, 0x00, 0xC0, 0xFB, 0x81, 0xB5 } };
	static GUID clsidListEditor =	// {5EA62D01-7A78-11D4-8078-0000C0FB81B5}
		{ 0x5EA62D01, 0x7A78, 0x11D4, { 0x80, 0x78, 0x00, 0x00, 0xC0, 0xFB, 0x81, 0xB5 } };

	StrUni stuBaseCmd;
	stuBaseCmd.Format(L"%nFROM UserViewField a%n"
		L"JOIN UserViewRec_Fields uf on uf.Dst = a.Id%n"
		L"JOIN UserView_Records ur on ur.Dst = uf.Src%n"
		L"JOIN UserView uv on uv.Id = ur.Src%n"
		L"WHERE a.Style IS NOT NULL AND");
	if (*m_pclsidApp == clsidNotebook || *m_pclsidApp == clsidListEditor)
	{
		Assert(!fFixOwned);
		stuBaseCmd.FormatAppend(L"%n\tuv.App in ('%g','%g')", &clsidNotebook, &clsidListEditor);
	}
	else
	{
		Assert(fFixOwned);
		stuBaseCmd.FormatAppend(L" uv.App = '%g'", m_pclsidApp);
	}
	stuMsg.Load(kstidChgStylePhaseFour);
	m_qprog->put_Message(stuMsg.Bstr());
	SetPercentComplete(0);

	OLECHAR rgch[1024];
	vhobjFix.Clear();
	Vector<StrUni> vstuFix;

	stuCmdCnt.Format(L"SELECT COUNT(*)%s", stuBaseCmd.Chars());
	CheckHr(GetOleDbCommand()->ExecCommand(stuCmdCnt.Bstr(),
		knSqlStmtSelectWithOneRowset));
	CheckHr(GetOleDbCommand()->GetRowset(0));
	CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
	CheckHr(GetOleDbCommand()->GetColValue(1, reinterpret_cast <BYTE *>(&cRows),
		isizeof(hobj), &cbSpaceTaken, &fIsNull, 0));

	stuCmd.Format(L"SELECT a.Id, a.Style%s", stuBaseCmd.Chars());

	CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtSelectWithOneRowset));
	CheckHr(GetOleDbCommand()->GetRowset(0));
	CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));
	iRow = 0;
	while (fMoreRows)
	{
		CheckHr(GetOleDbCommand()->GetColValue(1, reinterpret_cast <BYTE *>(&hobj),
			isizeof(hobj), &cbSpaceTaken, &fIsNull, 0));
		CheckHr(GetOleDbCommand()->GetColValue(2, reinterpret_cast <BYTE *>(*&rgch),
			isizeof(rgch), &cbSpaceTaken, &fIsNull, 0));
		int cchw = cbSpaceTaken / isizeof(OLECHAR);

		StrUni stuOld(rgch, cchw);
		StrUni stuNew;
		if (Delete(stuOld))
		{
			vstuFix.Push(L"");
			vhobjFix.Push(hobj);
		}
		else if (Rename(stuOld, stuNew))
		{
			vstuFix.Push(stuNew);
			vhobjFix.Push(hobj);
		}

		CheckHr(GetOleDbCommand()->NextRow(&fMoreRows));

		iRow++;
		SetPercentComplete((iRow * 50) / cRows);
	}
	SetPercentComplete(50);
	Assert(vhobjFix.Size() == vstuFix.Size());

	ceFix = vstuFix.Size();
	for (int ieFix = 0; ieFix < ceFix; ieFix++)
	{
		if (vstuFix[ieFix] == L"")
		{
			stuCmd.Format(L"UPDATE UserViewField SET Style = NULL where [Id] = '%d'",
				vhobjFix[ieFix]);
		}
		else
		{
			StrUtil::NormalizeStrUni(vstuFix[ieFix], UNORM_NFD);
			stuCmd.Format(L"UPDATE UserViewField SET Style = '%s' where [Id] = '%d'",
				vstuFix[ieFix].Chars(), vhobjFix[ieFix]);
		}
		CheckHr(GetOleDbCommand()->ExecCommand(stuCmd.Bstr(), knSqlStmtNoResults));

		SetPercentComplete(50 + ((ieFix * 50) / ceFix));
	}

	SetPercentComplete(100);
	CommitTrans();
	Terminate(m_hvoRoot);

	if (m_qprog)
		m_qprog->DestroyHwnd();
	END_COM_METHOD(g_fact, IID_IFwDbMergeStyles);
}
Esempio n. 13
0
// This test verifies that the slave run task label decorator can add
// and remove labels from a task during the launch sequence. A task
// with two labels ("foo":"bar" and "bar":"baz") is launched and will
// get modified by the slave hook to strip the "foo":"bar" pair and
// add a new "baz":"qux" pair.
TEST_F(HookTest, VerifySlaveRunTaskHook)
{
  Try<PID<Master>> master = StartMaster();
  ASSERT_SOME(master);

  MockExecutor exec(DEFAULT_EXECUTOR_ID);

  TestContainerizer containerizer(&exec);

  Try<PID<Slave>> slave = StartSlave(&containerizer);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
      &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  EXPECT_CALL(sched, registered(&driver, _, _));

  Future<vector<Offer>> offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(offers);
  ASSERT_EQ(1u, offers.get().size());

  TaskInfo task;
  task.set_name("");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->CopyFrom(offers.get()[0].slave_id());
  task.mutable_resources()->CopyFrom(offers.get()[0].resources());
  task.mutable_executor()->CopyFrom(DEFAULT_EXECUTOR_INFO);

  // Add two labels: (1) will be removed by the hook to ensure that
  // runTaskHook can remove labels (2) will be preserved to ensure
  // that the framework can add labels to the task and have those be
  // available by the end of the launch task sequence when hooks are
  // used (to protect against hooks removing labels completely).
  Labels* labels = task.mutable_labels();
  Label* label1 = labels->add_labels();
  label1->set_key("foo");
  label1->set_value("bar");

  Label* label2 = labels->add_labels();
  label2->set_key("bar");
  label2->set_value("baz");

  vector<TaskInfo> tasks;
  tasks.push_back(task);

  EXPECT_CALL(exec, registered(_, _, _, _));

  Future<TaskInfo> taskInfo;
  EXPECT_CALL(exec, launchTask(_, _))
    .WillOnce(DoAll(
        FutureArg<1>(&taskInfo),
        SendStatusUpdateFromTask(TASK_RUNNING)));

  driver.launchTasks(offers.get()[0].id(), tasks);

  AWAIT_READY(taskInfo);

  // The master hook will hang an extra label off.
  const Labels& labels_ = taskInfo.get().labels();

  ASSERT_EQ(3, labels_.labels_size());

  // The slave run task hook will prepend a new "baz":"qux" label.
  EXPECT_EQ(labels_.labels(0).key(), "baz");
  EXPECT_EQ(labels_.labels(0).value(), "qux");

  // Master launch task hook will still hang off test label.
  EXPECT_EQ(labels_.labels(1).key(), testLabelKey);
  EXPECT_EQ(labels_.labels(1).value(), testLabelValue);

  // And lastly, we only expect the "foo":"bar" pair to be stripped by
  // the module. The last pair should be the original "bar":"baz"
  // pair set by the test.
  EXPECT_EQ(labels_.labels(2).key(), "bar");
  EXPECT_EQ(labels_.labels(2).value(), "baz");

  driver.stop();
  driver.join();

  Shutdown(); // Must shutdown before 'containerizer' gets deallocated.
}